How to Build Software Using Only Codex" A teamine production app in 5 months. The catcte a single line of code. 🤯 Discover th, AGENTS.md setup, and observability tooagents to do the heavy lifting." +++

工程赋能:在智能体优先的世界中运用 Codex |译文

作者:Ryan Lopopolo,技术团队成员

译文

人类掌舵,智能体执行。

在过去五个月里,我们团队开展了一项实验:在完全不手写任何代码的情况下,构建并交付了一个内部测试版的软件产品。

该产品有内部的日常用户和外部的 Alpha 测试者。它不断发布、部署、出现故障并得到修复。不同的是,每一行代码——包括应用逻辑、测试、持续集成配置、文档、可观测性以及内部工具——都由 Codex 编写。我们估算,整个开发过程仅耗费了人工手写代码所需时间的十分之一。

我们刻意设定了这一限制,旨在促使我们构建能将工程效率提升数十倍的必要机制。我们只有几周时间,最终交付了约一百万行代码。要实现这一目标,我们必须深刻理解:当软件工程团队的核心职责不再是编写代码,而是设计环境、明确意图,并构建反馈闭环,让 Codex 智能体能够可靠完成工作时,会发生哪些变化。

本文探讨了我们与一支智能体团队从零构建全新产品过程中所获得的经验——哪些环节出现了故障,哪些问题被进一步放大,以及如何最大化我们唯一真正稀缺的资源:人类的时间与注意力。


实验背景与总体产出:用智能体生成整库

概要:起步条件、时间线、团队规模与产出指标。

我们从一个空的 git 代码仓库起步。第一个提交于 2025 年 8 月下旬完成。

最初的脚手架——包括代码仓库结构、持续集成(CI)配置、格式化规则、包管理器设置和应用框架——均由 Codex CLI 借助 GPT‑5 生成,并参考少量现有模板。甚至用于指导智能体在仓库中工作的初始 AGENTS.md 文件,也是由 Codex 编写的。

系统没有任何预先存在的人类编写代码作为基准。从一开始,代码仓库的结构就是由智能体塑造的。

五个月后,代码仓库已包含约一百万行代码,覆盖应用逻辑、基础设施、工具链、文档以及内部开发者工具。在此期间,Codex 由仅三名工程师组成的小团队共发起并合并了约 1,500 个拉取请求(PR),平均每位工程师每天完成 3.5 个 PR。令人惊讶的是,随着团队扩展至七人,整体吞吐量反而进一步提升。值得强调的是,这并非单纯追求产出数量:该产品已被数百名内部用户实际使用,其中包括每天活跃的内部重度用户。

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

不写人工代码。


角色重构:从“写代码”转为“设计环境与反馈”

概要:工程师职责转向系统设计、脚手架与效率杠杆。

不再进行人工编码,使工程工作的重心转向系统设计、脚手架构建以及杠杆效能的发挥。

早期进展比我们预期慢,并非因为 Codex 无能,而是由于环境定义不足。智能体缺少实现高层目标所需的工具、抽象和内部结构。我们的工程团队的首要任务转变为让智能体能够开展有价值的工作。

在实际操作中,这意味着我们采用深度优先的方式:将宏大的目标拆分为更小的构建块(设计、编码、评审、测试等),引导智能体依次完成这些构建块,并借此推动更复杂任务的实现。当某个环节出现问题时,解决方法几乎从不是“更努力尝试”。由于唯一的进展途径是让 Codex 完成工作,工程师总会介入任务,追问:“缺少哪项能力?我们如何让它对智能体既可读又可强制执行?”

人类几乎完全通过提示与系统交互:工程师描述任务,运行智能体,并允许其发起拉取请求(PR)。为推动 PR 完成,我们会指示 Codex 在本地自审其变更,并在本地和云端请求额外的特定智能体评审,针对来自人类或智能体的反馈进行响应,在循环中不断迭代,直到所有智能体评审者都满意为止(这实际上就是 Ralph Wiggum 循环)。Codex 会直接使用我们的标准开发工具(如 gh、本地脚本以及仓库内嵌技能)收集上下文,无需人工将内容复制粘贴到命令行界面。

