第一时间捕获有价值的信号
本文译自 OpenAI 官方博客 Harness engineering: leveraging Codex in an agent-first world。深入解析Agent优先时代的软件工程新范式,包括架构设计、知识库建设、代码质量保障等核心实践。
核心结论先览
过去五个月,OpenAI团队完成了一项惊人的实验:从零构建并发布了一款内部Beta产品,全程没有一行人工编写的代码。
这款产品已经拥有内部日常用户和外部Alpha测试者,完整经历了上线、部署、故障、修复的全生命周期。与众不同的是,每一行代码——包括应用逻辑、测试用例、CI配置、文档、可观测性工具甚至内部脚手架——全部由Codex生成。团队估算,整个开发过程仅花费了人工编写同等规模代码所需时间的1/10。
人类掌舵,Agent执行。
团队主动选择了”零人工代码”的约束,目的是探索如何将工程研发效率提升一个数量级。他们只有几周时间来交付最终达到百万行代码规模的产品。要实现这个目标,团队必须重新思考:当软件工程团队的核心工作不再是写代码,而是设计环境、明确意图、构建反馈闭环让Codex Agent能够可靠地完成工作时,究竟会发生什么变化?
本文分享了OpenAI团队用Agent团队从零构建新产品的经验教训:哪些环节出了问题,哪些能力产生了复利效应,以及如何最大化我们最稀缺的资源:人类的时间和注意力。
我们从空仓库开始
2025年8月底,我们向空仓库提交了第一个commit。
初始的项目骨架——仓库结构、CI配置、格式化规则、包管理器设置、应用框架——全部由Codex CLI基于GPT-5生成,仅参考了少量现有模板。甚至指导Agent如何在仓库中工作的AGENTS.md文件本身也是Codex写的。
整个系统从一开始就没有人工编写的代码作为锚点,从诞生起就是由Agent塑造的。
五个月后,这个仓库已经包含了约一百万行代码,涵盖应用逻辑、基础设施、工具链、文档和内部开发工具。在此期间,仅由3名工程师驱动Codex就完成并合并了约1500个PR,平均每个工程师每天产出3.5个PR。更令人惊讶的是,当团队扩张到7名工程师时,产出效率还在持续提升。重要的是,这并不是为了产出而产出:产品已经被数百名内部用户使用,包括很多日常重度用户。
在整个开发过程中,人类从未直接贡献过任何代码。这成为了团队的核心理念:不接受任何人工编写的代码。
重新定义工程师的角色
不需要人工写代码带来了一种完全不同的工程工作模式,核心聚焦于系统、脚手架和杠杆效应。
早期进展比我们预期的要慢,不是因为Codex能力不足,而是因为环境没有被充分定义。Agent缺乏实现高层目标所需的工具、抽象和内部结构。我们工程团队的核心工作变成了赋能Agent完成有用的工作。
实践中,这意味着我们采用深度优先的工作方式:将大目标拆解成更小的构建块(设计、编码、评审、测试等),提示Agent构建这些模块,再用这些模块解锁更复杂的任务。当某个环节失败时,解决方案几乎从来不是”让Agent再试一次”。因为唯一的前进方式是让Codex完成工作,人类工程师总会退一步思考:“缺少了什么能力?我们如何让Agent既能理解这种能力,又能遵守相关约束?”
人类几乎完全通过提示与系统交互:工程师描述任务,运行Agent,让它自动打开PR。为了推动PR完成,我们会指示Codex在本地评审自己的改动,请求本地和云端的其他Agent进行专项评审,响应任何人类或Agent给出的反馈,循环迭代直到所有Agent评审者都满意(这实际上就是Ralph Wiggum循环)。Codex直接使用我们的标准开发工具(gh、本地脚本、仓库内置技能)来获取上下文,不需要人类复制粘贴到CLI中。
人类可以评审PR,但这不是必需的。随着时间推移,我们已经将几乎所有评审工作都交给了Agent之间互相完成。
提升应用的可理解性
随着代码产出效率提升,我们的瓶颈变成了人类QA的容量。因为人类的时间和注意力是固定约束,我们致力于让应用UI、日志、应用指标等都能被Codex直接理解,从而给Agent赋予更多能力。
例如,我们让应用支持按git工作树启动,这样Codex可以为每个变更启动并驱动一个独立实例。我们还将Chrome DevTools Protocol集成到Agent运行时中,创建了处理DOM快照、截图和页面导航的技能。这使得Codex能够直接复现Bug、验证修复方案、推理UI行为。

