jixiaxue 知识库
blog / openai-blog · 2026-03-11-harness-engineering-codex

工程技术:在智能体优先的世界中利用 Codex

1 个章节 · 0 条产出 · 1 条证据
2026-03-11

工程技术:在智能体优先的世界中利用 Codex

来源: OpenAI Blog | 作者: Ryan Lopopolo(Codex 技术人员)| 日期: 2026-03-11 原文链接: https://openai.com/zh-Hans-CN/index/harness-engineering/

一句话总结

当代码全部由 Agent 生成时,工程师的核心任务不再是写代码,而是设计让 Agent 能可靠工作的环境、反馈回路和控制系统;Codex 团队用五个月、零人工代码产出约 100 万行代码和 1,500 个 PR 验证了这条路径。

速览

  1. 人类掌舵,智能体执行——五个月、约 100 万行代码、~1,500 PR,没有一行人工编写的代码;团队从 3 人扩到 7 人,吞吐量反增。
  2. 瓶颈不是 Agent 能力,而是环境规范——早期进展慢,是因为工具、抽象、结构不够明确,不是 Codex 不会写。
  3. 情境是稀缺资源,给地图不给百科全书——AGENTS.md 保持在 ~100 行作为目录,深层知识存在结构化的 docs/ 里,渐进式披露。
  4. 仓库即一切,Slack/Docs/脑子里的知识等于不存在——运行时 Agent 情境之外的信息都无法被访问;一切必须 checked in。
  5. 强制不变量,不微观管理——用自定义 linter 把规则机械化(架构层级、命名、结构化日志),错误信息里直接注入修复指令。
  6. 让 UI、日志、指标对 Agent 直接可读——Git worktree 启动 app、Chrome DevTools 接入、临时可观测性堆栈(LogQL + PromQL),把人类 QA 从瓶颈中解放。
  7. 最小化阻塞合并门——Agent 吞吐量远超人类注意力时,等待成本 > 纠错成本;测试偶发失败重跑而非阻断。
  8. 端到端自主闭环已跑通——Codex 可独立完成:复现 bug → 录视频 → 修复 → 再录视频 → 开 PR → 回复反馈 → 修构建 → 合并,仅在需要判断时找人。
  9. 技术债务像高息贷款,持续小额偿还——把”黄金原则”编码进仓库,后台 Codex 任务扫描偏差并发起小型重构 PR,替代每周五 20% 时间集中清理。
  10. 支撑结构比代码本身更重要——纪律更多体现在文档、linter、反馈回路和架构约束上,而非代码风格。

核心内容

一、工程师工作重心:从写代码转向造环境

实验从 2025 年 8 月下旬的空仓库开始。初始架构(仓库结构、CI 配置、格式化规则、包管理器、应用框架)由 Codex CLI + GPT-5 基于一小套现有模板生成,连指导 Codex 工作的初始 AGENTS.md 都是 Codex 自己写的。

人类几乎只通过 prompt 交互:描述任务 → 运行 Agent → 让它开 PR → 指示它本地审查、请求额外智能体审查、响应反馈,一直循环直到所有审查者满意(作者称之为 “Ralph Wiggum 循环”)。Codex 直接使用 gh、本地脚本和仓库内嵌技能收集情境,人类不需要复制粘贴任何内容到 CLI。

过去五个月的产出规模:约 100 万行代码,约 1,500 个 PR 被开启并合并,团队从 3 名工程师扩展到 7 名,每人每天平均处理 3.5 个 PR。产品已交付给数百名内部 alpha 用户,其中包括每天使用的高级用户。

团队核心理念:不手动编写代码。由于没有人工编码实践,工程师工作的重点转向系统、架构和杠杆作用。

早期进展比预期慢,根因不是 Codex 能力不足,而是环境规范不够明确——Agent 缺少实现高级目标所需的工具、抽象层和内部结构。解决路径是深度优先:把大目标拆成小的构建模块(设计、代码、评审、测试),让 Codex 构建这些模块,再用它们解锁更复杂任务。当事情进行不顺时,答案不是”再努力一点”,而是追问”还需要什么能力,该怎么让它对 Agent 清晰可读且可强制执行”。

