缰绳工程:当人类掌舵、Agent 执行时,如何构建软件
OpenAI 技术团队成员 Ryan Lopopolo 提出:代码已经免费了。工程师的角色正从写代码转变为设计缰绳——为 Agent 构建工作环境和约束条件。本文详解非功能性需求定义、知识沉淀、上下文刷新和 Prompt 注入等核心实践,并附 Q&A 精选。
引言
Ryan Lopopolo 是 OpenAI 的技术团队成员,过去九个月里,他专门使用 Agent 来构建软件——甚至禁止团队成员触碰编辑器。他每天消耗超过十亿个输出 token,自称"token 亿万富翁"。
在这场演讲中,他提出了一个核心观点:代码已经免费了。工程师的角色正在从写代码转变为设计缰绳(harness)——为 Agent 构建工作环境和约束条件,让 Agent 完成全部的软件工程工作。
代码是免费的
在过去六个月里,coding Agent 的能力以极快的速度提升。我们已达到这样一个阶段:实现不再是软件工程工作的稀缺资源。
在人类时间稀缺的世界里,任务要么是 P0 要么是 P2,那些 P3 永远不会被完成。然而,在代码免费且无限充裕的世界里,所有 P3 都会立即启动,可能是 4 倍并行。我们选择一个能解决问题的方案,就完成了。
当代码免费时,所有内部工具从一开始就可以有很好的本地化和国际化支持。我们可以让全球各办公室的同事用母语体验工具,而不必与其他团队的产能做任何权衡。
重要的不是代码,而是让你到达那里的 prompt 和护栏。
三样稀缺资源
我们今天这个世界稀缺的资源有三样:人类时间、人类和模型的注意力、模型的上下文窗口。
工程师的角色正在转向系统思维、系统设计和授权。每个工程师都拥有尽可能多可以同时驱动的团队成员(Agent),需要展望一天、一周、六个月后,搞清楚需要建立什么结构来有效地驾驭这种无限的代码生成能力。
让 Agent 做好工作的核心原则
明确非功能性要求
做好一份软件工程工作可能需要 500 个小决策,围绕那些未明确定义的非功能性要求。Agent 在训练期间看到了数万亿行代码,做出了你能想象的每一个可能选择。
因此,我们的工作是明确这些非功能性要求,以 Agent 能看到的方式写下来。如果 Agent 没有产生可接受的代码,我们的工作是完善和限制它们的输出。
你完全可以简单地说:不要生成垃圾代码,不要接受垃圾代码。你的代码库就不会有垃圾代码。
面向角色的知识沉淀
让每个团队成员记录他们擅长的领域知识,意味着每个驱动 Agent 的工程师都能获得整个团队的最佳知识。
一个具有产品导向的工程师知道什么意味着编写好的 QA 计划。让他以持久的方式记录这一点,意味着每个 Agent 都会遵循好的 QA 计划。我们可以一次性以高杠杆的方式完成,并在此基础上叠加。
持续刷新上下文
在 Agent 执行任务的过程中,上下文会随时间被分页出去。我们需要持续刷新上下文。
方法包括:让审查 Agent 通过成功的视角审查代码。Ryan 的代码库中有安全性和可靠性审查 Agent,它们作为每次推送和 CI 的一部分持续运行,检查网络代码是否有超时和重试,引入的代码是否有不可能被误用的安全接口。
适配上下文窗口
我们可以编写关于源代码的测试,让代码库适应缰绳和模型。比如,编写一个限制文件不超过 350 行的测试,榨取模型能力的更多价值。
提供好的错误消息,为模型和人类提供实际的补救步骤。通过 lint 或测试失败提供 prompt,告诉模型应该怎么做。
Prompt 无处不在
Ryan 分享了一个有趣的观察:代码交互复杂度的每次进步,都来自两方面——模型能力的提高,以及向模型注入 prompt 的越来越小众的方式。
Prompts powers、rules 文件、skills、lint 错误消息、审查 Agent 注入到 PR 的评论——这些都是 prompt。你可以将 Agent SDK 嵌入到测试中,使用嵌入代码中的 prompt 审查代码库的可接受性。
Ryan 甚至让 CodeX 看着 OpenAI 开发者指南上的 prompt cookbook,综合出一个关于如何编写 prompt 的 skill。用 Agent 写 prompt 来指导 Agent。
Q&A 精选
问:你实际的工作流程是怎样的?
我们从工单开始。把工单交给 Agent,同时给它一些能够操作应用的技能。我们希望开发流程的入口是 CodeX,而不是围绕它构建的环境。我们在代码库中有一堆小型的 mini 缰绳,让我们能够非常容易地插入额外的护栏。
我们围绕 5 到 10 个技能集中杠杆,不会在技能上做得太宽泛。所有复杂性都隐藏在技能之下,让 Agent 自己去弄清楚。
问:如何避免过度设计缰绳?
好的缰绳是在正确的时间给模型提供文本。模型被训练来遵循指令,缰绳应该做的就是在正确的时间将指令呈现给模型。
你不想把所有指令都前置加载,因为那样会让 Agent 不知所措。应该想办法推迟或及时呈现指令。比如,不需要预先告诉 Agent React 组件应该如何拆分,而是在 lint 或测试时再给出这个要求。
这种做法不会因为模型能力的提升而被淘汰,它只是关于在正确的时间给 Agent 正确的上下文。
问:你如何在通勤时使用 Agent?
我通常在下班前启动一个任务,把笔记本电脑连到手机上,放在后座,在回家的 30 分钟里让它自己跑。Skills 会告诉 Agent 一直跑到测试通过。
理想状态是 50 个 Agent 全天候运行,我根本不需要与它们交互。每当我必须向 Agent 输入"继续"时,就是缰绳的失败。
问:代码库越来越大,如何扩展 Agent?
即使你没有微服务,也应该以某种方式构建仓库,使你能够将目录子树限定为能够完成大部分更改。文件系统中的代码也是 prompt,让代码尽可能相同,让 Agent 无论在仓库的哪个地方都能获得可转移的上下文。
你应该有有界并发助手、可观察的命令、ORM、编程语言、CI 脚本方式、额外的 lint 规则——这些事情让模型生成的 token 更容易预测。
问:速度这么高,如何处理 code review?
每周五,我们称之为"垃圾回收日",全部工作是获取一周中观察到的每一处混乱,找出从根本上消除它的一劳永逸的方法。
我们将审查反馈分类到不同的角色(前端架构师、可靠性工程师等),然后为每个角色启动一个 review Agent,在每次 push 时触发。通过这个和不断追加文档,我们开始看到混乱持续减少。
问:Token 使用如何分配?
大约三分之一规划、三分之一 ticket 策划和文档、三分之一实现和 CI。我认为让 token 在 CI 中花费是必要的一部分,因为写代码不再是困难的部分。让代码被接受并推进产品向前,才是使代码有价值所需要的。
问:代码是一次性构建产物吗?
使用 LLM 作为模糊编译器是一个有趣的心理模型。代码库中为缰绳工程放入的所有上下文,都是关于哪些代码可以首先被构建的约束和优化过程。这与 LLVM 在编译 Rust 代码时所做的静态分析和优化非常相似。
结语
Ryan 想要构建的未来是:拿一个 token 预算和一个季度的目标,拿人类输入来排名最重要的成功指标,把它给机器,让它们持续工作推进产品向前。不需要人类的手明确地在方向盘上。
写代码之外有一整个软件工程宇宙——分类用户反馈、确保 PII 不泄漏、用户运营支持。当他不再需要产生代码时,他的头脑可以转向这些更高层次的活动,而 Agent 也足够好来做这些事情。
他的建议很简单:毫不犹豫地通过让 Agent 做全部工作来将你们自己从循环中移除。因为它们可以。





