过去五个月,我们团队一直在进行一项实验:构建并发布一款软件产品的内部测试版,全程未编写一行手动代码

该产品拥有内部日常用户和外部测试人员。它经历发布、部署、故障与修复的全过程。独特之处在于,每一行代码——包括应用逻辑、测试用例、持续集成配置、技术文档、可观测性系统及内部工具——均由 Codex 生成。我们估算,这种开发方式所需时间仅为手工编写代码的十分之一。

人类掌舵,智能体执行。

我们刻意选择这一约束条件,旨在构建能实现工程效率数量级提升的必要体系。在数周时间内,我们完成了百万行代码的交付。为此,我们必须重新思考:当软件工程团队的核心职责从编写代码转变为设计环境、明确意图、构建反馈闭环,以保障 Codex 智能体可靠工作时,工程范式将发生何种根本性变革。

本文将通过我们与智能体团队共同打造全新产品的实践,揭示系统崩溃的诱因、效能叠加的规律,并探讨如何最大化利用人类最宝贵的稀缺资源——时间与专注力。

从一个空的 git 仓库开始

首次提交到这个空仓库是在 2025 年 8 月下旬完成的。

初始的脚手架——包括仓库结构、CI 配置、格式化规则、包管理器设置和应用框架——都是由 Codex CLI 使用 GPT‑5 生成的,并参考了一小部分现有模板。甚至指导智能体如何在仓库中工作的初始 AGENTS.md 文件本身也是由 Codex 编写的。

系统中不存在预先编写的人类代码作为基础。从一开始,这个仓库就是由智能体塑造的。

五个月后,该代码库已包含约百万行代码,涵盖应用逻辑、基础设施、工具链、文档及内部开发者工具。在此期间,仅由三名工程师组成的小团队驱动 Codex 完成了约 1500 个拉取请求的创建与合并。这意味着每位工程师平均每日处理 3.5 个拉取请求,而随着团队扩展至七名工程师,这一处理效率仍在持续提升。尤为关键的是,这种产出并非盲目追求数量:该产品已被数百名内部用户使用,其中包括每日高频使用的内部核心用户。

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

重新定义工程师的角色

人类不再亲自动手编码,催生了另一种工程实践——聚焦于系统架构、开发框架与效能杠杆。

早期的进展比我们预期的要慢,不是因为 Codex 能力不足,而是因为环境定义不够明确。智能体缺乏实现高层次目标所需的工具、抽象概念和内部结构。我们工程团队的主要任务变成了让智能体能够完成有用的工作。

在实践中,这意味着采用深度优先的工作方式:将更大的目标分解为更小的构建模块(设计、编码、审查、测试等),引导智能体构建这些模块,并利用它们来解锁更复杂的任务。当某个环节失败时,解决方法几乎从来不是“再努力一点”。因为取得进展的唯一途径是让 Codex 来完成工作,所以人类工程师总是会介入任务并提出问题:“缺少什么能力?我们如何让智能体既能理解又能执行这种能力?”

人类几乎完全通过提示与系统交互:工程师描述任务,运行代理,并允许其开启拉取请求。为了推动拉取请求完成,我们指示 Codex 在本地审查其自身的更改,在本地和云端请求额外的特定代理审查,回应任何人类或代理给出的反馈,并在循环中迭代,直到所有代理审查者都满意为止(这本质上是一个拉尔夫·维格姆循环⁠)。Codex 直接使用我们的标准开发工具(gh、本地脚本和仓库嵌入技能)来收集上下文,无需人类在命令行界面中复制粘贴。

人类可能会审查拉取请求,但并非必须如此。随着时间的推移,我们已将几乎所有的审查工作推向了由代理之间自行处理。

提升应用程序可读性

随着代码吞吐量的增加,我们的瓶颈变成了人工质量保证能力。由于固定的限制一直是人类的时间和注意力,我们努力通过使应用程序用户界面、日志和应用指标本身对 Codex 直接可读,来为代理增加更多功能。

