
日期:2026年2月11日
作者:Ryan Lopopolo,OpenAI 技术团队成员
原文:https://openai.com/zh-Hans-CN/index/harness-engineering/
在过去五个月里,我们团队一直在做一项实验:构建并交付一款软件产品的内部 Beta 版本,而且其中没有一行代码由人工手写。
这款产品已经拥有内部日活用户和外部 Alpha 测试者。
它经历了完整的软件生命周期:交付、部署、故障以及修复。
更特别的是,从应用逻辑、测试、CI 配置、文档、可观测性到内部工具,整套代码都由 Codex 编写。
粗略估算,我们只用了传统手工编码约十分之一的时间。
人类负责掌舵,智能体负责执行。
我们刻意施加这一约束,是为了逼迫自己搭建出真正必要的支撑结构,把工程速度提升数个数量级。
最终,这个项目增长到约一百万行代码,而完成这一切只用了数周。
我们由此不得不回答一个核心问题:当软件工程团队的主要工作不再是写代码,而是设计环境、澄清意图、构建反馈回路,从而让 Codex 智能体能够稳定可靠地工作时,工程实践会发生什么变化?
这篇文章总结的,正是我们与一个智能体团队从零打造全新产品时得到的教训:哪些地方会出错,哪些问题会叠加,以及如何最大化利用我们唯一真正稀缺的资源,人类的时间与注意力。

我们在 2025 年 8 月下旬向一个空仓库提交了第一笔代码。
最初的架构,包括仓库结构、CI 配置、格式化规则、包管理器设置以及应用框架,都是由 Codex CLI 基于 GPT‑5、在少量现成模板的引导下生成的。
甚至连最初那份用来指导智能体如何在仓库中工作的 AGENTS.md,也是 Codex 写出来的。
系统里没有任何预置的人工代码。这个仓库从第一天起,就是由智能体塑形的。
五个月后,仓库已经增长到约一百万行代码,覆盖应用逻辑、基础设施、工具、文档以及内部开发者工具。
在这段时间里,大约有 1,500 个 Pull Request 被创建并合并,而驱动这一切的,只是一个最初由三名工程师组成的小团队。
折算下来,平均每位工程师每天可推进 3.5 个 PR。
更令人意外的是,随着团队扩大到现在的七人规模,这个吞吐量还在继续上升。更重要的是,这并不是为了产出而产出:产品已经被数百名内测用户实际使用,其中包括每天都在使用它的重度用户。
在整个开发过程中,人类从未直接提交过代码。这逐渐成为团队的一条核心原则:不手写代码。
既然不再依赖人工编码,工程师的工作重心自然转向了系统、架构与杠杆。
项目早期的进展比我们预想得慢,但原因并不是 Codex 能力不足,而是环境规范还不够明确。
智能体缺少实现高层目标所需的工具、抽象和内部结构,因此难以有效推进。于是,工程团队的主要职责变成了:帮助智能体具备完成有价值工作所需的条件。
在实践中,这意味着一种深度优先的工作方式:把更大的目标拆成更小的构件,如设计、代码、评审和测试。提示智能体先构建这些构件,再借此解锁更复杂的任务。
当事情进展不顺时,解决方案不再是“再努力一点”。因为唯一真正能推动工作的,是让 Codex 获得更多能力。于是,人类工程师不断追问:还缺什么能力?怎样才能让这种能力对智能体既清晰可读,又可被强制执行?
人类几乎完全通过提示与系统交互:工程师描述任务、运行智能体,然后让它自行创建 Pull Request。为了把一个 PR 推进到可合并状态,我们会要求 Codex 在本地审查自己的改动,在本地或云端发起额外的专用智能体审查,对来自人类或智能体的反馈逐条响应,如此循环,直到所有智能体审阅者都满意为止。
这本质上就是一个 Ralph Wiggum 循环。Codex 直接调用我们已有的开发工具,如 gh、本地脚本,以及嵌入仓库的技能,自己搜集上下文,而不需要人类把材料复制粘贴进 CLI。
人类当然也可以审查 Pull Request,但这已不再是必需流程。随着时间推移,我们已经把几乎全部审查工作都调整为智能体与智能体之间完成。
随着代码产出持续增长,我们的瓶颈逐渐变成人工 QA 能力。
既然人类的时间与注意力是硬约束,我们就不断尝试把更多信息直接暴露给 Codex,让应用的 UI、日志和指标都对它可读,从而为智能体增加新的能力边界。
举例来说,我们让应用可以基于 git worktree 启动,这样 Codex 就能为每一次修改拉起一个独立实例并亲自操作。
我们还把 Chrome DevTools 协议接入了智能体运行时,并构建了处理 DOM 快照、截图与导航的技能。这样一来,Codex 就能自行复现错误、验证修复,并直接推理 UI 行为。