二、情境管理:给地图,不给百科全书

Codex 团队把 AGENTS.md 从”百科全书”改造为”内容目录”,因为巨型指令文件会带来四个问题:

  • 情境是稀缺资源——巨大指令文件会挤掉任务、代码和相关文档,Agent 要么错过关键约束,要么针对错误约束优化。
  • 过多指导反而无效——当一切都”重要”时,一切都不重要,Agent 最终变成本地模式匹配。
  • 立即腐烂——巨大手册会变成陈旧规则的坟场,Agent 无法判断哪些仍有效,人类停止维护后就成了隐患。
  • 难以核实——单个 blob 不适合机械检查(覆盖率、新鲜度、所有权、交叉链接),漂移不可避免。

仓库知识以结构化 docs/ 目录承载,作为”记录系统”。AGENTS.md 保持约 100 行,作为地图指向更深来源。设计文档被编目并含验证状态,核心理念定义智能体优先操作原则;架构文档 提供域和包分层的顶层地图;质量评分追踪每个产品领域和架构层的差距。

计划是一流工件:临时轻量计划用于小变更;复杂工作写入执行计划并附进度和决策日志,全部提交到仓库;活跃计划、已完成计划和已知技术债务都版本化、集中存放。

这实现渐进式披露:Agent 从小而稳定的切入点开始,被引导到下一步该去哪儿查,而不是一开始被淹没。机械执行这一点——专职的 linter 和 CI 作业验证知识库更新状况、交叉链接和结构;定期运行一个”doc-gardening” Agent 扫描过期或废弃文档,发起修复 PR。

三、仓库即现实:Codex 可读性优先

Codex 在运行时无法访问仓库情境之外的任何内容——Google Docs、聊天记录、人们头脑中的知识都不存在。仓库本地的、已版本化的工件(代码、Markdown、模式、可执行计划)就是它能看到的全部。

团队的具体做法:把越来越多的情境推到仓库里。那次让团队对架构模式达成一致的 Slack 讨论——如果 Agent 发现不了,那它就像迟了三个月入职的新员工一样毫不知情。引导 Agent 的方式类似引导新队友:产品原则、工程规范、团队文化(包括表情符号偏好)都要显式化。

这一框架带来几个具体取舍:

  • 依赖选择偏向”枯燥”技术——可组合性强、API 稳定、在训练集里表现好的依赖项更容易建模。
  • 某些场景下重新实现子集比调用库更便宜——团队没有引入通用 p-limit 风格包,而是投入实现自己的带并发 map 辅助函数,理由是与 OpenTelemetry 仪表紧密集成、100% 测试覆盖、行为完全符合运行时预期。
  • 目标是让其他 Agent 也能参与——将系统转化为 Agent 可检查、验证、修改的形式,杠杆效应不仅对 Codex 生效,也对 Aardvark 这类其他 Agent 生效。

四、强制不变量:用 linter 把品味机械化

仅靠文档维持不了完全由 Agent 生成的代码库的连贯性。关键是通过强制不变量(而非微观管理实施过程)让 Agent 能快速交付又不削弱基础。示例:团队要求 Codex 在边界处解析数据形状,但不规定具体实现(模型偏好 Zod,但未指定特定库)。

严格架构模型:应用围绕一个严格边界与可预测结构构建。每个业务域划分为一组固定层,依赖方向严格验证,仅允许有限边。规则:

  • 每个业务领域内代码只能”向前”依赖:Types → Config → Repo → Service → Runtime → UI
  • 横切关注点(认证、连接器、遥测、功能标志)通过一个显式接口进入:Providers
  • 其他依赖都不被允许,通过自动化强制执行

这种架构通常要等到数百名工程师规模才会推行,但对编码 Agent 来说是早期先决条件——有约束速度才不降,架构才不漂移。

自定义 linter 与结构测试机械地执行规则,辅以一组”品味不变式”。具体示例:

  • 静态强制结构化日志记录
  • 模式和类型的命名约定
  • 文件大小限制
  • 特定平台的可靠性要求

