Skip to content

go-code-reviewer Skill 解析

go-code-reviewer 是一套面向 Go 代码审查的结构化判断框架。它的核心设计思想是:代码审查的重点是稳定地找出真正会造成故障、回归或团队协作成本的问题,并把这些问题按可执行的方式交付出来。 因此它把缺陷优先、强制门禁、参考资料按需加载、来源分类和残余风险放在同一个流程里。

1. 定义

go-code-reviewer 是一个面向 Go 代码和 PR 的缺陷优先审查 skill。它会先确定审查模式和范围,再依据仓库规范、Go 版本、差异边界和风险特征组织审查过程,最后输出一份结构化评审结果。结果不仅包含 findings,还包含已抑制项、执行状态、风险接受 / SLA、残余风险 / 测试缺口和简洁摘要。

2. 背景与问题

这个 skill 要解决的问题是:很多 review 要么太浅,要么太散,要么把历史债务和当前改动混在一起。

在没有明确审查框架时,常见问题通常集中在 6 类:

问题 典型后果
代码审查过于依赖个人经验 同类问题在不同审查者手里标准不一致
审查范围失控 明明只改了一个接口,却把整份文件从头到尾审一遍,噪音很多
误报太多 开发者分不清哪些是真缺陷,哪些只是 reviewer 的个人偏好
历史问题和本次改动混在一起 作者被不是自己引入的问题阻塞,PR 难以推进
审查深度和风险不匹配 小改动被过度审查,高风险改动反而审得不够深
输出不成体系 只有零散评论,没有严重性、证据、建议动作和后续时限

go-code-reviewer 的设计逻辑,就是把这些常见失真点拆成明确步骤:先校准审查模式,再限定边界,再收集证据,再给出有分级、有来源、有处理建议的结果。

3. 与常见替代方案的对比

在展开设计细节之前,先看它和几种常见做法的差别:

维度 go-code-reviewer skill 通用大模型直接 review 只跑 lint / test
缺陷优先
审查深度按风险调节
误报抑制
历史债务与当前改动区分
差异影响范围扩展
领域知识按需加载
输出可执行性
团队协作友好度

它并不是要替代 golangci-lintgo vetgo test,而是把这些工具发现的信号、代码上下文、项目规范和审查者判断组织成一套更适合团队使用的审查结果。

4. 核心设计逻辑

4.1 采用 defect-first vs 风格优先

go-code-reviewer 从一开始就把目标写得很清楚:review 的重点是真实缺陷、回归风险和项目规范偏离,而不是泛泛而谈代码风格。

这背后有两个判断:

  1. 在真实工程里,最贵的问题通常不是命名是否优雅,而是竞态、资源泄露、兼容性破坏、错误处理失真、数据库或 API 行为出错。
  2. 如果 review 总被低价值风格评论淹没,开发者会逐渐把 review 当成噪音,真正高风险的问题反而不容易被认真对待。

所以这个 skill 的出发点不是"尽量多提意见",而是"优先找出最应该修的问题"。

4.2 先选审查模式

go-code-reviewer 在正式审查前先选 LiteStandardStrict 三种模式,并要求在结果里写明模式和选择理由。

这样设计,是为了把审查深度和风险等级对齐:

模式 适用场景 设计目的
Lite 小范围、低风险变更 快速筛出高置信度问题,避免把小改动审成大工程
Standard 大多数日常 PR 在深度、速度和成本之间保持平衡
Strict 安全、并发、公共 API、大范围重构等高风险变更 主动扩大影响半径,执行更严格的验证和报告要求

如果没有这一步,审查很容易出现两种失真:简单改动被过度放大,复杂改动却只得到表层点评。模式选择机制本质上是在解决"审查资源该花在哪里"的问题。

4.3 把执行完整性放在第一道门禁

第一道强制审查门禁是执行真实性门禁,要求:没跑过的验证不能装作跑过

