AI-Native 系列 · 智能体工程 · 循环工程实录
AI 审查循环报告:十一天无声、一张群聊卡片与 24% 上限
问题出在哪里,我们做了哪些构建,六项决策及其原因,审查员在自我修复中发现了什么,以及下一步计划,每项都附带可证伪的观测点。
1 分钟速读——你将收获什么
这是什么。 这是一份关于 AI 审查循环的报告:AI 会审查制造业质量管理代码库的每个 pull request,判定结果通过新路径同步到团队群聊再返回。内容包括:问题(审查员预算耗尽十一天无人察觉)、解决方案(每个决策对应一张群聊卡片,审查员自身故障时用另一张)、六项设计决策及其原因、经验教训和下一步计划。
为什么重要。 对工程师来说:“永不沉默”是必要条件,但远远不够。发在没人看的地方,和没发没区别。对创始人来说:团队原本设定 90–95% 变更可自动合并,实测这个代码库的上限只有 24%,因为大多数变更都涉及必须人工签字的内容。提前知道这个上限,比花一个季度去追目标更有价值。对学生来说:这是一个在动手前先测量目标的完整案例。
读完后你可以做什么。 今天就能在自己的仓库里跑这两个测量(你的 reviewer 实际跑了多少次判定?你的 auto-merge 规则理论上能放行多少已合并的变更?)。复制下方的 30 分钟合同,把 reviewer 的判定同步到你们团队常用的频道,并为“reviewer 没有运行”单独设置一个告警。
这份 AI review loop 报告涵盖了什么,写给谁看
这份报告延续了该仓库的一个系列。AI PR Review That Cannot Lie 实现了 reviewer:每条结论都标明文件和行号,“unmeasured” 作为一种明确状态被发布,而不是沉默。接着 ANDON 系列将其总结为五条规则,第四期 the auto-merge envelope,结尾坦率指出:让机器人自动合并的那扇门从未打开过。与此同时,Visionboard 系列构建了我当前项目使用的仪表板,最后一期 the scoreboard,提出了下季度的三个目标,每个都有明确的反例。第二个目标是 a sensor that cannot be silent.
这份报告记录了这些设计在真实一周中的实际表现。2026-09-23,那天我和负责质量的联合创始人就 AI review loop 达成三点共识:reviewer 只判断两件事(变更是否符合需求,是否遵循工程规范);只有在它自己拿不准时才升级给人处理,我们估算大约只占 5% 到 10% 的 PR;所有通知都发到团队 chat,不用邮件。当天我就对这个估算做了测量,结果是 100%。
本报告分为三部分。报告:问题、解决方案,以及六项设计决策与背后的理由。复盘:这次构建带来的经验,包括 reviewer 在自我修复时发现的问题,以及一个让我损失半天信任的委托教训。计划:下一步怎么走,无论大小、长短,每一步都对应 Visionboard 的目标或 ANDON 的门,并明确写出可证伪的观测点。
读者对象:已经在用或即将使用 AI reviewer 的工程师;决定“auto-merge”能放行哪些内容的创始人;想要一套完整闭环(从失败到测量、设计、再到尚未证伪)的学生。代码库是私有的,但每个机制这里都还原得足够详细,足以复现。
一幅画面:出菜口、副厨,以及主厨口袋里的铃铛
整篇报告用这一幅画面贯穿,故事承接自厨房主题的 第一份报告,讲的是厨师晋级“经营餐厅”那一关。每道菜都要经过出菜口。副厨先品尝,并在点单上夹一张便签。主厨读完便签,自己再尝一勺,然后决定是让菜出还是退回去。对于副厨百分百有把握的冷盘,可以直接上桌。
有整整十一天,副厨都没上班。厨房的规矩是“绝不假装你尝过”,所以每道菜副厨的替班都夹了一张便签:未尝。规矩执行得一丝不苟。便签堆在出菜口。主厨在餐厅里,手里拿着手机,却从未经过出菜口。每道菜都只能等主厨来决定,这样虽然安全,但厨房原本承诺大部分菜能自动流转,结果悄然归零。没有人说谎,也没有人察觉。
解决办法,是在主厨口袋里放一个铃铛,而且有两种不同的响声。
| 在厨房里 | 在 AI 审查循环中 |
|---|---|
| 副厨夹在点单上的便签 | AI 在 pull request 上发布的审查摘要:给人类的问题、发现项,file:line,建议的判定,以及这次变更是否符合自动合并条件。 |
| “未尝”便签堆积在出菜口 | 47 个摘要里有 45 个写着“未测量”:审查员的预算上限被触发,根本没跑。都如实发布了,但无人理会。 |
| 橙色铃声:“这道菜我拿不准” | 一张标题为 需要你决策 的聊天卡片:AI 的未解答问题、所有未满足的自动合并条件,还有一个直达 pull request 的按钮。 |
| 灰色铃声:“我不在厨房” | 另一张卡片:审查员未运行,原因和修复方法都用大白话写清楚。这是系统故障,绝不会伪装成“关于菜品的问题”。 |
| 主厨走到出菜口做决策 | 点击按钮会在 GitHub 上打开对应的 pull request。审批操作必须在 GitHub 上完成,并在那里留下记录,绝不能通过聊天回复来完成。 |
| 餐厅亮起的灯:“菜已上桌” | A 已合并 卡片,由另一个工作流在 pull request 合并关闭时触发。循环在原点闭环。 |
画面在这里断裂:现实中副厨一旦下班,厨房立刻变慢,大家都能察觉。但评审“下线”时,表面上没有任何可见损失,因为人工流程依然畅通。这正是整个问题的根源,也是为什么必须有灰色提示环的原因。
第一部分 · 报告——问题,先测量再修复
就在那天晚些时候(美国时间,会议在中国时间 22:04 结束),我拉取了所有被评审标记过的 pull request,逐条阅读每份总结中写明的原因。这里看的不是标签本身:用于“AI 不确定”和“AI 没有运行”的其实是同一个标签。
| 读数(2026-09-23,共 47 个被标记的 pull request) | 数量 |
|---|---|
| 自动合并 | 0 |
| 因 AI 不确定或发现问题而升级(评审实际运行) | 2 |
| 因评审未运行(“未测量”)而升级 | 45 |
| 47 个中,打印出的原因(一个 pull request 可能有多个):评审未运行 · 变更不在自动合并路径 · 某个机器闸门为红 | 45 · 33 · 6 |
所有 pull request 中,最终需要人工处理的占比:47/47。范围:单一仓库,统计自评审首次标记到 2026-09-23 的所有记录。[已测量]
第二天又读了一遍,多了四个 pull request:共 51 个被标记,0 个自动合并,4 个由实际运行的评审升级,47 个评审未运行。分布没变,只是数量增加。
五个为什么,每个都能在仓库或日志里找到答案:
- 为什么每个 pull request 都需要人工处理? 因为 47 个总结里有 45 个写着评审未运行。
- 为什么没运行? 自 2026-09-12 起,每次调用都返回同一个错误:组织的月度消费额度已用尽,2026-10-01 才会恢复访问。
- 为什么额度会用完? 评审和我在那台机器上运行的所有其他任务共用一个 API key 和 $100 的月度额度,包括一个把文章翻译成四种语言的批处理任务。账单控制台只能按 key 查看花费,无法按任务区分,所以我无法确定具体哪个任务花得最多;但可以确定,评审是被饿死的那个。
- 为什么十一天没人发现? 评审任务设置为失败时不阻塞合并,所以工作流一直显示绿色。每个 pull request 都按“永不沉默”规则贴了“未测量”总结,十一天里无人理会,因为没人会特地点开准备手动评审的 pull request 的总结。永不沉默规则 的要求,但十一天里无人理会,因为没人会去点开他们本来就打算手动审查的 PR 总结。
- 根本原因: 审查器自身故障,却没有任何机制能把这个状态传递给人。「永不沉默」在页面上做到了,但在现实中失效了。
这个仓库的 lessons 文件两周前就有一条几乎一模一样的记录,写着:unmeasured needs someone watching it(未测状态需要有人关注),还写了下一步动作,但始终没有落地。用文字记录的教训,随时可能失效。这正是 ANDON 第三集 的主旨——规则要用数据表达,而不是只写成文字。显然我还得再学一遍。
第一部分 · 报告 —— 解决方案:让 AI 审查循环直接报告到团队活跃的频道
团队已经确定,聊天应用(飞书)是唯一的收件箱。所以这条循环分为四步:GitHub 运行审查器,脚本把总结转成聊天卡片,卡片上的按钮把人带回 GitHub,合并事件再发一张卡片回来。
卡片类型及其判定逻辑:
| 卡片类型 | 触发条件 | 人类操作 |
|---|---|---|
| 🟨 需要你决策 | 审查器已运行,但变更不符合自动合并条件:如路径不在允许列表、闸门为红、发现了问题,或有只有人能回答的问题。 | 阅读问题(目前测下来,平均每个 PR 2.3 个问题,n=7),点击按钮,去 GitHub 上做决定。 |
| ⚪ 审查器未运行 | 总结中出现「unmeasured」(预算、无效密钥),或没有总结且审查步骤未报告成功。 | 修复系统。卡片会写明原因和修复方法,并用粗体标明 PR 本身没有问题。 |
| ✅ 自动合并中 | 自动合并信封自动合并信封篇 挂起。 | 无需操作。可通过一个设置关闭。 |
| ✔ 已合并 | Pull request 合并关闭时触发。 | 无需操作,循环在此闭环。 |
| (无卡片) | 没有需要审核的内容,或有新的 push 取消了本次运行。 | 无需操作,这种沉默是明确声明的决策,下面会提到一个已知的例外。 |
首次端到端实测,2026-09-24:组织额度提升后,reviewer 在一个真实 pull request 上运行,提出了三个警告和两个需要人工解答的问题,团队群收到一张带问题的橙色卡片;修复后,合并又发出一张蓝色卡片。每一步都在真实 pull request 上跑通,不只是测试。
第一部分 · 报告——六项设计决策及其原因
| # | 决策 | 被否定的备选方案 | 原因 |
|---|---|---|---|
| 1 | reviewer 出错时单独发卡片。 灰色卡片,标题为“未运行”,并写明原因和修复方法。 | 所有非自动合并的情况都用一张“需要人工处理”的卡片。 | 这两种状态需要不同的人和不同的处理方式。混在一起就会让 45 个系统故障看起来像 45 个审核问题。如果一开始只用一种卡片类型,第一天就会 100% ping 所有 pull request,第二天就会被全员静音。 |
| 2 | 卡片类型由 summary 文本在代码中判定。 | 让模型来判断发哪种卡片。 | 路由器不能依赖被路由的对象。预算耗尽的 reviewer 没法被问“你是不是没钱了”。 |
| 3 | 审批只在 GitHub 上进行。 卡片上的按钮会把人带到 GitHub。 | 通过在群聊回复审批,借助带回调服务器的聊天平台应用实现。 | 这是一个质量证据系统:在审计时,必须能从同一条记录中回答“是谁批准了这个变更,什么时候批准的”。如果用聊天回复来审批,就会多出一条记录,可能和原始记录不一致。并且还需要额外维护一个应用、服务器和凭证。 |
| 4 | 当无法确定 reviewer 的状态时,必须发出告警。 只有明确收到“success”且没有 summary 时才保持安静。 | 除非步骤明确失败,否则保持安静。 | 缺失或异常的状态,正是配置出错时最常见的表现。默认必须是“响”的。唯一的例外是被新推送取消的运行,这种情况保持安静,因为新的运行会汇报。它的代价后文会说明。 |
| 5 | 用仓库实际测得的两个数字,替换原本 5–10% 的目标。 | 继续坚持“只升级 5–10%”的目标,并不断放宽 auto-merge 的范围,直到达成。 | 实测:最近合并的变更中,理论上只有 24% 有资格(详见第一部分,天花板)。追求 90% 就意味着要用证据链换取速度。替代目标是 Tier-1 auto-merge 比例和每次人工 review 的负担。 |
| 6 | reviewer 拥有独立的预算。 2026-09-24 已完成:新建了一个独立 workspace 的 key,这样支出能单独统计;组织限额也从 $100 提高到 $200。 | 所有项目共用一个 key,用完再加额度。 | 共享预算会导致最不重要的任务饿死最重要的任务。需要说明的是:组织的总额度依然覆盖每个 workspace,所以隔离并不彻底(详见 lessons 部分我的实际踩坑)。 |
第七个决策其实是“拒绝决策”:这个 loop 不做决策,只负责传递。reviewer 负责给出建议,哪些能 auto-merge 由规则文件决定,剩下的都由人来拍板。这正是 the Visionboard 在团队里的设计落地:agent 负责提案和报告,人类始终处于 loop 之上。在 small-team episode 里,纯人工字段变成了分权的角色。这里的角色是“代码所有者”,而卡片就是向这个角色发起请求的方式。
第一部分 · 报告——24% 上限:auto-merge 实际能覆盖多少
一个能加速决策流转的 loop,并不能告诉你到底有多少决策必须由人来做。所以第二个测量问的是:最近 60 个合并的 pull request,有多少只涉及 全部是 auto-merge 规则允许的文件,比如文档、计划、测试和 golden test case?这就是上限。再强的 reviewer,也不能自动合并规则禁止的变更。其中有一个 PR 恰好有 100 个文件(GitHub 每个 PR 最多返回 100 个文件),所以它的文件列表可能被截断,按未测算处理,剩下 59 个。
路径合规、可 auto-merge 的:最近 60 个合并 PR 里,59 个可测算的有 14 个(24%)。加上前端样式、组件和视图:15 个。再加 tooling 文件夹:20 个。范围:一个仓库,2026-09-24 测量;这是上限,不是预测,因为合规变更还得满足所有条件并通过 review。[实测]
最大的阻碍出乎意料,而且是我们自己造成的。其中有十九个涉及 AGENTS.md,也就是每个编码智能体在执行前必读的手册。仓库有一条规则:每次功能变更都必须同步更新手册,确保无论人还是智能体都不会参考过时的说明。而自动合并规则也明确禁止机器人合并对手册的修改,因为一旦手册变了,所有智能体的行为都会随之改变。两条规则叠加,所有功能变更都必须由人类审核,这是有意为之。机器人必须更新手册,但机器人不能批准对手册的更新。规则都没错,错在原先的目标设定。
如果把前端目录也纳入自动合并,理论上会多出一个可自动合并的 pull request,但实际上前端变更通常也会涉及受保护文件。如果再把 tooling 文件夹也放开(假设所有“如果”都成立),还能多出五个,但 tooling 目录里正好放着 gates 和 reviewer 本身:让机器人合并对评分器的改动,就等于让厨师自己给自己打分。所以我的建议是,团队下次决策时,保持现有规则不变,调整目标,先跑一个为期两周的试点。这里还有一道与软件无关的门槛:GitHub 不允许这个仓库开启分支保护,提示“Upgrade to GitHub Pro”(中译:升级到 GitHub Pro),所以机器人可以批准但不能合并。在这点改变之前,自动合并率结构性为零,这和 the envelope episode 里那扇门一样,始终关着。
更正,2026-09-25。 本文最初说这扇门需要每月 $4 的付费计划。实际上仓库所有者早已开通该计划。同账号下的其他私有仓库都能用分支保护,唯独这个仓库是从旧仓库 fork 出来的私有分支,fork 会继承上游网络的特性,而不是所有者的。报错信息给出的修复方法其实早已应用。真正的修复方式是解除 fork 关系。这和本文其他部分的教训如出一辙,只是层级更低:我只看了报错信息的描述,没有实际测量状态,而测量只需要几次 API 调用。
Part II · 复盘——reviewer 在自我修复时发现了什么
修复 review loop 的过程本身就是一组 pull request,所以刚刚复活的 reviewer 第一个下午就在给救活它的代码打分。它在我四个 pull request 上跑了十次,有五次要求返工,五次直接通过,而且每一轮——包括通过的——都指出了真实的问题。下面按顺序列出它抓到的点,顺序本身就是教训。
| # | 它发现的问题 | 错误类型 |
|---|---|---|
| 0 | 我自己的脚本给一个根本没有内容可 review 的 pull request 发了个假“需要你决策”的卡片。我是在 reviewer 上线第一天从群聊里自己发现的。 | 把空结果当成了发现项。 |
| 1 | 我修复时,如果 summary 里没有标记字符串就跳过发卡。如果以后模板名字被改了,所有卡片就会悄无声息地消失。 | 用偶然细节(字符串)当作真实条件(空),导致误判。 |
| 2 | 我新加的测试只检查了最后一张发出的卡片,而不是每次都发了新卡。这样有 bug 的分支也能靠前一次的卡片混过去。 | 一个永远不会失败的测试。已修复并做了变异测试。 |
| 3 | 生产命令行里混进了测试专用 flag,而且“没有 summary”有两种原因(无内容可审或 reviewer 崩溃),但走的是同一条静默分支。 | 测试脚手架混进了产品代码;两种状态共用一条代码路径。 |
| 4 | 整个崩溃告警依赖于 diff 之外 workflow 文件里的某一行,任何测试都不会读到。 | 保障写在测试外面。现在有专门的检查会读这个文件,如果那行没了就 fail。 |
| 5 | 我贴出来作为证据的 grep 输出少了一行。 | 我自己删减了证据。reviewer 发现输出和文件内容对不上。 |
| 6 | 我测 ceiling 时用的是 GitHub 每个 pull request 最多 100 个文件的列表,所以超大变更可能被误判为合格。还有我新加的“每次 review 的问题数”这个指标,没有写能 fail 的测试。 | 这是一个只会往好处偏的数字。 |
我最喜欢的那一条其实不是 reviewer 抓到的,而是我因为新加的测试挂了才发现的。当 reviewer 脚本崩溃时,告警卡片会用我写的这句话解释原因:“the script itself failed; this is not a budget or 401 problem”(中译:脚本本身出错;这不是额度问题,也不是 401 问题)。卡片的解释器会在文本里搜索“401”来识别无效密钥。结果它把我的免责声明当成了 401,提示读者去换密钥。告警卡片等于用那句“不是 401”自我诊断成了 401。修复方法是重写免责声明;教训是我写了个关键词检测器,然后自己把关键词喂给了它。
第 6 条还有个我不太自豪的后半段。reviewer 在提案最后一次更新时打了“hold”,群里收到了橙色卡片,我还是合并了,因为测试是绿的,我根本没点开那张卡。循环全流程都通了,最后的人没读。修复是后续的一个 pull request,天花板从 23% 提到 24%,因为把那个被截断的变更单独拿出来了。现在仓库的实现日志里写上了我自己破坏的规则:合并前要同时看测试结果和 reviewer 的最新结论,如果你要 override hold,得写下理由。
第 5 条是我本来会漏掉、同事也未必会提的。pull request 里写着“这是 grep 输出,目标行存在”。但我自己把 grep 输出截短了,reviewer 读 diff 上下文时比我展示的多数了一条。于是它没和我争论,而是把这个 claim 标成了“unverified”。这正是第一份报告的规则:没有证据就不能下结论,哪怕作者是自己。
第二部分 · 反思——得到的教训
- “永不沉默”是必要条件,但远远不够。状态必须能传到人耳朵里。reviewer 在 45 个 pull request 上都遵守了规则,但谁也没帮到。任何告警的测试标准不是“发出来没”,而是“24 小时内谁看见了”。这正是 Visionboard 的第二个目标,“a sensor that cannot be silent”(中译:一个不能沉默的传感器),而且还要更进一步:传感器不仅不能沉默,也不能被听不见。.
- 算比例之前,先把分母量出来。我们有一部分会议时间都在讨论 5–10% 的升级目标。实际数字是 100%,而且那里面有 45 个根本不是升级,而是传感器坏了。所有“未测量”都要单独归类,算比例时先把这类单独拎出来;如果全是“未测量”,那比例就叫“unmeasured”,不是 0% 也不是 100%。
- 共享预算会让最不重要的任务饿死最重要的任务。reviewer 和批量翻译、以及机器上的所有项目共用一个预算,最后饿死的就是它自己;控制台根本说不清到底哪个任务花了钱,因为所有花费都挂在一把老密钥上。关键路径要单独预算,花费要按任务而不是按密钥统计。
- 你写给别人的门,最后会来考你自己。我自己修循环的 10 轮 review,有 5 次被要求返工,唯一一次我没理的还是它对。reviewer 复活那天,review 最多的作者就是它的作者。这是目前为止最有力的证据,说明它每次 review 大约值 $0.25(估算:密钥的花费栏在大约 8 次 review 后显示 $1.96)。
- 交付结果,不要交付导航。帮我做这套系统的 agent 让我在账单控制台里来回点了四次:“设置,然后额度”,“速率限制”,“切换 workspace,再点账单”。最后一个目的地根本不存在。厂商自己的帮助中心写着“The default Workspace is not editable and cannot be removed.”(中译:默认 Workspace 无法编辑,也无法删除。) [5]我是个执行者,执行了一个规划者自己都没验证过的计划。它后来给自己写的规则是:让人去某地前,先自己验证目的地,给出一个链接和一个动作。如果这一步无法验证又不是必须的,就直接省掉,结果交付给人,不要让人自己找。人际层面也是一样:向上委托时,你应该把成品端上去,而不是递给上级一份菜谱和储藏室地图。
模式、反模式与底层机制
- 模式:两类故障,两种提示音。 “判定不确定”和“判定未执行”会被分别发到不同的卡片、不同颜色、不同负责人。
- 模式:路由器有意保持“笨拙”。 只依赖系统自身生成的文本做确定性分类,绝不让模型自我判断。
- 模式:默认高调提醒。 沉默必须是每种情况里明确声明的决策;凡未列明的都要响铃。
- 反模式:绿色假象。 一个允许失败但不阻塞流程的任务,表面显示绿灯,实际上什么都没做。不阻塞合并本身没错,但让它因此彻底隐身才是 bug。
- 反模式:没有上限的目标。 在测清规则允许的范围前就设定比例目标。
- 机制: jidoka。丰田的定义是:当出现异常时,“the machine or equipment can detect the abnormality and stop automatically, or the operator can stop the line by pulling the stop cord themselves”(中译:机器或设备能自动检测异常并自动停机,或者操作员可以自己拉停线绳让生产线停下) [1]。在厨房的比喻里,绳子是副厨的便条,铃是那块板:只有铃响在主厨身边,拉绳才有意义。聊天卡片就是这只铃。
- 第一性原理,归结为一句话: 一项检查,只有它的失败能以最短路径传递到能处理的人手里,才算真正存在。
第三部分 · 项目——下一步行动,分大小、远近
每一步都对应 Visionboard 的目标或 ANDON 的门,并且都带有可证伪的观测点和日期,风格参考记分板那一集。Visionboard 第二个目标(静默传感器)的证伪日期是 2026-10-07;前两个动作就是对它的检验。
| 短期(本月) | 长期(本季度) | |
|---|---|---|
| 小 | S1 · 每周读数进组会。 每周一,仓库会输出升级率、自动合并上限,以及每次评审的人力负担。 判错标准: 到 2026-10-07,灰色卡片已经发出,但团队里没人能说出它的含义;那就说明卡片文案本身有问题。 S2 · 补齐已知空白。 当前,任何被取消的评审都是静默的,包括因超时或手动取消,只要没有新的运行会补报。 判错标准: 日志中出现了“被取消且未重跑”的评审;那天起,这个例外就已经过宽。 | S3 · 评审员的校准。 对每个被评审员通过的 pull request,统计被回滚和被追溯到的 bug;对每个被 hold 的,统计有多少被人类原样合并。这就是 校准 问题,用来检验我们自己的评委。 判错标准: 到 2026-12-31,或累计 50 个评审 pull request(以先到者为准),如果它的“通过”和“hold”判定对回滚的预测还不如随机,那评审员就只是个格式化工具,定价也该按这个来。 |
| 大项 | B1 · 只开一次门。 将 fork 从上游网络解绑,启用分支保护,用现有规则跑两周试点。成功标准:至少三次真实自动合并,零回滚,每个评审 pull request 最多三个人类提问。 判错标准: 到 2026-10-31,或开门后两周(以较晚者为准),合格变更不足三次;那就说明上限比测得的还低,团队应直接承认这个仓库是人工评审,不再自欺。 | B2 · 让评审循环成为 Visionboard 的传感器。 升级率和自动合并率作为仪表盘的工程指标,“评审员 24 小时未运行”变成有名的触发器,不再只是张卡。这是 scoreboard 的第二个未来落地,也是第三个未来(双循环,判断签字决策是否带来实际动作)的第一步(详见 scoreboard episode). 判错标准: 到 2026-12-01,仪表盘已经显示了指标,但团队在讨论评审循环决策时完全没看它。 |
我有意没有做的三件事:在群聊中直接审批、在试点前放宽 auto-merge 规则、或者再造一个 reviewer 去审查第一个 reviewer。这三件事都很有意思,但没有一个能闭合当前还未闭合的循环。
30 分钟实现:review-loop 合同
这里说的是合同,不是代码。30 分钟是这份合同为读者预留的实现预算——前提是你的仓库已经有 AI reviewer 能生成 summary;这个时间我本人并未实际测量。
| 要素 | 规范 |
|---|---|
| 输入 | reviewer 的 summary 文件(可能为空),review 步骤的 outcome(success, failure, cancelled, skipped,或缺失),pull request 编号,聊天 webhook URL。 |
| 输出 | 最多发送一张群聊卡片:标题、颜色、正文、一个跳转到 pull request 的按钮。CI job summary 里还需写上一行,说明发了什么或为什么没发。 |
| 分类器 | summary 为空且 outcome 属于 {success, cancelled}:不发卡。否则 summary 为空:灰卡,“reviewer did not run”,合成原因。summary 含有“unmeasured”段落:灰卡,原因翻译为修复建议。summary 标明 auto-merge 合格:绿卡。否则:橙卡,列出需要人工回答的问题和所有未满足的条件。 |
| 不变式 | 灰卡和橙卡绝不会是同一张卡。审批操作绝不在群聊中完成。 |
| 接线 | notify 步骤用 if: always() 运行,GitHub 文档原文:"Causes the step to always execute, and returns true, even when canceled."(中译:让该步骤始终执行,即使被取消也返回 true。) [2] outcome 原样传递,这样空值也能作为参数。另一个 workflow 在 pull_request: closed 用 merged == true 发送 merged 卡片。 |
| 缺失 webhook | CI 里 exit 0,并在 job summary 里写上“chat not notified, here is how to get a webhook”。绝不因通知失败让 pull request 挂掉。 |
| 必须能 fail 的测试 | summary 为空时不发送任何内容;崩溃时只发一张灰色卡片;缺失 outcome 时响铃;被取消的运行保持静默;签名错误会被拒绝;测试会读取 workflow 文件,如果 被移除则测试失败。每个分支都做一次变异,确保测试能变红。if: always() 被移除。每个分支都做一次变异,确保测试能变红。 |
| 两项测量 | 根据标签和 summary 文本,统计升级分布(自动 / 升级 / 未运行);自动合并上限(最近合并的变更中,每个文件都符合自动合并规则的占比)。 |
| 有意不做 | 不支持从群聊直接批准、不去重重复告警、不做按人路由、不用模型做分类。 |
同一故事,五种出口
| 读者 | 本报告所支撑的决策 | 本周可执行的一个行动 |
|---|---|---|
| 学生 | 仅靠“安全”规则(绝不说谎、如实标记未测)但没有传递路径,是否足够。 | 找出你生活中的一个告警(比如低电量灯、烟雾报警器),问问是谁能听到,以及多久能听到。 |
| 工程师 | 你的 AI reviewer 的“未运行”状态,真的能被任何人感知到吗? | 统计你的 reviewer 过去 30 天内没有给出真实结论的运行次数。 |
| 创始人 | 你的代码库里,有多少变更理论上可以跳过人工审核? | 在设定任何自动化目标前,先算出最近 60 个合并变更的自动合并上限。 |
| 管理者 | AI review 的预算是否和批量任务隔离? | 查一下上个月 AI 预算是被哪个 job 花掉的(按 key),reviewer 是否有自己的额度? |
| 投资人 | 一个团队声称“90% 自动化”,背后是否有测量过的上限? | 问清分母,以及未测量的运行占比。 |
现实演练
挑一个你们团队信任的自动化检查,今晚故意把它的输入搞坏,比如用一个无效的 key 或空文件,看看明早这个故障会在哪里暴露、谁最先发现。如果答案是“在没人会打开的页面”或者“没人发现”,那你就遇到了本报告讨论的问题,而灰色卡片就是 30 分钟内能解决的办法。
延伸阅读
属于 AI-Native 系列 · Agent Engineering。文中所有数字均在其出现处标明范围,均来自 2026-09-23 和 2026-09-24 这两天某私有仓库的自测命令;每次 review 的成本是我根据账单控制台每个 key 的费用列估算的,并非精确计量。厨房只是一个模型,不是实际测量。
参考资料
- Toyota Motor Corporation.Toyota Production System. global.toyota —— 上文引用的 jidoka 段落,已逐字核对于 2026-09-24 的网页。
- GitHub Docs.Expressions: status check functions, always. docs.github.com —— 引用定义,已于 2026-09-24 按页面源码逐字核查。
- GitHub Docs. 控制工作流与作业的并发性。 docs.github.com —
cancel-in-progress,这是为何被新提交取代的评审会被取消,以及为何这种情况下保持静默。 - GitHub Docs. 关于受保护分支。 docs.github.com —— 分支保护规则;本仓库为私有 fork,API 返回“Upgrade to GitHub Pro”(中译:升级到 GitHub Pro),即便仓库所有者账号已是 Pro。
- Anthropic Help Center. 在 Claude 控制台创建和管理 Workspace。 support.claude.com —— 引用的默认 workspace 说明,已于 2026-09-24 对照页面逐字核查。
- Anthropic. Workspaces(Claude Platform 文档)。platform.claude.com —— 仅作描述,未引用原文:每个组织都有一个默认 workspace;消费额度可针对每个附加 workspace 单独设置,但受组织总额度限制。
- Feishu Open Platform. 自定义机器人使用指南。 open.feishu.cn —— 卡片推送所用的 webhook,仅作描述,未引用原文。