跳到主要内容
赞助推荐 搬瓦工怎么选:三网直连 CN2 GIA-E
工程实践

一万个 PR,0.5% 回退:xAI 怎么调 agent 环境

43 分钟阅读阅读(2)
赞助推荐 团队协作里的 AI 办公工作台

xAI 的 Grok Bot 团队把 agent 的可靠性建在代码库上:rules、skills、AGENTS.md 排在最后一层,真正起作用的是 lint 规则、目录边界、类型系统和验证流程。Lauren Tan 的 17 分钟分享拆成认知、使用、边界三部分,含四层约束结构与落地清单。

软件工程有一条老规矩:代码进生产之前,得有人看过。xAI 的 Grok Bot 团队上个月往生产推了一万一千个 pull request,其中大部分没人看过,回退率 0.5%。

赞助推荐 一人公司 · 创业装备库
赞助推荐 一人公司 · 创业装备库

说这话的人叫 Lauren Tan,网名 poteto,做过 React 核心团队,现在在 xAI 做 Grok Bot 的桌面客户端。分享只有 17 分钟,标题起得很自知之明:《All Code Is Slop (Except Mine)》。

原视频:https://www.youtube.com/watch?v=O_zcc6Xl12g

先说结论

她想讲的事情可以用一句话概括:让 agent 可靠的办法,不是把规则写得更长,是把错误变得写不出来。

现在讲 AI 编码的内容,重心基本都在提示词上。AGENTS.md 怎么写,skill 怎么拆,规则要不要分层,哪个模型更听话。她的排序几乎是反的:rules、skills、AGENTS.md 全在她那套结构的最上面一层,权重最低。

这个判断如果成立,很多团队现在的投入方向就是错的。所以这篇文章分两部分看:前面讲她凭什么这么排(认知),后面讲具体怎么落地(使用)。结尾会讲这套东西在哪些地方站不住。

第一部分:认知

一、她反对的不是提示词工程,是「提示词当主防线」

先把靶子说清楚。

提示词工程有用,这一点她没否认。她做的是更细的区分:规则能约束的,只是 agent 在没有更强信号时的默认选择。一旦代码库里存在反例,规则就废了。

她的原话是,agent 会把你的一条小修正当成永远不能破的严格规则,同时又会给自己找到绕过规则的理由。两头都发生。所以规则系统的实际强度,取决于代码库里最烂的那段示例。

用她自己的比喻说:你告诉 agent「不要用 setTimeout 打补丁」,但代码库里有三百处 setTimeout,每一处旁边都有注释解释为什么这里必须这么写。Agent 会读注释,也会读代码,它得出的结论是「这个团队允许这么做,只是嘴上说不允许」。

这就是规则和约束的差别。规则是请求,约束是事实。

二、代码库是花园,但 agent 让杂草长得快了一百倍

她用的比喻是花园。代码库是你种东西的土,agent 是长得特别快的新苗。

这个比喻在几年前就有人讲过,她加了一个新变量:速度。

以前代码一次来几个 PR。她记得 2024 年到公司,评审同事写的三个 merge request,那时候这是正常节奏。现在这个数字接近 300。

在这种流量下,技术债的性质变了。人写代码时,坏模式靠人传人,一个坏习惯要传染给三个人,得几个月。Agent 复制坏模式以小时计,而且是逐字复制。它不会觉得这段代码「虽然烂但情有可原」,它只看到「这里有个模式,我照着来」。

所以她的结论是:任何 workaround、反模式、过时代码、技术债,都很可能被下一个 agent 复制,因为它在你的代码库里看起来像个既定模式。

这句话值得停一下。它把「清理技术债」从一件可做可不做的杂事,变成了 agent 时代的准入条件。

很多团队的做法是把 agent 接进一个本来就有债的仓库,指望它只在新代码里保持干净。做不到。它的所有判断都基于周围五百行代码的样子。

三、四层结构:为什么规则在最上面

她把 agent 的工作环境分四层,越往下越重要。

xAI agent 环境的四层结构:代码库与架构、工具链、验证层、描述性指令

最底下是代码库与架构。这里面包括 API 设计、重构、目录结构。她的原话是「前两层是确定性的」,意思是这两层由你的代码决定,agent 没有解释空间。

第二层是工具链:linter、类型系统、编译器、测试。这些东西的执行不需要任何人同意,跑一遍就知道过没过。

第三层是验证:运行时验证和形式化验证。用来检测错误、检查系统应该满足的性质和不变量,也用来检查 agent 有没有真的理解你的意图。