例如,我们将应用程序设计为可按 git 工作树启动,这样 Codex 就能为每个变更启动并驱动一个实例。我们还将 Chrome DevTools 协议接入代理运行时,并创建了处理 DOM 快照、屏幕截图和导航的技能。这使得 Codex 能够直接复现错误、验证修复方案,并推理用户界面行为。

Diagram titled “Codex drives the app with Chrome DevTools MCP to validate its work.” Codex selects a target, snapshots the state before and after triggering a UI path, observes runtime events via Chrome DevTools, applies fixes, restarts, and loops re-running validation until the app is clean.

我们对可观测性工具也采取了相同做法。通过为每个工作树临时搭建的本地可观测性栈,将日志、指标和追踪数据暴露给 Codex。Codex 在应用的完全隔离版本上运行——包括其日志和指标,这些数据在任务完成后会被销毁。智能体可以使用 LogQL 查询日志,使用 PromQL 查询指标。借助这些上下文信息,诸如"确保服务启动在 800 毫秒内完成"或"这四个关键用户旅程中没有任何跨度超过两秒"这样的提示就变得可执行了。

Diagram titled “Giving Codex a full observability stack in local dev.” An app sends logs, metrics, and traces to Vector, which fans out data to an observability stack containing Victoria Logs, Metrics, and Traces, each queried via LogQL, PromQL, or TraceQL APIs. Codex uses these signals to query, correlate, and reason, then implements fixes in the codebase, restarts the app, re-runs workloads, tests UI journeys, and repeats in a feedback loop.

我们经常看到单个 Codex 运行在单个任务上工作长达六个小时(通常是在人类睡觉的时候)。

将仓库知识打造为记录系统

上下文管理是让智能体在大型复杂任务中高效运作的最大挑战之一。我们最早学到的经验很简单:给 Codex 一张地图,而不是一本千页说明书。

我们尝试了维护"一个庞大的AGENTS.md"。它以可预见的方式失败了:

  • 上下文是一种稀缺资源。庞大的指令文件会挤占任务、代码和相关文档的空间——导致智能体要么遗漏关键约束,要么开始为错误的约束进行优化。
  • 过多的指导反而失去指导意义。当所有内容都被标注为"重要"时,实际上等于没有重点。智能体最终只会进行局部模式匹配,而非有意识地全局规划。
  • 这种方法会迅速失效。单一庞大的操作手册会变成过时规则的坟场。智能体无法分辨哪些规则仍然有效,人类也停止维护它,这份文件最终会变成诱人却无用的摆设。
  • 很难验证。单个数据块不适合进行机械检查(覆盖率、新鲜度、所有权、交叉链接),因此漂移是不可避免的。

因此,我们不再将 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

设计文档经过编目和索引,包含验证状态和一套定义"智能体优先"操作原则的核心信念。架构文档提供领域和包分层的顶层映射。质量文档对每个产品领域和架构层进行分级,并随时间推移追踪差距。

计划被视为一等工件。短暂轻量级计划用于小型变更,而复杂工作则通过执行计划来记录,其中包含进度和决策日志并提交至代码库。活跃计划、已完成计划以及已知技术债务均进行版本控制并集中存放,使智能体能够在不依赖外部上下文的情况下运行。

这实现了渐进式披露:智能体从一个小而稳定的切入点开始,然后被引导至下一步该查看的位置,而不是一开始就面临信息过载。

我们通过机械手段强制执行这一点。专门的代码检查工具和持续集成任务会验证知识库是否保持最新、正确交叉链接且结构合理。一个定期运行的"文档维护"代理会扫描那些未能反映真实代码行为的过时或废弃文档,并提交修复拉取请求。

智能体可读性是目标

随着代码库的演进,Codex 的设计决策框架也需要同步进化。

由于该代码库完全由智能体生成,其首要优化目标就是 Codex 的可读性。正如开发团队致力于提升代码对新入职工程师的可导航性,我们人类工程师的目标是让智能体能够直接从代码库本身理解完整的业务领域。

