什么才是 Harness Engineering?OpenAI Ryan 伦敦演讲: Code is free, Agent 时代的软件工程分工

27 阅读52分钟

图片

导读:OpenAI 技术团队成员 Ryan Lopopolo 在伦敦这场演讲里,真正讲透的不是“code is free”,而是软件工程的分工已经变了。代码越来越便宜,真正稀缺的变成了上下文、guardrails、验证链路和反馈回路。本文分三部分:先把视频原内容的重点提纲压清楚,再给出 AI 趣实验对 Harness Engineering 的解读,最后附上完整中文字幕整理稿。

一、OpenAI Ryan 到底传达了哪些信息

Ryan 这场演讲和后面的访谈,核心信息我会压成下面 12 个要点。

1. 代码正在变便宜,实施不再是软件工程里最稀缺的资源。 他最反复强调的一句话就是 code is free。意思不是代码没有成本,而是相对于过去,“生成代码”这件事已经不再是最贵的环节。

2. 模型已经强到足以承担完整的软件工程任务。 Ryan 明确表达了一个前提:模型不再只是补全工具,而是已经能承担一名完整软件工程师的大部分工作,尤其是在真实仓库里解决真实问题。

3. 工程师的角色会从 implementer 逐渐转向 orchestrator。 当代码实现越来越便宜,工程师的价值就会从“亲手写实现”转向“定义问题、定义标准、设计系统、分配任务和验收结果”。

4. 真正稀缺的资源,变成了人类时间、注意力和模型上下文窗口。 他在演讲里明确提到三种新的稀缺资源:人类时间、人类和模型的注意力,以及模型的上下文窗口。

5. Harness 的本质,是把团队经验写成智能体可读的运行说明。 团队对“什么是好代码”“什么是可接受的 PR”“哪些非功能性要求必须满足”的经验,不能只停留在人脑和 review 习惯里,而要写进 docs、rules、ADRs、QA plans 和代码库结构里。

6. 好的仓库应该是 Agent 的唯一事实源。 对智能体来说,运行时访问不到的知识,基本就等于不存在。所以项目结构、命令入口、规则、边界、历史经验,都应该尽可能回写到仓库。

7. 好的 Harness,不是一次性塞满上下文,而是按阶段注入正确的上下文。 Ryan 很强调 progressive disclosure。不是把所有指令一股脑塞进去,而是在正确的时间,让智能体读到正确的要求和约束。

8. Guardrails 的作用,是把人的 taste 变成机器可执行的约束。 比如超时和重试、目录边界、依赖方向、结构一致性、组件拆分粒度,这些都不该只靠人工 review,而应该落成 lint、结构测试、依赖规则和 review agents。

9. 真正的 Agent 工作流,必须让智能体自己验证,而不是只会生成。 Ryan 反复讲 observability、tests、CI、review agents、QA plans,本质上都是在说:写完代码不是终点,能自己验证、自己修正、直到通过,才算完整工作。

10. Review 的重点会慢慢从“看代码”转向“看系统为什么会让它走偏”。 他们团队会把人类在 PR 里重复提出的问题,逐步沉淀成 review docs、review agents、lint 和失败测试。也就是说,review 的最终目标不是手工兜底,而是补齐系统缺口。

11. Skill 的价值不在于数量,而在于长期打磨。 Ryan 提到他们真正依赖的核心 skill 只有 5 到 10 个,重点不是无限新增,而是持续打磨,让这些 skill 真正承载团队的工作方式。

12. 最终目标不是让人更忙地盯着 Agent,而是让人从执行层抽离出来。 他理想中的状态,是 Agent 能 7*24 连续工作,而人只在真正需要判断、排序和验收的时候介入。人类不再是同步驱动每一步的人,而是系统的设计者和编排者。

图片

二、什么才是真正的 Harness Engineering? 

Ryan 这场伦敦演讲,把一个很多团队已经隐约感受到、但一直没被说透的问题讲清了。

真正的 Harness Engineering,不是让 Agent 多会一点,而是让系统少依赖人一点。

把这句话展开,我觉得最核心的是下面五层。

1. 它不是 Prompt 技巧,而是运行系统

Harness Engineering 并不是 “更高级一点的 Prompt Engineering”。

Prompt Engineering 解决的是“怎么说”。Context Engineering 解决的是“给它看什么”。Harness Engineering 解决的是“让它在什么系统里工作”。

所以真正拉开差距的,已经不只是模型会不会答,而是 Agent 能不能在你的仓库里稳定地把整件事做完。

图片

2. 它的核心不是“更聪明”,而是“更可完成”

很多团队已经能让 Agent 写代码,但还是不敢放手。问题往往不在模型,而在系统没有为 Agent 设计。

入口不清楚,命令不统一,目录边界不明确,review 标准只存在于资深工程师脑子里,出错后找不到日志、截图和验证路径。

这时真正拖慢 Agent 的,不是它写得慢,而是它没法自己确认“什么是对的”。

这也是 Harness Engineering 要解决的问题:

Harness Engineering,就是把“什么是好结果”这件事,从人的临场判断,升级成系统的默认能力。

3. 它真正值钱的资产,是 guardrails,不是 prompt

Ryan 讲得最有工程味的地方,不是 token,不是愿景,而是 review feedback 怎么回写。

这里面的差别很关键:

  • • prompt 主要改善一次输出

  • • guardrail 才能减少下一百次同类错误

所以 Harness Engineering 里最有价值的地方,不是某个单次表现很好的 prompt,而是 lint、结构测试、依赖规则、review agents、QA 计划和错误信息里的修复路径。

Prompt 是短期增益,Guardrails 才是长期复利。

图片

4. 它本质上是在重写软件工程分工

软件工程的默认分工已经在重排。

以后更有杠杆的人,不一定是最能扛实现的人,而更像这些角色:

  • 最会定义 success criteria 的人

  • 最会把 review 经验写成规则的人

  • 最会发现系统缺口的人

  • 最会让 Agent 自己完成验证的人

  • 最会把人类同步时间降下去的人

图片

Harness Engineering,不是让程序员少写代码,而是让“写代码”降级成执行层,让真正的人类价值上升到系统设计层。