这些 linter 是自定义的,团队在编写错误信息时会注入修复指令到 Agent 情境中——在人类工作流中这些规则可能显得束缚,在 Agent 工作流中它们是倍增器:一旦编码,所有地方立即应用。

团队明确区分哪些边界需要强制、哪些地方允许自主。类似领导大型工程平台组织:在中央强制边界(界限、正确性、可重复性),在本地允许自由(解决方案的表达方式)。生成的代码不总是符合人类风格偏好,这没关系——只要正确、可维护、对未来 Agent 清晰易读就达标。

人类品味通过反馈进入系统:审查评论、重构 PR、面向用户的 bug 会被记录为文档更新,或直接编码到工具中。当文档不够时,规则被转化为代码。

五、扩展 Agent 的可感知范围

随着代码吞吐量增加,瓶颈变成了人工 QA 能力。因为人类的时间和注意力是固定的,团队一直在给 Agent 增加能力,把应用的 UI、日志、应用指标等对 Codex 直接可读。具体实践:

  • Git worktree 驱动的应用启动——让应用可根据 git worktree 启动,Codex 为每次更改启动并驱动一个实例。
  • Chrome DevTools 协议接入 Agent 运行时——创建处理 DOM 快照、截图和导航的技能,使 Codex 能复现错误、验证修复、直接推理 UI 行为。
  • 临时的本地可观测性堆栈——日志、指标、追踪通过一个本地堆栈展示给 Codex,对任意给定工作树都是临时的(任务完成后该版本的日志和指标被删除)。Agent 用 LogQL 查询日志、PromQL 查询指标。
  • 长时单任务运行——经常看到单次 Codex 运行在单个任务上持续超过六小时(通常是人类睡眠时间)。

有了这些情境,像”确保服务启动在 800ms 内完成”或”这四个关键用户旅程中的任何跨度都不得超过两秒”这样的 prompt 就变得可行。

六、传统规范被反转:等待成本 > 纠错成本

Codex 吞吐量增加后,很多传统工程规范不再适用:

  • 仓库在运行过程中尽量减少阻塞合并门
  • PR 生命周期很短
  • 测试偶发失败通过后续重跑解决,而不是无限期阻碍进展

在低吞吐量环境中这样做是不负责任的;但在 Agent 吞吐量远超人类注意力的系统中,纠错成本低、等待成本高,这通常是正确选择。

Agent 产出覆盖范围(即”整个代码库”):

  • 产品代码与测试
  • CI 配置和发布工具
  • 内部开发者工具
  • 文档和设计历史
  • 评估框架
  • 审阅评论和回复
  • 管理代码仓库本身的脚本
  • 生产仪表板定义文件

人类始终参与其中,但抽象层级不同:优先处理工作、将用户反馈转化为验收标准、对结果进行验证。当 Agent 遇到困难,团队视为信号——识别缺失的工具、指导、约束、文档,把修复反馈到仓库里(修复本身也由 Codex 编写)。

端到端自主闭环:仓库最近跨过了一个门槛,Codex 能在一个 prompt 下端到端驱动新功能:

  1. 验证代码库的当前状态
  2. 重现已报告的漏洞
  3. 录制一个演示故障的视频
  4. 实施修复措施
  5. 通过运行应用程序来验证修复
  6. 录制第二个视频,演示解决方案
  7. 打开 Pull Request
  8. 回应智能体和人类反馈
  9. 检测并修复构建故障
  10. 仅在需要判断时才交由人工处理
  11. 合并更改

此行为很大程度上依赖仓库的具体结构和工具,不应在没有类似投入的情况下假定可泛化。

七、黄金原则:持续偿还技术债

完全自主的 Agent 带来新问题:Codex 会复现仓库中已存在的模式,包括不均衡或不理想的模式,随时间不可避免地漂移。

最初人类手动处理——团队过去每周五(占 20%)花时间清理”AI 残渣”,不具备可扩展性。