最上面才是描述性指令:rules、skills、AGENTS.md。她给这一层的定义是「需要判断力的东西」。

这个排序的实用价值在于它直接决定了投入产出比。最上面那层写起来最便宜,改一行文本就行,所以绝大多数团队都在那儿使劲。最下面那层最贵,要重构、要写规则、要改架构,所以很少有人动。

但效果是反过来的。最上面那层的边际收益衰减得极快,写到第三十条规则时,agent 已经开始漏读、错读、或者选择性遵守。最下面那层是永久的,写进编译器的东西不会忘。

规则的边际收益为什么衰减得这么快

这个现象有具体的机制,值得拆开看,因为它决定了你为什么该少写规则。

第一,上下文是有预算的。 规则文件从两百行涨到八百行,单条规则在模型眼里的权重就摊薄了。它不会按重要性排序,它按位置和相似度响应。写在第十七条的一条重要约束,可能因为跟当前任务语义距离远而被完全忽略。

第二,规则之间会打架。 你写「注释要解释为什么」,又写「禁止无意义注释」,agent 就要在两条之间做判断。这种判断没有确定性,同一个场景两次运行可能给不同答案。规则越多,这种灰色地带越多。

第三,规则无法表达例外,但现实全是例外。 你写「不要直接调数据库」,第二天就有一个场景必须绕。你补一条例外,第三天又有一个。补到第五条例外时,这条规则已经等于失效了,因为 agent 分不清哪条例外适用于当前情况。

第四,规则的失败是静默的。 这是最要命的一点。Agent 没遵守规则,你不会收到任何信号,你只会在几天后看到一个奇怪的实现。而 lint 的失败是响亮的,构建直接挂掉,谁都没法忽略。

四条合起来,结论很清楚:规则适合表达意图,不适合表达边界。边界交给工具。

四、三个禁令,一条判据

她给了三个真实案例,都在 Grok Bot 的客户端框架 Dune 里。Dune 可以理解成「Electron 版的 Next.js」,技术本身不复杂,特别的地方是把做桌面应用踩过的坑全部编码成了限制和 lint 规则。

三个禁令背后是同一条判据:任何需要微妙技巧才能正确使用的东西,最终都会导致粗心。

4.1 产品代码禁用 useEffect

React 的 useEffect 有它的用处,但经常被误用。圈内开玩笑说要用好它得有博士学位,这话刻薄但不算离谱,依赖数组漏一个变量就是一次隐蔽的 bug。

Agent 也不擅长。于是他们的处理很干脆:产品代码里禁掉,只在 Dune API 内部少数地方允许。

效果是这一类问题从 code review 的清单里消失了。她说这话的时候很轻描淡写,但这是整场分享里最值钱的一类收益:评审时需要考虑的项目数量,是可以被永久减少的。

4.2 目录即边界

在 Cursor(同样是 Electron 应用)里他们发现过一个反模式:agent 老把主进程代码 import 到渲染进程,造成长任务和界面卡顿。

到了 Grok Bot,他们把这件事结构化。顶层就两个目录,字面意义上叫 electron-renderer 和 electron-main,两个目录之间禁止互相 import,由依赖图分析器和 lint 规则拦。

这是我觉得最值得抄的一条。它不说「别这么做」,它让这件事在物理上做不到。Agent 想违反,连编译都过不去。

4.3 禁掉 99% 的注释

这条最反直觉,也是争议最大的。

她的理由有三层:注释老化得很快;没什么人真的读;更糟的是,注释给 agent 留了后门。

真实事故是这样的。在 Cursor 里,agent 特别喜欢用命令式定时器,setTimeout、requestAnimationFrame、requestIdleCallback,用它们去打补丁,弥合 VS Code 命令式风格和 React 声明式风格之间的架构冲突。

JavaScript 里定时器被大量创建销毁会带来频繁 GC,性能直接掉。而 agent 在每处补丁旁边写了注释,解释为什么这个临时方案是合理的。

等他们反应过来,定时器已经到处都是,性能明显下滑。

五、注释为什么是后门

这一节值得单独展开,因为它触及了一个更普遍的问题:为什么 agent 特别擅长用文字为自己开脱。

第一,注释不是强制的。你写一句「提醒下一个 agent 不要这么做」,看起来是好意,但它永远不会变成你可以依赖的东西。没人会跑一遍检查确认注释还在,也没有 CI 会因为你删了注释而失败。