5. 对个人和小团队来说,可以先跑通最小闭环

对个人和小团队来说,更好做法不是一上来造平台、做一百个 skill,而是先跑一条最小闭环:

  1. 先选一个高频、重复、可验证的任务

  2. 给它补一张最小入口地图

  3. 把一条最常见的 review 反馈写成 guardrail

  4. 给它至少一条自验证路径

  5. 每周回写一条系统规则

先把“人类经验 -> 系统能力 -> 下一次更稳” 这条复利链路跑起来。

图片

总结一下,最核心的是下面三点:

1. 代码越来越便宜,标准越来越值钱。

2. 上下文不是越多越好,而是越准越值钱。

3. 真正的复利,不来自单次生成,而来自反馈回写。

真正的 Harness Engineering,不是把人从代码里拿掉,而是把人的经验,从临场救火升级成长期有效的运行系统。

三、原视频字幕中文翻译全文

Harness Engineering:当人负责掌舵、智能体负责执行时,软件该如何构建

" Harness Engineering: How to Build Software When Humans Steer, Agents Execute — Ryan Lopopolo, OpenAI "

1. 主题演讲:代码越来越便宜,软件工程的分工正在改变

Ryan 的开场判断很直接:如果要走向 AGI 时代,我们就应该让模型去完成完整的工作。

下一位演讲嘉宾要讲的是 Harness Engineering:当人负责掌舵、智能体负责执行时,该如何构建软件。让我们欢迎 OpenAI 技术团队成员 Ryan Lopopolo。大家早上好,伦敦。我今天非常高兴来到这里。我是 Ryan Lopopolo,过去九个月里,我一直在专门和智能体一起构建软件。嗯,我算是个 “Token 亿万富翁”。我相信,如果我们真的要走向 AGI 时代,就应该让每个人都成为 Token 亿万富翁,让模型去完成完整的工作。 [00:00:17 -> 00:01:09]

他的前提也非常明确:模型已经有能力扮演完整的软件工程师。

这意味着,我们要真正接受一个前提:模型已经有能力扮演完整的软件工程师。我自己就做过这样的实验。我禁止团队成员碰编辑器,逼着大家必须通过模型把工作做完。今天我想讲的是,如何把这种工作方式真正落地到你的日常实践中,落地到你所在的代码空间和团队流程中,让智能体能够完成完整的软件交付。我想这里大多数人都已经认同这一点:软件构建方式已经变了。过去六个月,编码智能体几乎席卷整个行业,而模型能力也在以极快速度持续进步。现在,这些模型以及它们所运行其中的 harness,已经能执行更复杂的动作,在更长时间跨度内,以更高可靠性完成更难的任务。 [00:01:09 -> 00:02:06]

接下来就是整场演讲最有冲击力的一句:代码是免费的。

我们现在所处的位置是:实现已经不再是软件工程里最稀缺的资源。代码是免费的。我们可以用海量代码去解决团队管理、软件开发和用户问题中的各种需求。如今,限制团队“雇多少双敲键盘的手”的因素,已经只剩 GPU 容量和 token 预算。今天在座的每一位工程师,都可以随时调用相当于 5 个、50 个,甚至 5000 个工程师的产能,而且是一年 365 天、一天 24 小时不间断可用。 [00:02:06 -> 00:02:47]

既然实现不再稀缺,真正的问题就变成:怎么把这种产能部署到代码库和团队里。

我们唯一真正需要解决的问题,是如何把这些资源高效部署到代码库和团队中,把这种新能力真正用起来。在这个世界里,工程师的技能重心会越来越偏向系统思维、系统设计和授权,而不是亲手敲每一行代码。这种变化发生的原因有三个,而且几乎都集中在 2025 年末。 [00:02:47 -> 00:03:19]

Ryan 认为真正的转折点,是模型已经足够承担完整的软件工程工作。

对我来说,真正的转折点是 GPT-5.2。它发布时,已经能承担一个软件工程师的完整工作。至少在产出高质量代码、解决真实代码库里的真实用户问题这件事上,模型已经和你我足够“同构”。代码是免费的。我知道这听起来可能有点吓人,因为代码天然伴随维护成本,但既然生成代码是免费的,重构代码也是免费的,那这件事本身就不该再成为你纠结的重点。 [00:03:22 -> 00:03:54]

他要大家真正接受的,不是“AI 能帮忙”,而是“模型能生成、维护、重构,甚至删除代码”。

我们之所以把代码视为负担,是因为它会同步消耗团队工程师的注意力。但模型不是这样。它们极其耐心,而且可以无限并行。因此,生成、维护、重构乃至删除代码的能力,已经不再是配置工程资源时的硬约束。某种意义上,你必须真正相信:模型能够生成我们需要的每一行代码,也能判断什么时候该删、什么时候该重构、什么时候该把它做得更可靠。 [00:03:54 -> 00:04:31]

所以工程师的角色也变了:不是去亲手敲更多实现,而是去清除障碍、设计结构、驱动更多智能体。

作为软件工程师,你们真正的职责,是为智能体团队以及驱动这些智能体的人清除障碍,让它们能在长时间跨度内持续推进工作,把整件事真正做完。这里的核心假设是:你们每个人现在都相当于一名 staff engineer,手下有多少“团队成员”完全取决于你能并行驱动多少智能体,以及你有多少 token 可以支撑它们。你必须把眼光放到未来一天、一周,甚至六个月之后,去思考究竟该建立哪些结构,才能真正 harness 这份几乎无限的编码产能。 [00:04:31 -> 00:05:10]

我们今天在这个世界上看到的稀缺资源有三样。人类时间、人类和模型注意力以及模型上下文窗口。在这个人类时间和注意力稀缺的世界里,我们的任务是思考这些时间都花到哪里去了,想办法有效地自动化这些时间,并将这些同步的人类时间转移到更高效益的活动中。在一个人类时间稀缺,而编写代码又需要人类时间的世界里,我们有了堆栈排名。事物要么是 P0,要么是 P2。 [00:05:16 -> 00:05:50]

在他的视角里,代码便宜以后,很多过去永远排不到优先级的事,都有机会被做掉。

