用 Hermes 智能体实现自动化 PR 评审:GitHub 集成与提示词工程实战
2026/9/7 4:27:31 网站建设 项目流程

每次给仓库提 PR,等到 maintainer 有空 review 都得按天算。CI 全绿了,代码没人看,合并按钮就是不敢点。我自己维护的几个项目也这样——别人提上来的 PR,我点开之后看一眼改动量,超过 300 行的就想先放一放,然后就没有然后了。

这种状态持续了很久,直到我把 Hermes 接到 GitHub 上,让它在 PR 打开的第一时间做一轮自动化评审。这个思路本质上就是用 LLM 充当一个 7×24 小时在线的初审 reviewer:先扫逻辑问题、找边界漏洞、对照风格规范,再把结论直接贴在 PR 评论里。人类 reviewer 拿到的是已经过滤过一轮的完整报告,而不是一堆原始 diff。

这篇文章写给所有被 PR 评审拖累的独立开发者、技术负责人和 DevOps 工程师。我会把 Hermes 的定位、部署方式、GitHub 集成方案、提示词调优和踩坑记录全部过一遍,内容偏实操,命令和配置可以直接抄。

1. Hermes 是什么,我为什么把 PR 评审交给它

1.1 一句话介绍 Hermes

Hermes 是一个开源的智能体框架,核心能力是把大语言模型接到外部工具和平台上,让它能够自主完成一些工作任务。GitHub PR 自动化评审是它最常见的落地场景之一:当仓库里出现新的 Pull Request,Hermes 会拉取变更内容,用配置好的模型和提示词做分析,然后以评论形式输出评审意见。

它不是 IDE 插件那种“边写边提醒”的即时检查器,而是更接近一个专职 reviewer:有完整的上下文、有明确的评审标准、能逐条输出问题清单,还会给出修改建议。最关键的,它跑在独立的服务里,不占用任何人的开发时间。

1.2 自动化 PR 评审解决的几个痛点

我复盘过自己过去半年收 PR 的体验,最让人疲惫的其实是这四类问题:

  • 低质量 PR 占用太多注意力。比如该处理 null 的地方直接调用空对象方法、异常被吞掉、硬编码了一堆魔法数。这些一眼就能看出来的问题,完全可以交给工具拦下来。
  • 评审标准不统一。今天自己状态好,提的意见细一点;明天赶版本,看一眼就合了。自动化评审能稳定维持一个基准线。
  • 上下文切换的代价。从写代码切到评代码,大脑需要一个预热过程。如果机器先把初步结论列好,人的负担会小很多。
  • 开源项目的 contributor 体验。外部贡献者提一个 PR,几天没回应,人家就不想再提了。Hermes 能在几秒内先回复一轮,至少让贡献者觉得“这个项目是活的”。

1.3 Hermes 与 CodeRabbit、SonarQube 这类方案有何不同

这里需要说清楚,自动化 PR 评审的方案其实分两个流派:

  • 规则引擎流派:以 SonarQube、ESLint、golangci-lint 为代表。它们擅长查“是否符合规范”,比如未使用的变量、重复代码、潜在空指针、复杂度超标。优点是精准、快、无幻觉,缺点是只能查静态规则,看不懂业务逻辑。
  • LLM 推理流派:以 Hermes、CodeRabbit 这类智能体为代表。它们能理解代码的意图,顺着 diff 去推断可能的影响面,给出语义层面的建议,比如并发条件判断是否是线程安全的、Redis 缓存一致性的处理有没有漏洞等。缺点是存在幻觉,偶尔会提出根本不成立的问题。

我现在的做法是两者结合:CI 里先跑传统静态检查,任何 warning 直接让 PR 合不进去;Hermes 负责跑一遍“人脑模拟”,专门看静态检查看不见的东西。两个流派定位完全不同,不要试图用其中一种替代另一种。

2. 部署前的准备:模式选择与运行环境

2.1 三种部署方式怎么选

Hermes 本质上是常驻服务,部署方式和你的运行环境强相关。我实际测试下来,比较靠谱的有三种路线:

部署方式适合场景优点缺点
Docker Compose 单机部署个人项目、小型团队环境隔离、升级快、一条命令启动服务器内存要吃够
源码编译部署需要改内部逻辑的高级玩家可定制程度最高升级要自己管,依赖容易冲突
Kubernetes 部署中大型团队、多仓库接入弹性伸缩、多实例负载维护成本明显偏高

如果你的仓库只有一两个,我建议直接用 Docker Compose。服务器配置 2C4G 起步,只要能跑得动目标模型就行。如果你打算在本地用 Ollama 跑小模型做一个低成本方案,那部署机的内存建议 16G 以上,否则加载模型之后服务会非常卡。

2.2 配置文件的骨架与关键参数

Hermes 的主配置文件是 YAML 格式,我把自己在用的版本简化后贴一下,省的你去翻文档:

server: host: 0.0.0.0 port: 8080 github: app_id: 123456 private_key_path: /etc/hermes/private-key.pem webhook_secret: "your-webhook-secret" llm: provider: openai_compatible base_url: http://localhost:8000/v1 api_key: "sk-local-test" model: qwen2.5-coder:32b temperature: 0.1 max_tokens: 4096 review: # 只审查这些路径下的改动,避免把依赖锁文件也扫一遍 include_paths: - "src/**" - "api/**" exclude_paths: - "*.lock" - "vendor/**" # 按文件变更行数动态调整任务的拆分粒度 max_diff_size: 20000

这里有几个点值得细说:

  • temperature: 0.1。评审场景需要的是稳定性和确定性,不是创造性。如果温度调高,同一个模型对同一次提交可能输出完全不同质量的结论。
  • include_pathsexclude_paths非常关键。我一开始没加过滤规则,结果 Hermes 把package-lock.json、Go 的go.sum也拿去做了一次语义分析,白白浪费了输出长度和 token,而且这些文件本身也没有语义层面的“代码异味”。
  • max_diff_size是防止 PR 变更量过大时请求超时用的。超过阈值之后再拆分成多个文件批次处理,或者跳过部分文件的细粒度审查。

2.3 接入 LLM:本地模型还是云端 API

LLM 是整个评审系统的“大脑”,这个选择决定了评审质量和成本。

如果你对数据安全有要求,代码不能出内网,那就用本地推理。我的建议是优先考虑qwen2.5-coder系列或deepseek-coder系列,这两类模型在代码理解上足够扎实,对中英文混排的输出控制也不错。一个 32B 的量化版本,配合单张 3090 或 4090 就能跑起来,延迟在可接受范围内。

如果仓库是公开的,或者团队对代码保密要求不高,直接用云端 API 更省事。OpenAI 兼容的接口都可以接,只要在配置里把base_url指过去就行。我的体感是,参数量越大的模型对复杂跨文件逻辑的推理能力越强,但这部分的成本增量也很明显。可以先拿小模型跑一个月,看看误报率能不能接受,再决定要不要升级大模型。

注意:无论用哪种模型,都建议在配置里加上temperature: 0.1和合理的max_tokens。评审任务不是对话任务,不需要发散,也不需要长篇大论。

3. 接入 GitHub:三种集成方式实战

3.1 方式一:GitHub App(我推荐)

GitHub App 是官方推荐的机器人类集成方式,也是最“干净”的。它不需要用某个真实账号的 token,权限可以精确到仓库和操作类型,比如只读代码、写 PR 评论、接收推送事件。

创建一个 GitHub App 的大致流程:

  1. 在 GitHub 个人设置或组织设置里找到 Developer settings -> GitHub Apps -> New GitHub App。
  2. 设置 Webhook URL 为你的 Hermes 服务地址,比如https://hermes.example.com/webhook
  3. 在 Permissions 里把 Pull requests 的权限设为 Read & write,Contents 设为 Read-only。
  4. 生成私钥并下载,同时记下 App ID。
  5. 把私钥放到 Hermes 所在服务器的安全目录,并填到配置文件对应的位置。

