ARTICLE DETAIL

资讯详情

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

用 AI Agent 在 GitHub PR 上实现自动化 Code Review

用 AI Agent 在 GitHub PR 上实现自动化 Code Review 很多人一听到“自动化代码评审”第一反应就是CI里的静态检查或者SonarQube那套扫描规则。但今天我要聊的Hermes不太一样。它定位是在GitHub PR上直接执行的自动化Code Review Agent核心能力不是挑出你没加分号而是像一位有经验的同事那样去理解你这次改动解决什么问题、在哪里可能翻车、哪里还有边界情况没考虑然后把结论和疑问直接写到PR评论里。这个项目解决的是研发流程里最耗时、最容易被敷衍的环节——人工Review。尤其是当你维护的项目有一定规模或者团队分布在多个时区等一个人来Review可能比写代码还久。Hermes这种Agent可以7x24小时响应第一时间对PR给出初评意见帮维护者过滤掉明显有问题的提交也帮作者在提交前发现自己没注意到的漏洞。适合谁参考想给开源项目做自动把关的维护者或者企业内部想建设代码评审辅助体系的团队又或者你跟我一样纯粹是好奇大模型能不能真的当个“AI同事”这篇都能给你一个可落地的参考。1. 内容整体设计与思路拆解1.1 为什么选择“Agent”而不是一堆脚本早期我也尝试过用GitHub Action挂些Lint工具再配合几个简单的正则规则去扫代码。效果不能说没有但总感觉不够“聪明”。比如一个PR删了一行关键的错误处理静态检查完全看不出问题再比如调用某个废弃API编译时根本不会报错但运行时就是会出幺蛾子。这些问题的共同点是需要上下文理解而不是文本匹配。这正是Agent类应用比传统脚本更有价值的地方。Hermes的设计核心是把大模型的能力当作“评审员”而把GitHub的API和事件流当作“通信管道”。它不是简单的“触发-执行-返回结果”而是一个带有感知和决策的循环感知接收GitHub Webhook推送的PR事件拉取PR的元信息标题、描述、改动文件列表、Diff内容、评论等。决策根据配置的规则和历史对话决定这次评审要看什么、从哪里入手。执行调用代码分析的逻辑比如解析Diff、跑静态分析、提取关键函数生成评审意见。反馈把结构化的评审结果以评论形式发回PR必要时还能更新状态标签比如request-changes。有了这层循环Hermes才能真正做到“因为它知道你在改什么才知道该提醒什么”。比如你改了一个公共函数它知道要去搜调用方是否受影响你加了一个新依赖它会去检查License和已知的安全漏洞。这种能力脚本很难覆盖。1.2 整体架构形态与关键模块Hermes本身是用Python写的底层调用大模型API来做语义理解。整体架构上我更愿意把它理解成三层接入层负责跟GitHub交互。包括处理Webhook签名验证、调用REST API和GraphQL API拉取数据、管理Rating Limit。这层做不好后面全白搭——比如不处理重试和限流PR一多API直接给你的应用“断粮”。理解层这是核心也是跟普通CI最不一样的地方。它要把PR的Diff转化成大模型能高效理解的摘要把整个仓库的结构比如哪些文件改了会影响哪些模块也一并送过去。怎么组织Prompt提示词在这一层非常关键。不是把Diff全文塞给模型就完事了那样既有Token浪费模型也容易迷失在细节里。要把Diff按文件、按Hunk切碎再附上变更说明、关联Issue上下文让模型去“精读”。执行层负责把模型的分析结果转化成具体的GitHub操作比如创建评论、提交Review、添加Label。这一层要考虑权限控制哪些操作是自动执行的哪些需要等待人工确认。从实际部署来看我的建议是直接以Docker容器方式跑在服务器上或者挂在Kubernetes集群里通过GitHub App的方式跟仓库关联。直接用个人Token做测试可以但不适合长期用原因我后文会细说。1.3 方案选型的取舍在“自动化代码评审”这个需求上业界其实有几种做法用现成的CodeRabbit、Sourcery这类SaaS服务自己写GitHub Action或者用Hermes这类自托管Agent。我的选型逻辑是SaaS服务简单但代码会经过第三方服务器对于很多公司尤其是做硬件、做金融、做医疗的公司这是合规红线。而且你没法深度定制它的评审逻辑。GitHub Action更适合做固定流程比如“每次PR都要跑mypy”“都要跑测试”。但Action是无状态的很难跨多次评论保持上下文不适合做复杂的多轮交互评审。Hermes这种自托管的Agent代码在自己手里规则自己定数据不出内网同时有状态管理可以做多轮对话、追问作者、根据更新重新审查。代价是要自己维护一套服务复杂度确实更高但带来的可控性是前两种方案给不了的。正因为它可控所以在企业内部落地、在开源项目里做维护助手Hermes的边际效用是递增的。用久了你会发现它越来越像团队里的“虚拟成员”而不是一个冷冰冰的脚本。2. 实操过程与核心环节实现2.1 本地部署与最小复现先说我建议的启动方式。Hermes官方文档里挂了一个Docker镜像这是起步最顺的路。你得先在服务器上装好Docker和Docker Compose然后写一个简单的docker-compose.ymlversion: 3.8 services: hermes: image: hermes-agent/hermes:latest container_name: hermes-review ports: - 8080:8080 environment: - HERMES_MODEproduction - HERMES_GITHUB_APP_ID12345 - HERMES_GITHUB_PRIVATE_KEY_PATH/run/secrets/github_private_key - HERMES_MODEL_PROVIDERdeepseek - HERMES_MODEL_NAMEdeepseek-chat - HERMES_MODEL_API_KEY${DEEPSEEK_API_KEY} volumes: - ./config:/app/config - ./secrets:/run/secrets restart: unless-stopped这里面有几个字段我得重点说明。HERMES_MODEL_PROVIDER是模型供应商Hermes做了抽象层可以接DeepSeek、OpenAI兼容接口或者其他开源模型的API。HERMES_GITHUB_APP_ID和HERMES_GITHUB_PRIVATE_KEY_PATH是GitHub App的凭证后续创建App时会用到。启动容器后Hermes会监听/webhook路径。你需要把它暴露到公网或者在GitHub上用Smee这类工具做内网穿透调试。这一步能不能走通决定了整套系统能不能双向往来。2.2 创建一个GitHub App要让Hermes以“机器人”身份出现在你的仓库里最标准的做法是创建一 个GitHub App而不是用个人访问令牌。区别在哪个人令牌的权限是跟着人走的万一你的Token泄露别人就拥有了你账号的所有权限而GitHub App的权限是细粒度的可以只给它“读取PR”“写入评论”这两个权限风险面小很多。创建过程大概是进入GitHub账号的Settings - Developer settings - GitHub Apps点击“New GitHub App”。填名称比如hermes-reviewer填写Webhook URL就是你部署Hermes的那台服务器的公网地址后面记得加/webhookWebhook secret自己生成一段随机字符串。在“Permissions”里需要给这几个权限Pull requests: Read write让它能读取PR内容和发表评论Checks: Read write如果后续要写Check Run状态这个必须有Issues: Read write如果要让它根据PR关联Issue或者修改Issue标签就需要这个Contents: Read让它能拉取仓库代码内容来生成上下文生成私钥文件下载到本地这个私钥就是docker-compose.yml里用的github_private_key。安装App到目标仓库。这里有一个容易踩的坑Webhook secret一定要配。如果不配任何知道你Webhook地址的人都可以伪造请求、消耗你的模型配额、甚至给你的PR乱打标签。配好之后Hermes会用HMAC算法校验每次请求的签名来源不对的一律拒绝。2.3 配置第一个Review规则Hermes的核心可玩性在config.yml文件里。这是我见过最像“给Agent写说明书”的地方。它的语法定义了三件事什么时候触发triggers、在什么条件下生效conditions、具体做什么actions。举个我自己在用的最小配置rules: - name: security-sensitive-files triggers: - event: pull_request action: opened - event: pull_request action: synchronize conditions: - condition: changed_files_include patterns: - auth/** - payment/** - server/security/** actions: - action: request_review message: | 检测到本次改动涉及安全关键模块auth / payment / security。 请确认 1. 是否有完善的输入校验 2. 是否对权限变更做了日志记录 3. 是否需要更新安全设计文档 - action: add_label label: needs-security-review这条规则会拦截所有涉及安全相关目录的PR自动打一个needs-security-review标签并评论一段清单提醒作者和后续Reviewer。有意思的是conditions里的changed_files_include不仅支持路径通配还支持diff_content的正则匹配。比如你想检查“不允许直接拼接SQL”这种模式rules: - name: sql-injection-check triggers: - event: pull_request action: opened - event: pull_request action: synchronize conditions: - condition: diff_contains pattern: execute\\s*\\(.*\\$ flag: SQL拼接风险 actions: - action: comment message: | 检测到疑似SQL语句拼接请改用参数化查询避免注入风险。 示例 - 错误cursor.execute(fSELECT * FROM users WHERE id {user_id}) - 正确cursor.execute(SELECT * FROM users WHERE id ?, (user_id,))看到这你就能明白Hermes不是只靠大模型瞎猜它也支持确定性规则来做第一层过滤。大模型的优势在于理解模糊语义正则的优势在于精确命中两者结合才是完整的评审体系。2.4 给大模型配一套Review指南除了规则引擎Hermes还允许你通过REVIEW.md文件放在仓库根目录来指导模型的行为。这个文件的逻辑相当于你在给新人写团队的风格指南。我举个实际例子# Code Review Guidelines ## 沟通风格 - 使用中文回复语气专业、直接不要过度礼貌。 - 每条评论必须指出具体问题所在不能只说“这里需要改进”。 ## 重点关注 1. 逻辑错误例如数组越界、空指针、错误的条件分支。 2. 并发问题是否有共享状态被多线程读写是否缺锁或原子操作。 3. 错误处理异常被吞掉、返回值未检查、常见失败路径未覆盖。 4. 性能陷阱在循环里执行了查询、N1查询、不必要的大型对象拷贝。 5. 兼容性是否破坏了公共API的向后兼容性。 ## 输出格式 对于每个问题使用如下格式 ### 问题描述文件名行号 **严重级别**可选的 [P0/P1/P2] **具体原因**说明为什么这是一个问题。 **修改建议**给出可执行的修复方案必要时附代码片段。这份指南会作为System Prompt的一部分和每次PR的Diff一起提交给模型。如果你发现模型评论的质量不稳定先别急着换大模型先检查指南是不是写得太空。模型很吃“具体指令”这一套你告诉它“给出具体行号和修复代码”它就会认真很多。2.5 模型的参数选择与Prompt构造Hermes底层默认用的是DeepSeek的模型接口这也是最近社区里比较主流的选择。我实测下来在代码评审这个场景模型的参数设置跟普通聊天有区别**temperature温度**要调低建议0.1到0.2。评审需要的是稳定性和确定性不需要创造性。温度太高同样一段代码它今天说好、明天说坏你没法用。max_tokens要设得够大因为一次评论可能要覆盖多个文件多个问题。设小了评论被截断体验很不好。top_p可以保持默认0.9左右不用刻意调整。Prompt的构造上我强烈建议把“仓库上下文”和“Diff内容”分开。仓库上下文包括根目录的README摘要、项目技术栈、关键目录结构Diff内容则按文件分组。这样模型既知道这个项目是干嘛的又能聚焦在具体改动上。再说一个细节Hermes会对Diff做“超长截断”策略。PR动辄上千行一次全塞给模型不现实Token费用也吃不消。默认策略是只把每个文件的头部和关键变动部分提取出来如果文件太多优先处理在REVIEW.md里指定的高关注目录。这就要求你在配置config.yml时把max_diff_size这类参数设好让Agent知道你的项目重点在哪里。3. 功能进阶与场景玩法3.1 用“提问”方式做深层次逻辑审查单独的PR注释是“一次性的”但代码评审本质是“多轮对话”。你在Review时经常遇到这种情况某个PR逻辑绕了三层你第一遍没看懂于是写评论问作者“这里为什么不用XX方案”作者答了之后你可能还会追问。Hermes同样支持这种追问。当作者在PR里回复Hermes的评论比如“这个改动是因为老接口废弃了”Hermes会带着这层上下文重新审视代码。实测中这种多轮讨论比第一次生成的意见更有价值因为模型掌握了更多隐藏信息能做出更准确的判断。我遇到过的情况是第一轮模型报出一个“疑似错误使用API”的警告作者解释说是兼容旧数据的字段映射。模型读取上下文后自动把评论降级为“建议添加注释”并且在更新后的PR上确认代码没有逻辑问题。这种“越用越懂”的感觉是普通规则引擎完全做不到的。3.2 和GitHub Actions的配合Hermes不是要取代你现有的CI流水线而是弥补“人性化”的部分。一个成熟的自动化评审体系应该让机器做机器擅长的事让模型做模型擅长的事。我的建议是把Hermes作为“最后一道闸门”。具体流程PR打开后先跑GitHub Actions里的构建、单测、Lint。这些机械检查通过后Hermes再上场做语义级评审。如果Hermes给的结果是REQUEST_CHANGES作者修改后重新push触发新的审查。因为Single流程是串联的所以要确保Hermes只在CI通过后才介入避免模型在一堆构建错误里浪费时间。你可以通过GitHub Actions里的一个Job来调用Hermes的Webhook API也可以直接在Hermes的规则里配置skip_if_checks_pending: true。3.3 多仓库接入与权限隔离如果你管理的是一个组织下的多个仓库每个仓库可能有不同的评审规范。Hermes支持按仓库加载不同的配置。目录结构大概是config/ base.yml # 全局默认配置 repo-awesome-project.yml # 仓库专属配置在config/base.yml里可以声明哪些规则是全局生效的比如禁止提交密钥、禁止TODO在仓库专属配置里再叠加特定模块的规则。这样既保证了团队底线不会垮又能让每个仓库有自己的风格。部署层面我建议给不同等级的仓库分配不同的Access Token。比如内部核心仓库用高权限的App公开Demo仓库用只读权限的App。这样即使某个仓库被恶意提PR攻击者也影响不了其他仓库。4. 常见问题与排查技巧实录4.1 不触发Webhook收不到事件这是最先遇到的问题也是最常见的。如果你发现Hermes完全没有反应优先按这个顺序排查Webhook是不是内网地址GitHub无法从公网访问你的localhost。本地调试可以用smee把GitHub事件转发到本地但长期用一定得有公网地址。Webhook Secret校验Hermes日志会有类似signature verification failed的报错说明GitHub和Hermes两侧的Secret不一致。事件有没有订阅回到GitHub App设置页在“Subscribe to events”里必须勾选Pull request。我见过有人只配置了权限忘了订阅事件结果Webhook完全不来。4.2 评论乱码或格式错乱Hermes评论的默认格式是Markdown。如果你发现代码块没有正确渲染检查两件事模型返回的文本里是否有多余的转义字符config.yml里有没有设置comment_style: markdown。另外模型偶尔会自己造一些不存在的文件名和行号这就是幻觉。在REVIEW.md里强约束“每一条评论必须基于提供的diff不得自行编造”能缓解一大部分。4.3 API Rate Limit被耗尽GitHub的REST API限制是每小时5000次请求V4 GraphQL是单独的5000点。Hermes的每一次事件处理可能要调用好几个API拉PR详情、拉文件列表、拉Diff内容、发评论。如果仓库PR量大很容易撞限。我的建议是给Hermes的GitHub App配置更高等级的Plan同时从代码层面尽量减少API调用次数能用GraphQL合并的查询就不要发多次REST请求能用Webhook事件里自带的payload数据就不要额外去拉。4.4 模型评审质量忽高忽低这是使用中最大的挫败感来源。明明昨天评论质量很高今天同一个代码模型给出的意见却偏了。我排查后总结出三个原因Diff摘要策略PR的Diff太长被Hermes的截断策略切掉了一部分模型没看到关键逻辑凭片段脑补了。System Prompt冲突REVIEW.md里要求互相矛盾比如前面说“保持简洁”后面又要求“每条必须带代码片段”模型只能随机挑一个执行。模型本身波动大模型是概率性的相同输入也可能有不同的输出。所以一定要把温度调到最低并且在架构上加入“重试机制”——如果模型输出格式不符合要求比如JSON解析失败自动重新调用一次。4.5 PR频繁更新导致重复评论当作者根据建议改了代码push了新commitHermes如果又重新评论一份新的建议很容易产生噪音。GitHub的Review机制本身有“thread”的概念。Hermes在评论时尽量复用已有的评论线程先看这条评论针对的代码行是否已经有一个thread了有就追加没有才新建。如果你发现自己收到的评论总是刷屏可以检查config.yml里的dedup_mode设置有几个选项off不去重、file按文件去重、hunk按代码块去重。我推荐用hunk既保留了对新问题的讨论又不会没完没了重复旧结论。4.6 私钥和凭证管理不当GitHub App的私钥是敏感资产。如果你把它直接提交进仓库别人拿到后就能以你的App身份读取仓库代码、发表评论。强烈建议放在单独的secrets/目录加.gitignore并且在服务器上用环境变量传递。Hermes默认会检查私钥文件的权限如果权限大于0600它会直接拒绝启动这是比较贴心的设计。5. 实用建议与个人体会整套系统从搭建到现在跑了大半年我最大的感触是Hermes真正的价值不在于替代人而在于帮人把时间花在更值得的地方。以前Review一堆PR我至少有一小半时间在看“这个函数为什么要改名”“这个注释是不是写错了”这类的琐碎问题真正需要深入推敲的逻辑问题反而被挤掉。现在Hermes先筛一遍我每次打开PR看到的是它标注出来的“P0这里可能有空指针风险”“P1这条SQL建议参数化”效率提升不是一点半点。给准备上手的朋友三个建议第一先用小仓库试几天。不要一上来就给核心仓库配上你会发现它有很多需要调教的地方。先在Demo仓库跑通闭环看看它的评论风格、准确率再把规则体系调顺最后才上核心仓库。第二配置别贪多。规则越多误报率越高作者和Reviewer都会累。我建议第一批只要三条规则安全检查、提交信息规范、TODO标记清理。跑一段时间看团队的反馈再加下一批。第三把REVIEW.md当成活的团队文档。每隔一两周根据模型出的“昏招”去补充约束。比如有一段时间模型老是在类型标注上吹毛求疵我就在指南里加了一句“类型标注建议只针对新增函数对旧代码不做强制要求。”加完这句话误报率立刻降下来了。模型能不能变聪明很大程度上取决于你喂给它的规则是否清晰。自动化代码评审这条路远没有到“全自动”但已经能实打实地减轻负担。Hermes这种Agent让我看到了一个方向用大模型去理解意图用规则去兜底用工程手段去管理流程三者叠加比任何单方面努力都靠谱。如果你也想给自己项目找个靠谱的“AI同事”这个工具值得投入一下午试试。
返回列表