人类可以对拉取请求(PR)进行评审,但并非必须参与。随着时间的推移,我们几乎将所有评审工作转移为智能体之间的处理。


强化可读性:让 UI、日志、指标对智能体直接可读

概要:把应用和可观测性信号暴露给 Codex,压缩人工 QA。

随着代码产出量的提升,我们的瓶颈转向了人工质量保证(QA)能力。由于固定的约束是人类的时间和注意力,我们转而通过让应用的 UI、日志和应用指标等内容对 Codex 直接可读,来增强智能体的能力。

例如,我们让应用能够按每个 git 工作树启动,这样 Codex 就能为每次变更启动并驱动一个实例。我们还将 Chrome DevTools 协议集成到智能体运行时,并开发了处理 DOM 快照、截图和页面导航的技能。这使 Codex 能够直接复现 bug、验证修复效果,并推理 UI 行为。

arness_engineering

图示:“Codex 通过 Chrome DevTools MCP 驱动应用并验证其工作。”Codex 先选择目标,在触发 UI 路径前后分别对状态进行快照,通过 Chrome DevTools 观察运行时事件,应用修复,重启,并循环执行验证,直到应用状态完全清洁无误。

在可观测性工具方面,我们也采用了同样的方法。日志、指标和追踪通过本地可观测性栈暴露给 Codex,该栈在每个工作树中都是临时的。Codex 操作完全隔离的应用版本——包括其日志和指标,任务完成后这些数据会被销毁。智能体可以使用 LogQL 查询日志,使用 PromQL 查询指标。有了这些上下文,诸如“确保服务启动时间不超过 800 毫秒”或“这四个关键用户路径中的任何 span 都不超过 2 秒”这样的提示就变得可执行了。

full_observability_stack

图示:“在本地开发环境中为 Codex 配备完整的可观测性栈”。应用程序将日志、指标和追踪数据发送至 Vector,Vector 再将数据分发到包含 Victoria Logs、Metrics 和 Traces 的可观测性栈,各组件分别通过 LogQL、PromQL 或 TraceQL API 查询。Codex 利用这些信号进行查询、关联和推理,随后在代码仓库中实施修复,重启应用程序,重新运行工作负载,测试 UI 流程,并在反馈循环中重复这一过程。

我们经常看到单次 Codex 运行在某个任务上持续工作超过六小时(往往是在工程师休息期间)。


语境管理与知识架构:把仓库作为事实来源

概要:用目录式 AGENTS.md 和结构化 docs 提供“地图”。

在让智能体高效处理大型复杂任务时,语境管理是最大的挑战之一。我们最早学到的一条经验很简单:给 Codex 一份地图,而不是一千页的说明手册。

我们曾尝试过“单一庞大的 AGENTS.md⁠(新窗口打开)”方案,但结果以可预见的方式失败了:

  • 上下文是一种稀缺资源。一份庞大的说明文件会挤占任务、代码和相关文档的空间——结果是智能体要么忽略关键约束,要么开始优化错误的目标。
  • 过度指引等同于无指引。当一切都被标为“重要”时,实际上没有什么是真正重要的。智能体最终只会在局部进行模式匹配,而不是有意识地完成导航。
  • 内容会迅速腐坏。庞大的手册很快就会变成过时规则的“墓地”。智能体无法判断哪些内容依然有效,人类也停止维护,文件最终悄然变成看似有用却易误导的隐患。
  • 难以验证。单一的大文件不便于进行机械化检查(如覆盖率、新鲜度、归属、交叉链接),因此内容偏移不可避免。

因此,我们不把 AGENTS.md 当作百科全书,而是将其视为目录式入口。

代码仓库的知识库存放在结构化的 docs/ 目录中,并被视为事实来源。简短的 AGENTS.md(约 100 行)会注入智能体的上下文,主要作为目录式入口,指向其他更深入的事实来源。

