ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hermes 接入 GitHub PR:AI 自动化代码评审实战指南

Hermes 接入 GitHub PR:AI 自动化代码评审实战指南 先说结论这个标题拆开来看其实藏着四层信息——Hermes是执行体GitHub PR是落点自动化代码评审是业务目标而前面审查两个字则决定了它的核心动作不是帮人写代码而是在代码合入之前替团队把关。如果你正在维护一个多人协作的仓库每天有一堆 PR 等着被 review但又不想让每一次评审都变成排队等人工那这篇文章要聊的东西就非常适合你。我最早接触 Hermes 这套自动化评审方案时心里其实没抱太大期望。毕竟团队的代码评审问题很典型小改动没人看大改动看不过来关键 bug 全靠半夜被线上报警打醒。后来我尝试把 Hermes 接到 GitHub 的 PR 事件流里让它在每次 PR 打开或更新时自动拉取 diff按约定规则做一轮 AI 初评再把结果以评论和建议的形式回写到 PR 页面。跑了两周之后我发现它的价值不在替代人而在帮人省掉最耗精力的那部分判断成本——比如这次改动动了哪些文件、有没有明显的边界条件漏处理、新增代码是否和现有接口语义一致。下面我就把整套思路、配置方法和我实际踩过的坑完整写出来给想在自己的仓库里落地这套流程的朋友做个参考。1. Hermes 到底是什么以及它解决什么问题1.1 核心定位PR 审查版自动巡检Hermes 本质上是一个基于大语言模型的代码审查代理。它可以是一个独立服务也可以被封装成 GitHub Actions 里的一个 job不管哪种形态它做的事情都是同一个流程监听 PR 事件、拉取代码差异、调用模型分析、再把结构化结论写回 PR。很多人第一次听到AI 审查代码时会下意识联想到 lint 工具或者 SonarQube 这类静态检查。这里我先把边界说清楚lint 检查的是代码是否符合语法规则和风格规范SonarQube 检查的是代码里有多少坏味道和重复片段而 Hermes 这种模型驱动的审查 Agent 要做的是对代码变更的语义做评估。它不会因为少了一个空格而打断你但会因为你在改支付金额计算逻辑时漏掉了精度处理而提出疑问。这个差异决定了它在审查体系里的位置是偏上层的思考型检查而不是偏底层的规则型扫描。1.2 一个 PR 里Hermes 到底在看什么要理解它的能力边界得先知道一次审查的输入是什么。最基础的是 PR 的完整 diff包括新增文件、删除文件、修改文件的上下文行。其次还有配套的元数据commit message、修改涉及到的函数边界、是否改了公共接口、有没有删除关键错误处理分支。Hermes 内部会把这些信息结合成一个带上下文的 prompt 送去给模型解析。我实际使用下来Hermes 对下面几类问题最敏感改动破坏了既有调用契约例如把一个函数的返回类型从可空改成了不可空但调用方没有同步处理。错误处理被吞掉或绕过新增代码里 catch 之后什么都没做返回值异常时也没走兜底逻辑。并发与状态一致性隐患多个协程或线程里同时读写同一个字段而又没有加锁也没有使用原子操作。只覆盖了 happy path路径分支上明显存在空指针、越界访问、文件不存在等边界场景。与仓库现有模式不一致项目里统一用某个工具库处理日志新代码却自己拼字符串输出。这里要注意的是上面这些问题它不一定每次都能 100% 命中但如果提示词和评审规则设计得合理它能非常稳定地把这些问题中最值得人工关注的那一部分挑出来。1.3 为什么不是换个 lint 工具这么简单我团队里最开始也有人问既然要自动化为什么不干脆把 lint 规则开严一点原因很简单规则型工具没有跨文件、跨模块的全局视角。一个 PR 可能只改了十行代码但影响的是一个服务所有入口的请求转发逻辑。静态检查只会看这十行是不是格式整齐而 Hermes 会结合仓库里的周边代码去判断这十行放进来之后原有逻辑是否还能闭环。另一个原因是机器人判断的粒度不同。Hermes 的审查输出可以按阻塞性问题 / 建议修改 / 纯疑问三个级别分类还能直接生成可点击的 GitHub review suggestion。这就让它不只是报错而是能参与到 reviewer 和 author 的对话上下文里而不是像传统 lint 一样在 CI 里直接红色失败。这也是我把这项能力定位成自动巡检而非质量门禁的原因它可以巡视可以提醒但最终拍板应该还是人。2. 让 Hermes 接入 GitHub PR 的完整设计思路2.1 两种接入姿势GitHub App 与 Actions 工作流落地 Hermes 时首先要想清楚接入方式。我实践中比较推荐的是以 GitHub Actions 工作流为入口跑 Hermes仓库根目录放一个.github/workflows/pr-review.yml每次 PR 事件产生时触发执行。这种方式的好处是配置透明、对仓库侵入小普通成员也能通过改 workflow 文件调整流程不需要额外维护一台常驻服务器。GitHub App 方案则更适合那些要跨多个仓库统一做审查规则、消息需要异步推送、甚至想在看板里汇总审查结果的大型团队。App 方式需要自己部署回调服务好在 Hermes 如果提供 CLI 子命令也能被外部服务调用。小团队起步阶段我不建议一上来就搞 App先跑通 Actions 版把规则沉淀下来后续如果出现了几十个仓库都要用同一套配置的需求再迁移到 App 架构也不迟。2.2 Hermes 的执行链路事件到结果落回 PR一次完整的审查事件流大致是下面这样开发者提交 PR 或往已有 PR 推送新 commit。GitHub 根据 workflow 配置触发pull_request事件。Hermes 使用actions/checkout拉取目标分支与合并基准之间的代码。Hermes 调用 GitHub API 获取当前 PR 的.diff数据。后端接入的模型对 diff 和上下文进行推理。Hermes 把结论拆成摘要评论 行级评论 审查结论三种形态通过 GitHub API 写回 PR。人工 reviewer 后续在 PR 页面看到结果可以直接回复或补充。这个链路里最容易出问题的地方在第 5 步到第 6 步之间。模型返回的结果如果是纯自然语言没有结构化字段Hermes 就不知道哪条评论该放在哪个文件的哪一行。所以我在配置时都会要求 Hermes 使用 JSON 模式输出再在内部把 JSON 解析成一个个审查评论这条路走通之后整个过程才谈得上自动化。2.3 权限模型与 Token 设计千万别省这一步接入过程中最容易被忽略的是权限。Hermes 要读取 PR 信息需要contents: read权限要把评论发到 PR 页面需要pull-requests: write权限如果你想让它通过 commit 状态接口来标记审查中/审查完成还需要checks: write或statuses: write。在 Actions 里用的 token 通常是仓库自动生成的${{ secrets.GITHUB_TOKEN }}它的生命周期跟着 workflow 跑不会在账号里长期暴露。但有一点要注意如果你给 Hermes 配的是个人访问令牌而且这个 token 属于某个同事的账号一旦那个同事离职或者关闭了 token整个自动化流程就会瞬间失效。要么用机器人账号的 token要么直接用 GITHUB_TOKEN不要把人肉账号绑定在基建任务上。3. 关键细节审查规则的设定与提示词设计3.1 先写好角色 规则 边界三段式提示词Hermes 的审查质量说实话取决于你对它的期望描述。我最终沉淀出来的提示词模板可以拆成三段第一段是角色定义让它知道自己是个资深 reviewer第二段是项目规则告诉它当前仓库优先级最高的审查维度第三段是边界清单明确告诉它哪些东西不要提。实际示例大致是这样你是一个资深后端开发负责审查 PR。你熟悉项目的技术栈和业务背景。 请在审查时优先关注以下问题 1. 正确性风险内存泄漏、并发竞争、异常返回、空值处理。 2. 可维护性不合理命名、重复逻辑、错误注释。 3. 安全风险用户输入未校验、敏感信息进入日志。 不要报告以下内容 1. 纯代码风格问题例如空格、行长度。 2. 与本次改动无关的历史问题。 3. 基于臆测的潜在风险除非能给出明确触发路径。这样做的原因是模型如果没有边界约束很容易把一批风格偏好当成问题提出来导致真正重要的 bug 被淹没在噪音里。我试过一版没加边界清单的 prompt结果一次 PR 生成 47 条评论其中 30 条都是建议把单引号改成双引号之类的废话。加了边界清单后评论数量降到 12 条有效信息密度明显上升。3.2 diff 提取策略不是所有文件都值得喂给模型很多人以为喂给模型的上下文越多越准确实际上不是这样。一次改动 5000 行的巨型 PR如果把完整 diff 直接丢进去且不说 token 成本模型也容易在超长上下文里迷失重点给出一个非常笼统的平均意见。我采用的策略是先过滤再分组。Hermes 在拿到 PR 的变更文件列表后先把明显不需要审查的文件剔除掉比如package-lock.json、vendor目录、生成器产物、纯静态资源文件。剩余的文件再按变更难度分成两组结构性改动和普通业务改动。结构性改动比如接口定义、数据库字段、通信协议这些优先进入模型上下文普通业务改动可以用摘要模式或者只抽取关键函数。这个流程看起来简单但处理完后再送审模型给出有针对性意见的比例会提高不少。另外我会在 workflow 中设置- name: Setup Hermes uses: your-registry/hermes-actionv1 with: diff-strategy: filtered include-globs: | src/** tests/** exclude-globs: | generated/** vendor/** *.lockexclude-globs这个参数在大型仓库里必须配。之前我按默认配置跑一次 monorepo光生成的.pb.go文件就占了几千行 diff严重挤占了模型的注意力配额。3.3 审查结果的粒度摘要评论行级评论别混着发Hermes 支持把结论通过三种方式展示PR 顶部的整体摘要、代码 diff 里的行级评论、以及 review 结束时的总结批注。如果你的团队刚开始用 AI 审查我强烈建议先只开整体摘要 指定数量的行级评论不要一上来就让它在每个文件每行都发言。我设定过一套参数report: mode: combined summary: true inline: enabled: true max_comments: 16 min_confidence: 0.8 global: max_comments: 8max_comments设得太大会刷屏设得太小则可能漏掉从后往前看的人真正需要的重要提醒。16 这个数是我用了大半月的经验值它不仅控制住了评论数量还能保证最重要的问题不会因为排在后面而被丢弃。如果模型输出的问题超过 16 条我会让它总结在摘要里而不是所有都往文件行上贴。4. 从零跑通一条 Hermes 自动审查流水线4.1 先搭一个最小可用的 GitHub Actions workflow前文讲了很多思路这里直接给一个能跑通的最小配置。我在仓库里用到的pr-review.yml长这样name: Hermes Code Review on: pull_request: types: [opened, synchronize, reopened] issue_comment: types: [created] permissions: contents: read pull-requests: write jobs: hermes-review: if: contains(github.event.comment.body, /hermes) || github.event_name pull_request runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkoutv4 with: fetch-depth: 0 - name: Run Hermes review uses: your-registry/hermes-github-actionv1 with: github-token: ${{ secrets.GITHUB_TOKEN }} model: deepseek-hermes api-key: ${{ secrets.HERMES_LLM_API_KEY }} config-path: .github/hermes.yaml这里有一个设计小细节值得说明issue_comment加上if条件是为了支持团队成员在 PR 里手动输入/hermes来触发重新审查。为什么要这样做因为很多 PR 在收到 review 意见后作者会修改代码。虽然synchronize事件能自动触发一次新审查但如果在讨论过程中有人提了个建议作者只改了一行你觉得没必要再全量审一次那么手动命令触发就能很好地控制节奏避免每次讨论都引来一轮 AI 刷屏。4.2 Hermes 核心配置逐项解释工作流指定了.github/hermes.yaml里面的内容我大概是这样配的review: trigger: on_open: true on_sync: true on_comment: /hermes path: exclude: - *.md - docs/** - generated/** llm: temperature: 0.2 max_retries: 3 output: summary: true inline: true max_comments: 16 generate_suggestion: true blocking: labels: - blocking这个配置里有几个关键参数我挑出来说。temperature: 0.2是降低模型输出的随机性代码评审这种场合不需要创造性发挥越稳定越好我试过把 temperature 调到 0.8它居然给出了两个互相矛盾的建议。generate_suggestion: true是让 Hermes 对每一处行级问题生成一个 GitHub 可一键应用的 code suggestion这会大幅降低开发者修改问题的成本。blocking.labels表示它给 PR 打上blocking标签的标准这直接影响 CI 里是否设置 label 校验。4.3 改完代码后的增量重审必须处理旧评论一个真实场景是开发者看到 Hermes 提了几条 line comment自己改完代码并 push 了新 commit。此时如果只触发一轮新审查PR 页面上会同时保留旧的过时评论和新评论很容易把看 review 的人搞糊涂。Hermes 的机制是收到新的审查请求后先查当前 PR 上已经存在哪些机器人评论把对应的旧 inline comment 标记为 outdated或者根据配置直接删除。这个动作需要额外调用 GitHub GraphQL API建议你一定要开启这个选项否则评论累积两周后PR 页面看起来会像一个没人打理的论坛帖子。配置里可以这样打开review: cleanup: outdated_comments: true outdated_summary: true4.4 一次真实 PR 的审查结果长什么样下面是我实际见到的一次输出一个改动是给用户积分接口增加了缓存逻辑。Hermes 给出的摘要评论大概是这个级别本次改动整体思路清晰核心为引入本地缓存以降低数据库压力。需要注意以下几点缓存 key 仅由用户 id 拼接未包含积分类型字段会导致不同类型积分互相覆盖。当缓存未命中回源数据库时缺少并发控制可能出现缓存穿透建议在回源逻辑上增加单飞或分布式锁。过期时间设置较短建议结合业务指标观察命中率。三条信息里第二条是没有跑代码时也很容易漏掉的高价值提醒。如果这是一个两三百行的 PR人工 reviewer 很可能在 review 时只注意到功能流程顺不顺但很难马上想到缓存穿透这个点。Hermes 在这里更像一个能提前帮你把边界场景想一遍的辅助大脑。5. 我跑 Hermes 时踩过的 7 个坑与排查记录5.1 Review 评论没有出现bot 像睡着了一样第一个遇到的问题是 workflow 明明执行成功但 PR 页面没有任何评论。排查后发现问题出在 workflow 里的permissions配在了 job 级别而 Actions 默认的GITHUB_TOKEN是只读的导致 Hermes 调用 GitHub API 创建评论时没有权限。解决方案很直接把permissions提升到 workflow 顶层并显式声明pull-requests: write。同时记得避免使用过于宽泛的permissions: write-all最好按最小权限给以免安全扫描工具报警。5.2 PR diff 太大模型上下文被截断另一个高频坑是 PR 改动太大。默认的模型上下文窗口有限如果一次 PR diff 超过模型窗口Hermes 要么报错要么只审到一半结果会出现后半部分文件完全没有评论的情况。处理方式我在前面提过配置diff-strategy为filtered或sampled。我后来还把 workflow 里加了文件数量判断如果单次 PR 变更文件超过 30 个就跳过自动审查只在摘要中提示PR 过大建议人工 review。这比硬撑着让模型吞下一大堆半截上下文靠谱得多。5.3 行级评论落在错误的代码行这类问题非常影响体验。明明 diff 显示某行有改动评论却贴到了另一个相似函数附近。原因是 diff 上下文里的行号计算有偏差Hermes 内部在把模型输出映射回 GitHub line 时没有正确识别新文件行号。这个问题在很多 AI review 工具里都存在。排查以后我会在构造请求前先把 diff 文件的行号映射表拉取下来确保传给模型的输入本身带上新文件行号字段并要求模型在 JSON 输出里引用行号而不是只写代码片段。只要提示词里明确写每条问题必须包含 exact_line 字段评论错位的问题基本能消失。5.4 同一问题被重复评论翻来覆去刷屏当 PR 里同一个函数被修改了多次Hermes 每轮都可能针对当前版本提出相同的隐患。比如第一次 review 时它发现某函数缺少空值校验并提出了修改开发者还没改只是去改了另一个文件于是新一轮 review 又对同一个空值校验问题重复评论。对策是在 Hermes 的规则引擎里加一个相似度去重模块。每轮审查前先把历史评论里的标题和行号提取出来计算与计划生成问题的相似度如果相似度超过一定阈值就丢弃这条新评论。这个去重功能一开始让我觉得它不聪明但实际却挽救了 PR 页面的阅读体验。5.5 提示词写得太宽泛审查结果全是正确的废话早期我把提示词写成请检查这个PR的正确性和代码质量Hermes 的输出大多是建议完善单元测试建议优化性能这种放之四海皆准的废话。后来我把项目里常见的 Bug 类型和反面案例写进规则里比如本仓库历史 issue 中出现过金额精度丢失请重点检查改动是否涉及精度转换审查效果才有质的提升。提醒所有想用通用大模型做自动 review 的人不要指望模型自动理解你项目的业务坑。这些坑不写进提示词它不知道也不可能猜得到。5.6 并行审查多个 PR 导致结果互相覆盖当团队同时开了四五个 PRHermes 服务如果是自己部署的没有做并发队列控制可能会出现在进程里同时跑多个 review 请求最后写回结果时用的是同一个全局变量导致评论写到了不在审查范围内的另一个 PR 上。排查这个问题比较费劲因为现象像是评论随机漂移。最终解决方法是把每次 review 的上下文封装成独立对象并发处理时用 pull request ID 作为唯一隔离标识所有写操作都从该上下文中取值。在实际生产环境里这个并发设计比想象中重要得多。5.7 模型判断阻塞问题准确率不高乱打标签Hermes 如果直接给 PR 设置request changes状态一旦模型判断失误会很影响开发体验。这也是我建议团队在引入初期不要开启自动请求变更的原因。比较好的折中是使用 label 而不是官方 request changes 状态让 Hermes 添加blocking标签表示这里有几个问题需要人工确认然后再配合分支保护规则只有 maintainer 确认后才允许合入。这样既保留了强制校验入口又给了人最终裁判权。6. 团队落地 Hermes 后的一些个人经验6.1 先在建议模式跑上一周再决定要不要收严如果你们团队从没有用过 AI 代码审查我会特别强调开始的 7 天到 14 天Hermes 统一跑在建议模式它只发评论不建议不阻塞不打标签。这样做主要有两个好处。第一开发者不会产生被机器否定的抵触感。人是有情绪的突然有个 bot 在每个 PR 上都留言这里有风险团队很容易产生反感。先用建议模式让大家看到它确实能发现真问题信任感建立起来之后再慢慢打开更严格的开关。第二你有机会根据实际准确率调整规则。如果模型在某些文件类型上总出错也就是误报率偏高那就需要把这类文件加进 exclude 名单。盲盒式的上架规则只会让团队更混乱。6.2 人机分工AI 看低级错误人看架构与业务意图在一次项目回顾会上我们团队形成了一个很明确的共识Hermes 的评论可以作为开发者的第一轮自查清单但不能替代正式 reviewer。具体分工是机器负责性价比高的重复劳动比如变量作用域理解、空指针风险、错误处理缺失、资源泄漏人则聚焦在架构决策、业务方案、接口设计、跨模块影响这些机器没有全局思考能力的层面。这个分工落地后团队的迭代节奏明显快了不少。开发者在提交 PR 前会先跑到 Hermes 结果把基础问题清理掉reviewer 打开 PR 时看到的已经不是满屏低级错误而是真正需要讨论的架构问题。6.3 控制成本要从 prompt 长度和模型档位下手只要按 API 调用次数计费AI 审查就有成本。代码评审不是一个低频率动作每次 PR 的每次 commit 都可能触发消耗。控制成本有几个思路第一过滤掉低价值文件别为 lock 文件和生成的代码浪费 token第二采用令牌桶限流同一 PR 在短时间内多次 commit 时不每次都触发全量审查而是合并成一次延迟审查第三根据仓库重要性选择不同档位的模型重要业务模块用小而强的专用模型普通文档和测试代码可以用便宜的模型做粗粒度检查。6.4 后续扩展让 Hermes 不只是审代码最后说一个我准备往下做的方向。Hermes 的审查能力如果做得足够模块化可以进一步接风险卡片、自动化测试建议、甚至安全扫描联动。比如 Hermes 识别出某个改动修改了用户登录接口自动触发对应模块的集成测试或者识别出一个涉及 PII 数据的改动然后往 PR 上挂一个隐私影响提示的卡片。这些能力目前在配置层面都已经能通过写自定义规则和 webhook 完成只是需要团队一点点去积累和打磨规则库。我自己的经验是自动化代码评审这类工具最重要的不是 AI 模型本身有多强而是团队的规则积累和反馈闭环能不能转起来。Hermes 给了这套流程一个很适合延伸的载体但它不会替你定义什么叫好的代码。把标准想清楚、写进规则、持续迭代比换一个更强的模型要重要得多。
返回列表