这个门禁看起来朴素,但非常关键。很多 review 最大的问题不是判断错,而是把没验证过的东西写成了像验证过一样的语气。比如:

  • 没跑 go test,却暗示"测试看起来没问题"。
  • 没跑 go test -race,却给人一种并发安全已经确认过的印象。
  • 没有工具环境,却写出像是 lint 全部通过的结论。

这个门禁的价值在于:

  • 把"推测"和"已验证"严格分开。
  • 让结果的可信度有清晰边界。
  • 避免团队把一份语言上很笃定、实际上证据不足的 review 当成事实。

换句话说,这个 skill 先保护结论的可信度,再讨论结论本身。

4.4 保留 baseline 对比

第二道强制审查门禁是基线对比门禁。它要求在有历史上下文时,把每个 finding 标成 newregressedunchangedresolved;如果没有基线,也必须明确写出 Baseline not found

这条规则的重要性经常被低估,因为很多 review 默认只回答一个问题:"这里有没有问题?" 但对团队来说,往往还需要回答另外两个问题:

  • 这个问题是新引入的,还是以前就有?
  • 和上一次 review 相比,当前状态是在变好、变坏,还是没有变化?

加入 baseline 对比后,review 的信息密度会明显提高:

  • new 说明这是本次改动新带来的问题。
  • regressed 说明某个曾经解决或受控的问题又回来了。
  • unchanged 说明已知问题仍然存在,但状态没有变化。
  • resolved 则能帮助团队确认某些历史问题已经真正被消掉。

它的作用不是让输出更复杂,而是让团队能把一次 review 放回连续的工程历史里理解,而不是把每次审查都当作彼此割裂的单次快照。

4.5 把误报抑制做成强制门禁

第三道强制审查门禁是误报抑制门禁。它要求审查者在报告 finding 之前,先判断风险是否已经被上游 guard、中间件、调用路径限制或运行时保证挡住了。

这是 go-code-reviewer 最关键的设计之一,因为它直接决定了审查结果有没有信噪比。

评估报告已经证明了这一点:在 4 个微妙场景里,with-skill 的误报率是 0/19,without-skill 大约是 5/32,信噪比从 53% 提升到 89%。这说明它的价值并不只是"结构更整齐",而是同样能发现真实问题,但能少报很多没必要报的东西

这种设计解决的是两个常见问题:

  • 没有抑制机制,review 会塞满"理论上可能出问题"但上下文里其实不会出问题的评论。
  • 没有抑制说明,读者无法区分"刻意不报"和"没看出来"。

因此它不只是要求 suppress,还要求把 suppress 放进 Suppressed Items,并写清理由。这样团队知道哪些问题被过滤掉了,以及为什么过滤。

4.6 设置 Risk Acceptance 和 SLA 门禁

第四道强制审查门禁要求:对于每一条未解决的 finding,审查结果必须给出推荐的处理时限(SLA);如果选择暂时不修,还必须附上结构化的风险接受记录。

这个门禁解决的是大多数代码审查流程里一个很实际的漏洞:finding 被写进评论,作者点了确认,然后什么也没记下来——没有截止时间,没有责任人,问题慢慢从视野里消失。

SLA 的设计非常简洁:

  • High:3 个工作日内完成修复或有力缓解措施
  • Medium:14 个自然日内处理
  • Low:下一轮计划迭代时处理

Risk acceptance 记录包含责任人、理由、补偿性控制措施和复审到期日。这不是繁文缛节,而是为了让"暂时不修"成为一个可见的、有人负责的决定,而不是一个悄悄溜走的口头承诺。当团队决定暂时不处理某个问题,这个决定应当:

  • 明确说明,并写清理由
  • 指定责任人
  • 设定复审时间,以免无限期搁置

没有这个门禁,"之后再修"就是一句不留痕迹的口头表态。有了它,同一个决定变成了一条可以追踪、可以跟进的团队义务。

4.7 维护一份 Anti-examples 列表

go-code-reviewer 在 证据 Rules 里内置了一份明确的 anti-examples 清单,列出了那些看起来像风险、但经过仔细分析后不应该报出来的模式。在 finding 进入输出之前,会先检查这份清单。