第二,注释是 agent 的自我辩护材料。这一点在代码里表现得特别明显:当 agent 决定用一个临时方案时,它会写一段注释论证这个方案的必要性。这段注释在下一个 agent 看来,是一条来自「前人」的、有上下文的、可信的经验。

第三,注释会过期。三个月后架构变了,注释还在。那个「暂时这样」的临时方案,被注释固化成了长期方案。

她的处置是:把 lint 规则做成唯一合法的表达渠道,而且错误信息要写得对 agent 友好,直接指向根因,而不是给它一个继续打补丁的许可。

这里有个容易被忽略的设计点。错误信息是给人看的,还是给 agent 看的,写法完全不同。给人看的报错可以是 no-restricted-syntax,给 agent 看的报错要写成一句话:「这里用了 useEffect,请把副作用提到 Dune 的 effect 层,或者改成数据流」。后者能让 agent 一次改对,前者会让它试三次然后加个 disable 注释。

六、核心机制:修一次,编译一次

上面三件事背后是同一条原则,我认为这是整场分享唯一必须记住的一句:

每当我们修 agent,就把它变成确定性检查;或者想清楚怎么通过更好的 API 设计和架构,在代码里彻底消除这个问题。

这句话的结构值得注意。它给了一个二选一,但两个选项都是「一次性解决一整类问题」,没有「再提醒一次」这个选项。

这个机制的杀伤力在于复利。做够多次之后,你在 code review 里需要考虑的东西越来越少。到某个点,你会发现自己没什么可看的了。那时候就可以让 agent 自己合并大部分 PR。

她的团队现在就是这个状态:大部分产品代码不再需要深度人工评审,PR 默认成功。

这里有个转折需要说清:自动化不是靠「信任 agent」换来的,是靠「让错误变得不可能」换来的。信任是结果,不是前提。

多数团队把顺序搞反了。先担心 agent 不可靠,于是加规则、加评审、加人工卡点,然后发现卡点越加越多,效率反而下降。正确的顺序是先收紧环境,收紧到没什么可错的,卡点自然就撤掉了。

为什么 lint 比 prompt 可靠:执行位置决定可靠性

这一节可能有点技术,但它是整套方法的地基,值得说清。

提示词的执行位置在推理之前。它改变了模型「看到什么」,但不保证模型「做什么」。模型可以读到「禁止 useEffect」,然后在生成代码时因为它觉得这里有个特例而照样写。你事后检查时才发现,而检查本身又是靠人或者靠另一遍模型,成本很高。

lint 的执行位置在提交时。它不改变模型看到什么,它保证模型做出来的东西如果越界就进不去。这两者的可靠性差一个数量级。

更关键的是覆盖面。提示词只在模型注意到的地方起作用。一个复杂任务里有几十个决策点,模型对提示词的注意力会随着上下文增长而衰减。它可能记住了「不要 useEffect」,但在处理第六个子任务时忘了。Lint 没有注意力问题,它扫描所有到达该状态的代码路径,一视同仁。

还有一个隐蔽差别:可测试性。一条 lint 规则你可以写一个测试用例证明它有效:故意构造一段违规代码,看它是否报错。一条提示词规则你没法测试,你只能观察它这次守没守,而下次可能就不守了。

所以「把规则降级成检查」这件事的本质,不是形式主义,是把一个概率性约束换成一个确定性约束。前者你要反复确认,后者确认一次就永久生效。

信任是被验证出来的,不是被承诺出来的

她那套结构的名字叫信任金字塔,但整场分享里她一次都没说「要相信 agent」。

这个细节值得注意。她讲的是「投资 agent 的环境,这样你才能确定它们会做对」。顺序是:先有确定性,再有信任。信任是确定性的副产品。

现实里多数团队的顺序是反的:先试着相信,出问题后再收紧,收紧到没人敢用。这个循环走两轮,团队就会得出「agent 不靠谱」的结论,然后停在人工卡点上。

按她的路径,信任是分层建立的,每一层对应一类可以自动判定的错误:

信任层级 你能确认什么 对应的动作
第一层 代码能编译、类型正确 允许 agent 提交
第二层 测试通过、覆盖了改动路径 允许 agent 开 PR
第三层 运行时验证产物符合预期 允许人工只看证据
第四层 回退率稳定在阈值以下 允许自动合并

关键是每一层的准入条件是可观测的数字,不是感觉。你觉得它行了不算,回退率低于 1% 才算。

这个框架的实际用途是:当有人说「我们准备好让 agent 自动合并了吗」,你不用争论,去看数字落在哪一层。

七、验证:评审对象从代码变成证据

