资讯动态

AI代码评审实践:Hermes让PR审查自动化

发布时间:2026/9/4 22:22:42 来源:尧图企业网站定制
把PR审查从“人工逐行盯diff”变成一条流水线是我最近在一个中型服务端团队里做得最值的一件事。我们接入的是一个叫Hermes的代码评审智能体挂在GitHub上之后效果非常直接只要有人提交PR它会自动拉分支、读patch、跑静态分析和依赖扫描再把结论以review评论和check状态的形式回写到PR里全程不需要人盯多的十几分钟就能出结果。如果你正在为自动化代码评审这件事犯愁想找一个可以直接用的方案这篇文章就是我实操下来的完整复盘包含部署步骤、配置细节、踩坑记录和排查方法。1. 为什么要把代码评审自动化以及Hermes在整个评审链路里的位置1.1 人工PR审查的三个死穴先说痛点。很多人觉得PR审查只要团队约定“每个PR必须有两人review”质量就能上来。但现实往往是另一个样子一个迭代周期里服务端仓库一天可能产生10到20个PR每个PR平均改20到30个文件。如果每个reviewer认真看半小时起步。放在一个人身上光给别人的代码做把关每天就要消耗半天这还没算上讨论、返工和二次review的时间。于是很多PR开始出现两种结局要么挂着好几天没人碰要么被人秒点approve流于形式。第二个死穴是标准不一致。不同reviewer关注重点完全不同有人死抠命名和缩进有人只看业务逻辑有人只关心有没有测试。同样一个问题在这个PR里被揪出来在下个PR里可能就放过去了。新人刚进团队时没有安全感不敢轻易approve老手看多了又会审美疲劳。这种不一致靠制度很难彻底解决只能靠工具统一基线。第三个死穴是及时性。PR合入得越晚分支冲突概率越大上下文信息丢失越严重。开发者上午提交PR下午切去写新功能等review意见回来他已经想不起来当初为什么那么写。代码评审一旦变成异步低优先级活动质量门禁就成了空话。1.2 Hermes解决的是“兜底”不是“替代人”我一开始也对AI自动审查抱怀疑担心它生成的评论不够专业或者会淹没真人意见。实际用下来思路要反过来。Hermes在团队里充当的不是“更聪明的reviewer”而是一个从不错过任何PR的初级评审员。它所有的分析都基于仓库真实数据PR描述、改动文件、新增代码、调用关系、历史提交再结合规则引擎和模型推理把明显缺陷先筛一遍。真人reviewer不需要再从“这里有个魔法数”“这个函数太长了”“日志里打印了token”这类基础问题开始看起可以直接讨论架构取舍、业务语义和技术债这些机器不擅长判断的事情。换句话说Hermes帮团队把评审的关注点往上拔了一层。我们团队大概三周之后真人review的评论数量下降但意见质量明显上升因为大家不用再花时间指那些一眼就能看到的问题了。1.3 和GitHub原生功能以及第三方评审平台的区别GitHub自带CODEOWNERS和required reviews能强制指定某些文件必须有特定owner确认。但它只是一个“签名流程”不会去读代码不会判断这段逻辑有没有安全问题。它解决的是“谁必须同意”而不是“代码到底行不行”。第三方代码评审平台能力更强但往往偏重要搭服务、配权限体系、梳理流程对小团队来说维护成本不低。Hermes的优势在于它离GitHub很近本身就是为GitHub工作流设计的智能体可以挂在GitHub App或Actions里轻量地进入你现有的PR流程。它比静态规则检查工具更懂上下文因为静态工具只能识别“这行代码不符合某个lint规则”Hermes能结合函数上下文去分析“这个改动会不会影响到已存在的调用方”。2. Hermes审查PR的核心机制它是怎么“看懂”一次变更的2.1 一次PR从触发到出报告的关键链路要理解Hermes最好先看它完整跑一次审查时做了哪些事。我这里以自己使用的Hermes CLI版本为例整条链路大致是GitHub事件触发。PR的opened、synchronize、reopened动作会通过Webhook通知Hermes或者直接触发GitHub Actions里的审查Job。Hermes调用GitHub API拿到base指向的目标分支和head指向的PR分支生成标准diff。这里的diff是整个审查的核心输入。提取PR元数据。包括PR标题、描述、标签、关联Issue以及被修改文件所在模块的上下文。这些信息决定了后续分析的背景。做静态预扫描。对新增和修改的代码做格式、复杂度、安全扫描比如硬编码密钥、明显越权接口、异常信息打印敏感数据等。大模型对diff和上下文做语义推理。这一步主要找出跨文件的破坏性改动、潜在的空指针、并发问题、错误处理缺失这类需要理解业务语义的问题。规则引擎汇总结果。将基础扫描和语义推理的结果按严重程度分级生成review comment、summary和check run结论再根据策略决定是自动approve、要求修改还是仅标记意见不阻塞合并。H3 2.2 它看的远不止diff还有这些上下文我最初以为Hermes顶多是把PR里新增的行读一遍然后套用通用提示词让它找问题。后来看它的排查过程才知道它的输入比我想象的大得多。它能读取PR描述里写的“这次改动背景”能看目标文件的完整结构能追踪被修改函数在仓库里的其他调用点。比如你改了一个公共方法的签名Hermes不只是看这个方法本身它会搜索哪些地方调用了它然后评估这次改动可能造成多大范围的破坏。这个能力非常接近真人reviewer的工作方式。它还会参考提交历史。如果当前改动和某次回滚高度相似Hermes会给出类似版本问题的提示。对团队里不熟悉历史背景的新人来说这类信息极其有价值。Hermes也会看CI状态。如果CI失败它会先提示“此PR目前存在构建失败建议先修复再审查”避免在无效分支上空跑一轮分析。所以Hermes的有效性不在于模型有多聪明而在于它把diff、代码库结构、历史记录、运行状态这几层信息拼在一起再下判断。只有diff而没有代码库全貌再强的模型也只能产出泛泛而谈的建议。2.3 审查维度与规则引擎设计的参考这是整个方案最值得琢磨的部分。Hermes不是所有问题都一把抓而是按多个维度组织分析结果。我这边实际用到的审查维度可以给到一个基本参照正确性与Bug风险空指针、类型不匹配、错误的分支条件、异常吞掉后无日志、边界处理缺失。安全风险SQL拼接、命令注入、密钥硬编码、越权接口未加鉴权、用户输入未过滤。性能隐患N1查询、循环内重复IO、大对象未回收、无谓的深拷贝。可读性与维护性命名词不达意、函数过长且逻辑混乱、大量重复代码、注释与实现不符。测试建议新增逻辑没有对应测试、测试断言过弱、用例覆盖不到关键分支。规则引擎会把模型输出的自由文本和规则判断结合起来做到“模型负责理解规则负责分级”。例如配置一个禁止正则那么一旦模型发现代码匹配这个正则就会固定输出P1级别意见而不是让模型自己决定严重程度。这样就保证了团队关注的底线问题不会被模型的主观倾向带偏。2.4 为什么要坚持增量审查而不是全量审查刚开始有人提议既然Hermes能力足够不如把整个仓库一次性扫一遍把所有技术债都清出来。这个想法听着很爽实操却是灾难。全量扫描会产出大量和历史代码相关的问题PR review页面会被刷屏开发者根本无法分清哪些是本次改动引入的、哪些是存量问题。Hermes默认只在PR新改动上做严格审查对未修改的旧代码只做背景引用不主动给意见。这种方式也大大降低了模型调用成本。我测算过一个百文件范围的PR全量审查的token消耗可能是增量审查的十倍不止。Hermes还会判断变更文件数量如果单次PR改动过大会建议拆分成多个小PR再审查。这既是算力策略也是工程上鼓励小步提交的手段。后来我们团队确实因此减少了一次性提交几百行代码的情况。3. 实战从0把一个GitHub仓库接入Hermes3.1 安装Hermes并完成模型参数配置我这边基于Python环境部署假设你已经有了一个GitHub组织或个人账号以及能访问到的仓库。先安装Hermes本体python3 -m venv .venv source .venv/bin/activate pip install hermes-agentHermes本身不内置大模型需要接入一个支持OpenAI兼容接口的推理服务。我选的是自己项目里已经在用的DeepSeek系列模型理由是上下文窗口大、中文评审意见表达自然、单位token成本也更可控。配置方式通过环境变量完成export HERMES_MODEL_BASE_URLhttps://api.deepseek.com/v1 export HERMES_MODEL_API_KEYsk-你的密钥 export HERMES_MODEL_NAMEdeepseek-chat环境变量配好后可以先跑一条自检命令确认模型连通性。多数情况下这一步失败都是因为base url写错或模型名称与平台不匹配排查时先把这两个变量打出来确认一遍。3.2 为什么我推荐用GitHub App而不是个人访问令牌接入GitHub有两种常见方式一种是直接拿个人访问令牌另一种是注册GitHub App。我强烈建议团队使用GitHub App。原因有几个个人token跟着人走一旦人员离职或权限变动审查服务就会跟着失效个人token如果权限过大泄露出来风险很高。GitHub App是一个独立身份可以取名“hermes[bot]”只授权它需要的仓库和权限权限边界一目了然。创建GitHub App时需要按以下方式申请权限和事件订阅Pull requests权限设为Read and write用于读取diff、写review评论。Checks权限设为Read and write用于提交check run作为合入门禁。Metadata权限设为Read-only这是GitHub App运行的基础要求。订阅Pull request事件重点是opened、synchronize、reopened这三个类型。创建完成后下载私钥把App ID和私钥内容存到CI或运行端的环境变量里。Hermes启动时会用App ID申请一次installation token之后所有GitHub API调用都带上这个token。它不用你的个人身份也不会在你的名字下面留下review记录。3.3 用GitHub Actions接Hermes的最短路径如果你不想维护一个常驻服务GitHub Actions是最省事的接入方式。把Hermes作为Job跑在ubuntu-latest上每次PR事件触发时生成一次临时容器环境运行完立即销毁。对一个审查任务来说这个模型非常适合因为审查是无状态的不需要保留历史进程。这里是一个可以直接改用的workflow片段name: hermes-review on: pull_request: types: [opened, synchronize, reopened] jobs: review: runs-on: ubuntu-latest permissions: pull-requests: write checks: write contents: read steps: - name: Checkout code uses: actions/checkoutv4 with: fetch-depth: 0 - name: Install Hermes run: pip install hermes-agent - name: Run review env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} HERMES_MODEL_BASE_URL: ${{ secrets.HERMES_MODEL_BASE_URL }} HERMES_MODEL_API_KEY: ${{ secrets.HERMES_MODEL_API_KEY }} HERMES_MODEL_NAME: ${{ secrets.HERMES_MODEL_NAME }} run: hermes pr review --repo ${{ github.repository }} --pr ${{ github.event.pull_request.number }}这段工作流里有几个细节值得注意。fetch-depth: 0是为了拉全提交历史Hermes需要它来判断本次改动和之前提交的关系。pull-requests: write权限只写评论和结论文本不给写代码的权限这是最小授权原则。3.4 项目级配置规则开关和阈值怎么定在仓库根目录放一份.hermes.yamlHermes会自动读取并按此规则执行。我目前用的配置节选如下review: language: zh-CN diff: enabled: true max_files: 40 max_changed_lines: 600 severity: critical: fail high: fail medium: warn low: note rules: block_regex: - pattern: password\\s*\\s*[\][^\][\] severity: high reason: 疑似硬编码密码 auto_approve: enabled: true threshold: low output: summary_title: Hermes 自动化审查报告max_files和max_changed_lines是防滥用开关。超过这个阈值Hermes会拒绝自动审查并在PR下留言建议拆小PR。这个配置刚引入时会被一部分开发者嫌烦但它确实逼团队把大PR拆开效果是review时长明显下降。auto_approve这里不要一开始就开到high级别我建议先跑两周收集误报数据再决定要不要开。4. 完整跑一轮PR评审从提交代码到收到报告4.1 构造一个带问题的示例PR与其讲抽象概念不如看一个真实PR流程。假设团队正在开发一个兑换码功能有个开发者提了一个PR内容是在服务端生成兑换链接。改动的核心代码是def build_redeem_url(user_id: int, code: str) - str: logger.info(user %s trying to redeem with code: %s, user_id, code) return fhttps://example.com/redeem?userId{user_id}code{code}这个PR表面看没什么大问题代码也能跑。但Hermes在审查时会注意到两点第一code作为兑换码被打印到了日志如果日志平台有权限泄露整个兑换池都可能被拖走第二URL参数里直接带userId和code本身虽然不违反加密规范但这些参数会进入Web访问日志和浏览器历史隐私性差。这种问题如果让真人reviewer来找不熟悉这个业务上下文的人根本不会想到。4.2 收到的审查意见长什么样提交PR后Hermes会以机器人身份在PR下生成一条summary评论同时内联到有问题的代码行上。摘要评论一般长这样Hermes 自动化审查报告PR #873共发现 2 个P1问题1 个P2建议无P0阻塞问题。P1: 日志中输出未脱敏的兑换码存在敏感信息泄露风险。P1: 兑换链接将code直接放入查询参数可能进入访问日志建议改为POST或短期一次性票据。P2: logger格式化与参数化混用建议统一使用参数化写法。结论建议修改后合并。内联评论则直接出现在代码行旁边开发者一眼就能看到修改位置。整个PR从提交到收到第一个完整报告我实测大约8分钟。这个速度对GitHub Actions临时环境来说已经很快了因为它做的事情量并不小。4.3 处理误报与调整规则的真实经历Hermes在上线初期也会产生误报。最常见的误报类型是给了过强的建议例如在非热路径代码里要求做局部变量缓存或者要求把所有if-else改成策略模式。这类建议语气还很坚定容易让不熟悉的开发者产生压力。有一次Hermes在一个跑批脚本里对每行数据都断言非空然后抱怨“空值校验过多影响可读性”。那批数据恰恰来自上游未校验的外部接口空值校验不是过度设计而是必要的防御。团队讨论后决定不回退这个检查而是在review意见下面用hermes ignore标记它。Hermes会把ignore记录存下来以后出现同类型、同位置的路由就不再提。经过大约两周调教我这边报告的可接受率从最初的六成提升到九成左右。这个过程是必须的不要指望模型开箱就完全贴合团队口味。5. 运维中的典型问题与排查技巧实录5.1 PR一直没收到Hermes反馈先查这三样我遇到过的沉默问题基本都能归到三处。第一是Webhook根本没有到达在GitHub App的高级设置里能看到最近投递记录如果状态码不是2xx说明Hermes处理端有问题。第二是权限不对比如App没有订阅pull_request事件或者某个私有仓库没有授权该App访问。第三是模型API Key写错或过期调用直接失败Hermes会把错误记录在自己的日志里。排查顺序我建议是先看仓库下Hermes有没有check run记录如果没有说明Job或Webhook没触发看GitHub App投递记录再看Hermes服务日志。不要在PR页面干等GitHub的评论可能晚到几分钟但不会晚到半小时以上。有个细节容易忽略如果PR是从fork仓库发起的GITHUB_TOKEN默认只有只读权限Hermes无法在fork的PR上写评论。这时需要在workflow里额外配置pull_request_target事件或者让fork分支的构建先跑一次人工审批。这个限制是GitHub安全模型造成的不是Hermes的Bug。5.2 PR被插队导致冲突后Hermes审查会中断吗接口刚上线那阵我们团队遇到过经典场景feature分支开发周期较长主干频繁被其他PR合入等到feature分支想合并时已经落后主干几十个commitGit直接提示冲突。Hermes在遇到冲突时会给出明确提示但仍会尝试基于目标分支的最新版本做部分分析。如果代码连编译都无法通过Hermes的很多语义分析会失效所以最好先解决冲突再触发重新审查。解决这类“被插队导致冲突”的常规操作是定期把主干合入或变基到feature分支。命令层面可以这样处理git fetch origin main git rebase origin/main # 处理冲突后 git add . git rebase --continue git push --force-with-lease origin feature/xxx需要注意如果分支名所在的仓库开启了“禁止强制推送”保护规则git push --force-with-lease会失败。这种情况下改用merge方式git merge origin/main # 解决冲突后提交一个普通commit git push origin feature/xxx我在实战中更推荐feature分支定期rebase主干原因是提交历史更线性reviewer看commit记录时不会被大量merge节点干扰。如果担心强推风险可以只在个人feature分支上操作合回主干时走squash merge。5.3 审查机环境报错构建插件加载失败这类问题Hermes分析某些语言项目时如果开启了类型推断或测试影响分析会自动调用项目的构建工具。这就带来一类头疼问题审查本身没问题但构建环境配置不对导致审查失败。我印象比较深的是在一个Flutter项目里接入Hermes审查到一半报出这个错误Failed to apply plugin dev.flutter.flutter-gradle-plugin. Error: your project path contains non-ASCII characters.排查发现是CI Runner的工作目录用了默认路径里面带了一个中文用户名。Flutter的Gradle插件对非ASCII路径支持不好于是Hermes每次都在同一位置挂掉。解决办法是在GitHub Actions里显式指定一个纯英文的工作目录jobs: review: runs-on: ubuntu-latest defaults: run: working-directory: /tmp/hermes-workspace同时确保Runner上安装了匹配项目的JDK版本。多数Gradle项目在Java 17环境下更稳妥而老的Android项目可能还依赖Java 11不要盲目装最新版。建议在workflow里固定JDK版本- uses: actions/setup-javav4 with: distribution: temurin java-version: 17这类问题看起来和代码评审无关但它会消耗大量排查时间值得一开始就留意。5.4 GitHub API限流与事件丢失的兜底方案当仓库活跃度特别高、Webhook频繁触发时GitHub API限流会成为瓶颈。GitHub的REST API对核心接口有明确的速率上限超过后会返回403或429。Hermes如果在这个瞬间刚好要批量拉取数据就会失败。限流并不常见但当出现时通常会连续失败因为重试又消耗配额。我的兜底方案是加一个定时补偿任务。每隔半小时扫描一次最近未关闭的PR如果某个PR没有Hermes的check run或评论记录就补跑一次审查。这相当于给事件驱动加了一层轮询保险确保即使Webhook或API调用丢了最多延迟半小时也会被补上。排查限流时可以调用GitHub的速率检查接口看当前剩余配额。如果发现剩余量总是很低就要检查是否有人在脚本里高频调用GitHub API。有一个很容易被忽视的问题多个仓库共享同一个GitHub App时installation token会共享配额一个仓库的批量操作可能耗尽另一个仓库的配额。这个坑我们遇到过好几次。5.5 问题速查表我把排查过程中最常见的四类问题整理成一张表备查比较方便。现象常见原因快速排查解决思路PR没有Hermes评论Webhook未触发、权限不足、模型API异常查GitHub App投递记录和Hermes日志修复订阅事件、补充权限、检查API Key审查结果迟迟不出模型推理超时、变更文件过大看check run耗时调大模型超时时间、拆分PR构建类插件报错JDK版本不符、工作目录路径异常看崩溃堆栈固定JDK版本、设置纯英文工作目录GitHub API返回403/429触发限流查速率限制剩余量加补偿任务、错峰运行、减少重复调用6. 落地自动化代码评审后我对这套方案的几点反思6.1 自动approve的阈值不要一上来就拉满我最初也想把Hermes的严重问题级别直接设成“拦截合并”让高风险PR完全无法通过。但运行了两周后发现模型和规则仍有误判如果把medium级别也都设成fail团队会频繁被打断。更好的策略是分级处理P0和P1作为必改项门槛设置为required checkP2只做提醒不阻塞合并P3也就是风格偏好类完全不在check里体现。这样设计的好处是开发者的注意力被集中在真正重要的问题上而Hermes不会变成评论区里的“杠精”。团队逐渐接受后再把P2里某些反复出问题的规则提升为P1形成动态调节。这个节奏比一次性卡死要平滑得多。6.2 这套方案更适合什么团队不适合什么团队Hermes在小团队里价值最大特别是三到十个人的研发组。这个规模下没有专职的安全工程师和架构师开发者普遍要承担多种角色自动化代码评审相当于团队的隐性质量负责人。它对代码量庞大但维护人力稀疏的老项目也有显著帮助能快速排查接口越权和密钥泄露这类低级但致命的问题。不适合的是那种刚起步、业务方向还没跑通的团队。这类团队里大量代码都处于快速探索阶段两天后可能整体重写如果一开始就上严格的A I审查摩擦成本会超过收益。等业务模型稳定、PR数量和代码评审压力起来了再接入也不迟。团队文化也需要考虑。Hermes会在公开的代码评审页面直接指出问题部分开发者会对机器人意见比较敏感。我们这边解决方法是把报告重点放在“风险”而不是“批评”上默认分级客观陈述不在评论里用感叹号或情绪化表达。6.3 从单次评审扩展到发布门禁和质量看板Hermes跑顺之后我建议至少再做两件事让数据产生更大价值。第一把check run设置成目标分支的required status check。这样Hermes的审查结论直接决定PR能否被合入形成一个真正的自动化门禁。需要注意这个按钮一旦打开Hermes不可用时会block合入需要同步做好故障调剂的预案。第二定期拉取Hermes的审查数据生成简单看板。看什么指标每千行代码问题数、P1问题最多的是哪类模块、平均每个PR审查耗时、自动approve占比。这些数字能告诉团队质量状况和代码债务集中地。例如我们发现支付模块平均每百行出现一个P1问题这个信号会促使负责人主动申请重构而不是等问题爆发后再救火。我把这套改动推进后的体会是自动化代码评审的核心价值不在于把模型调得多聪明而在于让每一个PR都得到稳定、及时、有统一标准的第一次审查。真人的精力有限但Hermes不会累也不会因为今天是周五下午就草率approve。真正好的评审流程应该是机器先扫雷人再深入做判断。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价