纯文本

TEXT
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

代码仓库内的知识库结构布局。

设计文档经过分类和索引,包含验证状态以及定义智能体优先运行原则的一组核心信条。架构文档提供各领域及包分层的顶层地图。质量文档则对每个产品领域和架构层进行评分,并持续跟踪差距变化。

计划被视为一等公民。针对小型变更会使用临时、轻量的计划;而复杂工作则通过执行计划记录,并将进度与决策日志一并提交至代码仓库。进行中的计划、已完成的计划以及已知的技术债务都会进行版本管理并集中存放,使智能体在无需依赖外部上下文的情况下即可独立运作。

这实现了渐进式呈现:智能体从一个小而稳定的入口出发,并被引导逐步了解接下来应查找的信息,而不是一开始就被大量内容淹没。

我们通过机械化方式强制执行。专用的代码规范检查器和持续集成任务会验证知识库是否为最新、是否有交叉链接,以及结构是否正确。一个定期运行的“文档维护”智能体会扫描那些与实际代码行为不符、已过时或失效的文档,并自动发起修复拉取请求。

给 Codex 一份地图,而不是一千页的说明手册。


智能体可读性优先:将知识收敛到仓库

概要:仓库内可见即存在;选择“无聊技术”;用不变量而非微观管理。

随着代码库不断演进,Codex 的设计决策框架也必须相应更新。

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

从智能体的视角来看,任何在运行时无法在上下文中访问的信息,实际上都不存在。

存放在 Google Docs、聊天记录或人类记忆中的知识,对系统而言不可见。智能体所能看到的,只有仓库本地、具备版本控制的工件(如代码、Markdown 文档、数据结构、可执行方案)。

agent_knowledge

图示标题:“智能体知识的边界:Codex 看不见的内容就等于不存在。”图中,Codex 的知识被描绘成一个有限的气泡。气泡下方列举了若干不可见的知识示例——Google Docs 文档、Slack 消息以及人类的隐性知识。箭头表明:要让这些信息对 Codex 可见,必须将其以 markdown 形式编码进代码仓库。

我们逐渐意识到,必须不断将更多上下文信息纳入代码仓库。比如那次在 Slack 上的讨论,让团队达成了架构模式的共识——如果智能体无法检索到这些内容,它就如同对三个月后入职的新员工一样不可见,完全不会知道这些信息。

为 Codex 提供更多上下文,意味着要有组织地呈现并暴露正确的信息,让智能体能够据此进行推理,而不是用零散的指令让它不堪重负。就像你会为新成员介绍产品原则、工程规范和团队文化(包括表情符号偏好)一样,将这些信息传递给智能体,可以让其输出结果更契合团队预期。

这一思路让许多权衡变得清晰。我们倾向于选择那些能在仓库内完全掌握并推理的依赖和抽象。通常被称为“无聊”的技术,由于具备可组合性、API 稳定性以及在训练集中的表现,更容易被智能体建模。在某些情况下,让智能体重新实现部分功能,比绕过公共库中不透明的上游行为更高效。例如,我们没有直接引入通用的 p-limit 类包,而是实现了自有的并发 map 辅助函数:它与我们的 OpenTelemetry 监控深度集成,拥有 100% 的测试覆盖率,并且完全符合运行时的预期行为。

将更多系统内容转化为智能体可直接检查、验证并修改的形式,能够显著提升杠杆效应——不仅对 Codex 有益,对其他同样在代码库中工作的智能体(如 Aardvark)亦然。

仅靠文档无法确保完全由智能体生成的代码库保持一致性。我们通过强制执行不变量,而非对实现细节进行微观管理,让智能体能够快速交付成果,同时不削弱基础架构。例如,我们要求 Codex 必须在边界处解析数据结构,但并不限定具体实现方式(模型倾向使用 Zod,但我们并未指定必须采用该库)。

