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-lint、go vet 或 go test,而是把这些工具发现的信号、代码上下文、项目规范和审查者判断组织成一套更适合团队使用的审查结果。
4. 核心设计逻辑¶
4.1 采用 defect-first vs 风格优先¶
go-code-reviewer 从一开始就把目标写得很清楚:review 的重点是真实缺陷、回归风险和项目规范偏离,而不是泛泛而谈代码风格。
这背后有两个判断:
- 在真实工程里,最贵的问题通常不是命名是否优雅,而是竞态、资源泄露、兼容性破坏、错误处理失真、数据库或 API 行为出错。
- 如果 review 总被低价值风格评论淹没,开发者会逐渐把 review 当成噪音,真正高风险的问题反而不容易被认真对待。
所以这个 skill 的出发点不是"尽量多提意见",而是"优先找出最应该修的问题"。
4.2 先选审查模式¶
go-code-reviewer 在正式审查前先选 Lite、Standard、Strict 三种模式,并要求在结果里写明模式和选择理由。
这样设计,是为了把审查深度和风险等级对齐:
| 模式 | 适用场景 | 设计目的 |
|---|---|---|
Lite | 小范围、低风险变更 | 快速筛出高置信度问题,避免把小改动审成大工程 |
Standard | 大多数日常 PR | 在深度、速度和成本之间保持平衡 |
Strict | 安全、并发、公共 API、大范围重构等高风险变更 | 主动扩大影响半径,执行更严格的验证和报告要求 |
如果没有这一步,审查很容易出现两种失真:简单改动被过度放大,复杂改动却只得到表层点评。模式选择机制本质上是在解决"审查资源该花在哪里"的问题。
4.3 把执行完整性放在第一道门禁¶
第一道强制审查门禁是执行真实性门禁,要求:没跑过的验证不能装作跑过。
这个门禁看起来朴素,但非常关键。很多 review 最大的问题不是判断错,而是把没验证过的东西写成了像验证过一样的语气。比如:
- 没跑
go test,却暗示"测试看起来没问题"。 - 没跑
go test -race,却给人一种并发安全已经确认过的印象。 - 没有工具环境,却写出像是 lint 全部通过的结论。
这个门禁的价值在于:
- 把"推测"和"已验证"严格分开。
- 让结果的可信度有清晰边界。
- 避免团队把一份语言上很笃定、实际上证据不足的 review 当成事实。
换句话说,这个 skill 先保护结论的可信度,再讨论结论本身。
4.4 保留 baseline 对比¶
第二道强制审查门禁是基线对比门禁。它要求在有历史上下文时,把每个 finding 标成 new、regressed、unchanged 或 resolved;如果没有基线,也必须明确写出 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.mdskills/go-code-reviewer/references/pr-review-quick-checklist.mdskills/go-code-reviewer/references/go-security-patterns.mdskills/go-code-reviewer/references/go-concurrency-patterns.mdskills/go-code-reviewer/references/go-error-and-quality.mdskills/go-code-reviewer/references/go-test-quality.mdskills/go-code-reviewer/references/go-api-http-checklist.mdskills/go-code-reviewer/references/go-database-patterns.mdskills/go-code-reviewer/references/go-performance-patterns.mdskills/go-code-reviewer/references/go-modern-practices.mdevaluate/go-code-reviewer-skill-eval-report.zh-CN.md