替代方案是把”黄金原则”直接编码到仓库中,建立循环清理流程。这些原则是带主观意见的机械规则,为了保持代码库对未来 Agent 运行的可读性和一致性。示例:

  1. 更倾向于共享实用程序包,而非手工编写的辅助工具——将不变式集中管理
  2. 不使用”YOLO 式”探测数据——验证边界或依赖类型化的 SDK,避免 Agent 基于猜测的结构构建

团队定期运行一组后台 Codex 任务,扫描偏差、更新质量等级、发起有针对性的重构 PR;其中大多数可以在一分钟内审查并自动合并。

这个机制的功能类似垃圾回收——技术债务像高息贷款,不断小额偿还优于累积后痛苦集中解决。人类品味一旦被捕捉就能持续应用到每一行代码,不良模式在当天被发现和解决,而不是在代码库中传播数天或数周。

八、尚未解决的问题

到目前为止,这一策略在 OpenAI 内部发布和采纳过程中表现良好——为真实用户构建真实产品,把投资锚定在现实中,引导向长期可维护性。

尚不清楚的问题:

  • 完全由 Agent 生成的系统中,架构连贯性如何随时间演变
  • 人类判断力在哪些方面能发挥最大作用,如何把这种判断力编码以发挥更大作用
  • 随着模型能力增强,整个系统如何演变

构建软件仍然需要纪律,但纪律更多体现在支撑结构(工具、抽象、反馈回路)上,而不是代码上。当前最棘手的挑战集中在设计环境、反馈回路和控制系统方面,帮助 Agent 大规模构建和维护复杂、可靠的软件。

名言金句

  1. “人类掌舵。智能体执行。”
  2. “不手动编写代码。“(团队核心理念)
  3. “要给 Codex 的是一张地图,而不是一本 1,000 页的说明书。”
  4. “从智能体的角度来看,它在运行时无法在情境中访问的任何内容都是不存在的。”
  5. “构建软件仍然需要纪律,但纪律更多地体现在支撑结构上,而不是代码上。“

可行建议

  • AGENTS.md 保持薄(~100 行),作为目录而非百科全书——深层知识放在结构化 docs/ 里,由专职 linter 和 CI 验证新鲜度与交叉链接
  • 把设计文档、执行计划、技术债务作为一流工件签入仓库——版本化、编目、含验证状态,使 Agent 能独立运行无需外部情境
  • 早期就用自定义 linter 强制架构边界——严格分层(如 Types → Config → Repo → Service → Runtime → UI),横切关注点走单一 Providers 接口
  • 错误信息里嵌入修复指令——自定义 linter 报错时直接把修复指令注入 Agent 情境
  • 让 app 对 Agent 可读——git worktree 启动、Chrome DevTools 接入、本地临时可观测性堆栈(LogQL + PromQL)
  • 最小化阻塞合并门——吞吐量高时偶发失败重跑,避免等待成本超过纠错成本
  • 建立后台”黄金原则”清理 Agent——每日扫描漂移、发起小型重构 PR,替代周期性集中清理
  • 优先选”枯燥”技术——可组合、API 稳定、训练集表现好;必要时重新实现子集以换取可控性

资源清单

transcript

工程技术:在智能体优先的世界中利用 Codex

在过去五个月里,我们的团队一直在进行一项实验:构建并交付一款软件产品的内部 beta 版,其中没有一行代码是人工编写的

该产品有内部日常活跃用户和外部 Alpha 测试者。它经历了交付、部署、故障和修复的整个过程。与众不同的是,每一行代码 — 从应用逻辑、测试、CI 配置、文档、可观察性到内部工具 — 全都是由 Codex 编写的。据估计,我们只用了手工编写代码所需的大约 1/10 的时间就完成了这项工作。

人类掌舵。智能体执行。

我们有意选择这一限制,以便构建必要的内容,从而将工程速度提升数个数量级。我们用了几周的时间来交付最终达到一百万行代码的项目。为此,我们需要了解,当软件工程团队的主要工作不再是编写代码,而是设计环境、明确意图和构建反馈回路,从而使 Codex 智能体能够可靠地工作时,会发生哪些变化。

