Hermes接入GitHub PR评审:构建自动化AI代码审查机制 📅 发布时间:2026/9/9 2:19:30 👁 浏览次数: 如果你的团队还在靠人工去盯每一个 GitHub Pull Request那这篇文章大概率能帮到你。我最近把 Hermes 接到了团队的 GitHub PR 评审流程里做了一套自动化代码评审机制。简单说每当有人提交 Pull Request、或者往已有 PR 里补新 commitHermes 会自动拉取这次变更的 diff结合仓库自身的规则调用大模型给出结构化评审意见再以 GitHub Review 的形式贴回 PR 下。整个过程不需要 reviewer 一直盯着机器人会先帮你把第一道关。这个方案适合谁如果你是技术负责人、后端或前端开发、负责团队研发效能的工程师日常在 GitHub 上通过 PR 协作那么下面这套思路可以直接抄作业。如果你只是维护个人开源项目想找一个自动帮你看代码质量的工具也可以按这个方案改造成“个人自查机器人”。这篇文章不会只讲“我配好了一个机器人”这种空话我会把触发策略、上下文拼接、结构化输出、评论落位这些细节全部拆开讲并且附上可以执行的配置和代码片段。1. 项目定位与整体思路为什么 PR 审查值得交给自动化1.1 人工评审的瓶颈不完全是人手不够很多人把 code review 做不好的原因归结为“大家太忙”但其实真正的问题是琐碎反馈吞噬了注意力。十几人的开发团队一天可能产生 20 到 30 个 PR每个 PR 涉及三五个文件。reviewer 打开一个 PR 时看到的不仅是业务逻辑还要忍受大量一眼就能发现的低水平问题把密钥打进了代码、异常被静默吞掉、网络请求没设超时、命名风格跟仓库规范不一致。处理这些问题占用的精力甚至超过看业务逻辑本身。更麻烦的是上下文切换成本。一个后端工程师被拉去 review 前端样式问题等切回自己的任务时至少需要十几分钟重新进入状态。这个问题不是靠“增加评审人”能解决的我见过把四个 reviewer 挂在一个 PR 上结果每个人都在等别人先开口最后只剩一句 LGTM。给 PR 配上自动化代码评审首先不是要取代人而是把“用眼睛扫一遍低级问题”的工作从人身上剥离出来。1.2 Hermes 在自动化评审里扮演的角色Hermes 是我一直在维护的一套智能体运行框架核心能力是接收外部事件、按照预定义策略调用模型能力、最后执行动作。PR 审查只是其中一个 skill实现方式跟普通 CI 脚本不一样它不是一个在服务器上跑一次就结束的流水线而是一个一直监听 GitHub Webhook 的常驻服务。当 PR 事件到达后Hermes 会读取事件类型、判断规则、拉取 diff、组织上下文、调用模型、再把结论写回 GitHub。用一句话概括它的定位自动化评审是一道“前置筛网”。它不关心你这段缓存为什么不一致但它会先发现你是不是把数据库密码打在了代码里是不是有一个空的 except 吞掉了所有异常是不是没有处理用户输入边界。静态检查工具能发现一部分问题但很多需要语义理解的问题只能靠模型来判断Hermes 的设计目标就是把这种“类人判断”工程化。1.3 方案选型为什么不做成一个 GitHub Actions Action我在做之前也犹豫过为什么不直接写一个 GitHub Actions action塞到现有 workflow 里跑这样部署成本不是更低吗确实可以但有几个现实问题让 Actions 方案成为第二选择。第一Hermes 的目标不是只服务某一个仓库我需要让多个仓库共享同一套评审策略、同一个模型账号、同一份配置如果每个仓库各写一套 Action配置会开始漂移。第二Action 是无状态的每次运行都要重新初始化客户端上下文但 Hermes 需要按 PR 维度做状态管理比如同一个 commit 只能评审一次避免重复评论。另外Actions 的环境对任意代码的约束比较多比如需要处理 secrets、token 获取这些细节而用独立的 GitHub App 身份接入能拿到更干净的权限模型。如果你是单仓库、单项目、不太介意每个仓库重复配置一遍GitHub Actions 完全可以。但如果你想把它沉淀成一个团队级别的工程能力独立服务 Webhook 的架构会更耐久。1.4 这套方案的边界自动化只做提醒做不了最终判断做任何自动化评审工具最重要的一件事是先承认它的边界。Hermes 给出的意见本质上来自语言模型对当前 diff 的语义推断它可以判断“这段代码缺少超时时间”是合理的但如果涉及复杂的业务规则它只能提出“疑似”或者追问不应该给出强约束结论。所以我的定位是Hermes 的输出是人的参考不是取代人的终审。这也是为什么我采用 GitHub Review API但默认不会用REQUEST_CHANGES去卡合并。机器人可以把发现的问题拆成“高危提醒”“改进建议”“风格细节”真正的合并审批权还是保留在人工 reviewer 手里。这个边界想清楚之后整个系统的容错空间就大了很多就算模型偶尔误报最多只是一条噪音评论不会阻塞团队交付。2. 核心细节解析从 GitHub 事件到评审意见的完整链路2.1 触发策略别让机器人在错误的时间点乱“激动”PR 相关事件有很多种opened、edited、deleted、review_requested、review_request_removed、synchronize、ready_for_review、labeled等。最忌讳的就是把所有事件都接进来然后每个事件都触发一次完整评审。比如作者只是改了 PR 描述里的一个错别字edited事件也会发出来这时候重新拉 diff 调模型纯属浪费 token。我的触发配置很克制默认只监听四个 actionpull_request.opened新建 PR需要首次评审。pull_request.synchronize作者 push 了新 commit需要基于最新 diff 再评一次。pull_request.ready_for_review从 Draft 转成正式可审状态。pull_request.labeled如果想支持“人工打 label 手动触发评审”这个事件就很有用。opened和synchronize是主要评审时机。有人会担心 synchronize 太频繁作者每推一次 commit 就触发一次那确实会有噪音。常见做法是过滤掉完全没改变 diff 的提交或者对同一个 commit 哈希只评一次。还有一种思路只看 synchronized 之后最近一个 commit 的变化也就是基于 base 到 head 的完整增量不是增量之间的增量。Hermes 每次拿到的都是 Pull Request 的完整 diff所以评审结果覆盖的是整个 PR 的最新状态而不是某个单独 commit。2.2 上下文组装把 diff 拼成模型能看懂的“材料”拿到触发信号之后下一步是构造模型的输入。很多初版实现犯的错误是直接把 GitHub 的 diff 原文丢给模型也不解释任务也不给仓库规则这样模型只能凭通用经验猜。要得到稳定的评审质量上下文必须控制在足够小的范围内、并包含明确约束。Hermes 实际拼接的上下文包括四个部分系统指令说明你是一个资深代码评审专家只能依据 diff 和仓库规则给意见禁止臆造。仓库规则读取仓库根目录下的.hermes/review.md或rules.md作为评审基准。PR 元信息标题、描述、改动文件列表。描述能告诉模型这次改动的意图。Diff 内容按文件拆分的 patch并标注每个文件的新旧行号。理论上 5 万 token 的上下文窗口可以把大型 PR 全塞进去但事实是上下文越长模型越容易丢失关键信息成本也越高。实践下来diff 超过 1000 行或改动文件超过 20 个的 PR直接全量评审几乎不可用。Hermes 的做法是先判断规模超过阈值的 PR 只做问题扫描式评审或者只关注核心目录下的文件再生成一个“太多改动、建议人工优先看这几个文件”的整体提示。把上下文控制在小而准的范围比迷信长窗口更有用。2.3 结构化评审协议让模型输出 JSON 而不是散文我早期踩过一个坑让模型自由输出评审意见结果它把一份好好的代码评审写成了长作文连文件行号都没有人还得靠猜去找位置。所以后来我强制模型输出 JSON并要求字段固定。每个评审结论包括summary、blocking_issues、suggestions、optional_nits其中每个 issue 都带有file_path、start_line、end_line、severity、message。这种结构化要求看起来多此一举但它是整个自动化的关键。只有输出结构化后续才能把评审结果映射到 GitHub PR 的具体文件行上也才能做规则化的后续处理。比如 severity 是high的才考虑是否需要变更请求low的就只在 summary 里出现。模型输出格式不稳定是必然的所以代码里要做 JSON 解析兜底解析失败就让它重试一次设置比较低的 temperature 比如 0.2输出稳定性会有明显提升。2.4 反馈机制用 Review API不要在 PR 里刷普通评论评审结果要回写到 GitHub 上这里有一个关键选择用普通的 issue comment 还是 Pull Request Review。如果用普通评论每条意见就会在 PR 主对话里刷成一长串非常打扰人。而 Pull Request Review 会把意见整合到 Files changed 页面还能设置整体评价事件。GitHub 支持的 review event 有三种APPROVE、REQUEST_CHANGES、COMMENT。机器人默认应该用COMMENT因为一旦自动REQUEST_CHANGES作者看到的是机器人要求你改但最终负责人还没发话流程会很混乱。Hermes 会把high级别的问题放进 review body 前面把suggestion和nit放到文件行内 comment这样作者打开 PR 后第一眼就能看到最需要关注的内容。整体交互体验跟一个真实 reviewer 贴评论几乎一致而不会像一堆机器人刷屏。3. 实操过程把 Hermes 接入 GitHub 仓库的完整流程3.1 整体架构与前置条件在开始配置之前先花两分钟说清楚整个链路会用到哪些组件避免配置一半才发现少东西。整体架构由四块组成GitHub App提供机器人身份、权限和 Webhook 入口。Hermes 常驻服务接收 Webhook、处理事件、调用模型。模型服务任意兼容 OpenAI 协议的接口都可以按仓库预算选型号。目标仓库安装 GitHub App 的仓库必须开放 Pull requests 的读写权限。Hermes 服务可以部署在一台轻量服务器上也可以用 Docker 跑甚至本机调试时配合内网穿透暴露一个公网地址。我的建议是部署阶段直接放到一台有固定公网 IP 的服务器或容器平台因为 GitHub Webhook 需要回调你的地址。仓库本身不限规模公开或私有都可以但私有仓库要记得在 GitHub App 安装时勾选对应权限。3.2 创建 GitHub App权限配错了后面全是 403在 GitHub 上打开 Settings进入 Developer settings然后选择 GitHub Apps点 New GitHub App。名字我建议起一个跟机器人能对应上的名字比如hermes-review-bot。下面几个配置项很容易配错我逐个说明Homepage URL可以填你的仓库地址或项目页。Webhook URL填https://你的域名/hermes/webhook。Webhook secret自己生成一串随机字符串后面 Hermes 配置里要填同一个值。PermissionsPull requests 选 Read and writeChecks 可以选 Read-onlyMetadata 会自动变成 Read-only。如果需要读取 issue 内容补充上下文再把 Issues 选成 Read-only。Subscribe to events勾选 Pull request。创建完成之后页面底部可以生成 Private Key这是一个 PEM 文件一定要下载保存Hermes 后续需要用这个私钥生成 GitHub App 的 JWT。最后在页面左侧找到 Install App选择一个仓库安装。千万别忘了这一步只创建 App 不安装到仓库Webhook 永远不会发过来。用 GitHub App 而不是 Personal Access Token原因有三个App 的身份是独立的不会占用个人账号的 API 配额权限范围可以精确到仓库不会把你个人账号的全部仓库都暴露给服务如果某个仓库不需要评审了直接卸载 App 就行不需要改 token。3.3 Hermes 服务的核心配置样例Hermes 的配置我做成了 YAML 文件核心思路是把触发规则、模型参数、仓库列表和评审策略全部集中在一个地方。下面这份配置是我当前在用的精简版可以直接改成自己的值server: host: 0.0.0.0 port: 8080 github: app_id: 123456 # 你的 GitHub App ID private_key_path: /etc/hermes/private-key.pem webhook_secret: 替换成随机字符串 repositories: - your-org/backend-service - your-org/fe-webapp review: triggers: - pull_request.opened - pull_request.synchronize - pull_request.ready_for_review - pull_request.labeled model: provider: openai-compatible # 可切换任意兼容接口 base_url: https://api.你的模型服务.com/v1 api_key_env: LLM_API_KEY name: 你的模型名 temperature: 0.2 context: rules_path: .hermes/review.md max_diff_lines: 1000 max_files: 20 output: submit_review: true review_event: COMMENT关于模型选择我个人的经验是不要盲目追求最强模型。PR 评审对语义理解有一定要求但更多是分布式的小任务单次调用量很大所以成本权衡很重要。日常 PR 用中档模型就够只有面对架构性的重构 PR 才手工触发一次更高质量模型的专项 review这也符合大多数团队的成本预期。max_diff_lines和max_files这两个参数非常重要它们保护的是你的 token 预算也是保护模型输出质量。我曾经拿一个 5000 行改动的大 PR 做测试模型的输出明显开始丢字段把 review 变成车轱辘话。设上限之后系统会自动降级成“摘要式评审”而不是硬着头皮硬看。3.4 Webhook 接收与签名校验不能是个人都能推启动 Hermes 之后第一件要紧事是校验 Webhook 签名。GitHub 会在请求头里带一个X-Hub-Signature-256由请求体和你的 Webhook secret 用 HMAC-SHA256 计算出来的。如果服务端不校验签名任何知道地址的人都能伪造一条事件请求逼你的模型白跑几千次调用。代码很简单但这一层必须做。import hashlib import hmac def verify_webhook_signature(payload_body: bytes, signature_header: str, secret: str) - bool: if not signature_header: return False expected sha256 hmac.new( secret.encode(utf-8), payload_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature_header)核心路由的伪代码大致是下面这样先把签名逻辑放进去再按事件类型分发。GitHub Webhook 也可以直接在服务里用 FastAPI 暴露一个/hermes/webhook路径。app.post(/hermes/webhook) async def handle_webhook(request: Request): body await request.body() signature request.headers.get(X-Hub-Signature-256, ) if not verify_webhook_signature(body, signature, cfg.github.webhook_secret): return JSONResponse({error: invalid signature}, status_code401) event request.headers.get(X-GitHub-Event) data json.loads(body) if event pull_request: await handle_pull_request_event(data) return JSONResponse({ok: True})handle_pull_request_event里第一步是判断 action 是否在review.triggers列表里不在就直接忽略。接下来要拿到仓库名和 PR 编号用来组装后续的 API 请求。这里有一个很容易漏掉的地方data中的sender是触发人如果用机器人账号 push 代码有可能会无限循环触发通常要在触发条件里加入sender.type ! Bot这样的过滤或者直接跳过机器人自己产生的改动避免自己审自己。这个细节不处理好轻则浪费 token重则把 GitHub API 限流打满。3.5 上下文准备拉取 diff 和仓库规则下一步是拉取 Pull Request 的文件变更。这里不推荐直接从 Webhook payload 里找 diff因为默认 payload 里的 diff 内容非常有限尤其是大 PR 会经过截断。最稳的方式是调用 GitHub REST API# GET /repos/{owner}/{repo}/pulls/{pull_number}/files这个接口会按文件返回列表每个文件里有文件名、状态、新增行数、删除行数和 patch 文本。patch字段就是我们要的 diff。但要注意GitHub 的这个接口默认一页最多返回 100 个文件而且每个文件 patch 也可能很长。实际处理时需要循环翻页把文件们拼成统一结构再丢给下一步。拼接的逻辑也不是把全部文件一股脑塞进去我会按照“后端接口定义 核心业务目录 外围工具类”的优先级对文件排序优先把核心改动放进去。如果仓库里配置了.hermes/review.md规则文件还要读取它作为评审约束。举个例子一份规则文件可能长这样# 仓库评审规则 - 禁止提交任何形式的密钥、token、连接串硬编码 - 所有对外网络请求必须显式设置 timeout - 捕获异常后必须记录日志禁止直接 except Exception: pass - 数据库 Schema 变更必须提供 down migration - 新增暴露接口必须补充 Basic Auth 或签名校验这类规则文件的价值在于把仓库里约定俗成的东西显式化让模型在评审时有据可依。没有规则文件时模型只能凭通用常识而有了这几条硬性要求后评审质量提升非常明显。3.6 模型调用与结构化输出解析拿到 diff 和规则之后Hermes 会把所有内容拼进一个 Prompt同时要求模型只输出 JSON。大致结构是系统提示里写位置用户内容里先把 PR 描述放进去然后把规则文件原样放入最后是按文件组织的 diff。需要特别说明的一点是不要把完整 diff 直接放在首个系统指令里最好在用户消息里分段按文件用 Markdown 代码块包围。模型对代码块边界的识别比较稳定这样可以减少串格式的错误。records llm_client.chat( messages[ {role: system, content: SYSTEM_PROMPT}, {role: user, content: build_user_prompt(pr_context, rules, diff_records)}, ], temperature0.2, ) parsed parse_review_json(records.content)parse_review_json不能假设模型第一次就输出合法 JSON。我的处理方式是先尝试json.loads如果失败就把内容里首尾的 Markdown 代码块剥掉再试一次还失败就让模型基于上次输出重新生成一次。两次都失败就降级为普通文本总结通过 review body 提交而不是直接把异常抛出去导致整个流程中断。宁可让机器人少提几个点也不能让它因为一次解析失败造成大量重试。3.7 把评审意见贴回 GitHubAccess Token 与 Review API前面链路都走通之后最后一步涉及 GitHub API 的调用这里有两个技术细节需要注意。第一个是 GitHub App 的身份认证。直接用 App ID 调 API 是不够的需要用私钥生成 JWT再用 JWT 换一个 installation token。installation token 才是真正有仓库读写权限的令牌有效期为 1 小时过期就重新换。代码层面可以这样理解import time import jwt import requests # 1. 用私钥生成 App JWT now int(time.time()) app_token jwt.encode( {iat: now, exp: now 600, iss: cfg.github.app_id}, private_key, algorithmRS256 ) # 2. 用 JWT 换取安装级 token resp requests.post( fhttps://api.github.com/app/installations/{installation_id}/access_tokens, headers{Authorization: fBearer {app_token}}, json{} ) installation_token resp.json()[token]第二个细节是创建 Review 的 body 结构。调用POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews时body 大致如下{ commit_id: 当前 HEAD commit sha, event: COMMENT, body: 整体评审结论, comments: [ { path: src/api/client.py, line: 42, side: RIGHT, body: 这个网络请求缺少 timeout建议补充 3 秒超时设置。 } ] }这里有非常多初学者会踩的坑line必须是这个 PR 的 diff 中可见的行号不能是修改前文件里的行号更不能是文件里的普通行号。如果模型给出的行定位不准GitHub 会直接返回 422。后面第 4 节我会专门展开讲行号定位问题这里先有个概念就好。4. 常见问题与排查技巧实录4.1 Webhook 收不到请求先看 Recent Deliveries如果你配置好 GitHub App 之后发现 Hermes 完全没反应第一步不要去看服务日志先去 GitHub App 的设置页里找到 Advanced打开 Recent Deliveries。这个页面记录了 GitHub 每次向你的 Webhook URL 发送请求的完整情况包括请求头、请求体和响应状态码。如果 Recent Deliveries 里面是空的说明 GitHub 根本没有把事件发出来问题多半出在 App 安装或事件订阅上。此时检查一下 App 是否安装到了目标仓库再确认 Pull request 事件是否勾选。如果 Deliveries 里有请求但响应码是 500 或 404那就需要回到 Hermes 服务日志排查。如果响应码是 200但服务没有执行评审那就是事件分发逻辑没匹配上 action 类型。Webhook secret 不匹配的表现是请求到了你的服务器但签名校验失败被拒通常返回 401。这种情况在 Recent Deliveries 里会看到请求发出的响应是 401检查两边 secret 是否一致即可。4.2 Review API 报 422评论行号定位永远是最大坑我接 Hermes 的第一周几乎每天都会收到 422 错误。原因基本都是 comments 里的line没有落在 diff 可见行内。GitHub 对 Pull Request Review 的行内评论要求很严格你只能评论那些在 diff 中出现的行不能随便写一个源文件行号。我自己摸索出来的解决思路是这样的拉取 PR files 时GitHub 返回的 file 对象里面其实已经包含了changes信息patch 本身就是 diff。如果模型输出的行号报错可以尝试用不含行号的普通 review body 提交反馈把所有 issue 都写到 body 里至少保证信息能传达到作者。还有个策略是在 prompt 里明确要求模型issue 必须带有实际存在的新文件行号同时给出 diff 中的行号上下文。虽然模型还是会偶发搞错但配合 fallback 机制整体可接受。如果是在旧代码行删除的行上评论GitHub 要求指定side: LEFT这个字段很容易丢。我的建议是机器人默认只评论新代码行也就是新增的代码因为大多数评审场景关注的是新写进来的逻辑问题。4.3 机器人重复评论基于 commit 做幂等PR 每更新一次 commit就会触发一次synchronize。如果作者在一个小时内连续 push 三次Hermes 就会跑三次完整评审。这三条 review 全部堆到 PR 上看着非常吵而且作者可能只对你第一条意见回复了后面就又冒出三条新意见。解决办法是在服务端维护一个“已评审 commit”的缓存。每个 PR 都记录最后一次已评审的 head commit SHA当新事件触发时先比较当前 head 和已评审 head一致就跳过。这样同一个 commit 只会提交一次 review只有作者真的产生了新 commit 才会再次触发。GitHub 即使重复推送同一个 SHA 的事件也不会导致重复评论缓存可以直接放在内存里但服务重启会丢。正式使用建议用 Redis 保存key 可以是reviewed:{repo}:{pr_number}。4.4 模型输出不稳定降级策略比模型本身更重要模型输出的不稳定性只能缓解不可能完全消除。结构崩了、内容空了、格式对了但全是废话这些我都遇到过。Hermes 的应对方案是三级降级第一次解析 JSON 失败把模型返回文本里的代码块剥掉再解析一次还失败就重新问一次模型并附上错误信息连续失败的话放弃结构化输出把模型原始文本作为普通 review 提交。除此之外Prompt 里也要刻意压制“无效输出”。我发现如果只写“请评审以下代码”模型特别喜欢输出一堆“这段代码逻辑清晰、命名规范”的套话。后来我在系统提示里强调“评审只输出你必须指出的问题如果所有文件都没有明显问题blocking_issues 和 suggestions 都可以为空数组”。加了这句话之后无效输出明显减少人对机器人的信任度也会提升。4.5 权限与限流的速查清单最后放一个速查表整理了这段时间使用 Hermes 过程中最常遇到的状态码和原因按问题现象归类会更快。现象可能原因解决方式Webhook 请求 401Webhook secret 配置不一致对比 GitHub App 设置与 Hermes 配置调用 API 返回 401installation token 过期换 token 逻辑要自动处理1 小时过期返回 403App 未安装到目标仓库或权限不足检查 Install App 的仓库范围和 permissions创建 review 返回 422行号不在 diff 可见范围内fallback 到 PR 级 body修正 line 计算LLM 返回 429模型服务限流加退避重试降低并发GitHub API 限流短时间请求过多缓存 diff按 commit 幂等去重这里补充一点GitHub API 的限流是按 installation token 计算的正常 PR 评审场景不会触顶。但如果代码里没有对相同 diff 做缓存且规则文件每次都单独拉取高频 PR 下还是有可能接近限制。Hermes 会把仓库规则文件和 PR diff 都缓存 5 分钟多个事件命中同一窗口时就能避免重复拉取。5. 运行效果复盘与个人经验5.1 一段时间运行后的真实数据我自己的团队接入 Hermes 之后跑了两周大约 60 多个有效 PR。数据不算大规模但能说明一些问题。统计下来Hermes 平均每个 PR 会输出 3 到 5 条意见其中被开发者认为有效或值得修改的比例大概在五成左右。真正有实际价值的阻断级提醒主要集中在这几类硬编码密钥、异常被静默吞掉、网络请求未设置 timeout、多环境配置没隔离。最让我意外的一条是它在一次数据库变更 PR 中发现了缺少回滚迁移文件这是人工 review 很容易扫过去的内容。跑两周之后团队内部看待机器人不再像刚开始那样觉得“这东西是来添乱的”大家普遍接受了“合并前先让机器人看一眼”的习惯。需要强调的是不要把这个数据当成 Hermes 在所有仓库的普适结论。效果高度依赖仓库规则的完善程度和模型选择。如果一个仓库没有任何规则文件机器人只能靠通用常识输出意见价值会低很多。我强烈建议在接入 Hermes 之前先花半小时整理一份仓库级 review 规则这份规则比模型本身更影响评审效果。5.2 我眼中真正适合自动化评审的问题类型复盘之后我对“哪些问题适合让机器人找”有了更清晰的判断。第一类是“必须禁止”的硬性规则比如密钥提交、硬编码连接串、没有密码保护地暴露内网接口。这一类适合写进规则文件让机器人严格审查命中就提醒。第二类是代码风格类比如命名不一致、魔法数字散落、不必要的 import。静态工具其实也覆盖了一部分但模型对风格的判断更接近人的口味。第三类是明显的错误模式比如空 except、请求没有设置超时、循环里重复查询数据库这类问题背后往往是开发时间紧导致的疏忽机器人正好能补上。不适合自动化的包括复杂的并发设计问题、跨模块的业务语义判断、产品需求的实现合理性。这些还是需要人工 reviewer 带着上下文去理解。Hermes 对这些问题的处理方式是只标记为“疑似”或“建议确认”不让它变成阻塞项。5.3 Hermes 后续的扩展方向现在这套链路只处理了 pull_request 事件但底层的事件监听、上下文组装、模型调用、结果回写的框架完全可以复用到别的场景。Hermes 后续我计划扩展两个方向一个是把 CI 失败日志也接入进来让模型先分析 build failure 原因再把人拉入排障另一个是接 issue 事件当一份新 issue 进来时先让模型做信息补全和标签分类减少维护者整理成本。如果你只是想要一个能评价 PR 的小工具动手之前可以先把这篇文章里的 trigger 配置、context 拼装逻辑和 line fallback 机制抄走这三个点能救回你 80% 的踩坑时间。同时我建议把机器人定位成“看得细的 junior reviewer”而不是“自动的 merge 决策者”这样团队会更愿意接受它。