ARTICLE DETAIL

资讯详情

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

Hermes智能体框架实现自动化PR代码评审的完整实践

Hermes智能体框架实现自动化PR代码评审的完整实践 每个经历过大型项目的人估计都逃不过被 PR 支配的恐惧。一个改动几千行的 PR 躺在列表里嘴上说着“马上看”实际拖到下班也没看完好不容易打开 diff翻到第十个文件已经忘了前面改的是什么更别提那种凌晨两点被 CI 挂掉通知吵醒结果发现只是某个人忘了加分号的场景。所以当我第一次在内部项目里跑通 Hermes 自动化代码评审时我只有一个感觉这东西应该早点搞。Hermes 本质上是一个可编程的智能体执行框架我们可以把它当成一个不需要睡觉、不会情绪化、记忆力超级稳定的审查员给它接上 GitHub 的 PR 事件它就能自动拉取 diff、跑静态检查、按团队规范逐条核对然后把评审意见以评论的形式贴回 PR 页面。这篇文章我打算从设计思路、实操配置、参数调优到问题排查完整梳理一遍给想把代码评审自动化落地的团队一份可以直接抄作业的参考。1. 为什么需要自动化 PR 审查1.1 代码评审的常见痛点先说说没有自动化之前团队里的代码评审是什么状态。小团队三五个人可能还能靠口头沟通撑着一旦过了十个人PR 队列就会变成沼泽。最典型的问题有三个第一个是评审延迟写代码五分钟等评审两小时有时候一个 PR 挂两三天没人碰迭代速度被拖垮第二个是评审质量不稳定经验丰富的老员工一眼能看出来的问题新同学可能要盯半天而且每个人关注点不一样有的人只管逻辑对不对不看命名规范有的人对注释执念极深但完全放过了潜在的并发问题第三个是知识沉淀困难很多评审意见其实是在重复说同一类事情这个月在说“异常不要吞掉”下个月还在说因为没有工具把这类规则固化下来。这三个问题叠加在一起就会形成一种恶性循环评审越慢大家越想绕开评审绕开评审线上出问题的概率就越高出了问题又要花更多时间修留给评审的时间更少。我见过最夸张的一次一个涉及支付金额计算的 PR 因为“太忙了没细看”被直接合并两周后线上多了好几笔异常单。那之后我们团队才下定决心要把代码评审里那些机械的、重复的、规则明确的部分交给自动化工具。1.2 Hermes 能解决什么问题Hermes 在这套流程里扮演的角色不是取代人类评审而是先把那些“一眼就能看出问题”的部分扛下来。它擅长的事情包括但不限于检查代码风格是否符合团队规范变量命名、缩进、注释格式、检测明显的反模式空 catch、硬编码密钥、过度嵌套、核对是否缺少必要的测试用例、分析变更范围是否与 PR 描述一致甚至可以结合历史提交记录判断这次改动的风险等级。我们的实际使用效果是Hermes 能在 PR 打开的 1 到 3 分钟内给出第一轮意见把大概 60% 到 70% 的格式类、惯例类问题在人工介入之前解决掉。人工评审者会把注意力集中在架构设计、业务逻辑、性能隐患这些真正需要经验和判断力的地方。这相当于让工具先做粗筛人做精审两头都不耽误。而且 Hermes 的评审意见是记录在 PR 评论区的新人可以通过这些评论快速了解团队规范老手也可以拿它当兜底检查网。2. Hermes 的整体设计与方案选型2.1 Hermes 是什么很多第一次听说 Hermes 的人会以为它只是一个写死的规则检查器实际上它的定位更接近一个可以编排多种能力的智能体执行框架。你可以给 Hermes 配置多条 Skill每个 Skill 对应一类任务比如“安全扫描”“测试覆盖检查”“变更逻辑分析”。每个 Skill 内部可以调用不同的底层模型比如 DeepSeek、GPT、Claude 这类大语言模型也可以调用命令行工具比如 eslint、go vet、ruff还可以调用 GitHub API 拉取数据。这种设计最直接的好处是灵活。团队今天想换一个审查模型不需要重写整个系统只要改配置明天想加一条“所有数据库迁移文件必须附带回滚方案”的规则也不需要改代码加一条 Prompt 规则就行。我记得第一次跑通的时候我们只花了半天时间就把一个之前用 GitHub Actions 正则脚本实现的简易审查器迁到了 Hermes 上面功能还翻了倍。2.2 为什么选 Hermes 而不是其他方案在选择方案的时候我们也对比过其他几条路。最简单的是直接在 GitHub Actions 里写一堆 shell 脚本调 linter、跑测试、把结果用 bot 发到 PR 评论。这套方案对小项目来说够用但脚本逻辑一复杂就非常难维护尤其是“根据上下文决定是否报警”这类需求shell 脚本几乎写不动。另一个方向是直接用某个 AI 模型的 API把 diff 一股脑丢给它生成评审意见。这个方案的问题在于模型输出不稳定有时候给出很棒的建议有时候又开始胡说八道而且没有一个结构化的框架去管理“什么时候跑、跑哪些检查、结果怎么反馈”。Hermes 等于把这两者的优点结合到了一起规则的稳定性来自可编排的 Skill 和明确的 Prompt灵活性来自底层模型的可替换性再加上它本身自带事件监听和 GitHub 集成省去了我们搭一套消息管道的功夫。2.3 整体工作流程拆解Hermes 的 PR 审查流程按照我们项目的实际配置可以拆成五个阶段。第一阶段是事件监听Hermes 通过 webhook 监听 GitHub 仓库的 pull_request 事件也可以轮询某个组织下的所有仓库我个人更推荐 webhook实时性更好一些。第二阶段是数据收集Hermes 在收到事件后会调用 GitHub API 获取 PR 的 diff、提交记录、评论历史和变更文件列表这些数据会作为后续分析的原始素材。第三阶段是任务分发Hermes 的调度器会根据变更文件类型把检查任务分发给不同的 Skill比如 .py 文件交给 Python 规则 Skill.ts 文件交给前端规则 Skill涉及依赖变更的额外触发安全审查 Skill。第四阶段是汇总分析各个 Skill 的结果会汇总到一个统一的报告结构里这个结构包含风险等级、问题类型、文件位置和修改建议。第五阶段是反馈执行Hermes 把报告格式化为人类可读的评论通过 GitHub API 发布到 PR 的评论区同时如果有失败阻断级别的检查项还可以把 PR 标记为“请求变更”。这套流程里最容易被人忽略的是第二个阶段。很多人觉得把 diff 给模型不就行了但实际上一个完整的上下文比 diff 本身重要得多。比如 PR 的描述信息能告诉模型这次改动的意图变更文件里有没有新增的依赖能帮助判断风险提交信息是 fix 还是 feat 会影响检查的严格程度。我们踩过的坑是早期只把 diff 发给模型结果模型经常把无关的历史代码也当作新增问题来报噪音非常大。后来把所有元数据一并传给 Hermes让它用结构化的方式组织上下文准确率才上来。3. 核心细节解析与实操要点3.1 接入 GitHub PR 的两种方式Hermes 接入 GitHub 的方式主要有两种我在实际项目里都试过。第一种是 Webhook 模式在 GitHub 仓库的 Settings 里配置一个 Webhook URL指向 Hermes 暴露的 HTTP 服务事件类型选择 pull_requestGitHub 会在 PR 打开、同步、评论等事件发生时把事件数据 POST 到这个 URL。这个模式的优点是实时性高缺点是要求 Hermes 服务必须有一个公网可达的地址另外仓库多的时候需要在每个仓库里配置。第二种是定时轮询模式Hermes 启动一个后台任务每隔一段时间比如 60 秒调用一次 GitHub API查询指定仓库或组织下的 open PR 列表再筛选出“没有审查过”的 PR 进行处理。这个模式对服务的网络要求低甚至可以跑在一台内网机器上缺点是会有一点延迟而且访问 GitHub API 的频率要控制好不然会撞上速率限制。我们内部生产环境用的是 Webhook 模式本地开发调试用的是轮询模式两个互补。如果要在 Webhook 和轮询之间选我的建议是看你的服务部署位置。能拿到公网地址就果断用 Webhook省资源还及时部署在防火墙后面的话就老实轮询稳定性比实时性重要。3.2 关键配置项与参数计算Hermes 的配置文件支持多个关键参数这里挑我调过的重要配置展开讲。第一个是审查并发数concurrency。这个参数决定同时处理多少个 PR。别看它只是一个数字设大了会疯狂消耗上游模型的 API 额度设小了 PR 一多就会排队。我们当时的计算方式是估算一个 PR 的平均处理时间大约 40 秒再算高峰时每十分钟新增的 PR 数量大约是 8 个那么并发数至少要能在一波请求产生后十分钟内消化掉取一个安全系数最终设成了 4。这个值在高峰期够用平时也不会空转太多。如果你的 PR 量更大可以把并发数往上调但一定要确认模型 API 的 QPS 上限。第二个是模型路由配置。Hermes 允许为不同 Skill 指定不同模型我们的经验是简单规则类检查比如命名规范、行长度用速度快的轻量模型复杂逻辑分析比如并发安全问题、架构合理性用能力强的旗舰模型。这样既保证了响应速度又控制了成本。以 DeepSeek 为例它的 API 价格在同类模型里非常有竞争力我们的成本测算显示一个月处理 800 个 PR调用它的总费用大概是每个 PR 不到一毛钱相比人工评审的成本几乎可以忽略。第三个是风险等级阈值。Hermes 审查后会生成 0 到 1 的风险分数我们需要设定两个阈值0.7 以上标记为“请求变更”0.4 到 0.7 之间标记为“建议修改”0.4 以下默认通过。这个阈值不是拍脑袋定的我们用一个月的历史 PR 做了回测把人工标注的高风险 PR 喂给 Hermes看它在不同阈值下的命中率最终选了误报率最低的一组数字。3.3 审查规则与提示词设计审查规则是整个 Hermes 配置里最考验功力的一环。我刚开始图省事写了一条超大 Prompt试图让模型“检查一切不合理的地方”结果输出非常飘有时候像废话文学有时候又盯着一行样式问题长篇大论。后来我把规则拆成了四类。第一类是硬性规则比如“不允许出现硬编码密钥”“不允许吞掉异常”“禁止使用 eval”这类规则直接写死在 Skill 的检测逻辑里不需要模型判断准确率 100%。第二类是约定规则来自团队的编码规范文档比如“所有 public 方法必须有 Javadoc”“数据库字段名必须使用下划线命名”这类规则翻译成模型 Prompt让模型做判断。第三类是模式识别规则针对团队历史出过事故的代码类型比如货币计算必须使用 Decimal、文件上传必须校验文件类型这类规则是补充性的命中即高优提示。第四类是通用逻辑分析让模型从代码逻辑角度分析 diff 是否有潜在 bug这类规则最开放输出质量最依赖模型能力我们把它分配给旗舰模型。Prompt 设计上我学到的经验是“给示例比给定义重要”。比如定义“嵌套过深”大家都理解但模型容易把三层缩进也当问题所以我干脆给了两个正例和两个反例。正例是“这种三层嵌套可以接受因为每个分支都提前 return 了”反例是“这种五层嵌套就是典型的箭头式代码必须重构”。模型跟着示例学的速度比理解抽象概念快得多。4. 实操过程与核心环节实现4.1 环境准备与依赖安装搭建 Hermes 审查服务我推荐用 Docker 部署省去一堆本地依赖的麻烦。我在 Linux 服务器上用的命令是这样# 拉取 Hermes 镜像 docker pull hermes-agent/hermes:latest # 创建配置文件目录 mkdir -p /opt/hermes/config mkdir -p /opt/hermes/logs # 启动 Hermes 服务 docker run -d \ --name hermes \ -p 8080:8080 \ -v /opt/hermes/config:/app/config \ -v /opt/hermes/logs:/app/logs \ -e HERMES_MODEpr-review \ hermes-agent/hermes:latest如果你是本地开发调试也可以直接用 pip 安装命令行版本pip install hermes-agent安装完之后先不要急着启动我们要把 GitHub 的认证信息配好。推荐的方式是在 GitHub 上创建一个专属机器人账号然后生成一个 Fine-grained Personal Access Token这个 token 只需要分配给你要审查的仓库权限只勾选 Contents: Read 和 Pull requests: Read Write。注意千万不要用个人高权限 token 跑生产服务一旦泄露等于把你的整个代码库都交出去了。Token 配置在环境变量里export GITHUB_TOKENgithub_pat_xxxxxx export GITHUB_WEBHOOK_SECRETyour_webhook_secretWebhook Secret 是给 GitHub 回调验签用的配一个随机长字符串别用 123456 这种。4.2 Skill 配置与规则目录Hermes 的 Skill 配置放在 /opt/hermes/config/skills 目录下一个 Skill 就是一个 YAML 文件。我们团队目前维护了四个 Skill我建议新团队也从这四个起步覆盖度足够也不至于配置量太大。第一个是 code-style-skill.yaml主要做风格检查加载的语言规范包括 Python 的 PEP8 子集、TypeScript 的 ESLint 核心规则。第二个是 security-skill.yaml重点扫硬编码密钥、注入风险、不安全的反序列化、依赖版本漏洞。第三个是 test-coverage-skill.yaml它不真的跑测试而是分析 diff 中修改的代码路径是否有关联的测试文件如果没有就提醒补充。第四个是 logic-review-skill.yaml也就是让大模型做逻辑层面审查的通用 Skill。这里贴一段简化的 security-skill.yaml展示一下结构name: security-check description: 安全风险扫描 model: deepseek-chat enabled: true trigger: event: pull_request paths: - **/*.py - **/*.js - **/*.ts - **/requirements*.txt - **/package*.json rules: - id: SEC001 severity: blocker description: 检测硬编码的 API Key 或密钥 pattern: (sk-[a-zA-Z0-9]{20,}|api[_-]?key\\s*[:]\\s*[\][^\][\]) - id: SEC002 severity: warning description: 检测 eval / exec 等动态执行 pattern: \\b(eval|exec)\\s*\\( - id: SEC003 severity: warning description: 检测不安全的文件上传后缀 pattern: upload.*\\.(php|jsp|exe|sh)YAML 里的 pattern 用的是正则表达式你可以按自己项目的需要增删。这里要注意的是正则只匹配代码文本不做语义分析所以会有一定的误报。比如有人命名变量叫 api_key_validator就会被 SEC001 命中但其实不是硬编码。我们的解决办法是让 Hermes 把正则命中的结果作为“候选问题”送给模型做二次确认用模型的语义理解来过滤误报效果好了很多。4.3 运行、测试与结果验证配置完成后就可以启动 Hermes 了。如果你用的是命令行版运行hermes run --config /opt/hermes/config --repo owner/repo --pr 123这个命令意思是针对 owner/repo 仓库的第 123 号 PR 执行一次完整的审查流程。执行完后Hermes 会在终端打印出结构化的审查报告包括时间戳、变动文件数、各 Skill 结果、风险分数并自动把评论发布到 PR 页面。我在本地调试的时候习惯先加一个--dry-run参数这样 Hermes 只生成报告不打评论我可以先在终端里看结果是不是合理确认没问题再放生产。在第一次全量跑一遍之后我强烈建议做一次“回放验证”。挑最近合并的 20 个 PR其中 15 个是正常合并的5 个是后来出了问题的把这 20 个 PR 的 diff 丢给 Hermes看它的结论和真实结果是否吻合。这个回放能很直观地告诉你你的规则有没有在“正确的问题”上报警。我们第一次回放的时候发现 Hermes 对数据库迁移相关的 PR 完全沉默后来检查发现是 trigger 里的 paths 配置漏掉了alembic/versions目录补上之后就正常了。5. 常见问题与排查技巧实录5.1 高频问题速查表配置和运行 Hermes 的过程中我们遇到过不少稀奇古怪的问题。我把其中出现频率最高的几个列成一个速查表方便你直接对照排查。现象可能原因解决办法收到 webhook 但 Hermes 无响应Webhook Secret 验签失败比对 GitHub 后台配置的 Secret 与 HERMES_WEBHOOK_SECRET 是否一致评论发布失败Token 没有 Pull requests: Write 权限重新生成 token勾选对应仓库的 PR 写入权限审查结果全是“格式规范”类建议Prompt 里缺少语义分析引导增加 logic-review Skill并让规则示例覆盖逻辑问题模型 API 报限流错误并发数设置过高超过 API QPS调低 concurrency或换用响应更快的轻量模型同一个 PR 被重复审查未记录已处理 PR 状态开启 Hermes 的 dedup 开关或检查事件过滤逻辑中文注释被误报为乱码编码设置不正确确保 Hermes 服务环境变量 LANG 设为 UTF-8规则命中后没有评论展示风险等级低于汇报阈值调整 risk-score-report 阈值或强制指定 severity 为 warning 以上的规则必须展示这张表里的问题我们基本都挨个踩过。最让我难受的是第一个Webhook Secret 验签失败当时怎么查都没觉得配置有问题后来发现是 GitHub 后台保存 Secret 的时候自动给我加了一个换行符复制到环境变量的时候没注意导致两边永远对不上。排查这种问题的时候可以在 Hermes 的日志里看验签失败的具体原因通常会有明确提示。5.2 踩坑记录与避坑技巧第一个大坑是让模型直接访问仓库的全部代码。我们一开始设想既然要审 PR干脆把整个仓库的代码都发给模型让它上下文更充分。结果一个中型项目的代码就有几十万行API 请求直接超出 token 限制就算拆分成多个请求成本也扛不住。后来我们明确了一条原则只发 diff 相关的代码以及少数几个被修改的文件的完整内容。如果某个文件非常大那就只摘出和 diff 上下文相关的附近行。这样成本可控模型反而更专注在真正的变更上。第二个大坑是“模型太客气”。早期我们用默认的审查 Prompt模型给出的意见都是“建议优化”“可以考虑改进”这种软绵绵的说法。这要是给人看的还行给机器做卡点完全不够用。后来我在 Prompt 里加了非常强的约束判断属于问题就直接说“必须修改”不要加任何缓冲词如果拿不准就说“需要人工确认”禁止说空话。改完之后输出质量立竿见影评论里的垃圾信息少了 80%。第三个大坑是关于性能的。我们最初把 Webhook 服务、模型调用、评论回复都放在同一个进程里结果有一次一个 PR 有 80 多个文件diff 巨大处理时间快到一分钟期间队列里又进来 5 个 PR直接把内存打爆了。后续改成“事件入队 多 Worker 消费”的架构Webhook 只负责把 PR 事件丢进队列具体的审查任务由 Worker 进程异步处理再也没出现过进程卡死的问题。如果你的 PR 量不大可以不用上队列但如果你团队比较活跃建议早点做这个改造。结尾从最开始一个简单的“自动 lint”到后来用 Hermes 跑起来完整的 PR 审查流水线这个项目给我的最大收获不是省了多少时间而是它真的改变了团队对代码评审的认知。以前评审是“帮别人看代码”现在更接近“大家一起守质量底线”因为机器已经帮我们挡住了那些低级的、情绪化的、容易遗漏的问题人只需要做有判断力的决定。如果让我给正准备做类似事情的人一句建议不要追求一步到位先从一类最痛的问题开始比如“硬编码密钥”或者“吞异常”把这一条规则跑顺再慢慢加别的。Hermes 的优势就在于它是一个平台规则的扩展成本非常低你今天给它加一个 Skill明天它就多一项能力。我现在比较期待的方向是把历史的 PR 评论数据再喂回去让 Hermes 学习我们团队的偏好进一步减少人工二次过滤的工作量。这个坑我先挖后面跑出来了再跟大家汇报。
返回列表