这个帖子要说的是,在我们与智能体团队一起从零开始打造一款全新产品的过程中,所能学到的经验教训 — 哪些地方出了问题,哪些问题相互叠加,以及如何最大化利用我们唯一真正稀缺的资源:人类的时间和注意力。

首次提交到一个空的代码仓库是在 2025 年 8 月下旬。

初始架构 — 包括代码仓库结构、CI 配置、格式化规则、包管理器设置和应用框架 — 是在一小套现有模板的指导下,由 Codex CLI 使用 GPT‑5 生成的。就连指导智能体如何在代码仓库中工作的初始 AGENTS.md 文件本身也是由 Codex 编写的。

该系统没有预存任何人工编写的代码。从一开始,代码仓库就由智能体塑造。

五个月后,该代码仓库已经拥有约一百万行代码,从应用逻辑、基础设施、工具、文档到内部开发者工具应有尽有。在那段时间内,大约有 1,500 个 Pull Request 被打开与合并,而推动 Codex 的仅仅是一个由三名工程师组成的小团队。这相当于平均每位工程师每天处理 3.5 个 PRs 的吞吐量,而且令人惊讶的是,随着团队规模扩大到现在的七名工程师,吞吐量甚至还增加了。重要的是,这并非为了输出而输出:该产品已在数百名内测用户那里投入使用,其中包括每天都在使用的内测高级用户。

在整个开发过程中,人类从未直接直接贡献过任何代码。这成为团队的核心理念:不手动编写代码

由于缺乏人工编码的实践,工程师工作的重点转向了系统、架构和杠杆作用

早期进展比我们所预期的要慢,而这并不是因为 Codex 不具备相应的能力,而是因为环境的规范不够明确。该智能体缺乏实现高级目标所需的工具、抽象层和内部结构,因而无法取得进展。我们工程团队的主要任务成了协助智能体完成有用的工作。

在实践中,这意味着采用深度优先的工作方式:将更大的目标拆解为更小的构建模块(设计、代码、评审、测试等),提示智能体去构建这些模块,并使用它们去解锁更复杂的任务。当事情进行不顺利时,解决方案基本上再也不会是“再努力一点”。因为取得进展的唯一方式是让 Codex 来完成工作,而人类工程师则总是介入这项任务并追问:“究竟还需要什么样的能力,我们又该如何让这个能力对智能体来说既清晰可读又可强制执行?”

人类几乎完全通过提示与系统交互:工程师描述任务,运行智能体,并允许其打开一个 Pull Request。为了推动 PR 的完成,我们会指示 Codex 在本地审核其自身的更改,在本地和云端请求额外的特定智能体审查,对任何人工或智能体给出的反馈做出响应,并循环往复,直到所有智能体审核人员都满意为止(这实际上是一个 Ralph Wiggum 循环⁠(在新窗口中打开))。Codex 直接使用我们的标准开发工具(gh、本地脚本和嵌入代码仓库的技能)来收集情境,而无需人工将内容复制粘贴到 CLI 中。

人类可以审核 Pull Request(合并请求),但并非必须这样做。随着时间的推移,我们已将几乎所有的审核工作调整为用智能体对智能体的方式来处理。

随着代码吞吐量的增加,我们的瓶颈变成了人工 QA 能力。由于人类的时间和注意力是固定的限制因素,我们一直在努力通过令应用程序的 UI、日志和应用指标等内容对 Codex 直接可读,从而为智能体增加更多功能。

例如,我们令应用程序可以根据 git worktree 启动,因此 Codex 可以为每次更改启动并驱动一个实例。我们还将 Chrome DevTools 协议接入智能体运行时,并创建了用于处理 DOM 快照、屏幕截图和导航的技能。这使 Codex 能够复现错误、验证修复,并直接推理 UI 的行为。

我们对可观测性工具也做了同样的处理。日志、指标和追踪记录会通过一个本地可观测性堆栈展示给 Codex,对任何给定的工作树来说,该堆栈都是临时的。Codex 在该应用程序的一个完全独立的版本上运行,一旦任务完成,该版本的所有内容,包括日志和指标,都会被删除。智能体可以使用 LogQL 查询日志,使用 PromQL 查询指标。有了这些情境,像“确保服务启动在 800ms 内完成”或“这四个关键用户旅程中的任何跨度都不得超过两秒”这样的提示就变得可行了。

