从写代码到设计代码生产系统-吴军风格

从写代码到设计代码生产系统:理解 Ryan Lopopolo 的 Harness Engineering,需要回到工业革命的脉络里去

一、从一个具体的事件谈起

2026 年 2 月 11 日,OpenAI 在自己的官方博客上发表了一篇题为《Harness engineering: leveraging Codex in an agent-first world》的文章;作者 Ryan Lopopolo 是这个团队的成员之一。同年 4 月 7 日,他又在播客 Latent Space 接受了一场长访谈,进一步谈到了背后的方法论。

文章里描述了这样一件事:他们用大约五个月时间,从一个空仓库出发,构建并交付了一款内部 beta 产品。这个仓库最终大约有一百万行代码,约 1500 个 PR,应用逻辑、测试、CI、文档、可观测性和内部工具,全部由 Codex 这个代码生成 agent 写成;人类工程师并没有亲自手写一行业务代码。Ryan 自己估计,这相当于手写代码所需时间的十分之一。

在过去三年里,关于 AI 编程的报道层出不穷,类似量级的“震撼数字”也出现过几次。但 Ryan 这件事之所以值得专门写一篇文章来谈,并不在数字本身。真正值得关注的,是他在数字背后给出的那一整套工程范式——他把它命名为 harness engineering,姑且翻译成“驾驭工程”。

我对这件事感兴趣的原因是:从科技史的角度看,它并不是一个孤立的小创新,而是一类我们已经反复见过的事情——一种新的生产手段出现之后,关于“什么是有价值的劳动”的定义被重新写过一次。 工业革命如此,电气化如此,集成电路如此,互联网如此。AI 编程,看起来正在以同样的方式发生。

这篇文章想做的事,是把 Ryan 的观点放回到一个更长的技术史脉络里,再做一些必要的归纳和判断。

二、回到工业革命:生产手段更替时,发生过什么

要理解 harness engineering,先回到一段更老的故事。

十八世纪末到十九世纪初,纺织业先后出现了飞梭、珍妮纺纱机、水力织机和蒸汽动力。这些设备一个比一个能干。从产能曲线上看,每一次设备更替都意味着同一个工人能管的纱锭和织机数翻倍上升。表面上,这是一场关于“机器战胜人手”的故事。

但如果只看到这一面,就会错过更深的东西。

在工厂出现之前,纺织是一门“家庭作坊”行业。一个工匠的全部价值,集中在他的双手和经验上。机器普及之后,这一部分价值确实被压低了——纺纱本身,从一种稀缺技能变成了一种廉价劳动力可以做的事。但与此同时,一种过去并不存在的新岗位被催生了出来:工长(foreman)、机械师(mechanic)、工艺工程师(process engineer)和工厂经理(manager)。

这些角色做的事,并不是“自己上手纺纱”,而是设计机器的布局、维持机器的稳定、调度物料和人手、判断产出质量、规划新车间。他们的产出形态,从单件产品,变成了“一整条生产线的运转”。

我们事后回头看,会很容易得出一个结论:工业革命真正改变的,不是“会不会纺纱”这件事的定义,而是“什么样的劳动算高价值劳动”的定义。 一线手艺人的边际价值在下降,而设计、调度、维护这条生产线的人,他们的边际价值在上升。

电气化、汽车工业、集成电路、互联网这几次范式更替里,类似的事情一次又一次发生。每一次的细节都不同,但底层结构非常相似——当某种生产手段把人原本擅长的某一类劳动接管之后,人的价值就会向上一层迁移:从执行迁移到设计,从单件产出迁移到系统产出,从隐性手艺迁移到可复用规则。

我们可以这样理解 Ryan Lopopolo 这件事:它本质上是软件工程在 AI 时代经历的同一类迁移。代码生成本身被 agent 接管了,接下来重新被定价的,是人类如何设计这条“代码生产线”。

三、软件工程到目前为止的三个阶段

要看清楚 Ryan 的位置,可以先把过去半个世纪软件工程的演化,做一个粗线条的划分。

第一个阶段,可以叫手工作坊阶段。从上世纪六十年代到八十年代,软件主要由小规模团队手工开发。一个工程师的价值,几乎全部取决于他能写出什么样的代码。彼时优秀的工程师,往往就是那种“一个人能搭出整套系统”的天才。这一时期的代表人物,是 Ken Thompson、Dennis Ritchie 这一批 Unix 先驱。

第二个阶段,可以叫工业化流水线阶段。从九十年代开始,到 2010 年代中期成熟。版本管理、持续集成、自动化测试、云计算、敏捷开发、SRE 文化,逐步把软件生产从作坊转化为流水线。这一时期,“会写代码”已经不再是一个稀缺能力,真正稀缺的能力是“让一千个工程师协同工作而不出乱子”。这一时期的代表性事物,是 Google 的工程文化、亚马逊的服务化架构、Netflix 的混沌工程。

第三个阶段,正在以肉眼可见的速度展开。可以叫智能编排阶段。从 2023 年大模型驱动的编程辅助开始,到今天的 agent-first 实验,软件生产的一部分关键劳动——写代码——开始由模型直接承担。Ryan 这个团队的实验,是这一阶段一个比较纯粹的样本。