Codex 通过 Chrome DevTools MCP 驱动应用,并在循环中验证自己的修复是否真正生效。
图示:Codex 通过 Chrome DevTools MCP 驱动应用,并在循环中验证自己的修复是否真正生效。
我们也以同样的方式改造了可观测性系统。
日志、指标和追踪数据会通过一套本地可观测性堆栈暴露给 Codex,而且这套堆栈是针对每个 worktree 临时创建的。
Codex 始终在应用的一个完全独立副本上运行;任务结束后,这个副本连同日志和指标都会被删除。智能体可以用 LogQL 查询日志,用 PromQL 查询指标。
有了这类上下文,“确保服务在 800ms 内完成启动”或“这四条关键用户旅程中的任意一个 span 都不得超过两秒”这样的提示,才真正变得可操作。
Codex 在本地开发环境中使用完整的可观测性堆栈,对日志、指标与追踪进行查询、关联和推理。
图示:Codex 在本地开发环境中使用完整的可观测性堆栈,对日志、指标与追踪进行查询、关联和推理。
我们经常看到,单次 Codex 运行会在一个任务上连续工作六小时以上,而这通常恰好发生在人类休息的时段。
上下文管理,是让智能体在大型复杂任务上发挥作用时最困难的问题之一。
我们最早学到的一条经验非常简单:给 Codex 的应该是一张地图,而不是一本一千页的手册。
我们试过“一个超大 AGENTS.md 文件”这种办法。事实证明,这是个失败方案:
因此,我们不再把 AGENTS.md 当作百科全书,而是把它当作目录页。
仓库的知识库被组织在结构化的 docs/ 目录中,并被当作正式的记录系统来使用。一份简短的 AGENTS.md,大约一百行,会被注入上下文,作为入口地图,指向其他位置上更深入、更权威的信息源。
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
代码仓库中的知识存储布局。
设计文档会被系统化编目和索引,并附带验证状态与一组核心信念,用来定义智能体优先的操作原则。架构文档提供了领域和包分层的顶层地图。高质量文档还会为每个产品领域与架构层打分,并持续追踪其中的差距。
计划在这里被视为一等工件。较小改动使用轻量级临时计划;复杂工作则被记录进执行计划,并附带进度日志与决策日志,这些内容都会直接提交到仓库。活跃计划、已完成计划以及已知技术债务全部纳入版本控制并集中存放,让智能体即使不依赖外部上下文,也能独立运行。
这带来了渐进式披露:智能体从一个小而稳定的入口开始,然后被明确指向下一步应该查看的位置,而不是一上来就被海量信息淹没。
我们对此执行得非常严格。
专门的 linter 与 CI 作业会检查知识库是否及时更新、是否正确交叉链接、结构是否合理。一个定期运行的“doc-gardening”智能体还会扫描那些已不再反映真实代码行为的过时文档,并自动发起修复用的 Pull Request。
随着代码库不断增长,Codex 的设计决策框架也必须随之演化。
因为整个仓库都是由智能体生成的,所以我们首先优化的是 Codex 的可读性。就像团队会努力提高代码对新入职工程师的可导航性一样,我们的人类工程师也把目标设定为:让智能体能够直接从仓库本身推理出完整的业务领域。
从智能体的视角看,任何它在运行时无法通过上下文访问到的东西,都等同于不存在。存放在 Google Docs、聊天记录或人的脑海中的知识,对系统而言都是不可见的。它真正能看见的,只有仓库本地、可版本化的工件,例如代码、Markdown、schema 和执行计划。