从智能体的视角来看,任何在运行过程中无法在上下文中访问的内容,实际上等同于不存在。那些存储在谷歌文档、聊天记录或人们脑海中的知识,系统都无法触及。它所能看到的,仅限于仓库本地、版本化的工件(例如代码、Markdown 文件、架构图、可执行计划)。

Diagram titled “The limits of agent knowledge: What Codex can’t see doesn’t exist.” Codex’s knowledge is shown as a bounded bubble. Below it are examples of unseen knowledge—Google Docs, Slack messages, and tacit human knowledge. Arrows indicate that to make this information visible to Codex, it must be encoded into the codebase as markdown.

我们认识到,随着时间的推移,我们需要将越来越多的上下文信息推送到代码库中。那次在 Slack 上让团队就架构模式达成一致的讨论?如果智能体无法发现它,那么它就如同三个月后新加入的员工一样无从知晓。

为 Codex 提供更多上下文意味着组织和暴露正确的信息,以便智能体能够进行推理,而不是用临时指令使其不堪重负。就像你会向新团队成员介绍产品原则、工程规范和团队文化(包括表情符号偏好)一样,为智能体提供这些信息能使其输出更符合预期。

这一框架澄清了许多权衡取舍。我们倾向于选择那些能够在代码库中完全内化并进行推理的依赖项和抽象。通常被描述为“无聊”的技术往往更容易被智能体建模,因为它们具有可组合性、API 稳定性以及在训练集中的代表性。在某些情况下,让智能体重新实现功能子集比处理公共库中不透明的上游行为更经济。例如,我们没有引入通用的 p-limit 风格包,而是实现了自己的并发映射辅助工具:它与我们的 OpenTelemetry 检测紧密集成,拥有 100%的测试覆盖率,并且完全按照我们运行时的预期方式运行。

将更多系统内容转化为智能体可直接检查、验证和修改的形式,能显著提升杠杆效应——这不仅适用于 Codex,也适用于其他在代码库上工作的智能体(例如 Aardvark)。

强化架构与风格规范

仅靠文档无法维持完全由智能体生成的代码库的一致性。通过强化不变性原则而非微观管理具体实现,我们让智能体能够快速交付成果而不破坏基础架构。例如,我们要求 Codex 在边界处解析数据结构,但不对具体实现方式作硬性规定(模型似乎偏好使用 Zod 库,但我们并未指定必须采用该特定库)。

在具有严格边界和可预测结构的环境中,智能体最为高效,因此我们围绕一个刚性的架构模型构建了应用程序。每个业务领域被划分为一组固定的层级,具有严格验证的依赖方向和有限的允许边缘。这些约束通过自定义的代码检查工具(当然是由 Codex 生成的!)和结构测试来机械地强制执行。

下图展示了该规则:在每个业务领域(例如应用设置)内,代码只能通过固定的层级结构“向前”依赖(类型 → 配置 → 存储库 → 服务 → 运行时 → 用户界面)。横切关注点(身份验证、连接器、遥测、功能开关)通过单一显式接口进入:提供者。其他任何依赖方式均被禁止,并通过机制强制执行。

Diagram titled “Layered domain architecture with explicit cross-cutting boundaries.” Inside the business logic domain are modules: Types → Config → Repo, and Providers → Service → Runtime → UI, with App Wiring + UI at the bottom. A Utils module sits outside the boundary and feeds into Providers.

这类架构通常要等到拥有数百名工程师时才会考虑。但在编码智能体时代,这成了早期必备条件:正是这些约束条件,才能确保开发速度的同时避免质量衰退或架构漂移。

在实践中,我们通过自定义的代码检查工具和结构测试,外加一小套“品味不变性”规则来强制执行这些规范。例如,我们利用自定义检查工具静态强制实施结构化日志记录、模式与类型的命名约定、文件大小限制,以及特定平台的可靠性要求。由于这些检查工具是定制的,我们编写的错误消息会将修复指导注入到智能体上下文中。