每一个阶段的更替,都伴随着两件事:第一,原本稀缺的能力变得不再稀缺;第二,一种新的稀缺能力被催生出来。手工作坊阶段稀缺的是“会写”;工业化阶段稀缺的是“会协同”;智能编排阶段稀缺的是什么?这正是 Ryan 想回答的问题。

他给出的答案不是“会写更好的 prompt”,而是更深的一层:会设计让 agent 稳定工作的整套环境。 这个能力,他叫 harness engineering。

四、Ryan 的核心命题:humans steer, agents execute

Ryan 反复用一句话来概括这套范式——人类掌舵,agent 执行。

这句话本身并不复杂,复杂的是它如何被理解。

一种常见的误读是:人类只负责发指令,剩下的全部由 agent 完成。如果停在这一层,会得出“程序员要失业”的结论。但 Ryan 在文章里描述的实际工作分配,要细致得多。

他所说的“人类掌舵”,包括以下几件事——
设计 agent 工作的环境(designing environments)
表达意图(specifying intent)
构建反馈回路(building feedback loops)
维护约束(maintaining constraints)
沉淀判断(codifying judgment)

我们可以这样总结:人类工程师并没有从循环里消失,他们只是从 implementation layer,迁移到了 systems layer。 他们仍然在做关键的判断,仍然在拍板架构,仍然在守护边界,只是不再以“在键盘上敲源代码”作为主要产出形态。

从科技史的角度看,这是一种很常见的模式。蒸汽机普及之后,并不是所有人都不再做体力劳动;而是工厂里“管理蒸汽机的人”成了新的高价值角色。计算机普及之后,并不是所有人都不再算账;而是“会用计算机来组织数据的人”成了新的高价值角色。AI 编程的故事,本质上是同一种结构的第 N 次重演

在这种重演中,最关键的事情,从来不是“机器接管了哪一部分”,而是“人类该把自己的精力转到哪一层”。Ryan 的回答非常清楚:转到那一层,叫 systems layer。

五、Ryan 的方法论起点:用一个看起来不合理的约束逼出系统化

Ryan 在访谈里讲到一个细节,我认为是他整套方法论中最关键的起点:他给自己定下了一个看起来很极端的约束——完全不写任何代码。

他给出的理由是平实的。如果 OpenAI 希望把 agent 部署到企业内部,那 agent 在原则上就应该能做工程师能做的事;既然他和 coding harness 已经一起工作了大半年,那他就反过来设计自己的工作方式:唯一能完成工作的途径,就是让 agent 完成工作。

我们可以从两个角度来理解这件事。

第一个角度是工程角度。这种约束本质上是一种“自缚手脚”的实验设计。它封死了“我下次自己上手”的退路。每一次 agent 失败,都不再被允许归因为“我自己来更快”,而被强制归因为“系统里缺了什么”。是缺工具?缺文档?缺反馈通道?缺测试?缺 trace?缺 sandbox?缺验收标准?这种归因方式的好处是显而易见的:它逼着团队把所有原本依赖人类兜底的能力,逐步沉淀成 agent 可读、可执行、可验证的系统组件。

第二个角度是科学方法论的角度。任何一个新工具的极限能力,在一个允许使用旧工具兜底的环境里,是测量不准确的。要想真正知道 agent 能走多远,唯一的办法是把旧工具的退路砍掉。这一点和实验物理是相通的——在控制变量被严格设定之前,任何关于“它行不行”的判断都是不可靠的。

我们可以这样理解 Ryan 这种做法:他不是在主张所有团队都不写代码,而是在主张——只有当你真正禁止自己用老办法兜底,你才会开始严肃地构建那套使新办法可工作的系统。

历史上类似的事情发生过不止一次。福特最初推动流水线生产时,遭遇过强烈的内部阻力——很多老工人觉得“我自己慢慢做也能做好”。福特最终的做法不是说服每一个人,而是把生产组织本身改了,让旧办法在新组织里没有立足之地。生产方式的更替,常常需要这种“封死退路”的决心。

六、harness 的对象不是 prompt,而是整个生产环境

把 Ryan 这种方法论推一步:他所谓的 harness engineering,对象并不是单次对话,也不是某一段 prompt,而是整个软件生产环境。

prompt 当然仍然重要,但它只是 harness 的一个小部件。harness 真正包括的东西,至少有以下几类——

第一类是工具。 agent 必须能启动应用、读日志、查指标、跑测试、看 UI、生成截图、提交 PR、回应 review。这一系列能力如果没有从工具层做出来,agent 就只能停留在“会写代码但看不见结果”的阶段。

第二类是文档与知识。 repo 里要有 agent 能读懂的导航、设计文档、execution plan、quality score、reliability 规则、安全姿态。所有这些东西,是 agent 在 runtime 拿来推理的“上下文”。

第三类是约束。 不可妥协的架构边界、依赖方向、数据形状、命名约定,必须被机械化为 lint 和 structural test,而不是写在某个角落让 agent 自己去揣摩。

第四类是反馈。 trace、log、CI、review 评论、测试结果、quality score、技术债报告——这些信号必须以 agent 能消费的方式回流到 repo 里。

第五类是 workflow。 PR 的生命周期、issue 的状态机、agent 的 sandbox 权限、人类升级路径,必须有清晰的规则,让 agent 知道在每个状态下该做什么、不该做什么、什么时候必须停下来。