系统脚手架
人不再写代码

架构与边界:分层域模型与机械化约束

概要:严苛依赖约束与自定义 lint,保障速度与一致性。

智能体在具备严格边界和可预测结构的环境中效率最高,因此我们围绕一种严谨的架构模型构建了应用。每个业务域被划分为固定的层级,依赖方向经过严格校验,并且只允许有限的依赖边。所有这些约束都通过自定义的代码规范检查器(当然是由 Codex 生成的)和结构性测试进行机械化强制执行。

下图展示了规则:在每个业务域(如 App Settings),代码只能按固定的层级顺序“向前”依赖(Types → Config → Repo → Service → Runtime → UI)。跨域关注点(如认证、连接器、可观测性、功能开关)必须通过唯一且明确的接口 Providers 进入系统。任何其他依赖都被禁止,并由机械方式强制执行。

cross-cutting_boundries

图示标题为“分层域架构与显式跨领域边界”。业务逻辑域内包含模块:Types → Config → Repo,以及 Providers → Service → Runtime → UI,底部为 App Wiring + UI。Utils 模块位于边界之外,并向 Providers 提供支持。

这种架构通常要等到团队规模达到数百名工程师才会考虑实施。而在智能体编程模式下,它却是早期的必要前提:正是这些约束,才能在保证速度的同时避免系统腐化或架构漂移。

在实际执行中,我们通过自定义代码规范检查器、结构性测试,以及少量“风格不变量”来强制落实这些规则。例如,我们会利用自定义 lint 静态地约束结构化日志、模式和类型的命名规范、文件大小限制,以及平台特定的可靠性要求。由于这些 lint 是定制的,我们会在错误提示中嵌入修复建议,使智能体能够直接获取整改指令。

在人类优先的工作流程中,这些规则可能显得过于繁琐或束缚。但在智能体环境下,它们反而成为效率倍增器:一旦被编码,便可在所有场景中同时生效。

与此同时,我们明确界定哪些约束至关重要,哪些则无关紧要。这就像领导一个大型工程平台团队:在中心层面严格执行边界,在本地层面赋予自主权。我们高度关注边界、正确性和可复现性。在这些边界之内,我们允许团队——或智能体——在解决方案的表达方式上拥有充分的自由度。

生成的代码未必总能符合人类的风格偏好,这没关系。只要输出结果正确、可维护,并且对后续智能体运行具有良好的可读性,就已达标。

人类的风格偏好会持续反馈到系统中。评审意见、重构拉取请求以及面向用户的缺陷,都会被记录为文档更新或直接写入工具中。当文档不足以覆盖时,我们会将规则提升到代码层面。

用不变量保障一致性,而非微观管理。


吞吐量导向的合并策略:最小阻塞与快速反馈

概要:高吞吐量环境下,短 PR 与重跑优先于阻塞。

随着 Codex 吞吐量的提升,许多传统的工程规范反而变得事与愿违。

代码仓库采用最少阻塞的合并机制。拉取请求(PR)生命周期极短。测试中的偶发错误通常通过后续重跑解决,而不是无限期阻塞进度。在智能体吞吐量远超人类注意力的系统中,修正成本低,等待代价高。

在低吞吐量环境中,这样做是不负责任的;而在这里,这往往是正确的权衡。


“智能体生成”的范围:不仅是代码

概要:从产品代码到 CI、文档、评测与仪表盘,全由 Codex 产出。

当我们说代码库由 Codex 智能体生成时,我们指的是代码库中的全部内容。

智能体的产出包括:

  • 产品代码与测试
  • 持续集成(CI)配置与发布工具
  • 内部开发者工具
  • 文档与设计历史
  • 评估工具集
  • 评审意见与回复
  • 管理仓库本身的脚本
  • 生产环境仪表盘定义文件

人类始终在环中参与,但所处的抽象层级已不同于以往。我们负责确定优先级,将用户反馈转化为验收标准,并验证最终成果。当智能体遇到困难时,我们将其视为信号:识别缺失的内容——工具、护栏、文档——并通过 Codex 自身来补全和修正,始终将改进反馈回代码仓库。