我们经常看到单次 Codex 运行在单个任务上持续工作超过六个小时(通常是在人类睡眠时间)。

情境管理是使智能体在大型和复杂任务中有效发挥作用的最大挑战之一。我们学到的最早经验教训之一很简单:要给 Codex 的是一张地图,而不是一本 1,000 页的说明书。

  • **情境是一种稀缺资源。**一个巨大的指令文件会挤掉任务、代码和相关文档 — 因此智能体要么会错过关键约束条件,要么开始针对错误的约束条件进行优化。
  • 过多的指导反而变得无效**。**当一切都 “重要”时,一切都不重要了。智能体最终会在本地进行模式匹配,而不是有意识地进行导航。
  • **它会立即腐烂。**一本庞杂的手册会变成陈旧规则的坟场。智能体无法判断哪些信息仍然有效,一旦人类停止维护它,此文件就会悄然成为一个颇具吸引力的麻烦源头。
  • **这很难核实。**单个 blob 不适合进行机械检查(覆盖率、新鲜度、所有权、交叉链接),因此漂移是不可避免的。

因此,我们不再将 AGENTS.md 视为百科全书,而是将其视为内容目录

代码仓库的知识库位于一个结构化了的 docs/ 目录中,此目录被当作记录系统来使用。一份简短的 AGENTS.md(大约 100 行)被注入到情境中,主要用作地图,并指向其他地方更深层次的真实信息来源。

代码仓库内知识存储布局。

设计文档已被编目和索引,其中包括验证状态和一套核心理念,定义了智能体优先的操作原则。架构文档⁠(在新窗口中打开)提供域和包分层的顶层地图。一份高质量的文档会对每个产品领域和架构层进行评分,并随着时间的推移追踪差距。

计划被视为一流的工件。临时轻量计划用于小幅变更,而复杂工作则记录在执行计划⁠(在新窗口中打开)中,并附带进度和决策日志,这些日志会被提交到代码仓库。活跃计划、已完成计划和已知的技术债务都已进行版本控制并集中存放,使智能体能够在不依赖外部情境的情况下运行。

这实现了渐进式披露:智能体从一个小而稳定的切入点开始,并被指导下一步该去哪里查看,而不是一开始就被淹没。

我们严格执行这一点。专职的 linter 和 CI 作业会验证知识库的更新状况、是否已交叉链接且结构正确。一个定期运行的“doc-gardening”智能体会扫描那些不再反映真实代码行为的过时或废弃文档,并发起修复用的 Pull Request。

随着代码库的发展,Codex 的设计决策框架也需要随之演变。

由于该代码仓库完全由智能体生成,因此我们首先针对 Codex可读性进行了优化。就像团队会努力提升代码对新入职工程师的可导航性一样,我们的人类工程师的目标也是让智能体能够直接从代码仓库推理出完整的业务领域。

从智能体的角度来看,它在运行时无法在情境中访问的任何内容都是不存在的。存储在 Google Docs、聊天记录或人们头脑中的知识都无法被系统访问。代码仓库本地的、已版本化的工件(例如,代码、Markdown、模式、可执行计划)就是它所能看到的全部。

我们了解到,随着时间的推移,我们需要将越来越多的情境推送到仓库中。那次让团队在架构模式上达成一致的 Slack 讨论?如果智能体无法发现它,那么它就会像迟了三个月入职的新员工一样,对其一无所知。

为 Codex 提供更多情境意味着要组织和展示正确的信息,好令智能体能够基于这些信息进行推理,而不是用临时指令使其不堪重负。就像你会在产品原则、工程规范和团队文化(包括表情符号偏好)方面为新队友提供引导一样,将这些信息提供给智能体会带来更一致的输出。