他们的 code review 现在基本等于看验证产物:视频、截图、图表、形式化证明。

这句话第一次听会觉得不严谨。不看代码怎么保证质量?但仔细想,人看代码能发现的东西本来就有限,实话说大部分 review 是看风格和显而易见的问题。真正难发现的跨文件陷阱、时序问题、状态机死锁,人眼也看不出来。

7.1 运行时验证与 feature map

运行时验证说白了就是让 agent 自己跑代码,用上人也在用的调试工具,比如 Chrome DevTools 协议。

这里有个很实用的设计,他们叫 feature map,本质是从用户视角出发的功能站点地图。解决的是指代问题:你说「左边面板那个东西」,agent 只能猜;有了共享词汇表,它能对上是哪个功能。

这个思路可以推广。任何你跟 agent 协作时反复出现的表述歧义,都该变成一份结构化的对照表,而不是每次在对话里解释一遍。

7.2 自建 CLI 省 token

他们让 agent 复用自家的 CLI 和 driver,而不是每次都重新生成调用方式。省 token 只是一半的好处,另一半是 CLI 本身可测试。

这条对做平台的团队更有参考价值。Agent 每次重新拼装 HTTP 请求,既浪费 token 又容易错;包一个 CLI,等于把「怎么调用」这件事固化下来,顺便让它进了版本管理。

7.3 TLA+ 与 Lean

形式化验证他们刚开始用。

TLA+ 用来验证核心用户流程的模型,比如跨设备、跨平台的通知链路。Lean 用来证明某些算法,他们自己写了虚拟化库,用 Lean 保证不闪、不抖。

她自己也说这不是万能药,只是环境里多一层工具,整体还在试验阶段。

7.4 属性化 UI 测试

用了一个叫 Bombadil 的库做属性化接口测试,已经抓出几个界面 bug。

到这里可以看出一条线索:她用的每一样东西,都不是为 AI 新造的。TLA+ 是 1999 年的东西,Lean 是定理证明器,Chrome DevTools 协议是浏览器调试工具,属性化测试在 Haskell 圈用了十几年。

八、为什么说现在是测试的黄金时代

这是整场分享里我最认同的一句判断。

她引了 Cindy 的一条推。半年前 Cindy 说不信任 agent,因为小错误会溜进代码,缺的其实是验证流程。半年后,Cindy 说日常 70% 的 token 花在验证上。Lauren 说这跟她的观察一致,她自己的 token 也大部分花在验证。

然后她给了一个解释:这些验证手段没有一样是新东西,都是好开发工具,只是以前太贵,难懂、难写、难维护。

这个「贵」是具体的经济账。写一套 TLA+ 规格,一个资深工程师要两周,两周里不产出任何功能。写一个属性化测试框架,要有人懂 property-based testing 的心智模型。给每个功能写运行时验证脚本,人工维护成本很高,功能一改脚本就废。

Agent 把这几笔账都打下来了。规格可以让 agent 写,脚本可以让 agent 维护,测试用例可以批量生成,回归失败让 agent 自己去看日志修。

所以真正的变化不是「AI 会写代码了」,是「一些以前做不起的工程实践突然做得起」。这个视角比「效率提升」有用得多,因为它指向了具体的行动:去翻翻你团队当年因为太贵而放弃的那些实践清单。

值得重启的五项老实践

顺着这个思路,我列了几项在 agent 之前普遍被认为「性价比不高」的做法。它们现在都值得重新算账。

实践 以前为什么不做 现在为什么值得做
形式化规格(TLA+ / Alloy) 写一份规格两周,只有资深工程师能做 规格草稿让 agent 写,人只审关键不变量
属性化测试 需要懂 property-based 思维,用例难维护 用例批量生成,失败案例自动收敛成回归用例
依赖方向检查 配置复杂,收益抽象,没人愿意推 agent 会主动违反依赖方向,这项从「锦上添花」变成「必须」
变异测试 跑一次几小时,报大量等价变异,人工筛不过来 agent 可以批量判断哪些变异是等价变异
运行时契约断言 影响性能,生产环境不敢开 可在测试环境和预发全量开,agent 读断言失败日志自己修

挑一项的话,我会先做依赖方向检查。理由是它的投入最小,而 agent 最容易犯的就是这类错误,因为在它眼里所有文件都是可 import 的。

九、数字要怎么看

这类分享最容易变成数字崇拜,所以每个数字都得掰开看。