引入 anti-examples 的原因,是一类特定的失误:reviewer(包括模型)完全理解某个模式在理论上的风险,却忽略了让这个模式在实际场景里安全的上下文信号。例如:

  • 对一个只在单一 goroutine 里访问的 map 报竞态条件。
  • 对一个只有不到 16 个元素的切片警告缺少预分配。
  • 向一个 go.mod 里 Go 版本为 1.20 的项目推荐 slog
  • 对只读文件的 defer f.Close() 忽略错误发出警告。

这些误报不是因为 reviewer 不懂 Go,而是因为规则被套用时没有核查是否符合具体上下文。

通过把这些模式显式地编成清单,skill 在所有 reviewer 之间建立了一个共享的校准基准。对于"为什么在同一个包里直接用 == 比较哨兵错误是可以接受的"、"为什么对只读文件忽略 Close 错误不是缺陷",reviewer 不需要每次都从第一原理重新推导。anti-examples 把这些制度知识直接编进了 skill 里。

这也是为什么 anti-examples 列表会随时间增长:每一条记录都代表一类在真实 review 中出现过、经过评估后大家认同应该过滤掉的误报。它不是一张静态清单,而是从实际使用中积累下来的经验记录。

4.8 引入 Go 版本门禁

Go 生态迭代很快,但项目的最小 Go 版本并不总是最新。go-code-reviewer 专门设置了 Go 版本门禁,要求先读 go.mod,再决定哪些建议是合法的。

这个门禁解决的是"好建议放错项目"的问题。比如:

  • 对 Go 1.20 项目推荐 slog,其实不成立。
  • 对 Go 1.18 之前的项目推荐 typed atomics,也不成立。
  • 对旧版本项目要求用更高版本才有的语法或库,最终只会制造无效评论。

这个设计的重点不是展示 reviewer 懂多少新特性,而是确保建议能在当前项目里真正落地。

4.9 排除生成代码

生成代码排除门禁明确要求把 *.pb.go*_gen.go、mock 文件和带有 Code generated ... DO NOT EDIT 头的文件排除出 finding 范围。

原因很简单:生成文件通常不是修复缺陷的正确入口。直接对生成代码提 review comment,往往既不能解决问题,也容易误导作者去改不该手改的内容。

这条规则的价值在于:

  • 把审查注意力放回真正可维护的源头文件。
  • 避免审查者在噪音很多的生成文件里浪费精力。
  • 让"该去看生成器配置还是模板"这个判断变得清晰。

4.10 一定要按触发条件加载参考资料