我们可以这样理解:harness 是一个工程师把自己的判断、品味、经验和约束,系统化地“暴露”给 agent 的整套基础设施。 它的存在意义,不是替代工程师,而是让工程师的判断不再以一次性的方式被消耗,而是以可复用的方式持续生效。

从科技史的角度看,这种“让人类经验沉淀进系统”的事,过去也发生过。十九世纪末出现的工业制图、工艺标准、QA 流程,本质上都是把老工匠脑子里的隐性经验,转化为可被流水线消费的显性规范。Ryan 在 agent 时代做的事,只是这种沉淀活动在新介质上的又一次演化。

七、瓶颈的迁移:从代码产能到人类注意力

每一次生产手段的更替,必然伴随瓶颈的迁移。

汽车工业的早期,瓶颈是“造一辆能跑的车”;中期,瓶颈变成了“卖出去”;成熟期,瓶颈又变成了“维护和服务”。一个产业的英雄人物之所以会在不同时期更换,是因为不同瓶颈所需要的能力是不一样的。

软件工程到目前为止经历过两次明显的瓶颈迁移。手工作坊阶段,瓶颈是“能不能写出来”;工业化阶段,瓶颈变成了“能不能稳定地发布”。Ryan 这次实验暴露出来的,是第三次瓶颈迁移——

当 agent 把代码产能拉高到接近无限,瓶颈跑到了“人类注意力”那里。

他在访谈里反复强调一句话:模型工作可以并行,token 可以花,GPU 可以扩,但团队同步投入的人类注意力是稀缺的。

这句话的含义远比表面深。

过去的所有工程流程,几乎都默认了一个隐含前提:人是产能的瓶颈。所以每个 PR 都要认真审查,每个 gate 都要严格把关。这套流程在人是瓶颈的时候是合理的;但当 agent 把代码产能拉高十倍,这套流程会瞬间反过来变成最大的瓶颈。

OpenAI 文章里有一句很值得抄下来的话:他们后来调整的 merge philosophy——短寿命 PR、阻塞 gate 较少、flaky test 后置处理——放在低吞吐环境里是不负责任的,但在高吞吐环境里常常是正确的取舍。

这并不是 Ryan 在主张取消 review。他真正在主张的是:当人类 review 变成瓶颈,质量控制必须前移、机械化、agent 化。 工程师不应该再花大量时间逐行检查代码,而应该把过去常见的 review 意见,转化为 lint、structural test、文档规则、review agent、验收脚本。

我们可以从历史上类似的事情找到呼应。汽车工业进入大规模生产之后,质检并没有消失,但它的形式从“人逐个看”变成了“统计抽样 + 工艺过程控制 + 自动化测试”。生产手段升级之后,质量控制本身也必须升级,否则它会变成新的瓶颈。 Ryan 团队的做法,是在软件工程上完成同样的过渡。

八、AGENTS.md:从“百科全书”到“目录”

Ryan 文章里有一条经验,对所有团队都有直接借鉴意义。他们最早写过一个非常巨大的 AGENTS.md,把所有团队约定、风格偏好、注意事项都写进去。结果如可以预料的那样:上下文空间被严重挤占,所有规则都“重要”,等于没有规则;文档很快腐烂,与代码不一致;几乎没有办法机械验证。

后来他们把 AGENTS.md 改成大约 100 行的“目录”——一个稳定入口,指向 repo 内更深层的 source of truth。真正的知识被搬到结构化的 docs/ 目录里:design docs、execution plans、product specs、references、quality score、reliability、security 等等。计划本身也被当作“一等公民”,与代码一起 versioned。

这种做法的背后,有一个很值得记录的原则——从 agent 视角看,运行时拿不到的知识就等于不存在。

这条原则的含义比它的字面要深。

Slack 里某次架构讨论达成的一致——agent 没读到,等于不存在。Google Doc 里那份 design doc——没有进入 agent 上下文,等于不存在。某位资深工程师脑子里的那些“我们就是这么干”的隐性经验——只要他没把它写进 repo,对未来的 agent 而言就是不存在的。

从历史上看,这其实是文档观念的一次迁移。在工业时代之前,文档的功能主要是“留给后人看”。工业化以后,文档承担起了“协同工具”的角色——是工程师之间对齐预期的方式。到了 agent 时代,Ryan 的实践告诉我们,文档还要承担一个新的功能:让 agent 能够行动。 文档不只是给人读的解释材料,它是 agent 的工作内存、导航图、约束集合和验收依据。

更进一步,这些文档不能只是“被写下来”。Ryan 团队还做了两件事:用专门的 lint 和 CI 检查文档健康度,以及让一个常驻的 doc-gardening agent 定期扫“文档说的”和“代码做的”是否一致,发现偏差就开 PR 修。

我们可以这样理解这种做法:它把文档从“曾经写下的内容”,升级为“持续被验证的事实”。 这是一种从文学性到工程性的转变。

九、Agent legibility:当代码的首要读者不再是新员工

Ryan 提了一个很有概括力的概念:agent legibility,可以翻成“对 agent 的可读性”。