数字 基准对照 意味着什么
11000 个 PR/月(团队) 传统团队月均百级,中型团队千级 单看没意义,分母是 10 月有 227 人提过 PR
3000 个 PR/月(她个人) 一个工程师月均 10 到 30 个 PR 她说很多是睡觉时发的
0.5% 回退率 业界对「健康」的默认预期是 1% 到 5% 这是最硬的一个数:产量翻百倍,质量没塌
每天一个稳定版 桌面客户端常见月更或双周更 发布节奏被 agent 产能推着走
半年 她个人从零到能在睡觉时发 MR 这是入场券的价格,不是可选项

最该盯的是 0.5% 和 227 人同时出现。

227 人里相当一部分是偶尔贡献者,没有完整上下文。这种人在传统流程里最容易产出需要反复返工的代码,因为他们不了解约定,也不熟悉历史决策。有 227 个人还能把回退率压在 0.5%,说明防线不在人的水平上,在环境上。

反过来说,如果一个团队只有十个人,全是熟悉代码的老手,0.5% 的回退率并不能证明他们的环境建设得好。样本不同,数字的意义就不同。

十、三个反直觉的判断

整场分享里有三处说法跟主流直觉相反,我觉得都值得记下来。

第一,规则越少越好,因为每条规则都该被降级。 主流的做法是规则越写越多,覆盖越来越细。她的做法是规则写一条、降级一条,最终规则文件只剩下那些真的没法机器化的判断。

第二,禁注释比禁代码更有效。 大家默认注释是好事,是文档,是传承。她的观察是,在 agent 场景下注释主要起了「给偷懒找个说得过去的理由」的作用。

第三,自动化之前要先做减法。 多数团队想的是「把重复劳动交给 agent」,她说的顺序是先让代码库里没有值得重复的坏东西,再自动化。如果内部写代码这个循环本身在产出垃圾,自动化它只会产出更多垃圾,然后你要花越来越多 token 去修。

第二部分:使用

前面讲的是认知。这一部分讲怎么用,按落地顺序排。

十一、第一步不是换工具,是挑一条重复的评论

如果你现在就想动手,别去看什么 lint 配置大全,先做一件事:翻你最近的 code review,找一条你重复说过三次以上的评论。

典型的有这些:

  • 「这里不该直接调 API,走 service 层」
  • 「这个异常没处理」
  • 「别在这个文件里 import 那个模块」
  • 「这个查询没加索引条件」
  • 「这个 useEffect 依赖不完整」

挑出现频率最高的一条,把它变成机器检查。这一条改完,你团队每周能省下几十条重复评论,而且这条评论以后不会再出现。

这个起步方式的好处是不需要立项、不需要预算、不需要说服任何人。你自己一下午就能做完一条。

十二、lint 规则怎么写才对 agent 有效

三条原则,按重要性排。

第一条,报错信息写给 agent 看。 默认的报错是给懂这个规则的人看的,agent 不懂。你要在报错里写清三件事:你错在哪、根因是什么、应该改成什么样。

// eslint.config.js
{
  rules: {
    'no-restricted-syntax': ['error', {
      selector: "CallExpression[callee.name='useEffect']",
      message:
        '产品代码不允许 useEffect。副作用请提到 Dune 的 effect 层;' +
        '如果是数据获取,用 useQuery;如果是事件订阅,用 useSubscription。' +
        '不要用 eslint-disable 绕过,这条规则没有例外。',
    }],
  },
}

代码块末尾那句很重要。「这条规则没有例外」能挡掉一大半的 disable 注释。

第二条,优先管方向,别管细节。 检查「renderer 不能 import main」比检查「函数不能超过 50 行」有用得多。前者管的是架构方向,后者管的是风格偏好,后者 agent 很容易用拆分函数绕过。

用 dependency-cruiser 做方向检查:

// .dependency-cruiser.js
module.exports = {
  forbidden: [
    {
      name: 'no-main-from-renderer',
      severity: 'error',
      comment: '渲染进程不能引用主进程代码,会导致长任务和界面卡顿',
      from: { path: '^src/electron-renderer' },
      to: { path: '^src/electron-main' },
    },
  ],
};

第三条,规则要能被绕过检测。 允许 eslint-disable 的团队,等于没有规则。做法是把 disable 的数量做成 CI 指标,只允许下降不允许上升。

这三条做完,你会发现 lint 从「代码风格工具」变成了「架构约束工具」。这是它在 agent 时代的正确定位。

三种常见的写错方式

反过来说,有三类 lint 规则写了等于没写。

