1. 为什么我决定不再“人肉”审PR——自动化评审的价值边界
1.1 代码评审的真实瓶颈
不知道你们团队有没有这种状态:PR列表里永远躺着十几个待审的Pull Request,打开一个看两眼,发现改动太大,先放着;再打开一个,发现涉及自己不熟悉的模块,心里犯怵,又放着。结果到了周五,合并窗口关闭,一堆功能卡在评审环节上不了线,最后变成周五晚上拉人开会,三个人盯着一个屏幕逐行过代码。
我在这件事上的体会特别深。之前我在团队里承担大部分核心模块的评审工作,每天早上一小时、下午一小时固定用来审PR,但还是赶不上别人提交的速度。更要命的是,人工评审的质量非常不稳定:状态好的时候能一眼看出并发边界问题,状态差的时候连变量命名错误都要靠CI的lint插件提醒。后来团队从3个人扩到8个人,新人提交的PR里低级问题占比暴涨,我花在“帮新人纠正基础习惯”上的时间越来越多,真正应该投入的技术方案讨论反而没有时间做。
这就是我决定引入自动化代码评审工具的初衷。不是想用机器替代人,而是我实在太需要有人帮我先把那批重复性的、有明确规范的、一眼就能看出问题的活儿接走。
1.2 Hermes的定位:先把机械活干完,再找人看脑力活
我在调研自动化评审方案时试过不少工具,传统静态检查工具确实能抓到空指针风险、未使用的变量、明显的反模式,但它们普遍缺少对“这个仓库的特殊约定”的理解。团队里约定好的接口命名方式、特殊业务上下文、历史遗留代码的妥协方案,这些工具统统不认,动不动就把沿用了一年多的老写法报成错误,产生的噪音比提示还多。
Hermes给我的第一印象是它的定位想得很清楚。它不是要把SonarQube、ESLint这类静态分析工具干掉,而是站在这些工具之上,用Agent的方式把整个评审链路串起来。它接手PR之后,会自己读取diff、读取相关文件上下文、检索这个仓库的历史评审记录,然后产出一批带优先级、带定位、甚至带修改建议的评审意见。我只需要看它给出的意见里那些需要人做判断的部分,剩下的直接回车确认就行。
我把它理解成“首席过滤器”:所有机械性问题先过一遍机器,过滤掉85%的噪音之后,剩余15%需要人发挥判断力的内容才会推到评审者面前。这个定位决定了用它的姿势不是“找个工具替我做决定”,而是“让工具先跑一遍,我只看它跑完后剩下的真正需要人的部分”。
1.3 机器和人怎么分工,才不至于鸡飞狗跳
刚引入Hermes那一周,团队里出现过一些摩擦。有人觉得机器评论是在“挑刺”,有人觉得意见太机械,还有人担心这个工具会把代码风格强行统一成某一种。后来我组织了一次小范围的讨论,把机器评审和人工评审的分工边界列成一张表,贴在项目文档里,争论才慢慢停下来。
| 评审场景 | 交给人还是机器 | 原因 |
|---|---|---|
| 语法错误、明显空指针、资源未释放 | 机器 | 规则明确,不存在主观判断空间 |
| 变量命名、重复代码、方法过长 | 机器优先,人复核 | 能通过规则描述,但风格存在团队偏好 |
| 并发安全、事务边界、性能隐患 | 机器提示,人决策 | 机器能发现可疑点,但方案需要人来定 |
| 架构取舍、模块边界、技术选型 | 人 | 依赖业务认知和长期规划 |
| 新人代码习惯纠正 | 机器 | 机器没有情绪,不会让新人觉得被针对 |
这张表后来成了Hermes规则配置的指导思想。凡是能写清楚规则的,放手让机器去管;凡是需要凭经验判断的,机器最多给个可疑标记,绝不直接给结论。也就是说,工具可以帮你扩大评审覆盖面,但你自己心里要清楚哪些问题能交给机器,哪些必须兜底。这个边界想不清楚,自动化评审就会从一开始的工具辅助,演变成机器和人对骂的灾难现场。
2. Hermes的评审引擎:它到底是怎么读懂代码的
2.1 从Webhook到第一条评论:一次评审的完整流水线
很多人对自动化评审工具有一种误解,觉得它就是个“能在PR下面发评论的脚本”。实际上,从GitHub发出事件通知到Hermes在PR下面留下第一条评论,中间是一条相当长的流水线。
当一个开发者提交PR或者推送新commit时,GitHub会向Hermes注册的Webhook端点发送事件。Hermes收到事件后的第一件事不是立刻分析代码,而是先做一系列前置检查:这个PR来自哪个仓库、属于哪些规则集、是否处于免评审名单、当前是不是草稿状态。这些检查全部通过后,它才会去GitHub拉取这次变更的完整数据。
拉数据的动作比表面看起来复杂得多。Hermes不只需要diff文本,还需要完整的文件列表、每个文件变更前后的内容、PR描述、关联的Issue、目标分支的版本信息。为了拿到这些数据,它在本地维护了一个轻量级的仓库快照,每次评审前先对目标分支做一次增量同步,再基于快照计算diff。这样做的好处是diff的计算不受GitHub API返回格式限制,可以按Hermes自己的分析管道来组织数据。
拿到diff之后,真正的分析才开始。Hermes会把diff按文件、按代码块切分,对所有变更点做分类,然后并行进入分析管道。这条管道包含规则匹配、语义模型计算、Agent大模型综合决策等好几个阶段。等所有阶段跑完,它会把意见汇总、去重、按严重程度排序,最后通过GitHub Checks API的annotations机制写到PR的指定代码行旁边,再在PR下方留一条总结评论。整个过程对开发者是异步的,通常PR提交后的1到3分钟内就能看到结果,大PR或者涉及文件特别多的时候会慢一些。
2.2 三层分析:静态规则、语义模型、Agent决策
把Hermes的评审引擎拆开看,它内部是三层结构协同工作的。
最底层是静态规则匹配。这一层和传统lint工具做的事非常像:基于AST解析代码结构,匹配预先定义好的模式。比如“捕获异常后直接吃掉不做任何处理”“硬编码的数据库连接串”“不安全的反序列化方式”,这些都能用模式匹配的方式识别出来。静态规则层的优势是快、稳定、可解释,每条意见都能对应到具体规则;劣势是只能识别结构层面的问题,理解不了代码背后的意图,也看不懂跨文件的联动关系。
中间层是语义模型。这一层不是简单做正则匹配或AST遍历,而是会构建调用关系图、数据流图,分析变量在变更范围内的传递路径。举个例子,一个方法接收了来自外部请求的参数,这个参数流经三层调用之后,被直接拼进了SQL语句,语义模型能画出这条数据流路径,从而识别出SQL注入风险。单纯靠静态规则找这种问题非常吃力,但语义模型可以把“源头在哪里、流经哪些地方、最终落在哪里”串起来。
最上层是Agent决策。这是Hermes区别于传统静态分析工具的核心。静态规则和语义模型会产生一大批候选意见,里面有不少是边界情况、可疑但不一定有问题、或者和当前业务场景冲突的判断。Agent层会把这批候选意见连同PR描述、仓库历史、相关文件内容一起喂给大语言模型,由模型做一轮语义理解和综合打分,决定哪些意见保留、哪些丢弃、哪些合并,以及用什么语气呈现。Hermes被冠以“Agent”之名,正是因为有这一层决策能力——它不是在机械执行规则,而是会对规则输出做一次“人味”过滤。
三层配合下来的实际感受是:静态规则负责“地毯式扫描”,语义模型负责“深挖数据流”,Agent负责“站在评审者视角筛选”。缺了任何一层,评审结果要么太浅,要么噪音爆炸。
2.3 “仓库记忆”让评审从“懂语法”变成“懂你们团队”
我用过的多数评审工具都不带记忆,它们对待每个PR都像第一次见面,完全不知道这个仓库过去发生过什么。Hermes在这一点上做了件很关键的事:它会为每个接入的仓库维护一份“记忆库”,把历史PR的评审意见、开发者的解决方式、仓库里的规范文档、常见的例外情况都沉淀下来。
这个设计带来的直接好处是,当新PR里出现一个和历史问题结构相似的模式时,Hermes会参考过去那条评审意见的有效性来决定是否再次提醒。如果上次提的意见作者已经用另一种方式解决了,Hermes会更新自己的判断标准;如果上次的意见被作者标记为“无效”,Hermes会在后续同类场景里降低提醒强度。
我拿团队里一个真实的例子来说明。我们的Python服务里有一个历史遗留的数据库连接工具函数,早年间因为兼容性问题没有走标准连接池,这个情况在重构计划里挂了快一年。传统静态检查工具每次看到这个函数都会报“未使用连接池”的警告,开发者每次都要解释一遍原因。Hermes接入后,它在记忆库里看到了这条历史,也看到了之前开发者对这个警告的反馈,于是后续评审直接跳过这个已知问题,只在真正新引入的连接代码上做检查。单这一项,就少了一大批周期性噪音。
仓库记忆还有一个进阶价值:它能把评审标准逐渐对齐到团队本身的偏好。比如团队约定所有对外接口的响应必须包含requestId字段,这种约定写在规范文档里,传统工具读不懂,但Hermes能读取文档内容,结合历史评审记录里对缺失requestId的纠正,自动内化成一条新的检查规则。用了一段时间之后,Hermes的评审风格会慢慢长成“你们团队自己的评审风格”,而不是一套放之四海而皆准的通用模板。
3. 从零部署Hermes:GitHub侧全部配置细节
3.1 创建GitHub App:权限少给,事件按需订阅
Hermes接入GitHub的第一步,是在GitHub上创建一个GitHub App。不要图省事用Personal Access Token挂在个人账号下面,因为Token的权限是跟着人走的,一旦这个人调岗或者离职,整个评审链路就断了。独立的GitHub App有自己独立的身份、独立的权限边界,可以安装到指定仓库,出了问题可以单独吊销,这才是正确的做法。
创建GitHub App时有几个关键选项需要认真填。Permissions里最核心的是Pull requests,设置为Read & Write,因为Hermes需要读取PR内容和在PR上写评审意见。Contents设置为Read,用来读取仓库代码。Checks设置为Read & Write,走Checks API展示评审结果需要这个权限。Metadata固定为Read,这是GitHub App的强制要求。如果你的团队希望Hermes能关联Issue说明文档,可以额外把Issues设为Read,但我不建议给Write,评审工具不应该有修改Issue的权限。
订阅事件这里容易踩坑。不需要把Webhook事件全部勾上,只需要订阅真正会用到的:Pull request、Pull request review、Pull request review comment、Issue comment。其中Pull request事件是主事件,其余几个是运行时可能需要的辅助事件。事件订阅得越多,GitHub推给Hermes的无效请求就越多,白白消耗处理配额。
创建完成后会拿到一个App ID、生成一份私钥PEM文件,还有一个Webhook Secret。这三样东西要妥善保存,私钥文件丢失没法找回,只能重新生成。Webhook Secret在配置Agent时要用到,它是GitHub请求签名校验的凭证。
3.2 用Docker把Agent跑起来
Hermes服务端的部署方式我在Linux服务器上用的是Docker,整个流程非常顺。官方镜像托管在Docker Hub,直接拉取就行。部署时的核心是环境变量配置,下面这份是我在自己服务器上实际使用的启动配置:
docker run -d --name hermes-agent \ --restart=always \ -e HERMES_GITHUB_APP_ID=123456 \ -e HERMES_GITHUB_APP_PRIVATE_KEY_PATH=/app/key.pem \ -e HERMES_GITHUB_WEBHOOK_SECRET=your_webhook_secret \ -e HERMES_DB_PATH=/var/lib/hermes/store.db \ -e HERMES_LOG_LEVEL=info \ -v /data/hermes/key.pem:/app/key.pem:ro \ -v /data/hermes:/var/lib/hermes \ -p 8080:8080 \ hermes/agent:latest几个环境变量说明一下:HERMES_GITHUB_APP_PRIVATE_KEY_PATH指向容器内的私钥路径,私钥文件通过只读卷挂载进去,不进镜像,避免密钥泄露;HERMES_DB_PATH是仓库记忆和其他元数据的存储位置,我建议把它挂到宿主机持久化目录,否则容器重建后记忆库全丢;HERMES_LOG_LEVEL建议先设成info跑一周,确认稳定后再改成warn,没必要一开始就用debug刷屏。
端口方面,8000和8080是Agent默认提供Webhook接收端点的端口,我用的是8080。部署完成后需要把服务器公网IP加端口配到GitHub App的Webhook URL里,路径是固定的/webhook/github。配好之后可以在GitHub App设置页点“Redeliver”重发一次事件,看服务器日志是否正常收到,这就是最直接的连通性验证方法。
如果你手头没有公网服务器,也可以先在本地开发环境跑起来,用内网穿透类工具把Webhook地址暴露到公网,做功能验证。我早期调研阶段就是这么做的,验证完确定要长期使用了才搬上正式服务器。需要注意,本地验证方案只适合功能测试,生产环境务必用带TLS的域名地址,毕竟Webhook在裸HTTP下传输存在被伪造的风险。
3.3 Webhook事件怎么流转,评审时机怎么控制
GitHub的Webhook事件不是发一个Hermes就审一次的,实际的事件流转比她想象中讲究。
一个PR从创建到合入,会经历好几个状态变化:刚创建时发送opened事件、提交新commit时发送synchronize事件、从草稿转为正式PR时发送ready_for_review事件。Hermes在这几个关键节点都会触发评审,但触发的评审策略不一样。
对opened事件,Hermes做的是全量评审,分析整个PR的diff,产出一版完整的评审意见。对synchronize事件,也就是PR更新了commit时,Hermes做的是增量评审,只针对本次新增的commit变化做扫描,已经评论过的旧问题不再重复提。这个策略很关键,如果每次push都全量重审,PR更新到第20个版本的时候,评论区会被之前的旧意见刷屏,开发者反而找不到新意见。
ready_for_review事件是很多团队容易忽略的。草稿PR开发过程中会不断push commit,每一次push都会触发synchronize事件,如果你在草稿阶段就开启了评审策略,Agent会在PR还没开发完时反复输出半成品的评审意见,噪音非常大。我的建议是初始阶段可以先把评审触发事件限定为opened和ready_for_review,等团队熟悉了工作流,再决定是否开启synchronize增量评审。开发中的草稿PR,没必要让机器频繁打断思路。
3.4 另一种选择:嵌进GitHub Actions工作流
不是所有团队都适合独立部署Agent进程。如果你们团队对GitHub Actions已经很熟悉,不想再多维护一个常驻服务,Hermes也支持以Action的形式嵌进工作流里运行。
两种方式的使用场景不同。独立部署Agent适合那种希望Hermes作为“全天候评审员”的团队,PR一提上来就能自动评审,不依赖CI是否运行;嵌进Actions工作流适合评审跟随CI流程一起跑的团队,比如已经做好分支保护策略,要求PR必须通过所有CI检查才能合入,评审结果作为其中一个check参与门禁。
下面是嵌进工作流的配置示例,核心是触发时机和权限声明:
name: hermes-review on: pull_request: types: [opened, synchronize, ready_for_review] pull_request_review_comment: types: [created] permissions: contents: read pull-requests: write checks: write jobs: hermes: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Run Hermes Review uses: your-org/hermes-action@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} repo_path: ${{ github.workspace }}这个方案少了一个常驻进程,但代价是每次评审都从拉代码、构建索引开始,评审速度会比独立部署慢一些。另外actions/checkout需要设置fetch-depth: 0,否则只拉取到最新一个commit,没有完整的历史记录,语义模型层会拿不到充分的上下文。
4. 用一周时间打磨评审规则:从“什么都管”到“重点击破”
4.1 先跑通默认规则集,再谈定制
刚接入Hermes的建议是先打开默认规则集完整跑一周,不要上来就定制规则。
默认规则集覆盖的范畴其实很全面,大致分成五类:安全类(硬编码密钥、注入风险、不安全反序列化)、正确性类(空指针、越界访问、未处理错误)、性能类(冗余查询、大循环内重复创建连接、明显的复杂度问题)、可维护性类(重复代码、过深嵌套、过长方法)、工程规范类(缺少日志、缺少异常处理、测试覆盖明显不足)。
我见过两种极端做法。一种是不管三七二十一,先把默认规则全关掉,只留自己写的几条规则,结果漏掉大量问题;另一种是完全不调规则,默认规则跑完直接把意见全推到PR里,结果开发区弥漫着一种“机器人又来刷屏了”的氛围。正确的方式是一周缓冲期里只观察不干预:记下哪些规则产生的问题最有价值,哪些规则一直在报团队根本不关心的东西,哪些规则和现有代码风格冲突严重。一周之后,带着这份观察记录去改配置,定制的规则才会有针对性。
4.2 用skill文件把团队规范翻译成机器能执行的规则
Hermes把可扩展的审查能力做成了一套“技能”机制,团队可以通过配置文件把自己的规范描述给Hermes。配置层面用的是YAML,结构很直白,一组检查项组成一个skill,每个检查项包含规则描述、触发路径、严重级别和提示文案。
下面这份配置是我根据团队实际规范整理出来的片段,作用是约束新增Python代码里的异常处理模式:
- name: team-python-conventions include: - "**/*.py" rules: - id: no_broad_except level: warning description: "禁止使用裸except捕获所有异常" message: "捕获所有异常会掩盖真正的问题,建议先捕获具体异常类型" patterns: - "try/except: pass" - "try/except Exception: continue" - id: require_request_id level: error description: "对外接口响应必须包含requestId" message: "响应缺少requestId字段,将导致排查链路断裂" scope: changed_lines规则描述尽量写清楚“是什么问题”和“为什么这是问题”,因为这条message会直接显示在PR评论里,开发者看到理由充分、可执行的提示,才愿意跟着改。我见过有些团队在自定义规则时只写一句“不符合规范”,这种意见既没有解释也不可操作的评审意见,最终只会被开发者右键忽略。
skill文件写好后,可以放在仓库的.hermes/skills/目录或者通过Hermes管理接口上传。放在仓库里有个额外好处:规则变更跟随代码走,评审规则本身也有人review,不会出现某个人悄悄改了一版规则影响全团队的情况。
4.3 噪声治理:级别、忽略机制、路径裁剪
自动化评审工具最大的敌人是噪声。Hermes噪声治理有四个手段,我从最常用的顺序介绍。
级别设定是第一道闸。规则分为error、warning、suggestion三个级别,error级别建议设置为“不修复不能合入”,warning级别是“应该修复但不强制”,suggestion级别是“仅供参考”。严重级别的划分直接影响评审意见被开发的接受程度,一个全是error的PR会让开发者陷入防御性心态,一个全是suggestion的PR会被当成空气。我们团队的经验是error数量控制在每次评审0到3条,warning控制在8条以内,其余的杂项全部归入suggestion。
忽略机制是第二道闸。特色代码段可以通过注释标记让Hermes跳过:
# hermes-ignore: heredoc中的SQL结构特殊,不需要参数化检查 query = """ SELECT * FROM orders WHERE status = 'paid' """忽略标记必须写清楚原因,一方面方便人追溯,另一方面Hermes会把带注释的忽略请求记录到仓库记忆库,后续同样场景会降低提醒权重。这是它跟普通静态工具很大的不同:它不是简单跳过,而是真的会“记住”这个仓库什么时候、为什么选择不处理某类问题。
路径裁剪是第三道闸。对于vendor/、generated/、migrations/这类目录,绝大多数团队不需要评审工具介入,直接在配置里排除掉就行。如果不排除,每次涉及生成文件变动的PR,Hermes会产出大量问题,纯粹的浪费。
意见合并且去重是第四道闸。同一文件里同类问题会被聚合为一条意见,跨文件的重复模式会被合并成一条总览加若干代码锚点。这招对于大PR特别有用,没有聚合机制的评审工具,遇到500行以上的大PR,评论能刷到上百条,那是真正的灾难。
4.4 我踩过的三个配置坑
第一个坑是规则冲突。我给一个仓库同时启用了“通用Python规范”和“团队自定义规范”,其中“禁止使用全局变量”“禁止使用单例模式”这两条来自通用规范,但团队自己的配置文件里却明确要求某个老模块依赖全局配置对象。这两条规则在同一个文件上撞车,Hermes一会儿报这个,一会儿报那个,开发者直接被搞崩。教训是接入多处规则源时,一定要在配置里明确规则的优先级关系,团队自定义规则的优先级永远要高于通用规则,并且给每条自定义规则写好overrides字段指明它覆盖哪些通用规则。
第二个坑是超时。团队有个仓库的单次PR平均改动量在2000行以上,某些大PR甚至超过5000行。默认配置下,Hermes对超大PR执行全量分析,Agent层会因为上下文过长而处理缓慢,甚至超时失败。后来我把规则配置文件里对超大PR的策略改成“抽样分析”,只取改动量最大的前10个文件和风险密度最高的文件做重点评审,其余文件按静态规则快速扫描。效果是评审时间从15分钟降到3分钟左右,代价是确实会漏掉个别小众文件里的问题,但对超大PR来说,完全评审本身就不现实,抽样是务实的折衷。
第三个坑是把warning当error用。早期配置时我把很多规则都设为error级,觉得这样团队才重视。结果PR列表里大量红叉标记,分支保护策略要求error全部清零才允许合入,开发者为了合代码不得不反复修改,而有些warning意见确实可改可不改,这种强推反而激起了抵触情绪。后来我把error级规则收敛到只保留安全问题、正确性问题和严重性能隐患三项,其余全部降级为warning,PR的红叉率立刻下降,团队对工具的态度也从抗拒变成了接受。
5. 两周实测:指标、反馈与团队落地经验
5.1 对比数据:Hermes到底省了多少时间
接Hermes之前,我们团队有4个核心开发参与评审,每人每天平均花在PR评审上的时间是45分钟左右,其中估算有一半时间在找低级问题。接入Hermes之后,我拉了两周的实测数据,选取了5个活跃仓库、累计120个PR。
| 指标 | 人工评审为主 | Hermes辅助评审 |
|---|---|---|
| 每个PR首轮评审平均耗时 | 约6.5小时 | 约1.5小时 |
| 单条评审意见平均处理时间 | 4.5分钟 | 1.2分钟 |
| 评审意见被采纳率 | 约61% | 约78% |
| 机械性问题占比 | 约46% | 约12% |
| 评审者实际需要关注的意见数 | 全部 | 约30% |
几个数据背后的逻辑值得展开。首轮评审耗时从6.5小时降到1.5小时,原因是多方面的:Hermes在PR提交后1到3分钟内就给出意见,开发者可以趁早修复,不需要等评审人有空。评审人只需要看Hermes筛过一轮的结果,不再需要把每个PR从头到尾读一遍。
意见采纳率从61%升到78%,这里不完全是Hermes的水平比人高,而是它输出的意见是明确、可操作、有定位的,开发者更愿意去改。而人工评审经常会留下一些“这里是不是有问题”“这个逻辑要不要调整”这种模糊意见,开发者也不知道该不该改,最后就搁置了。
最让我意外的是机械性问题占比从46%降到12%,也就是说以前将近一半的评审精力花在找语法级、规范级问题上,现在这些问题由Hermes全部承接,评审人的精力被释放出来,可以去啃真正的架构设计问题。
5.2 评审意见怎么写,团队才愿意看
能发现问题是第一步,能把问题讲清楚让人愿意改才是关键。Hermes给我很大启发的正是第二点。它输出的评审意见遵循了很好的结构,每条意见都包含定位信息、问题描述、修复方向。我在人工评审时也慢慢学着用这个方式写意见,团队反馈明显变好。
public Order findOrder(String orderId) { // 这里直接查询了数据库,但调用方已经在上层方法里 // 加载过完整的Order对象,建议直接传入,避免二次查询。 }对比“这里查询多余”和上面的写法,后者给出了上下文关系和修复方向,开发者一看就懂。Hermes内部对意见生成有明确的模板要求:问题描述、触发场景、修复建议三要素齐全的才会推送到PR。这个设计让每条意见都有据可查,也便于后续统计哪些意见有效、哪些无效。
另外很重要的一点是定位精确度。Hermes的意见会通过Checks API的annotation直接绑到具体代码行,开发者鼠标悬停或者点击“Files changed”里的标注就能看到。相比之下,有些工具只在PR底部留一条长评论,写着“第3个文件第42行附近有问题”,开发者还要自己去找代码,体验差距非常大。
5.3 从“被抵触”到“真香”的三步走
新工具引入团队,最难的从来不是技术,是心态。我总结了三步走的落地节奏。
第一步是试点期。选1到2个非核心且开发活跃的仓库先跑起来,团队成员提前打好招呼,“自动评审先跑两周,大家观察一下它的意见质量”。这一时期Hermes产生的意见默认不参与分支保护,只是参考性质。策略是观察多、评论少,让代码自己说话。
第二步是复核期。团队约定所有Hermes的新增规则必须先经过人工复核才能启用,复核通过就保留,复核不通过就反馈调整。这个阶段产出了一份“常见误报清单”,比如哪些历史遗留代码会被反复误报、哪些规则不适合当前仓库。Hermes会根据这份反馈调整规则权重,有效意见的比例逐步上升。
第三步是固化期。把Hermes的评审结果接入分支保护策略,error级意见不清零不允许合入。这一步要让全员知道,不是工具在卡流程,而是团队自己约定了一套质量标准。固化的前提是前两步已经把误报率降到可接受范围,如果直接在接入第一天就开红叉,后面的抵触情绪会非常难处理。
整个周期我用了大约三周。第一周团队意见比较分裂,第二周开始有开发者主动在群里反馈“Hermes提的那个并发问题确实存在”,第三周基本没有人再抱怨这个工具了。
5.4 把评审意见变成团队规范的持续演进
Hermes落地稳定之后,它的价值已经不只是“每个PR的评审”,更重要的是它把团队的代码规范从“写在文档里的倡议”变成了“可自动执行的检查”。比如之前文档里写了“接口响应必须带traceId,方便线上排查”,但这句话说了很多次,总有新同事漏掉。Hermes接入后,我把这条规范写进了skill配置,后续再有人漏掉,就会收到一条精确到代码行的提醒。规范不再靠“老人盯新人”来执行,而是靠系统自动保障。
每周我都会抽半小时左右做一次规则效果复盘,方法其实很简单:看Hermes管理后台的意见统计,重点看哪些规则触发量大、哪些意见被标记为无效、哪些规则连续两周没有命中一次。无效率高的规则降级或调整,命中率为零的规则直接移除,触发量大的有效规则保留。这个反反复复调整的过程,本身就是把团队经验持续沉淀成自动化资产的过程。
6. 最后分享一个很多人不知道的实用技巧
前面讲了这么多,最后把我个人觉得最实用的小技巧分享出来:调整完规则集后,先用历史PR做回放验证,再上线新规则。
最开始我改规则经常是“改完直接生效”,结果没过多久就翻车了。有一次我给Java仓库加了一条静态方法检查规则,自测时用了一个小文件验证,感觉没问题就上线了。结果当天下午,历史PR里的旧代码大量命中这条规则,产生了几十条误报,开发者全在群里问怎么回事。后来才发现,这条规则对继承体系下的静态方法误判严重,而我的自测文件恰好没涉及继承场景。
现在我的流程是:任何规则调整先在本地模式跑一遍,拿过去90天已合入的PR做批量回放。Hermes支持一个类似回放的功能,可以读取历史PR数据重新执行评审,再对比新规则产出和历史人工评审意见的差异。重点看两方面:新规则能不能召回过去人审发现的问题,以及会不会对过去没有问题的代码报出问题。
# 在agent实例上对历史PR做规则回放验证 hermes replay --since 90d --repo owner/your-repo --dry-run实测下来这个方法能提前发现九成以上的误报风险。等回放结果确认没有明显问题,再执行正式生效操作。这个习惯保持住之后,我再也没有因为规则上线引发过大规模误报,算是这段时间踩了不少坑之后,最值得分享的一条经验。