他的判断是这样的——既然他们的代码大部分由 agent 生成、未来的修改也将由 agent 完成,那么“对 agent 可读”必须成为代码的首要约束之一。这并不意味着“代码可以不适合人读”。Ryan 的态度其实更微妙:代码不一定要符合所有人类的审美偏好,但只要它正确、可维护、对未来 agent runs 可读,就达到他们的标准了。

我们可以这样理解:human taste 没有消失,而是被重新定义了。 它从“我喜欢这个实现长什么样”,转向“这个实现是否可验证、可维护、可被 agent 稳定理解和复用”。

这种转变会反过来影响技术选型。OpenAI 文章中有一段表述值得记录下来:他们偏好那种 agent 能够完整 internalize 的依赖与抽象。传统上被称为“无聊”的技术——组合性强、API 稳定、训练集中出现得多——反而更容易被 agent 建模。文章给了一个具体例子:他们没有引入一个通用的并发限制库,而是自己写了一个 helper,让它与 OpenTelemetry 集成、测试覆盖完整、运行时行为可预期。

Ryan 在访谈里把这个逻辑推得更远——他甚至认为,一个几千行的小依赖,可能可以让 agent 一个下午重写一遍,只保留你真正需要的部分;之后做安全审查、修 bug、做适配时,agent 能直接深入修改,而不必等 upstream patch、发布、升级。

这种主张听起来反 DRY,但他自己也很清楚地承认:内部化依赖意味着你回到零,需要重新建立信心和测试。 这不是免费的。

我们可以从更深的层面理解这件事——当代码本身的生成成本下降,软件的价值就从“代码资产”转向“可验证的系统形状”。 过去之所以倾向复用第三方库,是因为重写很贵;Ryan 描绘的这个世界里,重写的边际成本下降了,但验证、可观测、边界、安全的成本依然很贵。所以“用不用第三方库”不再仅仅是“不要重复造轮子”的问题,而要追问——这个轮子对 agent 是否透明?我能不能用我自己的 harness 去约束、测试、审查、修复它?

这其实和工业史上的模块化进程,是同一类问题的不同形态。福特最早造车时,几乎所有零件都自己做;后来,零件供应链高度专业化、模块化;再后来,丰田又重新提出“看板生产”,要求把过多分散的环节再次拉回到一个可控的系统里。这种“内部化与模块化之间的钟摆”,每个产业都会经历。 软件工程在 agent 时代的钟摆,正在从“什么都用第三方库”,向“重要的部分内部化以方便 agent 操控”摆动。

十、让 agent 能看见应用:可观测性的角色变化

Ryan 团队后来的瓶颈,从代码产能变成了人类 QA 容量。他们的解法不是雇更多 QA,而是让 agent 自己具备 QA 能力。

具体做法分几步——
应用支持按 git worktree 启动,每一个 change 都对应一个独立实例;
把 Chrome DevTools Protocol 接入 agent runtime,给 Codex 写处理 DOM snapshot、screenshot、navigation 的 skill,让它自己去复现 bug、验证修复、推理 UI 行为;
每一个 worktree 配一套隔离的 observability stack,Codex 可以查 logs、metrics、traces,会用 LogQL、PromQL。

把这套搭起来之后,“确保服务启动低于 800ms”、“这四条关键用户路径里没有 span 超过两秒”——这种 prompt 才真正变得可执行

他们甚至让 Codex 直接 author Grafana dashboard 的 JSON,并响应 page。因为 dashboard、alert、log、code 都被 collate 在一起,告警发生时 agent 能知道是哪条日志触发了哪个 alert;如果某个 outage 没有触发 page,它还可以根据已有 dashboard 找到观测缺口并修复。

这件事的科技史含义比工程细节更重要。过去的可观测性工具,目标受众是人类 on-call 工程师。 它的设计哲学是“让一个被叫醒的工程师能够在最短时间内理解系统状态”。这一时期最好的可观测性公司,是 Datadog、Grafana、Honeycomb 这些。

到了 agent 时代,受众正在悄悄变化。当最终修复也由 agent 完成时,可观测性的目标受众,就从人类 on-call 变成了 agent。 这意味着——

dashboard 不一定要好看,要让 agent 能从中读出“下一步该做什么”;
log 不一定要丰富,要结构化、可被机械解析、易于压缩进上下文;
trace 不一定要可视化,要 agent 能直接消费的 tarball;
alert 不一定要带情绪,要提供因果链而不是孤立信号。

Ryan 在访谈中举了一个很有代表性的例子:他们工程师有人花了一个下午做了一个漂亮的 trace visualization 工具;后来发现,直接把 trace tarball 丢给 Codex 让它分析修复,反而更符合 agent-first 的路线。

我们可以这样总结:可观测性的演化,正在经历一个从“给人看”到“给 agent 用”的范式转换。 它将催生出新一类工具——agent-readable observability。这一类工具今天还没有标准答案,但接下来五年,它很可能会成为一个独立的细分市场。

十一、机械化的 invariants 与不被 micromanage 的 implementation

Ryan 还有一个观点,对所有正在用 agent 的团队都有方法论价值——文档本身不足以让一个完全 agent-generated 的 codebase 保持一致。 你不能只跟 agent 说“请写得优雅”,也别指望它自然遵守团队的 tacit taste。那些不可妥协的架构边界和 invariant,必须机械化。