我们对可观测性工具做了同样的处理。日志、指标和链路通过本地可观测性栈暴露给Codex,每个工作树的可观测性数据都是临时的。Codex在完全隔离的应用版本上工作,包括其日志和指标,任务完成后就会被销毁。Agent可以用LogQL查询日志,用PromQL查询指标。有了这些上下文,类似”确保服务启动时间低于800ms”或”这四个关键用户旅程中没有任何Span超过2秒”这样的提示都可以被自动完成。
我们经常看到单个Codex运行可以为一个任务持续工作超过6小时(通常是在人类睡觉的时候)。
让仓库知识成为事实唯一来源
上下文管理是让Agent有效处理大型复杂任务的最大挑战之一。我们学到的最早的教训很简单:给Codex一张地图,而不是一本1000页的操作手册。
我们尝试过”一个超大AGENTS.md”的方案,它以可预见的方式失败了:
- 上下文是稀缺资源。巨大的说明文件会挤占任务、代码和相关文档的空间,导致Agent要么遗漏关键约束,要么开始优化错误的目标。
- 过多指导等于没有指导。当所有内容都”重要”时,就没有什么是重要的了。Agent最终只会进行局部模式匹配,而不是有意图地导航。
- 内容会立刻过期。单体手册会变成过时规则的坟场。Agent无法分辨哪些规则仍然有效,人类也停止维护它,这个文件最终会成为一个吸引人的麻烦。
- 难以验证。单一blob不适合机械检查(覆盖率、新鲜度、所有者、交叉链接),所以漂移是不可避免的。
因此我们没有把AGENTS.md当作百科全书,而是把它作为目录。
仓库的知识库保存在结构化的docs/目录中,作为事实的唯一来源。一个简短的AGENTS.md(约100行)被注入到上下文中,主要作为地图,指向其他地方更深层的事实来源。
AGENTS.md
ARCHITECTURE.md
docs/
├── design-docs/
│ ├── index.md
│ ├── core-beliefs.md
│ └── ...
├── exec-plans/
│ ├── active/
│ ├── completed/
│ └── tech-debt-tracker.md
├── generated/
│ └── db-schema.md
├── product-specs/
│ ├── index.md
│ ├── new-user-onboarding.md
│ └── ...
├── references/
│ ├── design-system-reference-llms.txt
│ ├── nixpacks-llms.txt
│ ├── uv-llms.txt
│ └── ...
├── DESIGN.md
├── FRONTEND.md
├── PLANS.md
├── PRODUCT_SENSE.md
├── QUALITY_SCORE.md
├── RELIABILITY.md
└── SECURITY.md
仓库内知识库结构
设计文档被编目和索引,包括验证状态和定义Agent优先运营原则的核心信念集。架构文档提供了领域和包分层的顶层地图。质量文档为每个产品领域和架构层打分,随时间跟踪差距。
计划被视为一等 artifact。小变更使用临时的轻量级计划,复杂工作则被记录在执行计划中,包含进度和决策日志,并提交到仓库。活跃计划、已完成计划和已知技术债务都被版本化并放在一起,使Agent能够在不依赖外部上下文的情况下运行。
这实现了渐进式披露:Agent从一个小而稳定的入口点开始,学习下一步去哪里查找信息,而不是一开始就被信息淹没。
我们用机械方式强制执行这一点。专用的linter和CI任务验证知识库是否是最新的、交叉链接正确且结构正确。一个定期运行的”文档园艺”Agent会扫描不符合实际代码行为的过时或废弃文档,并打开修复PR。
Agent可理解性是核心目标
随着代码库的演进,Codex的设计决策框架也需要同步演进。
因为仓库完全是Agent生成的,所以它首先是为Codex的可理解性优化的。就像团队致力于提高代码对新工程师的可导航性一样,我们人类工程师的目标是让Agent能够直接从仓库本身推理完整的业务领域。
从Agent的角度来看,任何它在运行时无法在上下文中访问的东西实际上都不存在。存在于Google Docs、聊天线程或人们头脑中的知识对系统来说是不可访问的。只有仓库本地、版本化的artifact(例如代码、markdown、schema、可执行计划)是它能看到的。