那些P3项目永远也完成不了。然而,在一个代码免费且无限丰富的世界里,所有这些 P3 都会立即被踢出局,甚至可能同时被踢出 4 局。我们选择一个能解决问题的方案,然后把它放进去。我有幸在 OpenAI 内部构建了大量的智能体,以提高同事们的工作效率。当代码是自由的,所有这些内部工具从一开始就可以实现良好的本地化和国际化。 [00:05:50 -> 00:06:22]

重要的已经不只是代码本身,而是引导模型写出好结果的文档、线索和指导原则。

我可以制作出我的同事在伦敦、都柏林、巴黎、布鲁塞尔、苏黎世和慕尼黑都能用他们的母语体验的工具,而无需真正牺牲我其他团队的能力来制作高质量的工具。我们应该始终秉持这样的假设:我们所熟知、所依赖、所秉持的软件工程中最优秀的部分,在我们可能构建的任何产品中都始终存在。人类不再需要关心具体实施细节。重要的不是代码本身,而是引导你到达那里的提示和指导原则。这就是为什么要留下线索、文档、ADR、以用户画像为导向的文档,来说明一份好工作应该是什么样的。 [00:06:22 -> 00:07:10]

如果想让智能体也具备这种能力,团队过去积累下来的标准和历史就必须被系统化。

所有工单和代码审查的历史记录。正是这个过程,才让您和您的团队获得了今天所拥有的代码和产品。为了让你的智能体也能做到这一点,就必须发生以下情况。你的工作是构建系统、软件和架构,使你的团队能够取得成功。为此,我们需要让那些推动实施的人员能够理解这些内容。 [00:07:10 -> 00:07:36]

这就是 Harness 的起点:用适合智能体的方式组织系统,让上下文更可读、让结果更可预测。

这意味着,你要用适合智能体的方式去组织系统。编写代码时要尊重上下文这种稀缺资源,并想办法让完成工作所需的 token 消耗更容易预测。这也意味着,尽可能让整个代码库保持一致,减少模型为了完成任务而不得不额外激活的注意力范围。在这个世界里,大规模重构是免费的,所以“把一切做得更一致”会变成一件非常划算的事。 [00:07:36 -> 00:08:07]

2. 主题演讲:什么叫好代码,必须被写成系统规则

现在再也不会出现那种长达六个月都无法完成的迁移任务了,因为你只需启动 15 个智能体就能推动这项工作完成。这就是所谓的迁移,对吧?我们现在可以完成它们了。快点。那挺好的。 [00:08:11 -> 00:08:22]

[掌声] [00:08:22 -> 00:08:28]

Ryan 接下来把问题压得更深:真正难的不是生成代码,而是定义“什么叫好代码”。

这里存在一个元认识论问题,那就是做好工作意味着什么,而做好软件工程师的工作是很难的。我们需要在行业内待上多年才能完全理解编写高质量、可维护、可靠的代码意味着什么,这样我们的团队成员才能在此基础上进行构建,从而为代码库积累杠杆作用,以便进行单个补丁。嗯,这可能需要围绕那些未明确规定的非功能性需求做出 500 个小决定,才能编写出好的代码。这些代理和模型在训练过程中已经接触过数万亿行代码,这些代码能够满足你能想象到的所有非功能性需求。因此,我们的工作就是明确这些非功能性需求,并以一种智能体能够理解的方式将它们写下来,以便他们能够明白,怎样才能做好一份合格的工作,从而生成一个合并的补丁。 [00:08:31 -> 00:09:28]

如果智能体写不出可接受的代码,人类的任务就不是代写,而是改进约束、修正环境。

如果智能体没有做到这一点,那么我们的任务就是改进并约束它们的输出,让它们写出的代码达到可接受标准。你甚至可以直接告诉它:不要产出垃圾代码,也不要接受垃圾代码。只要约束设置得当,代码库里的劣质输出就会显著减少。但要做到这一点,就需要承受短期的速度损失,以便回退或双击进入某个任务,找出代理在您的环境中遇到的困难。 [00:09:28 -> 00:09:55]

先设置一些防护措施,让他们不再犯这些错误,然后在短期内解决一些障碍之后,想办法退后一步,把时间花在更有影响力的活动上。当我考虑以这种方式赋能我的团队时,我认为每个人都是自己领域的专家。我拥有一支多元化的全栈团队,成员都是前端架构、后端可扩展性方面的专家,并且具备产品思维。这些不同的角色通过带来不同的理解和不同的解决方案来完善我的团队的技能组合,从而满足这些非功能性需求。让队友把这些写下来,实际上意味着每个负责代理的工程师都能充分利用团队中每个人的优势。 [00:09:55 -> 00:10:43]

这里其实已经点出 Harness 的核心:把人类经验沉淀成可复用的系统资产。

我不需要通过低信号代码审查来学习如何编写好的质量保证计划。让我的团队中的一名工程师以持久的方式记录下来,意味着每个代理的轨迹都会得到一个良好的质量保证计划。我们可以一次性高效地完成这项工作,然后在此基础上进行叠加。那么,我们如何才能让智能体做好工作呢?我们有哪些工具和技术可以有效地引导我们的智能体,并不断提醒他们,围绕这些非功能性需求做出我们期望的特定选择意味着什么? [00:10:43 -> 00:11:21]

他给出的入口很实用:从 AGENTS.md、规则文件和自动压缩能力开始。

有很多方法可以做到这一点。方法有很多。我们可以写出优秀的 AGENTS.md 文件。与此同时,随着自动压缩能力不断进步,GPT-5.4 和 Codex 在这方面已经做得非常好了。 [00:11:21 -> 00:11:35]

另一层关键点是:上下文会不断衰减,所以要持续刷新,而且刷新方式应该围绕“什么叫成功”。

我现在基本已经不再需要手动输入 /new 了。我在 X 上发过几张照片:把笔记本固定在车后座上,让它在通勤路上继续跑任务。在这个世界里,你必须接受一个现实:上下文会随着时间推移被不断压缩、淡出,所以我们需要在智能体执行任务的过程中持续刷新上下文。一个有效做法,就是让审查流程一路围绕“什么叫成功”来展开。 [00:11:35 -> 00:12:10]