OpenAI 那篇文章里讲了具体做法:把业务 domain 切成固定层级(大致是 Types → Config → Repo → Service → Runtime → UI),用 custom lint 和 structural test 强制依赖方向;横切关注点通过 Provider 这种显式接口进入,其他边一律禁止。

Ryan 的关键判断是——约束 invariant,不要 micromanage implementation。 比如他们要求 Codex 在边界上解析数据形状,但不指定一定要用某个库。这样 agent 既能快速产出,又不会破坏地基。

我们可以从两个层面来理解这种取舍。

第一个层面是工程层面。把 invariant 机械化,意味着 agent 即使复制了不好的模式,也无法越过最关键的边界。这是一种“让坏模式无法扩散到致命位置”的设计,类似于核电站的多重防护——单点故障可以发生,但不能演化成系统性灾难。

第二个层面是组织层面。Ryan 在访谈里说自己心态像在 group tech lead 一个 500 人的组织——对一个 500 人组织的技术负责人来说,逐行点评每个 PR 是不合适的;更重要的是通过样本观察团队哪里卡住、哪里需要帮助、哪里已经跑得快,然后把注意力转到更高杠杆的位置。

他们的仓库有大约 500 个 NPM packages。一个七人团队搞这种结构,初看是过度架构。但 Ryan 反问得很有力:如果每个工程师驱动 10 到 50 个 agent,那这就更像一个几百人的团队。深度 decomposition、sharding、清晰接口边界——这些“大公司病”的产物,在 agent-first 团队里反而是早期 prerequisite。

这里有一个值得记录下来的判断——在 agent 时代,团队的“实际规模”不能按 head count 计算,要按并发执行单元计算。 这一点对很多还在用旧规模观估算自己组织复杂度的团队,是一个值得警惕的提醒。

十二、Review 的未来:从逐行审查到“信任包”

Ryan 在 PR review 上的看法,可能是这套方法论里最容易被攻击的一部分。他在 OpenAI 文章里说,人类可以 review PR,但不总是必须;随着时间推移,他们把几乎所有 review 努力推向 agent-to-agent。访谈里他说得更直接——大部分 human review 已经是 post-merge。

但他立刻补了一个限定:他们做的是 native application,不是连续部署的高可靠基础设施;发布分支与分发前的 smoke test,仍然有人类批准。

所以 Ryan 真正想说的不是“取消人类审查”,而是审查对象与信任机制要变

让我印象最深的,是他在访谈里那个具体设想:他希望 coding agent 在 PR 上附一个视频,展示功能在真实产品里能跑起来。这相当于把 agent 完整的工作轨迹压缩成一个 reviewer 可读的“信任包”。

这个类比非常精准——人类同事提 PR 时,我们不会要求他屏幕录制整个写代码过程;我们只要他给出足够证据,让我们相信代码可以 merge。 Ryan 把 agent 也当成 teammate 来看:不要 shoulder-surf 它的每一个动作,而要让它产出 reviewer 需要的压缩证据。

证据可以是什么?——单元测试、E2E 测试、trace、video walkthrough、log 摘要、review agent 给出的结论、CI 状态、structural check 结果、quality score、tech debt 更新。人类 review 的价值,从“逐行检查生成物”,转向了“检查验证体系是否覆盖了风险”。

从科技史的角度看,这其实是审计制度演化的一个重演。早期的工业生产里,质检是“逐件查验”;后来变成了“过程审计 + 抽样 + 统计过程控制”;再后来,软件行业把它进一步发展成了 SLO、错误预算、混沌工程这一整套机制。Ryan 这件事,是同一种演化路径在 agent 时代的下一站——审计的对象从“产物”,进一步前移到“验证体系本身”。

十三、错误不是修补,而是进入“垃圾回收”系统

Ryan 没有回避一个关键问题:完全 agent autonomy 会带来新麻烦。

OpenAI 文章里说得很坦诚:Codex 会复制 repo 里已有的模式,包括不均匀或次优模式;时间一长会出现 drift。他们最早每周五花 20% 时间清理“AI slop”,但很快发现这种打地鼠模式不可扩展。

他们后来做了两件事——
第一,把 golden principles 编码进仓库,作为有观点的机械规则,目标是维持代码对未来 agent runs 的可读性和一致性。例如偏好 shared utility package、不允许 YOLO 猜数据形状、网络调用必须有 timeout。
第二,建立 recurring cleanup process,让后台 Codex 任务定期扫偏差、更新 quality score、开 targeted refactoring PR;很多可以在一分钟内 review 并 automerge。

Ryan 把这事称为 garbage collection——技术债像高利贷,最好持续小额偿还,而不是让它复利增长到痛苦爆发。

这个比喻之所以重要,是因为它把“AI slop”从一个道德议题,变成了一个工程对象。Ryan 不否认 slop 的存在,他说的是:如果 agent 会复制坏模式,那就要设计一个持续回收坏模式的系统。 所谓 human taste,不是每次人类出来骂一句“这个写得丑”,而是把 taste 捕捉成原则、lint、review prompt、quality score 和后台清理任务。

