基于 GitCode API 的 PR 代码审查自动化实战:解析 amct 仓库 review.md Agent 技能
【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct
导读
本文围绕 CANN/amct 仓库内.agents/skills/gitcode-pr/commands/review.md这份 Agent 技能文档展开,系统讲解如何在 GitCode 平台上通过 API 完成 Pull Request 的自动化代码审查:从前置检查、变更获取、精确行号定位,到高信号 Bug 筛选、问题验证过滤,再到行内评论发布的全流程。读者完成本文后,将掌握一套可直接复用的 PR 审查方法论与 GitCode API(v4/v5 双风格)的调用规范,能够在自己或团队的开源仓库中落地 Agent 化代码审查。
一、技能定位:review.md 在 amct 仓库 Agent 体系中的角色
在 CANN/amct 仓库的.agents目录下,维护着一套面向开源协作的 Agent 技能体系(.agents/README.md)。其中gitcode-pr技能(.agents/skills/gitcode-pr/SKILL.md)负责 GitCode 平台上 Pull Request(合并请求)的创建、评论获取与审查,而本文的主角 commands/review.md 正是该技能中"PR 代码审查"子流程的完整操作手册。
从 SKILL.md 的触发条件看,当用户发出"检视 PR""审查 PR""review PR""给 PR 提意见"等指令时,Agent 会先通过 Read 工具读取commands/review.md获取审查流程,再逐条执行其中的步骤。该文档具有以下设计特点:
- 标准化的九步流程:从前置检查到评论发布,每一步都有明确的判定条件与终止分支;
- 双 API 风格并存:既支持 GitHub 兼容的 v5 API(
/repos/${owner}/${repo}/...),也支持 GitLab API v4 格式(/projects/${encoded_repo}/merge_requests/...); - 以"高信号问题"为核心:明确区分"值得标记"与"不要标记"的问题类型,将误报率控制在可接受范围。
此外,仓库提供了配套的评估用例 evals/evals.json,用真实 PR 验证该技能的有效性,本文末尾会展开分析。
二、审查流程总览:九步标准化流水线
review.md将一次 PR 审查拆解为 9 个顺序步骤,任何一步都有明确的产出物或终止条件:
| 步骤 | 名称 | 核心产出 / 终止条件 |
|---|---|---|
| 1 | 前置检查 | 任一条件成立则停止执行 |
| 2 | 获取项目规范上下文 | 规范文件路径列表(不含内容) |
| 3 | 获取 PR 变更摘要 | PR 信息、文件列表、diff |
| 3.1 | 确定问题代码的准确行号 | 目标文件 + 精确行号 |
| 4 | 代码审查 | 高信号问题列表 |
| 5 | 验证问题 | 每个问题经实证确认 |
| 6 | 过滤问题 | 最终高信号问题列表 |
| 7 | 输出审查摘要 | 终端输出 + 评论发布决策 |
| 8 | 准备评论列表 | 仅自检,不对外发布 |
| 9 | 发布行内评论 | 通过 GitCode API 写入 PR |
该流程还隐含两条贯穿始终的原则(文档开头的"Agent 假设"):
- 不测试工具:假定所有工具均正常,不做探索性调用,每次工具调用都应有明确目的;
- 子 Agent 信息同步:每个启动的子 agent 都需清楚上述假设,且在审查阶段需被告知 PR 的标题与描述,以理解作者意图。
三、步骤 1:前置检查——四类直接终止的情况
审查开始前,必须先检查以下四个条件,任一成立则立即停止,不进入后续步骤:
- PR 已关闭(closed);
- PR 处于草稿状态(draft);
- PR 不需要代码审查:例如自动化 PR、明显正确的微小变更;
- Claude 已在此 PR 上评论过:通过 GitCode API 检查 PR 评论历史,避免重复劳动。
其中有一条特别豁免:由 Claude(Agent)自己生成的 PR 仍然需要审查。这意味着自动化提交的代码同样纳入质量管控,只是跳过"是否已评论"等常规去重判断。
四、步骤 2~3:获取规范上下文与 PR 变更摘要
4.1 项目规范上下文
返回所有相关规范文件的文件路径列表(不含内容),来源有两类:
- 仓库根目录的规范文件,如
CONTRIBUTING.md、CODE_STYLE.md等; - PR 修改文件所在目录中的规范文件(后续评估规范合规性时,只考虑该文件路径或父目录中的规范文件)。
在 amct 仓库中,根目录即存在 CONTRIBUTING.md 与 CONTRIBUTING_en.md 等协作规范文件,属于此步骤会收集的对象。
4.2 获取 PR 信息与变更
通过 GitCode 的 GitHub 兼容 API(v5)拉取 PR 元数据、文件列表与 diff:
# 获取 PR 信息 curl -s "https://gitcode.com/api/v5/repos/{owner}/{repo}/pulls/{pr_number}" \ -H "Authorization: Bearer $GITCODE_TOKEN" # 获取 PR 变更文件列表 curl -s "https://gitcode.com/api/v5/repos/{owner}/{repo}/pulls/{pr_number}/files" \ -H "Authorization: Bearer $GITCODE_TOKEN" # 获取 PR diff curl -s "https://gitcode.com/api/v5/repos/{owner}/{repo}/pulls/{pr_number}" \ -H "Authorization: Bearer $GITCODE_TOKEN" \ -d "diff=true"结合 references/gitcode_api.md 的说明,{owner}/{repo}应从当前仓库的远程 URL 动态提取(git remote get-url origin后通过sed解析 SSH 或 HTTPS 两种格式),而不是硬编码——这一点对 fork 场景尤其重要。
五、步骤 3.1:确定问题代码的准确行号
发布行内评论的前提是拿到准确的行号。文档提供了两种方法:
方法 1:从 PR Diff 的 hunk header 推算
GET .../pulls/<PR_NUMBER>/files返回的patch.diff字段包含 hunk header:
@@ -old_start,old_count +new_start,new_count @@-old_start,old_count:原文件的起始行和变更行数;+new_start,new_count:新文件的起始行和新增行数。
注意:hunk header 只给出起始行号,仍需根据 diff 内容逐行累计计算实际行号,手动计算易出错。
方法 2:从 Raw 文件验证(推荐)
直接查询 PR head commit 对应的 raw 文件,用grep -n精确落点:
curl -s "https://raw.gitcode.com/${owner}/${repo}/raw/<HEAD_SHA>/path/to/file.cc" | grep -n "问题代码模式"文档给出的真实示例:
curl -s "https://raw.gitcode.com/${owner}/${repo}/raw/358192edfc1809f6fe17b0da0b1b8efd9880a52f/hcom_graph_optimizer.cc" \ | grep -n "if (it =="输出:844: if (it == (itMap->second).end()) {
最佳实践
- 先用 diff 定位大致范围:通过 PR diff 找到变更的代码块;
- 再用 raw 文件确认精确行号:避免手动计算偏差;
- 发布评论前验证:确保行号对应的确实是问题代码。
这一流程的有效性在 evals/evals.json 的line-number-accuracy用例中得到了验证:使用技能时准确锁定第 844 行(耗时约 126 秒),而评估结论也提示"用 raw 文件验证或 grep -n"是标准做法。
六、步骤 4:代码审查——只标记高信号问题
6.1 三个审查维度
| 维度 | 检查内容 |
|---|---|
| 规范合规性审查 | 变更是否符合项目规范(只参考该文件路径或父目录中的规范文件) |
| Bug 扫描 | 只关注 diff 本身,不读取额外上下文;只标记显著 Bug,忽略细微问题与疑似误报 |
| 代码问题检查 | 安全问题、逻辑错误等变更代码范围内的新引入问题 |
6.2 高信号问题的判定标准
标记以下类型的问题:
- 代码无法编译或解析:语法错误、类型错误、缺少导入、未解析引用;
- 无论输入如何,代码肯定产生错误结果:明显的逻辑错误;
- 明确、无歧义的规范违反:可以引用被违反的具体规则。
不要标记:
- 代码风格或质量问题;
- 依赖特定输入或状态的潜在问题;
- 主观建议或改进意见。
文档特别强调:"如果你不确定某个问题是否真实存在,不要标记它。误报会损害信任并浪费审查者时间。"这条原则与后续的"验证—过滤"两步骤形成闭环,保证最终进入评论阶段的问题都是经过实证的高置信度问题。
七、步骤 5~6:验证问题与过滤问题
- 步骤 5(验证问题):对步骤 4 发现的每个问题,结合 PR 标题、描述与问题描述进行确信验证。例如标记了"变量未定义",需确认代码中确实如此;规范合规问题,需确认被违反的规则确实适用于该文件且确实被违反。
- 步骤 6(过滤问题):过滤掉未通过验证的问题,得到最终的高信号问题列表。
两个步骤共同构成"提出—验证—收敛"的质量闸门,是避免噪音评论的关键设计。
八、步骤 7:输出审查摘要与评论决策
在终端输出审查结果摘要:
- 如果发现问题:列出每个问题及简要描述;
- 如果未发现问题:输出
未发现问题。已检查 Bug 和规范合规性。
随后根据--comment参数分派三种分支:
| 场景 | 行为 |
|---|---|
未提供--comment | 停止,不发布任何 GitCode 评论 |
提供--comment且未发现问题 | 用 GitCode API 发布摘要评论并停止 |
提供--comment且发现问题 | 继续步骤 8、9 |
其中"无问题"时的摘要评论有固定格式(以 Markdown 分隔线包裹):
--- ## 代码审查 未发现问题。已检查 Bug 和规范合规性。 ---九、步骤 8~9:发布行内评论
9.1 准备评论列表
步骤 8 仅用于自检:创建计划发布的所有评论清单,确认内容满意,但不在任何地方发布。
9.2 创建 Discussion 发布行内评论(推荐)
步骤 9 推荐通过 GitLab API v4 格式的 discussions 端点发布行内评论:
curl -s -X POST \ -H "PRIVATE-TOKEN: $GITCODE_API_TOKEN" \ -H "Content-Type: application/json" \ "https://api.gitcode.com/api/v4/projects/${encoded_repo}/merge_requests/<PR_NUMBER>/discussions" \ -d '{ "repoId": "'"${encoded_repo}"'", "iid": <PR_NUMBER>, "body": "评论内容", "line_types": "new", "position": { "base_sha": "<base_commit_sha>", "start_sha": "<start_commit_sha>", "head_sha": "<head_commit_sha>", "position_type": "text", "old_path": "文件路径", "new_path": "文件路径", "old_line": null, "new_line": <结束行号>, "start_old_line": null, "start_new_line": <起始行号>, "ignore_whitespace_change": false }, "assignee_id": <用户ID>, "proposer_id": <用户ID>, "severity": "suggestion" }'9.3 参数说明
| 参数 | 说明 | 必需 |
|---|---|---|
body | 评论内容 | ✅ |
line_types | "new"选择新代码(右侧),"old"选择旧代码(左侧) | ✅ |
position.base_sha | base 提交 SHA | ✅ |
position.start_sha | start 提交 SHA | ✅ |
position.head_sha | head 提交 SHA | ✅ |
position.new_path | 文件相对路径 | ✅ |
position.new_line | 结束行号 | ✅ |
position.start_new_line | 起始行号(多行选择) | 多行时 |
severity | 严重程度:suggestion、warning | ❌ |
多行选择说明:start_new_line为选中起始行号,new_line为选中结束行号;单行评论时两者设为相同值。
9.4 评论内容规范
- 每个评论提供问题的简要描述;
- 对于小型、自包含的修复,包含可提交的建议代码块;
- 对于较大修复(6 行以上、结构性变更或跨多个位置),描述问题与建议修复方式,不包含建议代码块;
- 永远不要发布可提交建议,除非提交该建议能完全修复问题;如需后续步骤,则不留下可提交建议;
- 每个唯一问题只发布一条行内评论,严禁重复。
十、误报列表:明确不标记的六类情况
review.md专门维护了一份误报列表,用于步骤 4 和 5 的评估判据:
- 已存在的问题(pre-existing);
- 看起来是 Bug 但实际上是正确的代码;
- 高级工程师不会标记的吹毛求疵;
- Linter 会捕获的问题(不要运行 Linter 验证);
- 一般代码质量问题(如缺乏测试覆盖、一般安全问题),除非规范中明确要求;
- 规范中提到但在代码中明确静默的问题(如通过 lint ignore 注释)。
这份清单有效约束了 Agent 的标记行为,防止将审查退化为噪音制造工具。
十一、注意事项:链接格式与 API 交互纪律
11.1 行内评论中的代码链接格式
在行内评论中链接代码时,必须严格遵循以下格式,否则 Markdown 预览无法正确渲染:
https://gitcode.com/{owner}/{repo}/blob/{full_git_sha}/path/to/file#L{start}-L{end}要点:
- 需要完整的 git sha;类似
$(git rev-parse HEAD)的替换在评论中不起作用; - 仓库名必须与正在审查的仓库一致;
- 文件名后使用
#,行范围格式为L[start]-L[end]; - 在评论行前后至少提供 1 行上下文(如评论第 5-6 行,应链接到 L4-L7)。
11.2 其他纪律
- 使用 GitCode API 与 GitCode 交互(获取 PR、创建评论),不要使用网页抓取;
- 开始前创建待办列表(to-do list);
- 每个问题必须在行内评论中引用并链接(引用规范文件时包含指向它的链接)。
十二、GitCode API 参考:双风格认证与快速检索表
review.md明确指出:GitCode 使用 GitLab API v4 格式,认证头使用PRIVATE-TOKEN。这与 GitHub 兼容的 v5 风格并存,references/gitcode_api.md 给出了对比:
| API 风格 | 认证头 | 端点格式 |
|---|---|---|
| GitLab API v4(推荐) | PRIVATE-TOKEN: <token> | /api/v4/projects/<encoded_path>/... |
| GitHub 兼容 | Authorization: Bearer <token> | /api/v5/repos/<path>/... |
其中项目路径需编码:owner/repo→owner%2Frepo(可用printf '%s' "owner/repo" | jq -sRr @uri)。
快速参考表
| 操作 | API 端点 |
|---|---|
| 获取 PR 信息 | GET /projects/${encoded_repo}/merge_requests/<PR_NUMBER> |
| 获取 PR 变更 | GET /projects/${encoded_repo}/merge_requests/<PR_NUMBER>/changes |
| 获取 PR 评论 | GET /projects/${encoded_repo}/merge_requests/<PR_NUMBER>/discussions |
| 发布普通评论 | POST /projects/${encoded_repo}/merge_requests/<PR_NUMBER>/notes |
| 发布行内评论 | POST /projects/${encoded_repo}/merge_requests/<PR_NUMBER>/discussions |
基本调用格式:
curl -s -H "PRIVATE-TOKEN: $GITCODE_API_TOKEN" \ "https://api.gitcode.com/api/v4/projects/${encoded_repo}/merge_requests/<PR_NUMBER>/discussions"十三、配套资源与效果验证
围绕review.md,gitcode-pr 技能还提供了完整的配套资源(均可从仓库根目录相对路径进入):
- SKILL.md:技能总入口,涵盖令牌获取(
GITCODE_API_TOKEN环境变量)、远程仓库 owner/repo 提取脚本、fork 原仓库查询、评论类型(DiffNote行内 /DiscussionNote普通)、创建/回复/删除评论、PR 创建流程与 Conventional Commits 标题规范等。其中"获取真正的数字 ID"一节值得注意:POST 创建评论立即返回的是哈希字符串(作为discussion_id),删除评论等后续操作必须先从列表接口拿到数字id,且不能用宽泛的contains(.body)匹配他人评论。 - references/gitcode_api.md:完整 API 参考,包含删除评论的状态码(
200成功 /401未授权 /403无权限 /404不存在)、每页 100 条的分页参数、raw 文件获取方式等。 - evals/evals.json:3 个评估用例——
basic-pr-review(识别it == end()后解引用it->second的逻辑 Bug)、line-number-accuracy(精确到 844 行)、review-and-comment(发布[TEST]前缀评论并清理)。从基准数据看,使用技能时with_skill_avg_duration_ms约 149.8 秒,明显快于未使用技能的约 215.8 秒,且行号定位与 Bug 识别均通过断言;评估同时记录了两项待改进点:使用技能时发现的问题数量偏少(1 个 vs 5 个)、评论发布用例需在测试环境运行。
结语:从文档到可落地的审查能力
commands/review.md的价值在于把"代码审查"这一高度依赖经验的协作行为,抽象成了 Agent 可执行、可验证、可度量的标准化流程。其核心方法论——前置门禁、diff 聚焦、高信号筛选、实证验证、过滤收敛、精确定位、规范发布——不仅适用于 GitCode 平台,也可以迁移到任何提供 PR API 的代码托管平台。对于 amct 这类持续演进的开源仓库,这样的技能文档正是保障社区协作质量与效率的基础设施。
文中涉及的所有流程细节与 API 参数,均可在仓库 .agents/skills/gitcode-pr 目录下按上述相对路径查阅原文与配套资源。
【免费下载链接】amctAMCT是CANN提供的昇腾AI处理器亲和的模型压缩工具仓。项目地址: https://gitcode.com/cann/amct
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考