我们意识到需要随着时间推移将越来越多的上下文推入仓库。那些让团队在架构模式上达成一致的Slack讨论?如果Agent不能发现它,那它就像三个月后加入的新员工不知道这些讨论一样,属于不可理解的信息。
给Codex更多上下文意味着组织和暴露正确的信息,让Agent能够对其进行推理,而不是用临时指令淹没它。就像你会向新队友介绍产品原则、工程规范和团队文化(包括emoji偏好)一样,给Agent这些信息会带来更一致的输出。
这个框架澄清了很多权衡取舍。我们倾向于使用能够在仓库中被完全内化和推理的依赖和抽象。通常被描述为”无聊”的技术往往更容易被Agent建模,因为它们具有可组合性、API稳定性,并且在训练集中有充分的代表性。在某些情况下,让Agent重新实现功能子集比解决公共库不透明的上游行为成本更低。例如,我们没有引入通用的p-limit风格的包,而是实现了自己的带并发控制的map辅助函数:它与我们的OpenTelemetry instrumentation紧密集成,有100%的测试覆盖率,并且完全符合我们运行时的预期行为。
将更多系统转化为Agent可以直接检查、验证和修改的形式,不仅提升了Codex的效率,也提升了其他在代码库上工作的Agent(例如Aardvark)的效率。
强制执行架构和风格一致性
仅有文档不足以让完全由Agent生成的代码库保持一致性。通过强制执行不变量,而不是微观管理实现,我们让Agent能够快速交付而不破坏基础。例如,我们要求Codex在边界处解析数据结构,但不规定具体如何实现(模型似乎喜欢用Zod,但我们没有指定这个特定库)。
Agent在有严格边界和可预测结构的环境中效率最高,所以我们围绕严格的架构模型构建应用。每个业务领域被划分为固定的层集合,有严格验证的依赖方向和有限的允许边缘。这些约束通过自定义linter(当然也是Codex生成的!)和结构测试以机械方式强制执行。
下图展示了规则:在每个业务领域(例如应用设置)内,代码只能按照固定的层顺序”向前”依赖(类型→配置→仓库→服务→运行时→UI)。横切关注点(认证、连接器、遥测、功能开关)通过单一明确的接口进入:Provider。其他任何方式都是不允许的,并且会被机械强制执行。