凡是不在代码仓库里、不能被运行时上下文访问的知识,对 Codex 来说都等同于不存在。
图示:凡是不在代码仓库里、不能被运行时上下文访问的知识,对 Codex 来说都等同于不存在。
我们逐渐意识到,随着时间推移,必须把越来越多的上下文推入仓库。
比如,一次让团队在架构模式上达成共识的 Slack 讨论,如果智能体无法发现,那么对它而言,这件事就和一个晚了三个月入职的新员工没什么区别:它根本不知道。
为 Codex 提供更多上下文,并不意味着用临时指令把它塞满,而是要把正确的信息组织好、呈现好,让它能够基于这些信息推理。
就像你会向新同事介绍产品原则、工程规范和团队文化,甚至包括大家偏爱的表情符号一样,把这些信息提供给智能体,会显著提高输出的一致性。
这一框架也迫使我们更明确地面对取舍。我们倾向于选择那些可以被完整内化到仓库推理过程中的依赖和抽象。
对智能体来说,那些通常被称为“朴素”或“无聊”的技术,往往因为可组合性强、API 稳定、训练数据中出现充分,反而更容易建模。
有时,与其绕开公共库里那些不透明的上游行为,不如让智能体自己重写一个功能子集,成本更低。比如,我们没有引入通用的 p-limit 风格包,而是使用了自己的并发 map 辅助函数:它与 OpenTelemetry 埋点深度集成,测试覆盖率达到 100%,其行为也完全符合我们的运行时预期。
把系统更多部分转化为智能体可以检查、验证并直接修改的形式,会直接提升杠杆。这不仅适用于 Codex,也适用于其他同样参与仓库开发的智能体,例如 Aardvark。
单靠文档,并不足以维持一个完全由智能体生成的代码库的连贯性。
真正的关键在于强制执行不变量,而不是微观管理实现过程。
只有这样,智能体才能高速交付,同时又不侵蚀系统基础。比如,我们要求 Codex 在边界处解析数据形状,但不会规定它必须如何实现。模型似乎偏爱 Zod,不过我们并没有硬性指定某个库。
智能体在边界严格、结构可预测的环境中表现最好,因此我们围绕一套非常严格的架构模型构建了整个应用。
每个业务域都被拆成固定层次,依赖方向受到严格校验,允许存在的边也只有有限几类。这些约束通过自定义 linter 和结构测试被机械地强制执行,而这些工具本身当然也是由 Codex 生成的。
规则大致如下:
在每个业务域内部,比如应用设置,代码只能沿着固定方向“向前”依赖:Types → Config → Repo → Service → Runtime → UI。
横切关注点,如认证、连接器、遥测和功能标志,只能通过一个显式入口进入:Providers。除此之外的任何依赖,都会被自动化规则直接禁止。