第一类,管风格不管方向。 检查函数行数、变量命名、import 顺序。这类规则 agent 很容易满足,也完全不影响它把设计做歪。它把一个两百行的函数拆成四个五十行的函数,架构问题一点没解决。

第二类,报错不指路。 只写「禁止使用 X」。Agent 收到这个报错,第一反应是找绕过方式,而不是理解意图。想让它改对,必须告诉它替代路径。

第三类,允许例外。 只要 eslint-disable 能生效,这条规则的强度就取决于 agent 的自觉性。可行的做法是把 disable 数量做成 CI 门禁,只许降不许升;更彻底的做法是这类架构规则直接禁止 disable。

一条规则的强度,取决于它被违反时会发生什么。构建挂掉是强,报个 warning 是弱,写进文档是零。

十三、AGENTS.md 该缩到多短

按她的逻辑,AGENTS.md 里每一条规则,你都该问一句:这条能不能变成机器检查?

能,就搬走,别留在这儿。不能,才留下。

按这个筛法,一份典型的两百行 AGENTS.md 大概能剩下二十行。剩下的应该是这些:

留下的 搬走的
项目的业务背景和目标用户 「不要用 any」(类型系统管)
哪些目录是禁区 「import 要排序」(linter 管)
提交信息的格式 「不要用 useEffect」(lint 管)
遇到不确定时的升级路径 「测试要覆盖边界」(CI 管)

留的部分有一个共同点:它们描述的是意图和边界,机器判断不了。搬走的部分有一个共同点:它们描述的是具体做法,机器能判断。

这个筛法还有个副作用:AGENTS.md 变短之后,agent 的遵守率反而上升。文件太长时,模型会漏读中段,而且不同段落的规则冲突时它不知道听谁的。

十四、验证闭环的最小可用版本

不用一上来就上 TLA+。最小闭环是三步。

第一步,给 agent 跑起来的能力。 让它能执行代码、能读日志、能开浏览器。这一步很多团队还没做,agent 只能改代码不能验证,等于闭着眼睛改。

第二步,定一份 feature map。 一页纸,把产品的功能按用户视角列出来,每个功能对应哪些页面、哪些操作、哪些状态。这份东西是给 agent 消除歧义用的。

第三步,把验证产物存档。 截图、录屏、trace、测试报告,全进 PR 描述。人的评审从「读 diff」变成「看证据 + 抽查 diff」。

三步做完,你就有了一个能自我验证的循环。后面加 TLA+、加属性化测试,都是在这个基础上叠。

把一次对话变成一条规则的五步

这是我认为最该固化成习惯的一个动作。她现在每次修 agent 都这么做,多数人只是改完就过。

第一步,记录触发场景。 不要只记「agent 又写错了」,要记它当时在做什么、看到什么上下文、做了什么错误决定。这个记录是后面抽象的材料。

第二步,抽象成类别。 问一句:如果换个功能、换个文件,它还会不会再犯同样的错?会,就是一类问题;不会,就是偶发失误,直接改掉就行。

第三步,判断能不能机器化。 能不能用一句代码查询把这种模式找出来?能,往下走;不能,说明它是个需要判断力的问题,写进 AGENTS.md 并配一个正反例子。

第四步,写法决定强度。 机器化的写成 lint,报错里带根因和替代路径;写规则的补一句「为什么」,因为判断类问题只能靠理解。

第五步,验证拦截有效。 故意构造一段违规代码,看规则有没有拦住。没拦住说明写错了位置或条件。这一步九成人会跳过,跳过之后你以为有了防线,其实没有。

五步走完,一次具体的失误就变成了永久的环境改进。这个动作跑一百次,你就有了她说的那个状态:评审时没什么可看的。

验证产物具体长什么样

「看验证产物」这句话很抽象,落到实操需要一份清单。按我理解她那套做法,一份合格的 PR 描述应该包含四块内容。

第一块,改了什么。 一句话说清这次改动解决了什么问题,不写实现细节。这一块是给未来的自己看的。

第二块,怎么验证的。 列出跑过的检查:单元测试、集成测试、类型检查、lint。每项给结果,不给结论词(不要写「测试通过」,写「142 passed, 0 failed」)。

第三块,证据。 界面改动给改动前后截图,交互改动给录屏,流程改动给状态图或时序图。这部分是替代「人读 diff」的关键,没有它评审就退回到通读代码。

第四块,已知风险。 这次改动影响了哪些模块,哪些地方没验证到,回滚方式是什么。这一块最容易省,但它是自动化合并的安全网——出问题时你不用猜,直接按写的回滚。