智能体直接使用我们的标准开发工具。他们会获取评审反馈、在代码中逐条回应、推送更新,并且通常会自行压缩并合并拉取请求(PR)。

说明手册
给智能体一份地图

自主性演进:单提示驱动端到端新功能

概要:测试、验证、评审、回滚等被编码后实现端到端闭环。

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

在收到单个提示后,智能体现在可以执行以下操作:

  1. 验证当前代码库状态
  2. 复现已报告的缺陷
  3. 录制演示故障的视频
  4. 实施修复方案
  5. 通过运行应用验证修复效果
  6. 录制第二段视频,展示问题已解决
  7. 提交拉取请求(PR)
  8. 回应智能体和人工反馈
  9. 检测并修复构建失败
  10. 仅在需要判断时才交由人工处理
  11. 合并更改

此类行为高度依赖于本仓库的具体结构和工具链,若无类似投入,不应假定可直接推广——至少目前尚不可行。

高自主性建立在可执行工具链与结构之上。


熵控制与垃圾回收:黄金原则与自动重构

概要:用有主见的规则加后台任务抑制漂移与技术债。

完全的智能体自主性也会引入新的问题。Codex 会复制仓库中已有的模式——哪怕这些模式本身存在不均衡或次优之处。随着时间推移,这必然导致偏移。

最初,这项工作完全依靠人工完成。我们的团队曾经每周五(占一周时间的 20%)都在清理“AI 残留垃圾”。毫不意外,这种方式根本无法扩展。

相反,我们开始将我们称为“黄金原则”的内容直接写入代码仓库,并建立了定期的自动清理流程。这些原则是有主见的、机械化的规则,旨在确保代码库在未来的智能体运行中保持可读性和一致性。例如:

  • 我们倾向于使用共享的工具包,而不是手写辅助函数,以便集中管理不变量。
  • 我们不会“YOLO 式”地随意探查数据——而是验证边界或依赖类型化的 SDK,从而避免智能体在猜测的数据结构上误操作。

我们会按固定节奏运行一组后台 Codex 任务,扫描偏离项、更新质量评级,并发起有针对性的重构拉取请求。这些 PR 大多可在一分钟内完成评审并自动合并。

这就像垃圾回收机制。技术债务犹如高利贷:几乎总是持续以小步偿还,比任其累积后再痛苦集中处理更优。人的风格偏好只需一次明确,之后便能在每一行代码上持续自动执行。这样,我们能够每天发现并解决不良模式,而不是让它们在代码库中蔓延数日或数周。

技术债务犹如高利贷,持续小步偿还更优。


展望与未知:脚手架即规范,环境即生产力

概要:已在内部实践有效,但长期一致性与人机边界仍在探索。

迄今为止,这一策略在 OpenAI 的内部发布和推广中运作良好。为真实用户打造切实可用的产品,使我们的投入立足于现实,并引导我们迈向长期可维护性。

我们尚不清楚,在一个完全由智能体生成的系统中,架构一致性在多年间会如何演变。我们仍在探索人类判断力在哪些环节能发挥最大杠杆作用,以及如何将这种判断力编码,使其能够持续累积。同时,我们也未知,随着模型能力不断提升,这个系统将会如何发展。

我们已经清楚地看到:构建软件依然需要严谨的规范,但这种规范更多体现在系统脚手架上,而非具体代码本身。那些维持代码库一致性的工具、抽象层和反馈机制正变得愈发重要。

我们当前最艰巨的挑战,是设计出环境、反馈循环和控制系统,帮助智能体实现我们的目标:在大规模下构建并维护复杂、可靠的软件。

随着 Codex 等智能体在软件生命周期中承担越来越多的工作,这些问题将愈发重要。我们希望通过分享一些早期经验,帮助你判断精力的投入方向,从而专注于构建产品。