带有显式横切边界的分层领域架构。
图示:带有显式横切边界的分层领域架构。
这种架构,在人类团队里往往要等到拥有数百名工程师时才会认真推进;但对于编码智能体,它是一项早期前提。没有这些约束,速度很快就会下降,架构也会开始漂移。
实际执行时,我们用自定义代码检查器和结构测试来落实这些规则,并辅以少量“品味不变量”。例如,我们通过定制 lint 静态地强制执行结构化日志、schema 与类型命名约定、文件大小限制,以及平台特定的可靠性要求。
因为这些 lint 是定制的,所以我们会把修复指令直接写进报错信息里,让智能体在看到错误的同时就获得改正方向。
在传统以人为中心的工作流里,这类规则容易显得迂腐甚至束缚;但有了智能体,它们反而成了倍增器。一旦规则被编码,就能立即、统一地作用到所有地方。
与此同时,我们也明确划定了哪些地方要强约束,哪些地方不必强约束。这和领导大型工程平台组织很像:边界在中央层面统一约束,自主权则保留在局部层面。你会非常在意边界、正确性与可重复性;而在这些边界之内,则允许团队或智能体在具体表达上拥有很大自由度。
生成出来的代码不一定符合人类的风格偏好,但这没有关系。只要输出正确、可维护,而且对未来的智能体运行来说清晰可读,就算达标。
人类的品味会持续反馈进系统。审查意见、重构 PR 以及面向用户的缺陷,都会被转化为文档更新,或者直接编码进工具。当文档已经不足以承载这些约束时,我们就把规则写成代码。
随着 Codex 吞吐量上升,许多传统工程规范开始不再适用。
这个代码库在运行时尽量减少阻塞式合并门。Pull Request 的生命周期被压得很短。测试的偶发失败通常通过后续重跑解决,而不是无限期阻碍进度。
在一个智能体吞吐量远高于人类注意力上限的系统里,修错的成本很低,等待的成本却很高。
如果是在低吞吐量环境中,这样做会显得相当不负责任;但在这里,它往往反而是更合理的选择。
当我们说,这个代码库是由 Codex 智能体生成的,我们的意思是:几乎整个仓库都是如此。
智能体生成的内容包括:
人类始终在环,但工作的抽象层级已经与过去不同。
我们负责设定优先级,把用户反馈转化为验收标准,并验证结果。当智能体卡住时,我们把它视为一种信号:说明还缺少某些东西,可能是工具、指导与约束,也可能是文档。随后,我们把这些缺口补回仓库里,而且修复本身仍由 Codex 完成。
智能体也能直接使用我们的标准开发工具。它们会拉取审查反馈、逐行回复、推送更新,而且经常会自己 squash 并合并自己的 Pull Request。
随着越来越多开发环节被直接编码进系统,包括测试、验证、审查、反馈处理以及故障恢复,这个仓库最近跨过了一个重要门槛:Codex 已经能够端到端推动一个新功能落地。
给定一个提示,智能体现在可以:
当然,这种能力高度依赖于该代码仓库的具体结构和工具链。没有做出类似投入的团队,不应假定这一行为今天就可以自然泛化。
完全自治的智能体,也会带来新的问题。 Codex 会复制仓库里已经存在的模式,包括那些并不均衡、也并不理想的模式。随着时间推移,这几乎必然会造成漂移。
一开始,人类通过手工方式处理这个问题。过去,我们团队每周五都会拿出将近一整天,也就是一周约 20% 的时间,专门清理所谓的“AI 残留物”。显然,这种做法根本不可扩展。
于是,我们开始把一些被称为“黄金原则”的内容直接编码进仓库,并建立起循环清理流程。
这些原则是带有明确偏好的机械规则,目的是维持代码库的可读性和一致性,以利于未来的智能体运行。
例如:
第一,我们优先使用共享工具包,而不是到处手写辅助函数,以便集中承载不变量;
第二,我们不允许“YOLO 式”地猜测数据结构,而是要么在边界处做验证,要么依赖类型化 SDK,避免智能体围绕猜测出来的结构继续搭建。我们会定期运行一组后台 Codex 任务,扫描偏差、更新质量评分,并发起有针对性的重构 Pull Request。其中大多数 PR 都可以在一分钟内审完并自动合并。
这套机制很像垃圾回收。技术债务就像高息贷款:持续、小额地偿还,总比任其累积,最后再痛苦地一次性清账要划算得多。人类的品味一旦被捕捉下来,就可以持续作用于每一行代码。这也意味着,我们能够按天发现并清除坏模式,而不是任由它们在仓库里扩散数天甚至数周。
截至目前,这套策略已经在 OpenAI 内部的发布与采纳过程中证明了它的有效性。为真实用户构建真实产品,帮助我们把投入锚定在现实问题上,也促使我们更认真地面对长期可维护性。
但我们仍不清楚,在一个完全由智能体生成的系统里,架构连贯性会如何随时间演化。我们还在学习,人类判断力究竟最该用在什么地方,以及怎样把这种判断编码进去,使它发挥更大的杠杆作用。与此同时,随着模型能力持续增强,这整个系统本身也会继续变化。
有一点已经很明确:软件开发仍然需要纪律,只不过这种纪律将越来越多地体现在支撑结构,而不是代码本身。那些维持仓库一致性的工具、抽象和反馈回路,变得比以往任何时候都更重要。
眼下我们最棘手的挑战,集中在环境设计、反馈回路与控制系统上。 这些东西决定了智能体是否真的能够帮助我们以规模化方式构建和维护复杂、可靠的软件。
随着像 Codex 这样的智能体在软件生命周期中占据越来越大的比重,这些问题只会变得更加关键。我们希望,通过分享这些早期经验,帮助你更清楚地判断精力该投入在哪里,从而直接开始构建。