这种架构通常是等到你有数百名工程师时才会考虑的事情。但对于代码Agent来说,这是早期的先决条件:这些约束使得能够在没有衰减或架构漂移的情况下保持高速开发。
实践中,我们用自定义linter和结构测试,加上一小组”风格不变量”来执行这些规则。例如,我们通过自定义lint静态强制执行结构化日志、schema和类型的命名约定、文件大小限制以及平台特定的可靠性要求。因为lint是自定义的,我们编写的错误消息会将修复指令注入到Agent上下文中。
在以人为先的工作流中,这些规则可能显得迂腐或约束性强。但对于Agent来说,它们成为了倍增器:一旦编码完成,它们会立刻应用到所有地方。
同时,我们明确区分哪些地方约束重要,哪些地方不重要。这类似于领导大型工程平台组织:集中强制执行边界,允许局部自治。你非常关心边界、正确性和可复现性。在这些边界内,你允许团队——或Agent——在解决方案表达上有很大的自由度。
最终生成的代码并不总是符合人类的风格偏好,这没关系。只要输出正确、可维护,并且对未来的Agent运行是可理解的,就达到了标准。
人类的风格偏好会持续反馈到系统中。评审意见、重构PR、面向用户的Bug都会被捕获为文档更新,或者直接编码到工具中。当文档不足以覆盖时,我们会将规则提升到代码中。
产出效率改变合并哲学
随着Codex产出效率的提升,很多传统的工程规范变得适得其反。
仓库采用最小化的阻塞合并门控。PR生命周期很短。测试不稳定通常通过后续运行解决,而不是无限期阻塞进度。在Agent产出效率远远超过人类注意力的系统中,修正成本很低,而等待成本很高。
这在低产出环境中是不负责任的。但在这里,这通常是正确的权衡。
“Agent生成”的真正含义
当我们说代码库是由Codex Agent生成的时候,我们指的是代码库中的一切。
Agent产出:
- 产品代码和测试
- CI配置和发布工具
- 内部开发工具
- 文档和设计历史
- 评估工具
- 评审意见和响应
- 管理仓库本身的脚本
- 生产仪表盘定义文件
人类始终在环中,但工作在比以前更高的抽象层。我们排列工作优先级,将用户反馈转化为验收标准,验证结果。当Agent遇到困难时,我们将其视为信号:识别缺少什么——工具、护栏、文档——并将其反馈回仓库,始终通过让Codex自己编写修复来实现。
Agent直接使用我们的标准开发工具。它们拉取评审反馈,内联响应,推送更新,并且经常压缩并合并自己的PR。
不断提升的自主水平
随着更多开发循环被直接编码到系统中——测试、验证、评审、反馈处理、故障恢复——最近仓库跨越了一个有意义的阈值:Codex可以端到端地驱动新功能开发。
给定单个提示,Agent现在可以:
- 验证代码库的当前状态
- 复现报告的Bug
- 录制演示故障的视频
- 实现修复
- 通过驱动应用验证修复
- 录制第二个视频演示问题已解决
- 打开PR
- 响应Agent和人类的反馈
- 检测并修复构建失败
- 仅在需要判断时升级到人类
- 合并变更
这种行为高度依赖于这个仓库的特定结构和工具,如果没有类似的投资,不应该假设可以通用——至少目前是这样。
熵和垃圾回收
完全的Agent自治也带来了新的问题。 Codex会复制仓库中已经存在的模式——即使是不均衡或次优的模式。随着时间推移,这不可避免地会导致漂移。
最初,人类手动解决这个问题。我们团队曾经每周五(每周20%的时间)清理”AI垃圾”。不出所料,这种方式无法扩展。
相反,我们开始将我们称为”黄金原则”的内容直接编码到仓库中,并构建了定期清理流程。这些原则是明确的、机械的规则,保持代码库对未来Agent运行的可理解性和一致性。例如:(1) 我们更喜欢共享工具包而不是手工编写的辅助函数,以保持不变量集中化;(2) 我们不”YOLO式”探测数据——我们验证边界或依赖类型化的SDK,这样Agent就不会意外地基于猜测的结构构建功能。定期运行一组后台Codex任务扫描偏差,更新质量评分,并打开针对性的重构PR。大多数这些PR可以在一分钟内评审完毕并自动合并。
这就像垃圾回收。技术债务就像高息贷款:持续小额偿还几乎总是比让它复利累积再痛苦地一次性解决要好。人类的风格偏好只需要被捕获一次,然后就会持续应用到每一行代码上。这也让我们能够每天发现和解决不良模式,而不是让它们在代码库中传播数天或数周。
我们仍在学习的东西
到目前为止,这个策略在OpenAI内部上线和采用过程中效果良好。为真实用户构建真实产品帮助我们的投资锚定在现实中,并引导我们走向长期可维护性。
我们还不知道的是,在完全由Agent生成的系统中,架构一致性会如何随着时间推移而演变。我们仍在学习人类判断在哪里能产生最大杠杆作用,以及如何编码这些判断以产生复利效应。我们也不知道随着模型能力不断提升,这个系统会如何演变。
已经明确的是:构建软件仍然需要纪律,但纪律更多体现在脚手架而不是代码本身。保持代码库一致性的工具、抽象和反馈循环变得越来越重要。
我们现在最困难的挑战集中在设计环境、反馈循环和控制系统,帮助Agent实现我们的目标:大规模构建和维护复杂、可靠的软件。
随着像Codex这样的Agent承担软件生命周期中更大的部分,这些问题将变得更加重要。我们希望分享这些早期经验能帮助你思考应该在哪里投入精力,这样你就可以专注于构建产品本身。