Ryan 举的第一个 guardrail 例子很典型:把“超时和重试”这种 review 习惯,直接写成持续运行的审查机制。

对吧?我们的代码库里有负责安全性和可靠性的审查智能体,它们会在每次 push 和 CI 过程中持续运行,读取这些文档和待提交的补丁,然后做一些非常具体的检查。比如,这段网络代码有没有超时和重试?新引入的接口是不是足够安全、可靠,而且不容易被滥用?我相信在座很多人都处理过那种本来只要加上重试和超时就能避免的线上事故。我自己就犯过这种错,修 bug 的时候居然漏掉了这些机制。 [00:12:10 -> 00:12:51]

他给出的做法不是“下次注意”,而是“写一个 lint,把这个问题从系统里彻底消掉”。

对于这个非功能性需求,我不是可靠的代码审查员或编写者。然而,花时间编写一些文档,编写一个专门针对我的代码库的 lint,它会在我每次调用 fetch 时检查,以确保有重试和超时机制,这意味着我已经彻底解决了这个问题,而我之所以能够做到这一点,是因为我依赖于这个公理:代码是自由的,代理能够很好地完成工作,我可以完全迁移代码库,从而一劳永逸地彻底解决这个问题。为了以这种方式运作,我们需要退后一步,看看代码库中的代理和人类一次又一次犯下的那些持久性错误。弄清楚我们为什么要花时间做这件事。设计一个解决方案,系统地消除这类不良行为,然后继续观察、改进并对这些非功能性需求做出更多选择。 [00:12:51 -> 00:13:51]

这里再往前一步:代码库本身也应该为了模型去做工程优化。

我在这里使用的一个非常巧妙的技巧是,你可以编写与代码检查分开的源代码测试。正确的?如果我们知道上下文是有限的,我们可以编写一个测试,限制文件长度不超过350 行。我们正在调整代码库,使其与模型相匹配,进行一些工程优化,以提高上下文效率,并充分发挥我们现有模型的能力。 [00:13:51 -> 00:14:22]

错误信息也不只是报错,而应该直接给出下一步该怎么修。

我们还可以考虑提供良好的错误信息,为模型和用户提供实际的补救步骤,以便他们知道下一步该怎么做。仅仅说我们因为在循环中等待而导致 lint 失败,或者说我们在代码库的这个深处遇到了未知问题,以及为什么模型会编写一个名为 is record 的函数,这些都是不够的。我们需要做的是通过代码检查或测试失败来提供提示,告诉用户“不不不,这里根本不应该有未知类型”,因为我们在边缘进行解析而不进行验证,而且这里确实有一个类型,它是从我们人工智能未来的 Zot 承载基础设施派生出来的。你可以像这样提示,我今天在这里谈到的就是一个提示,你可以在完全不触碰模型权重的情况下做到这一点。这里有个有点意思的题外话:我们编写代码与这些模型交互的方式越复杂,我们取得的每一次进步似乎都来自于模型能力的提升,以及向这些模型中注入提示的越来越小众的方式。 [00:14:25 -> 00:15:36]

这段把 Harness 的注入点说得很清楚:system prompt、规则文件、skill、lint 报错、review agent 评论,都可以成为提示入口。

提示这件事,大家应该都很熟悉了。它可以来自 system prompt、规则文件、skill,也可以来自我刚才提到的 lint 报错信息,或者来自那些会在 PR 中自动注入评论的审查智能体。我们要求实现型智能体在提交 PR 之前,必须先把这些评论处理干净。把提示注入工作流的方法有很多,其中一种就是把 Agent SDK 嵌入测试里,让测试在运行时根据代码中的约束,判断这份补丁是否可接受。如果我发现自己花了很多时间反复写“如何写提示词”的提示,那我也可以把这件事本身交给智能体。我已经让 Codex 参考 OpenAI 开发者指南里关于 prompt 编写的建议,提炼出一套专门的写提示 skill。这样一来,当我在代码库里发现某个地方需要通过提示来提升智能体表现时,就可以直接调用这套 skill 生成更合适的提示。 [00:15:36 -> 00:16:45]

Ryan 还特别强调了产品思维工程师的价值:他们能把 QA 计划写成可持续复用的标准。

你以这种方式将所有这些优势编码到你的存储库、你的团队和智能体中,可以产生非常好的效果。这让我意识到,我们团队中一位具有产品思维的工程师能够给我们带来巨大的帮助。他们知道如何编写一个好的质量保证计划。要编写一个好的质量保证计划,你必须记录你拥有的所有功能、关键用户旅程以及用户如何与你的应用程序、Web应用程序、API和服务进行交互。一旦你把如何编写一个好的质量保证计划的要点写下来,并期望所有面向用户的工作都有一个质量保证计划,那么审核人员就可以提出期望,证明你已经有效地编写了该功能。 [00:16:47 -> 00:17:33]

目标并不是让人盯得更紧,而是让智能体拥有完成完整工作所需的工具、token 和上下文。

质量保证计划会说明一个 PR 应该附带哪些材料,才能让人和智能体都知道“这项工作已经做完整了”。这样我就能更信任最终结果,也能进一步减少自己对智能体执行过程的干预。整个流程的目标,都是为了确保智能体拥有完成完整工作所需的工具、token 和上下文,让我不再需要充当那个同步驱动一切的人。这些模型本质上就是渴望更多 token。我们完全可以通过重构代码库、引入子智能体以及其他工程手段,为它们提供更好的上下文条件,从而持续提升输出质量。 [00:17:33 -> 00:18:20]

演讲最后的落点也很清楚:让自己从执行层抽离出来,让智能体去完成完整工作。

今天我真正想传达的是:你完全可以按自己的方式去创造东西。别犹豫,放心让智能体把整件工作做完,让自己从执行层抽离出来,因为它们已经具备这个能力。 [00:18:22 -> 00:18:39]

3. 访谈上半场:工作流、skills 和渐进式上下文

访谈的第一组问题,集中在一个很实际的话题上:当你几乎不亲手写代码时,真实工作流到底是什么样。