这一框架明确了许多取舍。我们倾向于选择那些可以完全内化于在仓库中进行推理的依赖项和抽象。对智能体来说,通常被称为“枯燥”的技术,由于其可组合性、API 稳定性和在训练集里的表现,往往更容易建立模型。在某些情况下,让智能体重新实现部分功能子集比绕过公共库中不透明的上游行为更便宜。例如,我们没有引入通用的 p-limit 风格包,而是投入使用了我们自己的带并发的 map 辅助函数:它与我们的 OpenTelemetry 仪表紧密集成,具备 100% 的测试覆盖率,并且其行为完全符合我们的运行时预期。

将系统的更多部分转化为智能体可以检查、验证并直接修改的形式,可以直接提高杠杆效应 — 这不仅适用于 Codex,也适用于其他智能体(例如Aardvark) 也在参与代码库的开发。

仅靠文档本身,是没法保持完全由智能体生成的代码库的连贯性的。**通过强制执行不变量,而非对实施过程进行微观管理,我们令智能体能够快速交付,而且不会削弱基础。**例如,我们要求 Codex 在边界处解析数据形状⁠(在新窗口中打开),但不规定具体实现方式(模型似乎偏好 Zod,但我们没有指定特定库)。

智能体在具有严格边界和可预测结构⁠(在新窗口中打开)的环境中最为高效,因此我们围绕一个严格的架构模型构建了该应用。每个业务域都划分为一组固定的层,依赖方向经过严格验证,并且仅允许有限的一组边。这些约束是通过自定义的 linter(当然是由 Codex 生成的!)和结构测试机械地强制执行的。

下图展示了规则:在每个业务领域内(例如应用设置),代码只能“向前”依赖于一组固定的层(Types → Config → Repo → Service → Runtime → UI)。横切关注点(认证、连接器、遥测、功能标志)通过一个单一的显式接口进入:Providers。其他任何内容都不被允许,并将通过自动化方式强制执行。

这种架构通常要等到你拥有数百名工程师时才会推迟。对于编码智能体来说,这是一个早期的先决条件:有了约束,速度才不会下降,架构才不会漂移。

在实践中,我们通过自定义的代码检查器和结构测试来强制执行这些规则,并辅以一小组“品味不变式”。例如,我们通过自定义 lint 静态地强制执行结构化日志记录、模式和类型的命名约定、文件大小限制,以及特定平台的可靠性要求。由于这些 lint 是自定义的,我们编写错误信息时会在智能体情境中注入修复指令。

在以人为本的工作流程中,这些规则可能会让人感到迂腐或束缚。有了智能体,它们就成了倍增器:一旦编码,它们就能立即应用于所有地方。

同时,我们还明确指出了哪些地方需要限制,哪些地方不需要限制。这类似于领导一个大型工程平台组织:在中央层面强制执行边界,在本地层面允许自主权。你非常重视界限、正确性和可重复性。在这些边界内,你允许团队或智能体在解决方案的表达方式上拥有很大的自由。

生成的代码不总是符合人类的风格偏好,这也没关系。只要输出是正确的、可维护的,并且对未来的智能体运行而言清晰易读,就可以算作达标。

人类的品味会不断反馈到系统中。审查评论、重构的 Pull Request 和面向用户的 Bug 会被记录为文档更新,或直接编码到工具中。当文档不够完善时,我们会将规则转化为代码

随着 Codex 的吞吐量增加,许多传统的工程规范变得不再有效。

该代码仓库在运行过程中尽量减少阻塞合并门。Pull Request 的生命周期很短。测试偶发失败通常通过后续重跑来解决,而不是无限期地阻碍进展。在一个智能体吞吐量远超人类注意力的系统中,纠错成本低,而等待成本高。

在低吞吐量环境中,这样做是不负责任的。而在这里,这通常是正确的选择。

当我们说代码库是由 Codex 智能体生成的,我们指的是整个代码库。

智能体的产出包括:

  • 产品代码与测试
  • CI 配置和发布工具
  • 内部开发者工具
  • 文档和设计历史
  • 评估框架
  • 审阅评论和回复
  • 管理代码仓库本身的脚本
  • 生产仪表板定义文件