在以人为本的工作流程中,这些规则可能显得迂腐或束缚手脚。但在智能体主导的世界里,它们却成为效率倍增器:一旦编码完成,便能即刻应用于所有场景。

与此同时,我们明确界定哪些地方需要约束,哪些地方不需要。这类似于领导一个大型工程平台组织:在中心层面执行边界,在局部层面允许自主。你非常关注边界、正确性和可复现性。在这些边界之内,你允许团队——或者说智能体——在解决方案的表达方式上拥有显著的自由度。

生成的代码并不总是符合人类的风格偏好,这没关系。只要输出结果正确、可维护,并且能让未来的智能体运行顺畅,就达到了标准。

人类的审美偏好会持续反馈到系统中。审查意见、重构拉取请求以及面向用户的错误都会被记录为文档更新,或直接编码到工具中。当文档不够用时,我们会将规则提升为代码。

吞吐量改变合并哲学

随着 Codex 吞吐量的提升,许多传统的工程规范反而变得适得其反。

该代码库以最小的阻塞合并门运行。拉取请求的生命周期短暂。测试失败通常通过后续运行来解决,而不是无限期地阻碍进展。在一个智能体吞吐量远超人类注意力的系统中,修正成本低廉,而等待代价高昂。

在低吞吐量环境中,这将是不可取的。但在此处,这通常是合理的权衡。

“智能体生成"的实际含义

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

智能体生成的内容包括:

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

人类始终参与其中,但工作在与以往不同的抽象层级上。我们负责确定工作优先级,将用户反馈转化为验收标准,并验证结果。当智能体遇到困难时,我们将其视为一种信号:识别缺失的部分——工具、防护措施、文档——并通过让 Codex 自行编写修复方案,将其反馈回仓库。

智能体直接使用我们的标准开发工具。它们拉取审查反馈,在代码行内进行回复,推送更新,并经常自行压缩合并其拉取请求。

自主性不断提升

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

仅需一个提示,智能体现在就能:

  • 验证代码库的当前状态
  • 重现已报告的缺陷
  • 录制视频演示故障
  • 实施修复
  • 通过运行应用程序验证修复
  • 录制第二个视频,展示解决方案
  • 开启一个拉取请求
  • 响应代理和人工反馈
  • 检测并修复构建失败
  • 仅在需要判断时升级至人工处理
  • 合并变更

这种行为在很大程度上依赖于该代码库的具体结构和工具,不应假设在没有类似投入的情况下能够普遍适用——至少目前还不能。

熵与垃圾回收

完全自主的代理也带来了新的问题。Codex 会复制代码库中已有的模式——即使这些模式不均衡或不够理想。随着时间的推移,这不可避免地会导致代码漂移。

最初,人类手动处理这个问题。我们的团队过去每周五(占一周时间的 20%)都在清理“AI 垃圾”。不出所料,这种做法无法规模化。

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

这就像垃圾回收机制。技术债务如同高息贷款:持续小额偿还几乎总是优于任其复利累积再痛苦地一次性清偿。人类审美标准一旦确立,就会在每一行代码中持续执行。这也让我们能够每天发现并解决不良模式,而不是任由它们在代码库中扩散数日甚至数周。

我们仍在探索

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

我们尚未完全了解的是,在一个完全由智能体生成的系统中,架构一致性如何随着时间推移而演变。我们仍在探索人类判断在何处能发挥最大杠杆作用,以及如何编码这些判断以使其产生复合效应。同时,我们也不清楚随着模型能力持续增强,这一系统将如何演进。

显而易见的是:构建软件依然需要严谨性,但这种严谨性更多地体现在架构层面而非代码本身。那些保持代码库一致性的工具、抽象层和反馈循环正变得日益重要。

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

随着 Codex 等智能体在软件生命周期中承担更多职责,这些问题将愈发重要。我们希望通过分享早期经验,帮助您思考应在何处投入精力,从而专注于构建本身。