从历史上看,这种“持续清理 + 持续偿还”的做法并不新鲜。汽车工业的 TPS(丰田生产体系)里,有一项核心原则叫“jidoka”(自働化)——一旦在生产线上发现缺陷,就立即停下、就地解决、把根因写进流程。Ryan 的 garbage collection,本质上是软件工程在 agent 时代的 jidoka。 区别只是,机器从生产线变成了 agent,故障从机械问题变成了 slop 问题。

我们可以这样理解:一个真正稳定的 agent-first 系统,不在于“不会出错”,而在于“它出的每一个错都会被吸收为系统的一段免疫力”。

十四、Symphony:从“看终端”到“让 issue tracker 成为 control plane”

Ryan 后续工作里最值得单独拿出来谈的,是 Symphony。OpenAI 在 2026 年 4 月 27 日发布了 Symphony 的相关文章,它直接继承了 harness engineering 的实验。

故事是这样的——团队在“无人手写代码”的工作流里继续推进时,下一个瓶颈出现了:context switching。每个工程师每天能稳定推 5 到 10 个 PR,但代价是不断在 tmux pane 之间切换;同时管理 3 到 5 个 Codex session 就开始痛苦:忘记哪个 session 在做什么、agent 卡住时不知道、长任务总要回头检查。这相当于团队拥有了一群能力很强的 junior engineer,却不得不让 human engineer 去 micromanage 他们。

Symphony 的核心设计简单又深远——不要直接监督 agent,让 agent 从任务系统里拉活。 Linear 这类项目管理看板成为 coding agent 的 control plane;每一个 open task 对应一个 agent workspace;agent 持续运行,人类 review 结果。

这一步真正的意义在于——它把工作单位从 Codex session / PR,提升到了 ticket / deliverable。这是一次抽象层级的跃迁。

OpenAI 文章给了一个具体数字:有些团队上 Symphony 三周后 landed PRs 增加了 500%。但更深层的变化是——每个 change 的感知成本下降了。人不再亲自驱动实现,因此 speculative task 变得便宜——试一个想法、探索一个 refactor、测试一个假设,不行就丢掉。产品经理和设计师甚至可以直接向 Symphony 提 feature request,拿回一个包含真实产品视频 walkthrough 的 review packet。

我们可以从科技史里找到对应。早期个人电脑时代,开发者要直接面对 CLI;GUI 之后,普通人开始能够直接使用计算机。后端服务时代,传统部署需要工程师亲自调机器;Kubernetes 之后,部署变成了“声明状态”,调度本身被抽象掉。Symphony 在 agent 时代做的事,是把“管理 agent 的劳动”从手工进一步抽象为声明式的 ticket queue。 它解决的不是技术问题,而是“人类注意力如何不被 agent 数量淹没”的问题。

Ryan 在访谈里特别提了一个 Symphony 的 rework state 设计,我认为符合 agent-first 时代的成本观——
如果 PR 不可 merge,就把 worktree 和 PR 整个丢掉,从头再来;
然后追问“它为什么是垃圾”,先修 prompt、skill 或 guardrail,再把 ticket 重新推入 progress。

这背后是一个值得记录的判断:当代码的边际成本接近零,保留错误路径不一定值得。 有时候丢弃 + 补护栏 + 重跑,比 patch 干净。这种思路在传统工程师脑子里很难一下接受,但在 token 便宜、模型够强的时代,是一种合理的取舍。

十五、从“放盒子里”到“给目标 + 上下文 + 工具”

Ryan 还有一个我认为非常值得记录的演进观察:早期 agent 适合放在预定义 scaffold 或状态机里,但 reasoning model 一旦变强,过度僵硬的 scaffold 反而会限制它。

他们后来“反转”了系统——
不是先搭一个环境再把 coding agent spawn 进去,而是让 Codex 本身成为入口,再通过 skill 和 script,给 Codex 提供启动 stack、设置环境变量、查询 observability 数据的能力。

这并不意味着“取消边界”。Ryan 自己补了一句关键限定:给它 context 和 tools。
也就是说,box 不是没有,而是 box 变成了整个 harness:权限、工具、repo 结构、workflow policy、observability、CI、lint、skill、sandbox、human escalation——共同构成一个可操作的环境。

这种思路上的演化也有历史对照。早期工业自动化,主要靠固定流水线和死板的状态机;进入电气化和自动化的成熟期,引入了反馈控制(feedback control),让设备能够根据实时信号自我调整。Ryan 从“硬编排”向“给 agent 目标 + 上下文 + 工具”的演进,本质上和工业自动化从开环控制走向闭环控制,是同一种范式跃迁。

我们可以总结一条很有用的判断:模型能力越强,控制系统的设计就越应该向“目标 + 反馈”方向偏移,而不是向“步骤 + 步骤”方向偏移。 这是工业控制论的一条老规律,在 AI 时代被重新激活。

十六、文本是 agent 的血液

Ryan 还有一句话值得抄下来——模型 fundamentally crave text。

他们做的很多事,本质上都是在把文本注入这个系统让 agent 能用。比如某次缺 timeout 导致 page,他们直接在 Slack 里 @ Codex,让它不光给那个调用加 timeout,还要更新 reliability documentation,把“所有网络调用都必须有 timeout”写进规则。这样团队不只是修了一个点,而是把“什么是好”持久编码进流程知识。