Ryan,你能不能先讲讲,在你几乎不亲手写代码的情况下,真实工作流到底是什么样的?你通常是怎么接一个任务、再把它交给智能体推进的? [00:19:41 -> 00:20:13]

Ryan 的回答也很明确:工作流的起点不是编辑器,而是工单。

你的配置是什么?你会怎么着手处理一个任务?当然。我们团队的工作方式,基本都是从工单开始。可能是一个要上线的功能,也可能是一项可靠性改进,或者是某个应用能力的迭代。 [00:20:13 -> 00:20:30]

他们的设计原则不是“给应用再包一层壳”,而是让 Codex 直接成为入口点。

我们会把工单直接交给智能体,再给它配上一组 skill,让它能真正操作我们的应用。我们的目标是让开发流程的入口始终是 Codex,而不是某个我们额外包在外面的壳。换句话说,我们是从外向内设计这套系统的。Codex 是入口点,我们给它工具,也给它操作说明。与其搭一个大而全的外部环境,不如通过 skill 直接教 Codex 怎么启动应用、怎么拉起本地可观测性栈,从而获取日志和遥测数据。 [00:20:30 -> 00:21:06]

这段最关键的信息是:他们搭建本地开发工具链时,默认第一个调用它们的就是 Codex。

我们还给它一项 skill,让它可以启动 Chrome DevTools,并通过本地 CLI 接入应用;这个 CLI 背后再通过一些 daemon 进程完成连接。也就是说,我们搭建整个仓库和本地开发工具链时,默认假设第一个调用它们的就是 Codex。这也意味着,代码库里会有很多小型组件,便于我们持续添加新的护栏。比如一整套自定义 ESLint 规则,会被接入工作区里的每个 PNPM package;我们还有另一类本地开发工具,可以做更高层的结构性测试,校验的不是语法或运行行为,而是代码本身的组织方式。 [00:21:06 -> 00:21:56]

这些结构性检查的意义,不是更严格,而是把低价值 review 问题直接前置消灭。

比如 package-private 依赖关系、技术栈不同层之间的边界,或者确保某个 zod schema 不会在多个文件里重复出现,某个异步 helper 只有唯一的规范实现。之所以要做这些,是因为我们观察到智能体有时会为了局部一致性,重新造一个近似实现,而不是复用已有工具。发现这种模式之后,我们就补了一批小型的结构检查工具,把这些坏习惯直接拦掉,避免人类在 review 时继续为这种低价值问题分心。 [00:21:56 -> 00:22:38]

这里也回答了一个常见误区:skill 的价值不在于越多越好,而在于把复杂性稳定封装进去。

这套做法的好处是,它优化的是智能体的工作方式,而不是要求人类持续跟上代码库的高频变化。我们真正依赖的核心 skill 大概只有 5 到 10 个,不会无限扩张。相比不断新增 skill,我更倾向于持续打磨已有的 skill,因为基础设施和本地开发工具变化太快了,人根本不可能每次都手动跟进。我们做的是把复杂性封装进 skill 里,让智能体自己去消化。一个很典型的例子是,我们后来从直接使用 Chrome DevTools Protocol 切到另一套方案时,我大概有三周都没意识到这件事已经发生了。 [00:22:38 -> 00:23:28]

整个过程都很顺,因为 Codex 会自己利用现有文档和上下文把事情做下去,文章里也写了更多细节。你那篇《Harness Engineering》里专门有一节讲 skill:究竟应该做成成百上千个 skill,还是尽量收敛成少数几个核心 skill。顺着这个问题往下问,你怎么避免把 harness 设计得过于复杂?以及,你们会不会经常给自己补一些小工具? [00:23:28 -> 00:24:00]

Ryan 认为最不容易过时的部分,不是技巧,而是上下文管理本身。

你们会开发定制工具吗?会。但这里真正要吸取的教训是:怎样才能确保自己今天做的这些工作,不会因为模型能力提升而迅速过时?我的答案是,去做最基础、也最不容易过时的上下文管理,把“完成一项可接受任务到底需要哪些要求”这件事沉淀下来。 [00:24:00 -> 00:24:28]

他说得很直白:上下文永远不会过时,关键是要在正确的时间给出正确的文本。

我认为上下文永远不会过时。模型必须被明确告知任务要求,而 harness 的职责就是在合适的时候把这些要求递到它面前。模型本质上就是被训练来遵循指令的,所以一个好的 harness,核心不是“塞更多说明”,而是在正确的时间提供正确的文本。 [00:24:28 -> 00:25:03]

这段其实就是 progressive disclosure 的最好例子:先做原型,再在后面阶段注入更细的约束。

你不应该在一开始就把所有指令一股脑塞给智能体,那样只会把它淹没。但在整个 PR 过程中,凡是关于“什么叫好工作”的要求,最终都应该被逐步触发。一个好的 harness,应该做的是延迟注入、按需注入这些说明。比如你希望 React 组件被拆得更细,尽量无状态,便于做快照测试,那就没必要在最开始把这些约束全部预加载进去。你可以先让智能体完成原型和初步实现,再在 lint 或测试阶段告诉它:现在你已经把大部分工作做完了,接下来需要把组件进一步拆分,让它们更小、更无状态,并且优先通过 hook 管理本地依赖,而不是层层传 props。 [00:25:03 -> 00:25:46]

4. 访谈中段:协作、代码审查、代码库结构与角色迁移

智能体这时会意识到:这是一条新指令,我需要基于现有补丁再做一轮调整,让结果符合这些要求,然后再把它提交到 GitHub。这样的工作方式,不会因为模型能力继续提升就失效。 [00:25:46 -> 00:26:11]

关键就在于:在正确的时间,把正确的文本和上下文交给智能体。再往下一个相关问题是,很多人都在问 Codex 模型和 Codex 框架本身,以及它和其他框架相比到底有什么差别。 [00:26:11 -> 00:26:28]