这四块加起来,一个 PR 的评审时间可以从二十分钟压到三分钟。压缩的不是深度,是找信息的成本。

十五、平台侧:把四层映射到 agent 平台

如果你在做 agent 平台,这套结构几乎是现成的架构参照。

她的层级 平台里对应的东西
代码库与架构 权限模型、接口 schema、模块边界,让 agent 不可能越权或越界
工具链 类型定义、契约测试、静态检查,在提交前就拦掉
验证层 沙箱执行、trace 回放、hook 拦截、状态机断言
描述性指令 系统提示、skill、工具描述、AGENTS.md
feature map 工具能力清单 + 用户视角的功能地图
外循环 定时调度 + 状态机 + 多 agent 编排

这里有个判断标准可以带走:你的平台把「防错」放在哪一层,决定了它的可靠性上限。 靠提示词防错的平台,永远在跟模型的随机性搏斗;靠 schema 和沙箱防错的平台,错误在结构上就发生不了。

十六、个人侧:一个人怎么用出 3000 个 PR

她个人一个月 3000 个 PR,这个数听着夸张,拆开看是合理的。

前提是她所处的环境已经把「判断成本」降到了很低。她的每个 PR 不需要重新解释背景,不需要来回确认架构方向,因为方向已经写进 lint 和目录结构了。她能发这么多,不是因为她打字快,是因为每个 PR 需要她做的决策少。

个人要复制这个路径,能做的有三件:

第一,把自己的项目边界定死。 目录结构、模块职责、依赖方向,先想清楚再写代码。边界清楚的项目,agent 一次能做对的范围大得多。

第二,写自己的 verification script。 一个能跑起来验证「这次改动有没有破坏核心功能」的脚本,比十条提示词有用。

第三,把重复的解释沉淀下来。 你每次跟 agent 解释同样的事,就该把它变成一份文件,而不是下次再说一遍。这份文件最终会变成你的 feature map 加 AGENTS.md。

十七、30/60/90 天路线

如果要在团队里推,我给一个保守的节奏。

第 1 到 30 天:只做一条规则。 挑最高频的那条 review 评论,写成 lint,跑起来,观察一个月它被触发了多少次。这个数字会说服你自己。

第 31 到 60 天:做目录边界和验证脚本。 把最容易出问题的依赖方向用工具锁住,同时写出第一个能自动验证核心功能的脚本。这一步的产出不是效率,是「感敢让 agent 自己跑」。

第 61 到 90 天:开一个小范围的自动合并。 挑一个低风险模块,让 agent 的 PR 在 CI 全绿的情况下自动合并。观察回退率,如果稳定在 1% 以下,扩大范围。

这里最容易失败的地方是第 90 天之后。自动合并跑通了,团队会急着扩大范围,然后回退率上升,然后回到人工卡点,然后放弃。她的做法是每次回退都问「这一类问题能不能在代码层面消除」,而不是「要不要加一条规则」。

第三部分:边界

她的分享有说服力,但有几处需要打折扣,不然容易被当成万能药。

十八、六个要打折的地方

第一,入场成本是半年,而且她没说团队规模。 227 人提 PR 说明这是个几百人的组织。几百人半年的人力投入去建 lint 体系、验证基础设施、自研框架,这个账在几十人的团队里算不过来。她提了一句「你可以比我快得多」,但没说依据。

第二,Electron 客户端是相对封闭的领域。 UI 状态可枚举,功能边界清楚,所以 feature map、属性化 UI 测试、Lean 证明虚拟化库这些做法成立。换成分布式后端、数据管道、有强合规要求的金融系统,同样思路要重新设计一遍。

第三,形式化验证的实际覆盖很窄。 TLA+ 只覆盖了通知这一条流程,Lean 只覆盖了一个虚拟化库。她说「已经找出很多错误」,但没有量化。这块目前是探路,不是主干。

第四,11000 个 PR 的口径要小心。 里面包含 agent 自动生成的修复 PR。她描述的发布流程是:每次发版,Grok Bot 自动在 Cursor 里起项目,对整个应用做 fuzz,像真实用户一样用,发现问题就开 PR 修,自动合并。这类 PR 数量会非常大,不能等同于人类的有效功能产出。

软件工厂外循环

第五,禁注释在有些场景不成立。 业务规则、合规要求、算法出处这类信息必须留在代码里。她的语境是客户端产品代码,注释的主要成分是「解释为什么这样写」,那确实可以砍。

第六,隐性门槛是「团队能写 lint 规则」。 写一条能准确表达架构意图、又给出可执行错误信息的 lint 规则,是稀缺能力。多数团队连 ESLint 配置都是抄来的,抄来的规则写不出好报错。