人类始终参与其中,但工作的抽象层次与过去不同。我们优先处理工作,将用户反馈转化为验收标准,并对结果进行验证。当智能体遇到困难时,我们将其视为一个信号:识别缺失的内容 — 工具、指导与约束、文档 — 并将其反馈到代码仓库中,始终由 Codex 自己编写修复。

智能体可以直接使用我们的标准开发工具。他们会拉取审查反馈、在行内回复、推送更新,并且经常压缩并合并他们自己的 Pull Request(合并请求)。

随着越来越多的开发环节被直接编码到系统中 — 包括测试、验证、审查、反馈处理和恢复 — 该代码仓库最近跨过了一个重要门槛,使 Codex 能够端到端地驱动一个新功能。

给定一个提示,智能体现在可以:

  • 验证代码库的当前状态
  • 重现已报告的漏洞
  • 录制一个演示故障的视频
  • 实施修复措施
  • 通过运行应用程序来验证修复
  • 录制第二个视频,演示解决方案
  • 打开 Pull Request
  • 回应智能体和人类反馈
  • 检测并修复构建故障
  • 仅在需要判断时才交由人工处理
  • 合并更改

此行为在很大程度上取决于此代码仓库的具体结构和工具,不应在没有类似投入的情况下假定它可以泛化 — 至少目前还不行。

**完全自主的智能体也引入了新的问题。**Codex 会复现代码仓库中已存在的模式 — 甚至包括那些不均衡或不够理想的模式。随着时间的推移,这不可避免地导致漂移。

最初,人类是手动处理这个问题的。我们的团队过去每周五(占一周的20%)都要花时间清理“AI 残渣”。不出所料,那并不具备可扩展性。

相反,我们开始将我们称为“黄金原则”的内容直接编码到代码仓库中,并建立了一个循环清理流程。这些原则是带有主观意见的机械规则,旨在保持代码库的可读性和一致性,以便将来运行智能体。例如:(1) 我们更倾向于使用共享的实用程序包,而不是手工编写的辅助工具,以便将不变式集中管理;(2) 我们不会使用“YOLO 式”探测数据 — 我们会验证边界,或依赖类型化的 SDK,这样智能体就不会意外地基于猜测的结构进行构建。我们会定期运行一组后台 Codex 任务,扫描偏差、更新质量等级,并发起有针对性的重构 Pull Request。其中大多数都可以在一分钟内完成审查并自动合并。

其功能类似于垃圾回收。技术债务就像一笔高息贷款:不断地以小额贷款的方式偿还债务,总比让债务不断累积,再痛苦地一次解决要好得多。人类的品味一旦被捕捉,就会持续应用于每一行代码。这也使我们能够每天发现并解决不良模式,而不是让它们在代码库中传播数天或数周。

到目前为止,这一策略在 OpenAI 的内部发布和采纳过程中表现良好。为真实用户打造真实产品,帮助我们将投资锚定在现实中,并引导我们实现长期的可维护性。

我们尚不清楚的是,在一个完全由智能体生成的系统中,架构连贯性会如何随着时间的推移而演变。我们仍在学习人类的判断力在哪些方面能发挥最大作用,以及如何对这种判断力进行编码,使其发挥更大作用。我们也不知道,随着时间的推移,模型的功能不断增强,这一系统将如何演变。

显而易见的是:构建软件仍然需要纪律,但纪律更多地体现在支撑结构上,而不是代码上。保持代码库一致性的工具、抽象和反馈回路变得越发重要。

我们当前最棘手的挑战集中在设计环境、反馈回路和控制系统方面,帮助智能体实现我们的目标:大规模构建和维护复杂、可靠的软件。

随着像 Codex 这样的智能体在软件生命周期中占据越来越大的比重,这些问题将变得更加重要。我们希望通过分享一些早期的经验教训,帮助你理清投入精力的方向,以便你可以直接开始构建

证据原始数据 (1 条)
transcript-raw
/Users/eamanc/Documents/pe/jixiaxuegong/blog/openai-blog/2026-03-11-harness-engineering-codex/transcript-raw.md