你们怎么看这个问题?虽然你不直接做 Codex 本身,但能不能谈谈你理解里的 Codex 框架,以及这种框架在架构设计里意味着什么?我觉得一个很关键的点是,实验室不只是训练模型本身,它们也会针对模型实际运行的框架上下文做后训练优化。比如补丁工具怎么用、Bash 工具的调用语义是什么,这些都会进入模型实际表现的一部分。正因为第一方框架本身参与了后训练过程,直接依赖这些第一方框架往往会有天然优势。 [00:26:28 -> 00:27:11]

至少我是这么看的。所以,不管是通过 SDK,还是更直接地接入 Codex 的应用服务端,只要你能沿着它原生的使用方式去引导它,就能更充分地吃到这些后训练带来的优势。这样一来,你自己的注意力就可以集中在更重要的部分,比如“什么样的代码才算正确”。至于 Codex 自身的框架能力会怎么继续演进,我对此很有信心,那本来就是这些编码智能体团队的职责。 [00:27:11 -> 00:27:44]

所以,我的工作重点并不是自己去造一个编码框架,而是找到接入这些框架、并把智能体引导好的方法。这也意味着,我更应该关注不同模型版本之间的行为差异,而不是一头扎进底层实现细节里。我要关心的是“我观察到了什么行为、我想要什么行为”,而不是“它内部为什么这样工作”。这也自然引出了下一个问题:在协作平台上,你有什么推荐? [00:27:44 -> 00:28:21]

说到协作平台,Ryan 的答案很朴素:仓库和 GitHub 里的 Markdown 文件,本身就是协作中心。

在软件开发生命周期中,您是否使用任何平台供代理、工程师和开发人员协作完成任何工作?有什么建议或工具吗?是的。目前,我们主要使用仓库和 GitHub 中的 Markdown 文件作为中心辐射型平台。想想看,在 Google Docs 中协作处理文档,你打开文档,写一些东西,征求反馈,其他人评论,你采纳建议等等。 [00:28:21 -> 00:28:55]

这里很关键:PR 不只是代码提交入口,而是人和智能体共同工作的“洁净室”。

这就像是围绕某个具体工作成果搭出来的一间小型“洁净室”。PR 也承担着类似作用。所以我们把它看成一个 hub-and-spoke 式的协作广播域,所有人和智能体都围绕它协同工作。由于我们优化的是吞吐量,而不是每一步都卡死审批,所以没有任何一次贡献会天然被阻塞。人可以选择要不要审查。 [00:28:55 -> 00:29:19]

智能体也一样,可以选择审查,也可以选择不审查。实现型智能体可以接受、延后处理,甚至拒绝某条反馈。这样做的好处是,差异生成过程中的每个参与者,都可以自行判断该如何提供、接收和响应反馈,而不是被硬编码成单一路径。我们希望模型保留足够的推理空间。 [00:29:19 -> 00:29:47]

他也明确反对把每一条反馈都变成必须机械执行的命令。

如果你要求每一条反馈都必须机械处理,反而可能导致编码智能体被所有审查者“围殴”,最后走向灾难性失败。我们真正想要的,是代码能够被接受,而不是无限追求完美、陷进细节泥潭。接下来一个更现实的问题是:那些长期亲手写大量代码的人,应该怎么开始过渡到这种工作方式? [00:29:47 -> 00:30:17]

对普通工程师,他给的起点也很务实:先用编码智能体增强你对现有代码的信心。

他们怎么跨过“我还是得检查每个 PR,还是得从 Codex 里复制粘贴代码”的心理障碍?普通工程师到底该如何开始?我觉得有两条路。一条路,是先用编码智能体增强你对现有代码的信心。 [00:30:17 -> 00:30:39]

我想我们都会同意,更多的测试肯定是件好事,对吧?确保我们的程序规范明确,并且在用户交互时行为正确,这当然是好事。而且,这些代理非常擅长结合代码的预期用途来分析现有代码,并编写测试来验证其行为。因此,使用编码智能体来增强你对代码质量的信心,也能提高代理成功识别代码的能力,这意味着你无需花费太多精力去仔细审查代理的输出结果。另一种思考方式是审视你如何分配时间。 [00:30:39 -> 00:31:21]

你是盯着编辑器写代码吗?是在等待测试运行吗?是在等待人工审核反馈吗?持续集成(CI)流程缓慢,你是否在等待?或许你有很多不稳定的测试,而你可以使用代理来逐步自动化那些耗时的部分。 [00:31:21 -> 00:31:38]

他的逻辑始终一致:人类最该做的是定义工作、排优先级、做编排,而不是反复盯执行。

你的时间很重要,因为我们工作的重中之重在于定义必须完成的工作,确定工作的优先级并安排时间,然后有效地授权团队成员完成这些工作。嗯,如果我们能够委派的任务越来越多,并且更多地扮演排序和编排的角色,即使你只是考虑如何管理你的团队,那么我们就能更并行、更深入地执行这些委派的任务。如果我预先设置了一些基本功能,可以非常轻松地启动响应Kafka 队列事件的方法,那么我就不需要和每个工程师一起仔细检查他们是否正确地实现了消费者。这些类似的构建模块式技术也同样适用于代理,并且可以很好地堆叠。 [00:31:38 -> 00:32:30]

你是如何在车里使用代理的?嗯,我还没有使用最近在 CarPlay 中推出的新语音模式。我还没准备好。但我通常会离开办公室前启动一个任务。 [00:32:30 -> 00:32:49]

“在车里跑任务”这段听起来像段子,但其实是在讲一个目标:尽量减少人类同步介入。

呃,我会把笔记本电脑连到手机上,固定在后座上,让它在我回家那 30 分钟里自己慢慢跑。大多数时候,我们调用的 skill 会直接告诉智能体:把任务一路做下去,直到测试通过为止。这样我就不需要不停伸手去按“yes, continue”。本质上,我是在尽可能把自己的时间用 token 消耗填满。我的理想状态是:有 50 个智能体 24 小时不停运转,而我几乎不需要和它们交互。 [00:32:49 -> 00:33:20]

这句非常值得单独记住:每次你不得不对代理说“继续”,都是 harness 没有提供足够上下文的一次失败。