以 Docker Compose 部署为例,环境变量这样挂载:

services: hermes: image: hermes-agent:latest ports: - "8080:8080" volumes: - ./config.yaml:/app/config.yaml:ro - ./private-key.pem:/etc/hermes/private-key.pem:ro environment: - HERMES_CONFIG=/app/config.yaml

App 的安装对象可以是某个仓库,也可以是整个组织。我的建议是最小权限原则:只安装到需要审查的仓库,不要一股脑装到组织下全部仓库。

3.2 方式二:Webhook

如果你不想折腾 GitHub App 那一整套权限体系,仓库的 Webhook 也能干同样的事。在仓库 Settings -> Webhooks 里添加一个 Payload URL,把pull_request事件勾上,Hermes 收到事件后就会触发生成评论的流程。

Webhook 的优点是配置快,缺点是需要自己处理一些边缘情况。比如 GitHub 的 webhook 可能重复推送同一事件,Hermes 需要有去重机制;比如pull_request事件下还有很多 action 类型,openedsynchronizereopened,如果你不想要重复审查,就得在配置里过滤掉某些 action。

我建议在配置里显式声明要响应的事件类型:

webhook: events: - pull_request.opened - pull_request.synchronize

这样只有新开 PR 和更新代码时才触发,能省不少模型调用量。

3.3 方式三:GitHub Actions

还有一种更轻的做法是直接用 GitHub Actions 跑 Hermes。在仓库的.github/workflows/pr-review.yml里写一个 workflow,当pull_request事件触发时,把 Hermes 的 CLI 当作一个步骤运行。

name: Hermes PR Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Hermes review uses: your-org/hermes-action@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} model-endpoint: ${{ secrets.LLM_ENDPOINT }} model-key: ${{ secrets.LLM_KEY }}

这种方式的优势是零基础设施成本,GitHub 帮你托管执行环境。劣势也很明显:如果你是私有仓库,代码会被送到 Actions 的虚拟机里,虽然 GitHub 有隔离机制,但很多企业不一定愿意走这条路;另外 Actions 是有分钟数配额和队列等待的,高并发时不够灵活。

3.4 权限边界与安全加固

接入 GitHub 之后,信息安全就成了不能忽略的问题。我做了一次彻底的安全加固,核心思路就是“能少给就少给”。

  • 私钥文件权限必须设置为 600,且只允许运行 Hermes 的系统账户读取。
  • 批评性评论是 GitHub App 的权限,默认只需要 Read-only 的地方不要放开 Write。
  • 如果 Hermes 服务暴露在公网,Webhook 一定要校验X-Hub-Signature-256签名,否则任何人都可以伪造事件触发你的模型调用,烧你的 token。
  • LLM 的 API Key 不要写死在配置里,用环境变量或密钥管理服务注入。

提示:GitHub 的 Webhook 签名校验方式是用 Webhook secret 对请求体做 HMAC-SHA256。如果你用的是反向代理,要确保传给 Hermes 的是未经修改的原始请求体,否则签名永远校验不过。

4. 核心能力打磨:审查规则与提示词工程

4.1 Hermes 默认会检查什么

Hermes 自带一套基础审查策略,默认 Prompt 里包含了对以下几类问题的关注:

  • 代码风格是否与仓库保持一致
  • 有没有明显的内存泄漏、资源未关闭等问题
  • 异常处理是否合理,有没有吞掉关键错误
  • 是否存在并发访问导致的数据竞争
  • 数据库操作有没有缺少索引或产生 N+1 查询
  • 配置文件、环境变量是否被硬编码

这套默认策略对一般项目已经够用。但如果你有特定的项目约束,比如必须使用某种日志格式、禁止使用某个废弃 API,那就需要自定义审查规则。

4.2 自定义审查规则与提示词工程

Heremes 支持通过自定义提示词来注入项目级约束。我把这些规则放在一个review-rules.md文件里,然后把它作为一个固定前缀塞进系统提示词。

我的做法参考如下:

你是一名资深后端工程师,正在对一个 Pull Request 做代码评审。 请按以下优先级输出问题: 1. P0:会导致线上故障或严重安全问题 2. P1:明显逻辑错误或性能风险 3. P2:代码规范、可读性方面的问题 项目规范: - 禁止在业务代码中直接使用 System.out.println,必须使用日志框架 - 所有涉及金额计算的字段必须使用 BigDecimal - 对外接口不允许直接返回数据库实体类 - 新增依赖必须同步更新 dependencies.md 文档 输出要求: - 先给出整体结论,再逐条列出问题 - 每条问题必须注明文件路径和行号 - 对不确定的问题用“建议确认”标注,不要妄下结论

把这份规则作为固定提示词和待审 diff 一起送入模型,效果会比你让模型自由发挥稳定得多。理由很简单:你给了它明确的价值排序和输出格式,它就知道哪些该报、哪些不该报、该以什么顺序报。

4.3 分仓库、分级别的审查策略

不要对所有仓库一视同仁。我维护的仓库里,核心 SDK 和内部服务对评审严格度要拉满,而工具脚本类型的仓库只需要最基础的检查。

在 Hermes 配置里可以按仓库做规则映射:

repositories: - name: my-org/core-sdk review_level: strict custom_rules: /etc/hermes/rules/core-sdk.md - name: my-org/scripts review_level: basic

strict级别下我还会开启“文件级拆分审查”:把 diff 拆成多个片段,分批送入模型,最后汇总结果。这样做能避免一次输入太多内容导致模型遗漏细节,但代价是更多的模型调用次数。

4.4 提示词调优的实用经验

调提示词是最耗时间的环节,但也是收益最大的。我踩了几次坑之后总结出三条经验:

  • 不要问开放式问题。比如“请检查有没有问题”这种提示词,模型的输出会很泛。你要改成“请重点检查缓存更新逻辑的一致性,以及并发场景下是否会出现脏读”。
  • 给模型提供修改示例。如果希望它输出的建议格式是“问题描述 -> 影响分析 -> 修改建议”,那就给一段现成的示例再让它开始。模型对格式的模仿能力远比我们想象的强。
  • 允许模型上报不确定性。在提示词里写一句“如果你认为某个问题可能不成立,请明确标注‘建议确认’”,这样能大幅减少硬性误报。

另外,如果发现模型长期漏掉某类问题,就把这类问题直接写进提示词的失败案例区,比如“在最近一次评审中,模型没有发现数据库查询未绑定索引的问题,请在本次评审中特别注意”。

5. 运行效果与实战复盘

5.1 一次典型 PR 评审的完整链路

我截一个真实的运行链路给你看,这样能更直观地理解 Hermes 在哪里工作。

假设有开发者向core-sdk仓库提交了一个 PR,改动内容是新增一个 Redis 缓存工具类:

  1. GitHub 收到pull_request.opened事件,通过 Webhook 推送给 Hermes。
  2. Hermes 校验签名,确认事件合法。
  3. Hermes 调用 GitHub API 获取该 PR 的 diff 数据。
  4. 过滤掉exclude_paths中的文件,得到有效改动内容。
  5. 把改动内容按文件拆分成多个块,每块单独送入 LLM,并附上仓库自定义规则。
  6. LLM 返回每块的分析结果,Hermes 汇总去重。
  7. Hermes 以评论形式发布评审结论,并给每条问题标注严重级别。
  8. 如果有 P0 问题,Hermes 还可以通过 GitHub Actions 拉一个“request changes”状态。

从事件触发到评论发布,整体耗时大约 30 秒到 2 分钟,取决于模型响应速度和 diff 大小。这个速度已经远快于任何人工 reviewer 的响应。

最终评论的样子类似这样:

### 整体结论 改动清晰,整体逻辑没有明显问题。建议处理以下细节后合并。 ### P1 - `src/main/java/com/example/RedisCache.java:87`:`expireTime` 为 `null` 时,传入 `redisTemplate.opsForValue().set` 会导致空指针。建议增加默认值。 - `src/main/java/com/example/RedisCache.java:112`:key 拼接时未使用参数化方式,Redis key 中直接拼接了用户输入,存在 key 污染风险。 ### P2 - `src/main/java/com/example/RedisCache.java:45`:方法注释与实际参数名称不一致。

5.2 我踩过的三个坑

第一个坑是重复评论。第一次配置时,我没有过滤pull_request.synchronize之外的 action,结果每个新 commit 都触发了一轮评审,评论把 PR 刷了好几屏。解决办法是在配置里明确events列表,让 Hermes 只对openedsynchronize响应。

第二个坑是大 diff 导致模型漏检。有一个 PR 改了 40 多个文件,一次性塞给模型后,输出里只讨论了前 10 个文件,后面的全被忽略了。后来我开了文件级拆分功能,把每个文件单独处理,再汇总。虽然调用次数变多了,但覆盖面完整了。

第三个坑是误报被当作真报。再聪明的模型也有幻觉,Hermes 报过一个“数据库连接未关闭”的问题,我看完代码发现那个连接是连接池在统一管理,根本不归业务代码管。后来我在提示词里加了一句:“如果上下文明确显示资源由连接池或外层框架管理,请忽略对该资源的关闭检查。”误报率立刻降下来了。

5.3 让评审结果更可信的调整

做了一些调整之后,Hermes 的评审质量终于稳定到我愿意放心让它挡 PR 的程度。核心是这几件事:

  • 给每条问题都附上具体的文件路径和行号,没有行号的问题一律不输出。这条约束让模型没法输出含糊其辞的意见。
  • 对 P0/P1 级别的问题要求模型给出“为什么这是问题”和“可能出现什么后果”,避免只有结论没有依据。
  • 定期抽检评论质量。我每周花十分钟把 Hermes 的评论和最终人工合并的修改做对比,如果发现某个类型的问题它总是漏,就补充到提示词里。

现在 Hermes 在我这里的定位是“初筛员”,不是“终审法官”。它把 80% 的明显问题挡在门外,剩下的 20% 需要依赖人做的架构级判断和产品级取舍。

6. 常见问题速查表

6.1 接入阶段的问题

症状排查方向解决办法
Webhook 请求一直 403签名校验失败确认请求体原样转发,检查 Secret 是否一致
没有收到任何评论Webhook 没触发先去 GitHub 仓库的 Recent Deliveries 看请求状态;再到 Hermes 日志看事件是否被过滤
Review 报告缺失部分文件exclude_paths误伤检查路径匹配规则,确认不是 glob 写错
报错 “App is not installed”App 没安装到该仓库到 App 设置页确认安装范围

6.2 运行阶段的问题

症状排查方向解决办法
评论重复发布事件 action 未过滤在配置中只保留openedsynchronize两类事件
模型返回超时diff 太大开启文件级拆分,或调高max_diff_size阈值
服务器内存满载模型加载 + 并发请求限制并发数,用队列串行处理请求;必要时换量化模型
评论发不出去GitHub Token 权限不足检查 App 权限的 Pull requests 是否为 Read & write

6.3 质量调优问题

如果发现模型总是提出“无关痛痒”的问题,大概率是提示词里缺少价值排序。在提示词里明确“只关注可能导致线上故障、性能退化、安全问题或严重逻辑错误的问题”,模型就会更克制。

如果发现漏检严重,就先打开文件级拆分,保证每个文件都被完整读到,然后再根据漏检的具体案例更新提示词。如果连拆分后还是漏,问题可能出在模型本身的能力上限,这种时候换一个更大的代码模型更实际。

提示:任何一个自动化评审系统都不可能完全替代人工评审。它的价值在于把人的精力从不必要的低层次问题上解放出来,让你有更多时间去处理真正的核心设计和架构决策。我的原则始终是:机器先审一遍,人再审一遍,但人的这一遍要用来思考“这个方案整体方向对不对”,而不是盯在“这一行缩进是不是多了个空格”上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询