他们还做了一件挺有方法论意义的事:对 session log 做 skill distillation。Codex 自己的 session log 收集到 blob storage,每天跑 agent loop 分析“团队哪里做得不够好”,再把结论反馈回 repo。PR comment、failed build——这些都是信号,代表某个时刻 agent 缺上下文;这些信号要被吸收,然后塞回 repo。

这件事让 harness engineering 具备一种自改进的味道。它不是一次性配置,而是持续学习系统:agent 失败 → 失败变成文本信号 → 文本信号被分析 → 规则、skill、文档、工具更新 → 未来 agent 更少失败。这个循环越顺畅,团队的经验复利越强。

更进一步,Ryan 还说了一个反共识但其实合理的判断——改 agent behavior 比改 human driver behavior 便宜得多。 团队里每个人都去养成新习惯很难;但你把新习惯写进 shared skill、lint、workflow prompt 或 CI,所有 agent 立即继承,所有人间接受益。

十七、CLI-first 与 token 效率:工具的输出格式正在被重新评估

Ryan 对工具输出格式有非常具体的偏好——CLI 对 agent 友好,因为 token efficient,而且容易被改造得更 token efficient。

他举的一个例子很具体:构建输出常常是一大墙文本;过去 dev productivity team 会写工具把真正的异常抽出来放到顶部。给 agent 的 CLI 也应该这样——格式化命令不必输出每个已格式化文件,agent 只需要知道 formatted or not;测试输出尽量只吐失败部分。

这听起来是细节,但在 agent-first 系统里有结构性意义。人读日志可以扫一眼跳过;LLM 处理日志时,无关 token 会占 context、干扰注意力、增加成本,还可能触发错误推理。 好的 agent tooling 应该把输出压缩成“下一步行动所需信息”。

我们可以从科技史里找到一个对应:早期电报时代,因为按字数收费,电报员发明了一整套缩写、词典和专用编码,让一句话用最少的字传达。今天,给 agent 的 CLI 输出格式,正在经历类似的“信息密度优化”。 这是一种我们以为已经过时的工程纪律,在新介质上的重新登场。

我们可以从这里推导出一条更广的判断——未来五年,整个软件生态的接口都会逐步为 agent 优化。 日志、CLI、错误消息、lint message、dashboard、trace、PR comment、issue description,都会在原本的“人类友好”目标之外,新增一个“agent 友好”目标。这两个目标有时一致,有时分歧;分歧的部分将成为新一代工具的设计空间。

十八、Ghost Libraries:当代码便宜时,软件可以以 spec 的形式分发

Ryan 在访谈里还谈到一个挺未来感的概念——Ghost Libraries

Symphony 的开源形式很特别。它不是先给一个完整实现,而是先给一个高保真的 spec,让 coding agent 可以在本地重新组装出来。OpenAI Symphony 文章里说,仓库第一眼看到的是一个 SPEC.md,定义问题和预期解法,而不是只给一个复杂的监督系统。

Ryan 描述他们提取 spec 的过程很有方法论意味:从内部 proprietary repo 里抽 scaffolding,开新仓库,让 Codex 参考原 repo 写 spec;再让一个断开的 Codex 实现 spec;再让另一个 Codex 比较实现与 upstream,更新 spec 让它更少偏离;如此循环,直到 spec 能高保真地复现系统。

这是一种非常不同的软件分发观。

我们可以这样理解:过去我们分发软件,主要分发 source code、binary、library、API。Ryan 描绘的世界里,如果 agent 足够会写代码,spec 本身就可能成为软件资产——它描述问题、边界、流程、接口、状态机、成功标准和非目标,由本地 agent 根据具体环境生成实现。

OpenAI 的 Symphony spec 强调:它是 scheduler / runner 和 tracker reader,ticket 写入通常由 coding agent 在 workflow runtime 里完成;它不强制单一 sandbox 或 approval policy,而要求实现者明确自己的 trust and safety posture。

这一变化有两个值得记录的后果。

第一,软件变得更 adaptable。 spec 可以让 Jira、Bitbucket、Linear、GitHub 等不同环境替换具体集成,只保留更柏拉图式的抽象。

第二,工程里“实现细节”的价值在下降,“可复现的高质量规格”的价值在上升。 如果 agent 能从 spec 生成不错的实现,那么真正稀缺的就是——问题定义是否准确?边界是否清晰?验收标准是否可执行?安全姿态是否明确?观测是否足够?

这又回到 Ryan 的主线——工程师的价值从写代码转向设计可执行环境。

从更宏观的角度看,这意味着软件分发模式可能正在经历一次相变。从 source code 时代,到 binary 时代,到 SaaS 时代,再可能到“spec + agent”时代。每一次相变,都伴随着分发成本的下降和定制成本的下降。 这是一种值得长期关注的趋势。

十九、Ryan 也承认的限制:这套方法不是万金油

Ryan 的观点尽管激进,但他不盲目。OpenAI 文章在结尾很坦诚地说:他们也不知道完全 agent-generated 系统的架构一致性多年后会如何演化;也还在学人类判断在哪里最有杠杆、怎么把判断编码进去。文章的结论不是“软件工程不需要纪律”,而是纪律更多体现在 scaffolding 上,而不是代码本身——工具、抽象、反馈回路对维持代码库一致性越来越重要。