呃,实现这一点的方法是很好地定义工作,找到自动安排工作的方法,这样我就不用点击按钮了。对吧?每次我不得不输入“继续”给代理,就好像安全带没能提供足够的上下文信息来解释“继续完成”的含义一样。每次你必须与代理交互,都是失败。 [00:33:20 -> 00:33:43]

随着组织知识图谱的扩展,你需要采取哪些实际步骤来实现渐进式披露?随着代码库越来越大,人员越来越多,你如何扩展代理以更好地适应这种情况? [00:33:43 -> 00:34:03]

说到代码库扩展,Ryan 的教训也很直接:单 package 很快就会乱掉,因为对智能体来说边界不够清晰。

我刚开始做这个项目时,是从一个空白仓库起步的,然后直接建了一个 Electron 应用,基本就是单 package 结构。最后很快就乱掉了。因为没有包级私有边界,我没法强制规定哪些 API 是公开的、哪些不是。对智能体来说,文件系统里也没有足够明确的“钩子”,让它知道哪些领域彼此独立、哪些不该混在一起。 [00:34:03 -> 00:34:30]

所以他的结论是:即使你没有微服务,也要把代码仓库结构化到足够让智能体读得懂。

所以我们最后走向了一个更“重架构”的组织方式,几乎像是在模拟一家一万人工程组织的代码结构。我们的 PNPM workspace 里有数百个 package,按业务领域和技术栈层次隔离;同时还有很多小型 util package,用来封装可复用能力,并通过 lint 强制这些能力被统一复用。我越来越相信,在这个时代,即使你并没有真正采用微服务,只要代码仓库的结构足够清晰,让智能体能够把改动范围收敛到某个目录子树里,大多数变更的质量就会明显提升。别忘了,文件系统里的代码本身也是文本,而文本本质上就是你给编码智能体的提示。所以,尽可能让代码长得一致,才能让智能体无论看向仓库的哪个位置,都能获得可迁移的上下文。 [00:34:30 -> 00:35:30]

比如,你应该只有一种方法来编写有界并发辅助函数。你应该只有一种方法来构建可观察的、带有侧效应的命令。你应该只有一个对象模型( OM),对吧?你应该只有一种编程语言。你应该只有一种编写持续集成(CI)脚本的方法。 [00:35:30 -> 00:35:47]

你应该只有一种方法来添加额外的代码检查规则,等等。因为这意味着,无论模型在哪里查找,你希望它生成的标记都更容易预测,预测结果也更一致。所以,我的建议是,找到一些方法来……将代码结构化,使其在仓库的子仓库中本地化,以便与系统进行大多数交互,然后找到一种方法,利用这些代理将代码库完全迁移到相同状态。你知道,授权团队中的某个人担任独裁者,宣布必须这样做,对吧? [00:35:47 -> 00:36:17]

或者,你知道,大家一起想办法,把它写下来,不断改进代码,使其反映实际情况,诸如此类。我们有一些关于代码审查的问题。现在你们的开发速度如此之快,你们是如何进行代码审查的?呃,你们是不是根本不看代码?你们是不是只相信测试覆盖率? [00:36:17 -> 00:36:36]

呃,你们是如何编写好的测试的?你们是如何克服那种心理障碍的?比如,我需要在合并代码之前手动检查所有内容。所以,同样的道理,你需要审视自己把时间花在了哪里,并找到减少时间的方法。呃,你知道,我们刚开始的时候,对吧,第一件事就是弄清楚…… [00:36:36 -> 00:36:59]

如何让代理可靠地生成我们认可的代码?我们遇到的一个大挑战是,即使是三人团队,每个工程师每天也要提交三到五个 PR ,合并冲突就非常棘手,对吧?因为这些 PR 通常都很大。我们当时在处理代码库的同一部分。所以我们从两个方面着手。 [00:36:59 -> 00:37:21]

他们解决 review 瓶颈的方式也很典型:不是多加人,而是把反馈回写成系统闭环。

一方面,我们把代码树拆得更细,尽量降低合并冲突;另一方面,我们也在想办法缩短 PR 挂着不合并的时间,因为 PR 开得越久,冲突概率就越高。而 PR 之所以长期不关,根本原因往往是代码审查需要人类介入,人成了瓶颈。为了解决这个问题,我让团队里每个工程师每周拿出一天,也就是周五,我们把它叫作“垃圾回收日”。这一天唯一的工作,就是把一周里所有导致 PR 难以合并的“垃圾问题”集中找出来,再设计办法,从源头上彻底消灭它们。于是,一个闭环就建立起来了:人类在 PR 里给出的反馈,本质上是在暴露智能体缺失了哪些上下文。我们把这些信息写回代码库,再通过失败测试或自动注入的审查提示把它们重新喂给智能体,让它在下次出现类似行为时可以自我修正。 [00:37:21 -> 00:38:27]

这段其实就是第二部分里那句“反馈回写”的原始出处。

这背后的核心,就是把原本需要人同步给出的代码审查反馈,逐步迁移成代码库里的文档,再通过失败测试或预先配置好的审查智能体,自动把这些文档“冲浪”出来,放进当前代码的上下文里进行检查。要做到这一点,前提是这些文档必须集中放在一个所有流程都能挂接上的位置。我们还要求团队把 review 反馈按角色归类,比如前端架构师、可靠性工程师、可扩展性工程师等等。然后为每一类角色都配一个 review agent,在每次 push 时自动触发,判断这份代码是否足够好,并找出所有会阻止 PR 合并的 P2 及以上问题。 [00:38:27 -> 00:39:21]

5. 访谈下半场:token、plan mode、代码可抛弃性与未来愿景

接下来话题转到很多人最关心的:这些 token 到底花在什么地方。

随着这些文档不断被补充,我们开始看到“垃圾代码”越来越少。接下来大家也很好奇:你每天花掉的这十亿个 token,主要都用在什么地方?其中有多少是花在代码审查上的? [00:39:21 -> 00:39:38]

还有一个给初学者的追问。假设有人已经买了 200 美元的 Pro 套餐,如果被迫把使用量砍掉五分之一,应该怎么把 token 用得最值?毕竟谁都会遇到配额限制。 [00:39:38 -> 00:39:52]