参考资料加载门禁要求:一旦代码命中了并发、安全、数据库、HTTP、测试质量等触发条件,必须先加载对应的 references/*.md,再进行该类判断。

这不是普通的"有空可以看看",而是一个硬性约束。这样设计,是因为很多 Go 审查的失误,不是审查者完全不懂,而是少了一层特定领域的检查框架。例如:

  • 审查 gRPC + 数据库链路时,少看 deadline 传递、metadata 透传、连接池配置。
  • 审查并发代码时,只盯住 mutex,忽略 goroutine 生命周期、取消路径和错误聚合。
  • 审查测试时,只看有没有测试,没看边界条件、失败路径和断言完整性。

评估报告里 Eval 7 是一个很典型的例子:with-skill 借助 reference loading 正确抑制了 err == sql.ErrNoRows 这种灰区问题,同时把真正的 gRPC / DB 领域缺陷完整抓出来;without-skill 则多报了 4 条噪音意见。

4.11 做影响半径扩展,但又严格控制边界

这个 skill 在 diff review 时不会只盯着 patch 本身,而是会主动追踪接口实现者、跨包调用方、结构体构造点和使用点,把这些加入审查范围。这是它很强的一点。

但它又同时设置了 Diff-boundary rule:对于不在 diff 里的 impact-radius 文件,只看受当前改动影响的函数和路径,不顺手把整份文件审成一次历史债务大扫除。

这两个设计必须一起看,缺一不可:

设计 解决的问题
影响半径扩展 防止只看改动行,漏掉接口变更、签名变更、结构体字段变更带来的连锁影响
差异边界限制 防止 reviewer 借机把整个文件的旧问题都翻出来,制造大量与本次改动无关的噪音

这也是为什么它在 Eval 8 里表现非常突出:with-skill 输出是"4 个要修的问题 + 4 条已知历史债务记录",without-skill 则是"10 个问题混在一起"。前者更适合开发者处理,也更适合团队决策。

4.12 区分 introduced / pre-existing / uncertain

Change Origin Classification Gate 要求每个 finding 都标注来源:

  • introduced:本次改动引入或修改出来的问题
  • pre-existing:原本就存在的历史问题
  • uncertain:当前证据不足,暂时无法准确归类

这是整份 skill 最有团队协作意识的一层设计。它解决的核心问题是:不能让开发者为自己没引入的历史债务背锅,但也不能因为不是这次引入的,就把高风险问题当作没看见。

因此它的处理方式不是简单二选一,而是更细:

  • introduced 问题通常应当阻塞合并,或至少要求显式接受风险。
  • pre-existing 问题原则上不阻塞当前 PR,但要保留可见性,并建议后续建 issue 跟踪。
  • uncertain 先按 introduced 处理,允许作者用 git blame 等证据重新归类。

这个机制的意义非常实际:它同时保护了作者、公平性和代码库健康度。

4.13 有 Residual Risk vs 只保留 Findings

很多 review 流程只保留最终 findings,剩下的信息要么丢掉,要么散落在评论里。go-code-reviewer 则专门保留了 Residual Risk / Testing Gaps

这一层解决的是"有价值但不适合放进 findings 的信息怎么办"的问题。主要包括:

  • 因为 volume cap 被挪出去的低优先级问题
  • 不在 diff 中、但确实存在的中低风险历史问题
  • 没跑到的验证项和测试空白
  • 证据还不够完整、但值得提醒的风险点

它的价值在于:既不让主 findings 失焦,也不让已经确认过的风险悄悄消失。

评估报告里 Eval 8 的 4 条 Residual Risk 就很能说明问题。它让 review 结果从"只有阻塞项"升级成了"阻塞项 + 债务台账 + 验证空白",这更接近真实团队需要的输出。

4.14 设置严重性分层和数量上限

工作流程 第 10 步要求对 findings 做合并、排序,并采用按严重性分层的数量上限策略:

  • High 全部保留
  • Medium 在剩余额度内优先保留
  • Low 只有在还有空间时才进入 findings
  • 超出的内容进入 Residual Risk

这个设计不是为了"少报问题",而是为了避免结果失焦。真实 review 里最常见的失败之一,就是把高危问题、一般问题和细枝末节平铺在一个长列表里,导致开发者不知道该先修什么。

这个策略有三个好处:

  • 保证高危问题永不被数量限制吞掉。
  • 让 findings 保持可处理规模,不至于变成一份冗长清单。
  • 通过 merged finding,把同类问题集中表达,而不是在 5 个位置重复讲同一件事。

4.15 严格输出格式

go-code-reviewer 的输出格式要求非常细,包括 Review 模式、Findings、Suppressed Items、Execution Status、Risk Acceptance / SLA、Open Questions、Residual Risk / Testing Gaps、Summary。

这不是形式主义,而是为了让一份 review 结果能够同时服务几类读者:

  • 作者:知道哪些要立刻修,哪些是历史债务,哪些只是提醒
  • 审查者 / 团队:知道结论建立在什么证据之上
  • 维护者:知道哪些验证没跑、哪些风险被暂时接受了
  • 后续流程:知道哪些问题需要建 issue、跟 SLA、做复审

如果没有这些固定栏位,review 结果很容易因为 reviewer 风格不同而质量波动很大。

这套严格格式同样延伸到 No-Finding Case:当没有发现任何可操作的问题时,review 仍然必须输出 Review 模式 声明、Execution Status 和 baseline 汇总。这是刻意为之——一份在没有 finding 时悄悄沉默的 review 是不可审计的。输出一份与其他任何 review 结果形式相同的最小化结构,能够证明:代码经过了审查,标准被执行了,没有发现值得报告的问题。

5. 这个设计解决了哪些具体问题

SKILL.md 和评估报告可以看出,这个 skill 重点解决的是以下几类工程问题:

问题类型 skill 中的对应设计 实际效果
审查深度失衡 Lite / Standard / Strict 模式选择 小改动不被过审,高风险改动不被轻审
证据与结论脱节 执行真实性门禁 没验证的内容不会被写成像是已经验证过
缺少时间维度的判断 Baseline Comparison Gate 团队能分清问题是新增、回归、延续还是已解决
误报过多 误报抑制门禁 + Suppressed Items 保持高信噪比,并让过滤理由可见
未解决的 finding 缺乏时限和责任人 Risk Acceptance and SLA Gate 每条 finding 都有承诺的处理期限;暂缓决定需要记录责任人、理由和复审时间
理论上有风险但实际安全的模式被误报 证据 Rules 中的 Anti-examples 列表 校准基准在 reviewer 之间共享且持续积累,无需每次从第一原理重新推导
建议不适配项目版本 Go 版本门禁 避免给出当前项目无法采用的建议
生成文件干扰审查 生成代码排除门禁 把注意力集中到真正该改的代码
领域判断失准 参考资料加载门禁 审查时自动补足并发、安全、数据库、HTTP 等领域检查框架
只看改动行,漏掉连锁影响 影响半径扩展 能追踪接口、签名和结构体变更带来的外溢影响
历史债务阻塞当前 PR Origin 分类 + Residual Risk 既保留历史问题可见性,又不把它们全算到作者头上
输出过长但不可执行 严重性分层、数量上限、结构化输出 结果更聚焦,也更方便团队协作

评估数据也支持这一点:在 4 个微妙场景里,with-skill 的误报率是 0/19,without-skill 约为 5/32;信噪比从 53% 提升到 89%;并且只有 with-skill 能稳定产出结构化的 Residual Risk。这说明它的价值不是"多找 bug",而是在不漏掉高风险问题的前提下,让审查结果更准、更稳、更适合团队使用。

6. 主要亮点

6.1 把代码审查从"提意见"升级为"风险分流"

这是这个 skill 最重要的亮点。它不把 review 看成一串评论,而是看成一次有输入边界、有证据要求、有优先级排序的风险处理过程。

6.2 强调判断的稳定性,而不是审查者临场发挥

这个 skill 里很多关键决策都不是"凭经验看着办",而是"先跑规则,再做判断",例如:

  • 先选模式,再决定审查深度。
  • 先看 go.mod,再做版本相关建议。
  • 先确认影响半径,再决定哪些额外文件应纳入审查。
  • 先触发 reference loading,再评价并发、安全、数据库等领域问题。
  • 先做 suppress,再决定哪些内容值得进 findings。

这说明它追求的不是 reviewer 看起来多聪明,而是不同人用这套 skill 时,结果仍然有可预期的一致性。

6.3 既讲严格,也讲公平

很多 review 体系只强调"严格",结果是历史债务和本次改动混在一起,作者体验很差。go-code-reviewer 在这方面更成熟:

  • introduced 问题要求修复或明确接受风险。
  • pre-existing 问题保留可见性,但默认不阻塞合并。
  • uncertain 问题先保守处理,再允许用证据重新归类。

Risk Acceptance and SLA Gate 进一步强化了这一点。当某个 finding 无法立即修复时,这个门禁要求做出明确决定——不是一句消失在评论里的口头承诺,而是一条记录了责任人、理由和复审时间的条目。这让团队的义务保持可见,也让期限有据可查。

这种设计让它既能守住质量底线,也不会把代码库的全部历史问题一次性压到当前作者身上。

6.4 误报管理透明,而不是暗箱处理

很多 review 工具即使没有报某个问题,也不会说明是"看过后认为没问题",还是"根本没想到"。go-code-reviewer 则通过 Suppressed Items 把这种差别公开化。

证据 Rules 里的 Anti-examples 列表进一步深化了这一点:它显式记录了那些经验积累后认为永远不该报的模式,让误报管理有两个可见层次——针对具体上下文的 Suppressed Items,以及跨所有 review 共享的类级校准基准 Anti-examples 列表。

这非常重要,因为它提升了结果的可解释性。团队不仅知道"报了什么",也知道"为什么有些看起来可疑的点没有报"。

6.5 在复杂场景下优势更大

评估结果很明确:教科书级场景里,它和通用 Claude 的缺陷检测能力没有差别,优势主要体现在流程;但在微妙场景里,它的差异化价值明显变大。

特别是以下两类场景:

  • 灰区判断很多的 review:它能稳定压低误报。
  • 多文件影响半径分析:它能把"当前必须修"和"历史债务待跟踪"分开。

这说明它不是为了替代 Go 基础知识,而是为了在复杂、容易失真的 review 场景里提供更稳的框架。

7. 什么时候适合用,什么时候不该硬用

场景 是否适合 原因
审查 Go PR、diff 或一组改动文件 适合 能完整发挥模式选择、边界控制、Origin 分类和结构化输出的价值
需要判断代码是否符合仓库规范 适合 它会优先读取 constitution.md,其次 AGENTS.md
涉及并发、安全、数据库、HTTP、公共接口变更 非常适合 参考资料加载和影响半径扩展会明显提升审查质量
只想要一句非常随意的主观评价 不太适合 这和 skill 的设计目标不一致
任务是写代码、调试故障或补测试 不适合 这些属于别的 skill 或工作流,不是代码审查

8. 结论

go-code-reviewer 的真正亮点,不是它比通用模型"更会找 bug",而是它把 Go 代码审查里最容易失真的几个环节系统化了:审查深度怎么选、证据和推测怎么分开、误报怎么压低、历史债务怎么处理、复杂领域检查怎么补齐、最终结果怎么交付给团队。

从设计上看,这个 skill 非常典型地体现了生产级 review 体系的几个原则:先校准审查深度,再收集证据;先控制误报,再报告问题;先区分责任归属,再决定处理动作。 这也是它为什么特别适合复杂 PR、灰区判断和多文件影响分析,而不是只适合教科书式的 Go 缺陷检查。

9. 文档维护

当以下内容发生变化时,这份文档应该同步更新:

  • skills/go-code-reviewer/SKILL.md 的审查模式、门禁、工作流或输出格式发生变化。
  • skills/go-code-reviewer/references/*.md 的检查项、触发条件或领域指导发生变化。
  • evaluate/go-code-reviewer-skill-eval-report.zh-CN.md 中支撑本文结论的关键数据发生变化。
  • 项目对 review 规则、SLA、Residual Risk 或 Origin 分类的团队约束发生变化。

建议按季度复查一次;如果 go-code-reviewer skill 有明显重构,则应立即复查。

10. 相关阅读

  • skills/go-code-reviewer/SKILL.md
  • skills/go-code-reviewer/references/pr-review-quick-checklist.md
  • skills/go-code-reviewer/references/go-security-patterns.md
  • skills/go-code-reviewer/references/go-concurrency-patterns.md
  • skills/go-code-reviewer/references/go-error-and-quality.md
  • skills/go-code-reviewer/references/go-test-quality.md
  • skills/go-code-reviewer/references/go-api-http-checklist.md
  • skills/go-code-reviewer/references/go-database-patterns.md
  • skills/go-code-reviewer/references/go-performance-patterns.md
  • skills/go-code-reviewer/references/go-modern-practices.md
  • evaluate/go-code-reviewer-skill-eval-report.zh-CN.md