专题系列 · Harness

五个月,零行人工代码,一百万行 AI 代码

OpenAI 工程团队五个月写了百万行 AI 代码,却发现代码库有传染性——坏模式被 AI 无限复制。他们的解法:用 GC Agent 清 agent 的垃圾,用知识即代码阻止问题蔓延。

RAFA · 2026.03.22

Harness系列: AI早知道 · 第三篇


每个周五下午,OpenAI 内部代号 "Project Hulk" 的团队都会停下来,做同一件事:清理代码。

不是修 bug,不是上线功能——是专门去找那些"写得不对"的代码,把它们清掉。团队里的人给这个仪式起了个名字:AI slop 巡检

起初,这占用了他们大概 10% 的时间。几个月后,这个数字涨到了 20%。一个人一周工作五天,一天用来清垃圾——这不可持续,他们知道。

但问题比"效率低"更深。他们花时间清的那些垃圾代码,不是随机出现的。它们有规律:一个被 AI 写出来的烂模式,会在代码库的 10 个地方被 AI 复制。清完这一处,下周另一处又长出来了,用的是同样的写法。

这不是 bug,是特性。AI agent 在写代码时,会学习并放大它在代码库里看到的模式——包括坏的那些。


代码是有传染性的

理解这一点,是理解 OpenAI 整套 harness 工程的前提。

在人工编码的时代,一个工程师写了一段糟糕的代码,它大概率会停在那里,因为没有人愿意再模仿它。团队的代码审查文化、个人的工程品味,都在无形中阻止坏模式传播。

但 AI agent 没有品味。它有的是模式识别——哪种写法在这个代码库里出现得最频繁,它就会优先使用哪种。你往代码库里放一个反模式,agent 会在接下来的所有相关位置都用上它,速度和规模超过任何人工传播。

Project Hulk 团队的吞吐量是每人每天 3.5 个 PR。相比之下,传统工程团队的平均水平大概是每人每天 0.5 个。七倍的速度,意味着代码质量问题也在以七倍的速度累积。

传统的 PR review 流程在这里成了反模式——不是因为 review 没有价值,而是按照旧节奏审查代码的工程师,物理上跟不上 AI 的吞吐量。

他们需要一个新的答案,来解决代码库的传染性问题。


用 agent 清 agent 的垃圾

他们的解法,是引入第二类 agent——Garbage Collection Agent(GC agent)

GC agent 不写新功能。它的唯一任务,是在代码库里巡逻,找出三类问题:

  • 冗余代码:同样的逻辑被实现了两次
  • 过时代码:实现的是已经废弃的需求
  • 规范违反:写法不符合当前的架构约束

找到之后,GC agent 发起重构 PR,由 Evaluator agent 验证,由工程师做最终决策——不是一行一行看代码,而是看"这个 PR 做了什么,以及为什么"。

这个方案有效,但它只能在一个前提下工作:代码库本身必须有结构,让 agent 能推理"什么是规范、什么是违反规范"。

如果你的代码是面条式的——业务逻辑混在数据访问里,API 层和 UI 层耦合在一起——GC agent 不知道什么该删、什么该留。它需要一个清晰的架构层次作为参照系。

这把他们带到了一个反直觉的结论。


约束越多,跑得越快

在人写代码的时代,小团队常常把严格的分层架构(Clean Architecture 之类)视为负担——层次太多,规则太死,灵活性差。独立开发者尤其不喜欢:一个创业公司为什么要按大公司的架构规范来?

Project Hulk 发现,对 AI agent 来说,这个逻辑完全反过来了。

agent 极擅长局部优化,极不擅长处理全局耦合。如果层次清晰,agent 可以在一个完全解耦的模块里疯狂迭代,完全不担心影响其他部分。如果层次混乱,agent 动一处,另外三处崩掉,debug 耗时远超出功能本身。

他们不是通过"告诉 agent 应该遵守什么规范"来实现约束——而是通过 linter 机械地强制执行:违反分层规则的代码,在 CI 阶段直接报错,agent 的 PR 合不进去。

这条规则对 agent 是强制的,对工程师也是强制的。约束本身不区分对象。

约束不是限制速度的绳子,而是让 agent 能快速移动而不腐烂的护栏。


那些消失在 Slack 里的决策

GC agent 和架构约束解决了"坏代码传播"的问题。但 Project Hulk 还发现了另一类更根本的问题:知识断层

在传统团队里,大量决策活在非正式的地方:Slack 频道的讨论、Google Doc 里的技术方案、工程师之间的一句话。这些知识对人来说不难获取——打开历史记录、找人问一句,就能知道当初为什么这么决定。

对 agent 来说,这些全都不存在。

不是 agent 懒。是因为它的知识边界,就是它能访问的 repo 边界。Slack 里的那条讨论、那份 Google Doc、那次会议上的一句话——agent 在下一秒就会违背它们,不是故意的,是因为它根本不知道。

他们把这个原则叫做 "Knowledge as Code"(知识即代码)

所有对 agent 行为有影响的知识,必须以结构化文档的形式存在于 repo 里。不只是"是什么",还要有"为什么不是另一种"。

架构决策为什么这样定?某个库为什么不用?某种模式为什么被禁止?这些理由,必须和代码一起活在 repo 里,否则它们对 agent 等于不存在。


AGENTS.md:一份地图,而不是一本书

执行 Knowledge as Code 最直接的方式,是把所有知识都写进 AGENTS.md。很多团队这样做了——结果是 AI 变得更笨了。

原因是:他们把 AGENTS.md 写成了百科全书。

一份几千行的说明书,每次 session 开始就全量注入 context——这份文件本身就吃掉了大量的上下文窗口,让 agent 没有空间处理真正的任务。

Project Hulk 的做法是分层披露:

  • 根目录 AGENTS.md:100 行以内的"地图"。告诉 agent 项目分几个模块、每个模块负责什么、核心约束有哪些。不讲细节,只讲方向。
  • 各子目录 README:当 agent 进入某个具体模块时,才加载该模块的详细约束。

agent 不需要在开始工作前记住所有东西。它需要知道的,是"现在这个任务,我该去哪里找相关的规则"。


什么转移了

Project Hulk 的实验结束时,这个团队有一百万行生产代码,其中没有一行是人工写的。

但这不是这个实验最值得注意的地方。

最值得注意的是他们对"工程师做什么"这件事的重新定义:工程师不再是代码生产者,而是 agent 集群的环境设计者

他们花时间的地方,从"写正确的代码"变成了"设计让 agent 只能写出正确代码的环境"——包括架构约束、知识文档、GC agent 的巡检规则、AGENTS.md 的信息密度。

代码本身成了廉价的输出。发现一段代码写得不好,正确的做法不是让人去改,而是升级产生这段代码的 harness——文档、约束、知识,更新之后让 agent 重新生成。

工程纪律没有消失,它转移了。从代码本身,转移到了代码产生的条件。


下一篇:我受够了 Claude Code 的黑箱,所以自己造了一个——极简主义黑客 Mario 如何用 1000 token 挑战大厂的繁重架构