多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Hermes智能体接入GitHub PR审查:自动化代码评审实战与避坑指南

Hermes智能体接入GitHub PR审查:自动化代码评审实战与避坑指南 一提到 GitHub PR 审查很多人的第一反应是“又要花时间看代码了”。我在团队里算看 PR 比较多的那类人每周几乎有一半时间耗在 review 上有时候一个下午就在几个 PR 之间来回切。后来我把 Hermes 接进了 GitHub 的 PR 流程让它先做一轮自动化代码评审人工只看它筛出来的问题和它拿不准的地方节奏一下就变了。这篇文章就围绕 Hermes 这个智能体讲清楚它到底怎么干活、我为什么要拿它做 PR 自动化评审、完整的接入过程以及那些文档里不会写但实际一定会踩的坑。这套方案不是什么大厂的专利也不需要很重的平台支撑。一个能跑 Docker 或 Python 的服务器、一个 GitHub Token、一个模型 API Key基本就够了。适合那些 PR 数量开始多起来、团队人数在 5 人以上、但又不希望为了 code review 引入一套重型 SaaS 工具的团队。读完这篇文章你可以照着把它搭起来也可以只参考思路把其中一部分用在自己的流程里。1. 先搞清楚Hermes 是怎么干活的1.1 Hermes 的本质一个能“动手干活”的智能体很多人一听到 Agent、智能体第一反应是“这不就是个聊天机器人吗”。其实区别挺大。聊天机器人是你说一句、它回一句所有事情都在对话框里结束。Hermes 这一类智能体框架的核心是“感知 — 决策 — 行动”的闭环它能拿到外部信息基于大模型做判断然后通过工具去执行具体动作再根据执行结果决定下一步。拿人做类比更直观。普通对话机器人是“顾问”你问它意见它只动嘴。Hermes 更像“实习生”你给它一个目标和必要的工具它会自己去查资料、跑命令、整理结果、把结论写进指定的地方。做 PR 审查这件事本质上不是“聊天”而是“读完 diff、给出意见、提交 review”这刚好是智能体擅长干的活。我用的 Hermes 是开源的那套 agent 框架支持本地部署。它有几个关键设计一个是 Skill技能相当于给智能体预置的“岗位说明书和操作手册”另一个是 Tool工具让它能真正调用外部系统比如 GitHub API、文件系统、命令行。把这两样组合起来就能把“审查 PR”这个流程变成它的一项固定技能。1.2 为什么我选 Hermes 而不是直接写脚本你可能会问PR 自动审查而已直接写个 Python 脚本调用 GitHub API再丢给大模型不也行吗确实行我也这么干过。但脚本方案有几个很别扭的地方脚本的逻辑是写死的换一个审查场景就要改代码、改参数。没有记忆和上下文管理的概念多文件、多轮审查时模型的上下文组织全靠自己拼。输出格式不统一想让它“在指定位置评论、按严重级别分类、总结摘要”得自己写很多胶水代码。扩展性差下次想做 commit message 检查、issue 分类又要重新写一套。Hermes 把这些都抽象成了可配置的东西。它自带模型调用管理、上下文组装、工具调用的基础能力我只需要写好“审查 PR 这个岗位”的 Skill告诉它用什么工具、按什么顺序执行、输出什么格式剩下的执行细节由框架处理。换项目、换语言、换审查规范改 Skill 文件就行不用动主程序。对工程团队来说这种“行为可编程、逻辑可维护”的设计比一坨脚本好太多了。1.3 一套 PR 自动审查系统由哪些部分构成先说整体架构免得后面看配置时一头雾水。我把这套系统拆成四层触发层负责回答“什么时候启动一次审查”。最常用的是 GitHub Actions在 PR 打开、更新、被评论时触发也有团队用定时任务去扫指定时间段内的 PR。执行层就是 Hermes 这个 agent。它接收触发层传来的 PR 信息加载对应的 review Skill开始干活。模型层Hermes 本身不产生判断它背后接了大型语言模型。我这边接的是 DeepSeek 的 API你也可以用其他兼容 OpenAI 协议的模型服务。模型负责“读代码、发现问题、组织语言”。反馈层Hermes 干完活之后通过 GitHub API 把审查结果写回 PR可以是在代码行内评论、也可以是整体 Review 摘要、还可以在 CI 里阻塞合并。这四层各干各的通过配置和 API 串起来。我最喜欢这个结构的一点是每一层都能单独替换今天用 Actions 触发明天想改成 webhook没问题今天用 DeepSeek明天想换别的模型改个环境变量就行。2. 为什么说 PR 自动化评审是“生产力投资”2.1 人工评审的痛点我估计你也有先说一个让我下决心做自动化的场景。有一次我 review 一个改动涉及前端组件、后端接口、数据库迁移三个部分。我在三个文件之间来回点得先回忆这个组件当初为什么这么设计、再查那个接口的调用方是谁、还要看数据表现在的数据量——还没开始真正审20 分钟已经过去了。这还只是一个 PR团队一天少说有三五个。另一个痛点是记忆断层。我们不可能对所有代码都保持新鲜记忆尤其是那些一个月前写的模块。人工 review 时经常出现的情况是看着一段代码觉得“好像有问题”但想不起来当初的背景或者压根没注意到某个文件的改动因为 PR 里文件太多了GitHub 默认折叠了部分文件。还有个更实际的问题重复劳动。每次 PR 都可能犯同样的低级错误比如忘了处理 None、没写单测、日志里直接打了敏感信息。人工审一遍看到这些会很烦躁但你又不能不看因为不看就可能漏到线上。2.2 自动化评审能做什么、不能做什么我必须先把预期管理做对自动化的价值在于“初筛”和“兜底”不是“替代人”。在我实际使用中Hermes 能做的包括从 diff 里找出明显的逻辑问题比如空指针风险、越界访问、忘记 return。识别测试缺失。新增了函数但完全没有对应单测它会直接指出。检查代码风格和规范一致性比如命名、格式、异常的吞掉方式。发现潜在的安全隐患比如敏感信息硬编码、SQL 字符串拼接、不安全的依赖版本。总结 PR 的影响面给人工 reviewer 提供一个“先看哪里”的地图。它不能做什么也很清楚不能理解业务上的“为什么”不懂团队内部的政治和默契也不知道某个看似糟糕的实现是为了兼容某个历史问题。这些判断必须由人来下。我给自己定的原则是让 Hermes 当“先读一遍代码的实习生”它把报告和行内评论交上来我来做最终裁决。有了它很多 PR 我可以只花十几分钟看重点而不是花一个多小时从头到尾啃。2.3 什么样的团队最适合上这套方案不是所有团队都需要。如果你的 PR 量很少一周就两三个那人工 review 完全够没必要引入自动化的运维成本。但如果你的团队有下面几个特征那这套方案会很值5 人以上开发团队每天有多个 PR 同时在流动。存在大量“例行维护型”代码改动比如依赖升级、配置调整、格式重构。团队成员分布在多个项目里没人能对所有代码保持全局记忆。有开源项目或对外项目需要给外部贡献者的 PR 做基础质量检查。我见过一些开源项目其实已经把类似的事情做得非常重了比如自动跑 lint、自动跑测试、自动检查 CLA 签名。把 Hermes 加进去之后能再多一道“自动读代码”的关卡对维护者来说是实打实省时间。3. Hermes 接入 GitHub PR 审查的完整实操3.1 部署与模型配置我这边是用 Docker 部署的 Hermes原因很简单本机环境太杂团队其他成员也要用同样的环境容器化可以保证行为一致。基础安装大概三步前提是你已经装好了 Docker 和 Git# 拉取 hermes 相关镜像不同版本按仓库说明调整 docker pull hermes-agent/hermes:latest # 准备一个工作目录 mkdir -p ~/hermes-review cd ~/hermes-review接下来要配置模型服务。Hermes 支持通过环境变量或配置文件指定模型 provider。我用的配置文件大致长这样具体字段以你选的版本为准model: provider: openai-compatible base_url: https://api.deepseek.com/v1 api_key: ${DEEPSEEK_API_KEY} model: deepseek-chat temperature: 0.1 max_tokens: 4000这里有个细节审查代码这种事温度一定要调低我直接设成 0.1。如果温度太高模型会“发挥”输出一些其实并不存在的问题。审查需要的是稳定、保守、可预期不是创意。然后启动容器docker run -d \ --name hermes-review \ -e DEEPSEEK_API_KEY你的key \ -v ~/hermes-review:/workspace \ hermes-agent/hermes:latest3.2 给 Hermes 配上 GitHub 的“手”和“眼”让 Hermes 能操作 GitHub核心是给它一个 GitHub Token。这里强调一下我用的是 fine-grained personal access token不是经典的直接给全部 repo 权限。在 GitHub 后台创建 fine-grained token 时仓库权限这样配最稳Repository access只勾选需要被审查的仓库Permissions → Pull requestsRead and write因为要提交 reviewPermissions → ContentsRead only因为要拉取代码和 diffPermissions → IssuesRead only如果要让它顺带关联 issue 就开拿到 token 之后把它放进 Hermes 能读到的环境变量里我习惯命名成GITHUB_TOKEN这样很多现成工具默认就能读到docker run -d \ --name hermes-review \ -e DEEPSEEK_API_KEY你的key \ -e GITHUB_TOKEN你的token \ -v ~/hermes-review:/workspace \ hermes-agent/hermes:latest这里提醒一句Token 千万别写进代码仓库尤其是 public 仓库。我看过不止一次有人把 token 直接写在 workflow 文件里提交上去这是一等一的安全事故。3.3 编写一个 review_github_pr 的 Skill这是整套方案里最核心的部分。Hermes 的 Skill 一般是一个目录里面有描述文件、提示词文件和脚本文件。我做了一个叫github_pr_review的 Skill结构如下skills/ └── github_pr_review/ ├── SKILL.md # 技能说明给 Hermes 看的岗位手册 ├── review.py # 实际操作脚本拉diff、调API、提交评论 └── prompts/ └── reviewer.md # 审查提示词定义模型怎么读代码SKILL.md里写的不是给用户看的而是给 Hermes 看的“操作指引”大意是当收到一个 GitHub PR 审查任务时按以下步骤执行。我写的核心流程是这样的1. 从任务参数中获取 owner、repo、pull_number。 2. 调用 review.py 拉取 PR 的完整 diff 和基本信息。 3. 将 diff 按文件拆分逐个交给审查提示词处理。 4. 汇总所有发现的问题按严重级别排序。 5. 通过 GitHub API 提交 review行内评论走 PR review comments。review.py里主要做两件事拉取数据和提交评论。拉取 diff 用的是 GitHub REST API关键接口是GET /repos/{owner}/{repo}/pulls/{pull_number}/files这个接口能拿到每个文件的 patch也就是真正的代码改动内容。提交整体审查意见用的是POST /repos/{owner}/{repo}/pulls/{pull_number}/reviewsbody 里带上event: COMMENT或者event: REQUEST_CHANGES、comments数组放行内评论。这就是 Hermes 作为 agent 和普通脚本最不一样的地方它有明确的“动作”——不只是给出建议文本而是直接把 review 提交到 PR 上。3.4 用 GitHub Actions 把它串成自动化流程部署好 Hermes、配好 Skill 之后还需要解决一个问题一个 PR 产生时怎么自动触发 Hermes 跑起来我用的是 GitHub Actions。在仓库里建.github/workflows/pr-review.yml内容大致如下name: Hermes PR Review on: pull_request: types: [opened, synchronize] jobs: hermese-review: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkoutv4 - name: Run Hermes review env: GITHUB_TOKEN: ${{ secrets.HERMES_GITHUB_TOKEN }} DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} PR_NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} run: | docker run --rm \ -e GITHUB_TOKEN$GITHUB_TOKEN \ -e DEEPSEEK_API_KEY$DEEPSEEK_API_KEY \ -e PR_NUMBER$PR_NUMBER \ -e REPO$REPO \ hermes-agent/hermes:latest \ run skill github_pr_review \ --params repo$REPO,pull_number$PR_NUMBER这个 workflow 会在 PR 打开opened或有新提交synchronize时启动。这里我没有在pull_request事件里加review_requested因为实际体验中PR 刚创建时自动审一次新代码推上来再审一次已经覆盖了绝大部分场景。还有一个细节要处理重复评论的问题。如果 Hermes 每次跑都提交新的 reviewPR 上会堆满重复意见。我的做法是在review.py里先查一下这个 PR 是否已经有 Hermes 机器人的 review有的话就先删除原来的、再提交新的。这样 PR 上始终只有一份“当前状态”的自动审查结果不会刷屏。3.5 一次真实 PR 审查的运行记录记录一次实际的执行过程更能说清楚这套系统工作起来是什么状态。有一天同事提交了一个 PR改动内容是给现有的订单查询接口加一个排序参数。PR 刚 push 上去Actions 就被触发了。Hermes 容器启动拉下了这个 PR 的 diff里面有订单查询服务的主逻辑、一个数据模型的字段调整、还有两个测试文件的用例补充。Hermes 的审查结果分了三块整体摘要说明这次改动是给订单查询增加排序能力涉及查询服务、模型层和测试。行内问题在数据模型字段那里提了一个问题说新增字段没有默认值可能会导致存量数据在反序列化时报错。改进建议建议把排序字段的校验提到入参层避免无效值穿透到数据库层。我看了之后发现“存量数据没默认值”这个点确实是我们会踩的坑就给同事提了一句。其他建议属于可选优化没有强制。整个 PR 从提交到收到自动审查结果大概 3 分钟。换成以前同事可能要等我有空才能看到。这个案例里有意思的不是 Hermes 发现了什么高级 bug而是它把“人工 reviewer 可能会忽略的盲区”提前拎了出来。增量字段做兼容处理这种事最容易在快速迭代中被漏掉。4. 把提示词和规则打磨到“好用”的状态4.1 审查提示词的三个层次让 Hermes 审查效果好的关键不在框架配置而在提示词。我把提示词拆成三层每层解决不同的问题。第一层是角色和目标。告诉模型它是“资深代码审查工程师”任务是找出代码中的缺陷和风险输出清晰、可执行的意见。这一层要让模型进入状态避免把代码审查做成“代码赞美”。第二层是项目上下文。这一层写项目的技术栈、已知规范、重点目录。比如我有个 Java 项目规范里要求所有对外接口必须做参数校验那这一层就会写上这条让模型遇到“Controller 层没校验参数”的情况时优先提醒。项目上下文写得好审查结果才会有“我们自己人”的感觉而不是放之四海皆准的空话。第三层是单 PR 的具体指令。这一层针对当前这次审查比如说“重点看数据库迁移文件”“对新增的并发逻辑做风险分析”。这一层的指令可以由触发参数动态拼进去。三层提示词分别放在 Skill 的不同文件里组合之后再发给模型。好处是改规范只改一层不用把一整段提示词推倒重来。4.2 不同技术栈的审查侧重点同一个提示词审所有项目效果会很差。不同语言、不同场景容易出问题的点完全不一样。我自己维护了多套针对不同技术栈的审查要点放到各自的 Skill 或提示词片段里。举几个例子技术栈 / 场景重点审查项Python 项目类型注解是否缺失、异常是否被过度吞掉、None处理是否安全、上下文管理器是否用对Java Spring 项目空指针风险、对 null 的防御、Bean 注入方式、事务边界是否合理、对外接口参数校验JavaScript / TypeScript异步操作有没有 catch、回调地狱迹象、可选链使用、any是否被滥用前端 React组件依赖数组是否写对、副作用清理函数是否存在、状态更新的不可变性问题数据库迁移脚本是否锁表风险、是否为存量数据提供默认值、回滚方案是否缺失所有项目通用敏感信息硬编码、基本的安全问题、测试是否覆盖新增逻辑、死代码表格里的这些点看起来都不难但让一个模型记住每次都要检查需要在提示词里明确列出来。模型不会自动知道你的团队在意什么你要把它写进“工作要求”里。4.3 控制误报让 Hermes 学会“闭嘴”自动化审查最怕的是什么是狼来了。如果 Hermes 每次都报一堆“可能有问题”而且大部分其实不是问题那团队很快就会无视它整套系统就废了。我控制误报的方法有三个严重级别分级。我把问题分成 P0必须修比如安全问题、明显的 bug 风险、P1应该修比如缺少测试、异常处理不当、P2建议风格与优化。默认只有 P0 和 P1 会触发REQUEST_CHANGESP2 只作为普通评论出现。提示词里明确写“不要对没有充分把握的问题使用确定性语言”。也就是说如果模型不确定是 bug就用“建议确认一下”的措辞而不是“这里一定会出问题”。这能显著降低对抗情绪。维护一个 ignore 列表。有些模式是项目有意为之的比如为了向后兼容写的冗余逻辑。把这类规则放进项目上下文里让它不要重复报警。还有一个更进阶的做法把人工 review 的结果反馈给 Hermes。当我关闭某条 Hermes 的评论并标记为“无效”时后续的 skill 规则会把这类意见加入忽略规则。这就形成了一个简单的学习闭环虽然需要一点手动维护但时间长了审查噪音会明显下降。5. 踩坑实录与问题排查5.1 GitHub API 限流第一个拦路虎接入第一天我就遇到了限流。当时 Hermes 审查几个 PR 之后突然全部失败日志里出现 403。查了一下是 GitHub API 的 rate limit 被触发了。未认证的请求一小时只有 60 次认证之后是一小时 5000 次按仓库的请求量本来够用问题是pull request files接口每次会返回完整 diff如果一个 PR 有几十个文件一个 PR 就可能消耗掉几十次请求。我的解决办法分两步。一是确保所有请求都带上了 token这能直接拿到 5000 次/小时的额度。二是做缓存对同一个 PR 的 diff 在本地保存一份重复审查时不重复请求。还有一个更省的做法用 GitHub 的 GraphQL API 替代 REST可以在一次请求里拿更多数据但 GraphQL 的查询逻辑更复杂我们最后没采用对大多数团队来说REST 加缓存已经够了。5.2 上下文窗口不够长 PR 怎么审刚开始跑正式 PR 时第二个坑来了一个大 PR 改了 30 多个文件diff 加起来几万行。模型的上下文窗口根本塞不下。我当时试过直接把大 diff 截断结果 Hermes 只审查了前面几个文件后面全漏了。后来我换成了“分片审查”策略。每个文件单独跑一轮模型调用让模型基于“这个文件的 diff”产出意见然后再跑一个汇总调用把各文件的意见合并成一份完整的 review。好处是每个文件都能被审到坏处是模型看不到文件之间的跨文件影响。针对这个问题我做了个折中对超过一定行数的关键文件单独看同时把变更文件清单和目录结构传给模型让它感知到“有哪些文件一起变了”跨文件的深度联动留给人来判断。5.3 Review 评论刷屏机器人也是要面子的有一版配置我印象很深Hermes 能在 PR 上留下几十条行内评论改了几个小问题直接刷了一整屏。同事在群里说“这个机器人话太多了”。确实满屏的 P2 级风格建议会让真正的 P0 问题被淹没。我的调整方案是“评论分层”P0 和 P1 的问题走行内评论P2 的优化建议统一汇总到整体 Review 的 body 里不占用行内评论位。整体 body 里还加了一个摘要区用列表把最需要关注的 3 个问题放在最上面。这么一改PR 页面看起来清爽多了人也能一眼抓到重点。5.4 权限与安全别把 Token 玩坏了自动审查涉及到代码和安全这块我宁可多啰嗦几句。Token 权限遵循最小化原则只给这个仓库的读权限和提交 review 权限不给写代码的权限。另外GitHub Actions 的 secrets 里存的 token 和生产环境隔离每个人都有自己的一套测试 token不要共用一个。还有一个容易被忽视的点模型服务的安全性。代码 diff 是敏感数据尤其对闭源项目来说把代码发到外部模型 API 之前一定要确认这件事符合公司或团队的数据安全规范。如果要求严格可以用私有化部署的模型服务或者启用本地小模型。技术上限可以妥协数据红线不能碰。5.5 模型的“幻觉”误判它太自信了最后这个坑很有意思。有一次 Hermes 在一个 PR 里斩钉截铁地指出“这里有一个数组越界访问会导致程序崩溃”我看了半天发现那段代码的索引是在循环里动态计算的边界条件其实是安全的。模型看到“下标访问”就条件反射地认为越界属于典型的幻觉误判。这种事没法完全避免但可以降低概率。我后来在提示词里加了一句“在报告 bug 之前先走一遍伪代码执行过程确认该路径在真实逻辑中可达且会触发问题。”这招对减少误报很有效。模型的推理链路一旦被要求“先模拟执行再下结论”它的中位数水平会提高不少。当然这是概率性问题不要指望 100% 准确这也是为什么我一直强调最终决定必须由人来下。6. 最后说点个人体会这套方案从我搭起来到现在跑了大半年最大的感受不是“省了多少时间”而是团队对 PR 审查的心态变了。以前 review 是一个需要“专门腾出时间”的任务现在成了一个自动化的起点——PR 一开机器先把底稿交上来人只需要做判断题。我个人觉得做这类自动化最有价值的不是技术本身而是把团队的代码习惯逐渐沉淀成了机器可读的规则。审查标准不再藏在某几个人的脑子里而是在 Skill 文件里、在提示词里、在 ignore 列表里。新人来了看一遍配置就知道团队在意什么老员工改代码也会心里有数“自动审查会盯什么”。如果你也想试我的建议是不要一步到位。先把“自动生成 PR 摘要和影响面分析”跑起来让团队适应机器人参与 review 的感觉再逐步加入行内评论、严重级别、阻塞合并这些能力。给人和机器都留一个磨合期这套系统才能真正长在你的团队里。
返回列表