访谈里 Ryan 把任务分了象限。他认为 hard and new 的问题仍然需要人类驱动;其他象限在合适 scaffold 加 drive-to-completion 的系统下,已经大体可解。人类有限的注意力,应该放在 hardest stuff——纯白纸的问题,或者最深的 refactoring——因为这些地方的接口形状还不清楚,正是人类判断最有价值的地方。

他还提到,当前模型对某些“从零到一”的产品想法和最复杂的重构,仍然需要同步互动。原因是:如果你脑子里的东西没进到模型 context 里,模型也不知道;white space 项目常常要在 agent trajectory 中才显露出缺失信息,需要 harness 或 scaffold 把这些非功能要求、模板和框架偏好提取出来。

这一点的重要性,怎么强调都不过分。它意味着——Ryan 这套方法不是要把人完全移走,而是要把人放到更难、更新、更高杠杆的问题上。 routine implementation、QA smoke、CI 修复、merge queue、文档 gardening、技术债清理、dashboard 定义、review comment 处理——这些都该逐渐交给 agent;目标选择、架构方向、产品 taste、风险边界、复杂拆解、组织约束——这些仍然需要人类强参与。

我们可以这样理解:agent 时代的人机分工,并不是“AI 拿走全部”或“人类守住全部”的二选一,而是一个新的分工边界。 这条边界本身会随着模型能力提升而持续向上漂移,但它存在的事实不会消失。

二十、工程能力的分化:未来十年最值得关注的趋势

如果把 Ryan 这套方法论作为一个时代信号来读,它最深的含义是——工程师群体正在出现一次结构性分化

一部分工程师会停留在“我用 Cursor / Codex / Claude Code 写代码很快”这一层。他们的生产力比不用 AI 的时候确实会高,可能高到几倍。但他们仍然在做“一次性劳动”——写代码、修 bug、review PR。这些劳动的单位价值会随着 agent 能力提升而持续下降。

另一部分工程师会转向“设计让 agent 工作得好的系统”。他们的产出单位价值会越来越高,因为他们做的每一件事——每一条 lint、每一个 structural test、每一份约束文档、每一个 verification skill——都能被复用无数次

这两种工程师的长期杠杆率差异不是 2 倍、5 倍,而是 10 倍、100 倍

我们可以从历史上找到对应的分化。工业革命时期,工厂里同样有“会操作机器的工人”和“会设计、维护、改造机器的工程师”。两者的工资差距,在最初并不明显;几十年之后,就出现了量级差异。软件工程的这一次分化,速度可能要比工业革命快得多——因为 AI 的迭代速度本身比蒸汽机快得多。

在这种分化里,评价一个工程师价值的标准也会随之改变

  • 不是看他写了多少代码,而是看他让多少代码不需要再被人写。
  • 不是看他修了多少 bug,而是看他让多少同类 bug 以后不会再出现。
  • 不是看他参与了多少 review,而是看他把多少 review 意见转化为机械化规则。
  • 不是看他知道多少隐性经验,而是看他把多少隐性经验沉淀进了 repo。

简单一句话——评价一个工程师的标准,正在从“做了什么”,变成“使什么不再需要做”。

二十一、一个总结性的判断

我们可以把 Ryan Lopopolo 这次实验的意义,放在一个比较克制的位置上来理解。

它不是软件工程的“终结”。代码生成被 agent 接管,并不意味着工程纪律的消失;恰恰相反,它意味着工程纪律的层级被进一步抬高——从代码本身,转移到代码产生、验证、合并、修复、演化的整个系统。

它不是“程序员的失业书”。相反,它把工程师推向一个更难、更复杂、更需要长期判断力的位置——从打字员,变成生产线设计者;从手艺人,变成系统架构者;从执行者,变成组织记忆的维护者。

它也不是 OpenAI 一家公司的内部花活儿。Ryan 自己也明确说,这套方法严重依赖他们仓库的具体结构、Codex 的特定工具、团队的特殊条件,不应该被假设能直接泛化到所有团队。但其中提炼出的工程原则——AGENTS.md 当目录、知识 repo-local 化、约束机械化、反馈 agent 化、错误进入 garbage collection、issue tracker 当 control plane——几乎对每一个正在严肃使用 AI 编程的团队都具有借鉴意义。

如果让我用一句话来概括 Ryan 的 Harness Engineering 观,可以这样写——

AI 时代的软件工程,不是让模型替你写代码,而是把你的工程判断、团队规范、产品品味和质量标准,变成一群 agent 可以持续执行的生产系统。

这件事的意义,在更长的时间尺度上看,类似于一百多年前,福特把“造一辆车”变成“造一条造车的生产线”——改变的不是产品本身,而是产生这种产品的方式。

回看历史,每一次“产生方式的改变”,都意味着一次新的财富分配和一次新的能力溢价。理解这次改变的人会站到杠杆的长端,并把过去靠手艺攒下的判断变成系统的一部分;不理解的人,会发现自己越来越像一个被流水线包围的手艺人——还在勤恳地做事,但每件事的边际价值,已经悄悄不一样了。

工业革命用了一百年完成这件事。
AI 编程时代,留给每一个工程师的窗口,可能只有十年。
窗口不会永远开着,但今天动手,依然来得及。