这套方法对模型迭代不敏感,这既是优点也是局限

有个角度值得单独说,因为她没提。

她的整套体系建在代码层。Lint 规则、目录边界、类型系统、验证脚本,这些东西跟用哪个模型毫无关系。换成更强的模型,这套约束照样生效;换成更弱的模型,它反而更值钱,因为弱模型更容易犯错,约束帮你兜住。

这是优点:环境建设的投入不会因为模型换代而贬值。多数「提示词技巧」的保鲜期是三个月,模型一升级就失效。

但同一件事反过来看是局限。模型能力提升是免费的,你什么都不做它也会变强。环境建设要花人力,而且见效慢。所以在任何一年里,「等模型变强」永远是比「建环境」更省事的选择。

这个选择在短期是对的,长期会吃亏。因为约束的收益是复利的,模型变强带来的收益是线性的,而且天花板受限于你给了它什么样的工作环境。一个在烂代码库里跑的强模型,产出还是烂代码。

十九、什么团队不该抄

有三种情况,这套方法会明显亏本。

交付压力极大、几乎没有重构窗口的团队。 建环境需要时间,这段时间产出是下降的。如果团队正处在生死线上,先活下来。

代码量很小、生命周期很短的项目。 三个月的项目,花两周建约束体系不划算。这类项目直接上 agent 加人工评审更实际。

没有明确架构的项目。 她的方法前提是「架构方向是清楚的,只是需要被机器执行」。如果架构本身没想清楚,写不出有意义的 lint 规则,写出来的只是风格检查。

我的补充

二十、我会怎么用

她的框架我用得上的地方有三处,说具体一点。

第一,把「修一次」当成硬性动作。 我现在的习惯是 agent 犯错就改这一次,改完继续。她的做法是每次犯错都问一句:这是不是一类问题?如果是,当场变成检查。这个动作的成本是每次多花五分钟,收益是这一类问题永久消失。我打算把它写成自己的检查清单。

第二,报错信息当成文档写。 我们团队的 lint 报错基本是默认文案,agent 看了不知道怎么办,只能猜。改写成「你错在哪、根因、应该改成什么样」,这个投入很小,收益是 agent 一次改对的概率明显上升。

第三,验证产物入库。 我们现在的评审还是读 diff。截图、录屏、trace 这些证据没有进 PR,人只能靠想象判断「改了之后界面对不对」。把证据补上,评审质量会明显不一样。

她讲的 AGENTS.md 收缩,我持保留意见。原因是我们的规则文件里有一部分是「业务判断」,比如某类客户的数据不能出现在某个页面上,这种规则确实没法完全机器化。但可以机器化那部分确实该搬走,这个方向我认。

我还没想清楚的两个问题

第一个,环境的维护成本拐点在哪。 Lint 规则会越积越多,每条都要人维护,规则之间还可能冲突。写到两百条时,团队的精力会不会被规则本身吃掉?她没提这件事,我猜他们团队有专门的人做这块。小团队没有这个角色,拐点会更早到。

第二个,怎么在没有平台工程师的团队里复制。 她的方法默认团队里有人能写依赖图分析器、能写自定义 lint、能搭验证基础设施。这是平台工程师的活。十几个人的产品团队通常没有这个人,那么这套东西的最初几步该怎么起步,她没给答案。

我的临时答案是:从开源现成规则集起步,只做加法和配置,不自己发明。等团队真的感觉到约束的价值,再投人做定制。这跟她的路径不一样,但对小团队更现实。

最后

她在结尾说,在建软件工厂、把能自动化的都自动化之前,先把自己的代码库调好。如果内部写代码这个循环本身在产出垃圾,自动化它只会产出更多垃圾,然后你要花越来越多 token 去修。

这句话对当下的意义比对她的团队更大。多数团队已经在上自动化了,代码库还是原来那个。

如果你只记一件事,记这个顺序:先清债,再加约束,再上验证,最后才谈自动化。中间跳过任何一步,后面都会用 token 还回来。

赞助推荐 一键部署 AI 大模型
赞助推荐 一键部署 AI 大模型
赞(0)
未经允许不得转载:80aj » 一万个 PR,0.5% 回退:xAI 怎么调 agent 环境
赞助推荐 低成本上手 Claude Code 的中转选择
赞助推荐 低成本上手 Claude Code 的中转选择
赞助推荐 一键部署 AI 大模型
赞助推荐 一键部署 AI 大模型