Ryan 的估算很有代表性:token 大致会分散在规划文档、具体实现和 CI 持续运行这三类事情上。

你显然不想每隔六个小时就手动复制粘贴一百万行代码,也不想一直浪费 prompt cache。那么这件事该怎么想?我的粗略估计是,大概可以按三分法来理解:三分之一用在规划、工单整理和文档,三分之一用在具体实现,三分之一用在 CI 里持续跑的那些流程。 [00:39:52 -> 00:40:18]

他对 plan mode 的看法也很鲜明:如果人根本不会认真读计划,那提前生成计划反而可能编码错误指令。

你们会用 plan mode 吗?我们早期用过一种 exec plan,有点像一个原型版 skill,用来告诉智能体应该如何写出带里程碑和验收标准的计划。但在我的 harness 里,我其实几乎不用 plan mode。我的预期是,我应该把工单扔进去,它就能直接把活干完,而不需要先绕一圈写计划。 [00:40:18 -> 00:40:42]

他的建议不是不用计划,而是如果要用,就把计划也当成一个需要严格 review 的工件。

因为大多数情况下,我根本不会去看计划。所以,我发现如果你使用了计划,却在完全不看的情况下就批准了它,实际上你是在编码一堆你并不一定想执行的指令。所以,如果你要使用计划,我的建议是将它们作为单独的 PR 提交,只包含计划,并让人工审核计划的每一行,在合并和启动之前,需要人工批准才能生效。因为如果你使用计划,你实际上是在浪费时间发布一些错误的指令。所以,你要尽量减少这种情况的发生。 [00:40:42 -> 00:41:21]

这里有个非常关键的判断:真正难的不是写出代码,而是让代码被接受、被验证、继续推动产品往前走。

但我认为,获取用于持续集成 (CI) 的token是必要的,因为编写代码……耗时更长才是难点。比如,代码被接受,以及推动代码和产品向前发展,这才是让编写的代码真正有价值的关键所在。大家都听说过“高级工程师会给出高质量的代码审查”这种说法,我们也希望我们的高级工程师作为代理能够做到这一点。有人问,代码是可抛弃的构建产物吗? [00:41:21 -> 00:41:53]

他的回答也很有代表性:代码可以被看成可抛弃的构建产物,而规范更像真正稳定的源头。

是的。我认为我们在 Symphony 里已经探索过这个问题。Symphony 是我们发布过的智能体编排器。我们的思路是:库本身更像一份定义非常明确的规范,而代码只是这份规范“编译”出来的产物。我觉得,把 LLM 看成一种模糊编译器,是个很有意思的思维模型。 [00:41:53 -> 00:42:19]

“LLM 是模糊编译器”这一段,其实把 Harness 的作用讲得很形象:上下文、规则和结构就像编译前的约束与优化过程。

我们在代码库中为框架工程添加的所有上下文实际上就像是约束和优化步骤,决定哪些代码可以构建。这与LLVM在编译 Rust 代码过程中进行的静态分析和优化步骤非常相似,只不过是用一种模型替换了另一种模型。这有点像把 Rust 编译器的代码生成后端从 LLVM 换成 Cranelift。你仍然会期待,所有关于 Rust 代码规范的规则都能成立,后端依然能生成有效的机器码,只是生成过程不同,最后吐出的 x86 指令可能不一样。LLM 也是类似的思路:你只是换了一个“后端模型”。我们希望代码的结构能够限制代码的编写方式,使其符合我们的标准。 [00:42:20 -> 00:43:21]

访谈最后回到未来图景:给定预算和目标后,把季度、半年甚至一年的工作持续交给机器推进。

从宏观层面来说,你能给我们描绘一下你正在构建的未来吗?上下文仍然重要吗?人们如何进行工程、利用工程、进行上下文工程?未来会是什么样子?我想要实现的功能是,我可以用有限的预算和季度、半年甚至一年的工作量,结合人工反馈来确定最重要的成功指标和可靠性指标,然后交给机器,让它们持续运行并推进我的产品发展。 [00:43:21 -> 00:44:01]

呃,完全不需要我亲自干预。正如我们之前所经历的。从早期原型到内部 alpha、内部beta、外部 alpha,我感觉软件工程流程的新环节就像是从零开始,我们不得不逐步构建能力,就像能力雷达图一样,比如“我这边很厉害,那边可能比较弱”。你知道,当我们第一次部署软件时,代理在产品发布前进行 QA 冒烟测试的能力很弱。我们之前没有在这方面投入任何时间。 [00:44:01 -> 00:44:45]

他也明确说,真正的未来并不只包括写代码,而是包括 QA、用户反馈、运维支持、日志合规这些完整的软件工程工作。

没有文档,也没有任何工具可以让代理下载产品、启动它,并进行各种检查,以确保我们最关键的用户流程都经过了充分的验证和测试。所以,因为我不想碰电脑,我们需要找到方法让代理自己构建工具来完成这部分工作。而且,除了编写代码之外,软件工程还有很多其他方面,对吧?比如,我还要对用户反馈进行分类,对页面进行分类等等。我正在确保生产环境中的日志不会泄露任何个人身份信息 (PII)。 [00:44:45 -> 00:45:21]

所以他的最终落点不是“人类不重要了”,而是人类可以把精力转到更高层次、更高杠杆的工作上。

我正在确保Twitter 上的氛围良好,用户喜欢我的软件,并且我们的用户运维人员拥有完善的运行手册支持,以便他们能够对大量用户问题进行分类和缓解,然后将这些功能集成到代码中,从源头上避免问题的发生。由于我不再需要编写代码,我的精力可以转移到其他更高层次或更灵活的工作上,但智能体也足以胜任这些工作。 [00:45:21 -> 00:45:49]

最后一句其实可以当整场访谈的总结:写流程、写验收标准,会越来越像软件工程里的“元编程”。

利用这些智能体编写流程和验收标准,就成了工作中类似元编程的部分。 [00:45:56 -> 00:46:01]


AI 趣实验 出品 (全平台同名)

谢谢你读我的文章,既然看到这里了,如果觉得不错,关注我,顺手点个赞、在看、转发三连吧~