摘要
1) 一句话总结 一个小型工程团队在“零行人工手写代码”的约束下,通过构建高度适配AI的开发环境与反馈回路,利用Codex智能体在五个月内成功交付并维护了一款百万行代码级别的软件产品。
2) 核心要点
- 研发效能与规模:在0行人工代码的前提下,产出近100万行代码(涵盖应用逻辑、CI、文档、内部工具等),开发耗时仅为手写代码的约1/10。
- 团队吞吐量:团队由3名工程师起步(现增至7名),累计合并约1,500个PR,平均每位工程师每天产出3.5个PR,且吞吐量随团队扩大而提升。
- 工程师角色转变:人类不再直接写代码,而是转向系统设计、脚手架搭建与杠杆效应管理,通过拆解目标、编写提示词和构建反馈回路来驱动智能体。
- 提升智能体“可读性”:为智能体提供独立的运行实例,接入Chrome DevTools协议、LogQL和PromQL,使UI行为、日志和指标对AI直接可见、可查、可执行。
- 仓库即唯一真源:摒弃超长说明文档,将
AGENTS.md精简为约100行的目录;将结构化的仓库内文档作为系统记录,实现上下文的“渐进式披露”。 - 机械化强制架构:通过自定义linter和结构化测试,严格限制代码的单向依赖层级(Types → Config → Repo → Service → Runtime → UI),以硬约束保障代码库不腐化。
- 高吞吐量合并策略:采用最少阻塞的合并门禁,PR生命周期极短;在AI高吞吐量环境下,纠错成本远低于等待成本。
- 端到端自主性:智能体已能独立完成复现Bug、录制故障/修复视频、编写代码、响应评审反馈到最终合并的完整功能闭环。
3) 风险与缺口
- 代码漂移与“AI泥沙”:智能体会复制仓库中已有的不良模式,初期曾耗费人类每周20%的时间手动清理(现已通过后台AI任务定期进行“垃圾回收”来缓解)。
- 泛化能力受限:智能体当前的高自主性高度依赖该仓库特定的结构与工具链,目前无法直接泛化到其他缺乏同等投入的环境中。
- 长期架构演进未知:尚不清楚在一个完全由智能体生成的系统中,架构一致性在多年时间尺度上会如何演化。
- 核心控制挑战:目前最棘手的难题依然集中在如何设计环境、反馈回路与控制系统,以确保智能体能规模化地构建和维护复杂软件。
正文
在过去五个月里,我们团队一直在做一项实验:在0 行人工手写代码的前提下,构建并交付一款软件产品的内部 beta 版本。
这款产品既有内部日活用户,也有外部 alpha 测试者。它会发布、部署、出故障并被修复。不同之处在于:从应用逻辑、测试、CI 配置、文档、可观测性到内部工具的每一行代码,全部由 Codex 编写。我们估计,相比手写代码,完成这些工作大约只用了原来的 1/10 时间。
人类掌舵。智能体执行。
我们刻意选择了这样的约束,这样才能迫使我们只构建那些真正能让工程速度成数量级提升的必要能力。我们只有几周时间,要交付最终规模达到百万行代码的系统。要做到这一点,我们必须弄清楚:当软件工程团队的主要工作不再是写代码,而是设计环境、表达意图、构建反馈回路,让 Codex 智能体可靠地完成工作时,哪些东西会发生改变。
这篇文章总结了我们用一支“智能体团队”从零搭建一款全新产品的经验:哪些东西坏了、哪些效应会叠加,以及如何最大化我们唯一真正稀缺的资源——人类的时间与注意力。
从一个空的 git 仓库开始
对一个空仓库的首次提交发生在 2025 年 8 月下旬。
最初的脚手架——仓库结构、CI 配置、格式化规则、包管理器配置以及应用框架——由 Codex CLI 在 GPT‑5 的帮助下生成,并由一小套既有模板进行引导。就连用于指导智能体如何在仓库中工作的第一版 AGENTS.md,也是由 Codex 写出来的。
没有任何既存的人类手写代码可以作为锚点。从一开始,这个仓库就由智能体塑造。
五个月后,这个仓库在应用逻辑、基础设施、工具链、文档与内部开发者工具等方面累计已接近百万行代码。在这段时间里,一个仅由三名工程师驱动 Codex 的小团队,累计开启并合并了约 1,500 个 pull request。按此计算,平均吞吐量约为每位工程师每天 3.5 个 PR;更令人意外的是,随着团队规模扩大到如今的七名工程师,吞吐量反而还在提升。更重要的是,这并非“为了产出而产出”:这款产品已经被数百名内部用户使用,其中包括每天使用的内部重度用户。
在整个开发过程中,人类从未直接贡献任何代码。这逐渐成为团队的核心理念:不手写代码。
重新定义工程师的角色
不再进行“上手写代码”的人类工作,引入了一种不同类型的工程工作:围绕系统、脚手架与杠杆效应展开。
早期进度比我们预期慢,并不是因为 Codex 做不到,而是因为环境的规格说明不足。智能体缺少必要的工具、抽象与内部结构,无法朝着高层目标持续推进。于是,我们工程团队的主要工作变成了:让智能体能够做出有用的工作。
具体来说,我们采用深度优先的方式:把较大的目标拆成更小的积木(设计、编码、评审、测试等),提示智能体去构建这些积木,再用它们解锁更复杂的任务。当某件事失败时,解决办法几乎从来不是“再努力一点”。因为推进项目的唯一方式就是让 Codex 去做工作,人类工程师总要走进任务本身,反问自己:“缺少的能力是什么?我们如何让它对智能体既清晰可见、又可执行并可约束?”
人类几乎完全通过提示词与系统交互:工程师描述任务、运行智能体,然后允许它发起一个 pull request。为了把 PR 推到完成状态,我们会指示 Codex 在本地复查自己的改动、在本地与云端请求额外且更具体的智能体评审、响应任何来自人类或智能体的反馈,并在一个循环里迭代直到所有智能体评审者都满意(本质上就是一个 Ralph Wiggum Loop)。Codex 直接使用我们标准的开发工具(gh、本地脚本、仓库内嵌的 skills)来收集上下文,人类无需把内容复制粘贴到 CLI 中。
人类当然可以审查 pull request,但并非必须。随着时间推移,我们把几乎所有评审工作都推向了“智能体对智能体”的处理方式。
提升应用对智能体的可读性
随着代码吞吐量提升,我们的瓶颈变成了人类 QA 的产能。既然固定约束始终是人类的时间与注意力,我们就努力通过让应用 UI、日志、应用指标等对 Codex 直接“可读”,来为智能体增加更多能力。
例如,我们让应用能够按 git worktree 启动,这样 Codex 就能为每个变更启动并驱动一个独立实例。我们还把 Chrome DevTools Protocol 接入了智能体运行时,并创建了用于处理 DOM 快照、截图与导航的 skills。这使得 Codex 能直接复现 bug、验证修复,并推理 UI 行为。
我们也对可观测性工具做了同样的事。日志、指标与 trace 通过一个本地可观测性栈暴露给 Codex;这个栈会针对每个 worktree 临时创建,用完即销毁。Codex 在一个完全隔离的应用版本上工作——包括它的日志与指标——任务完成后一起被清理。智能体可以用 LogQL 查询日志、用 PromQL 查询指标。有了这些上下文,“确保服务启动在 800ms 内完成”或“这四条关键用户旅程里没有任何 span 超过两秒”这类提示词就变得可执行。
我们经常看到一次 Codex 运行会在单个任务上持续工作超过六小时(往往发生在人类睡觉的时候)。
让仓库内知识成为唯一真源
在让智能体能够胜任大型复杂任务这件事上,上下文管理是最大的挑战之一。我们最早学到的一条简单经验是:给 Codex 一张地图,而不是一本 1,000 页的说明书。
- **上下文是稀缺资源。**一份巨大的说明文件会挤占任务本身、代码与相关文档的空间——结果要么是智能体错过关键约束,要么开始围绕错误目标做优化。
- **指导过多会变成 无指导。**当一切都“很重要”时,就等于没有重点。智能体会倾向于做局部模式匹配,而不是有意识地导航全局。
- **它会迅速腐坏。**一份巨大的手册很快会变成陈旧规则的坟场。智能体无法分辨哪些仍然有效;人类也会停止维护;最终这个文件悄无声息地变成一个“看起来很权威、实际很误导”的陷阱。
- **它难以验证。**一个巨型 blob 不利于做机械化校验(覆盖率、时效性、所有权、交叉链接等),漂移几乎不可避免。
所以我们不把 AGENTS.md 当作百科全书,而是把它当作目录。
仓库的知识库放在结构化的 docs/ 目录中,并被视为系统记录(system of record)。一份较短的 AGENTS.md(大约 100 行)会被注入上下文,它主要充当地图,指向其他更深层的权威信息来源。
仓库内知识库布局如下。
设计文档会被归档与索引,包括验证状态以及一组定义“agent-first”运作原则的核心信念。架构文档 提供了领域划分与包分层的顶层地图。一份质量文档会对每个产品领域与架构层进行评分,持续跟踪随时间变化的缺口。
计划被当作一等公民工件。小改动用轻量且短生命周期的计划;复杂工作则记录在带有进度与决策日志、并签入仓库的 执行计划 中。活跃计划、已完成计划以及已知技术债都会被版本化并放在同一处,使智能体无需依赖外部上下文也能工作。
这实现了渐进式披露:智能体从一个小而稳定的入口开始,并被教会下一步该去哪里找信息,而不是一开始就被海量内容淹没。
我们用机械方式强制执行这一点。专门的 linter 与 CI 任务会校验知识库是否最新、是否有正确的交叉链接、结构是否符合约定。一个周期性运行的“文档园艺(doc‑gardening)”智能体会扫描陈旧或过时、与真实代码行为不一致的文档,并发起修复用的 pull request。
目标是让系统对智能体可读
随着代码库演进,Codex 用于做设计决策的框架也必须随之演进。
由于仓库完全由智能体生成,它首先针对的是 Codex 的可读性 做优化。就像团队会让代码对新入职工程师更易导航一样,我们人类工程师的目标是:让智能体能够仅凭仓库本身就推理完整的业务领域。
从智能体的视角看,凡是它在运行时无法“就地访问”的东西,等同于不存在。存在于 Google Docs、聊天线程或人的脑海里的知识,对系统而言不可见。它能看到的只有仓库本地、可版本化的工件(例如代码、markdown、schema、可执行计划等)。
我们逐渐意识到,必须不断把更多上下文推进仓库里。那场在 Slack 里对齐架构模式的讨论?如果智能体发现不了,它的“不可读”程度就和三个月后入职的新同事完全一样。
给 Codex 更多上下文,意味着要把正确的信息组织好并暴露出来,让智能体能够在其上推理,而不是用临时的零散指令把它淹没。就像你会在产品原则、工程规范、团队文化(甚至表情包偏好)上为新同事做 onboarding 一样,把这些信息提供给智能体,会带来更一致、更对齐的产出。
这种框架也帮助我们看清了许多取舍。我们更偏好那些能在仓库内被完全内化并推理的依赖与抽象。常被称为“无聊”的技术,往往因为可组合性、API 稳定性,以及在训练语料中的可表征性,而更容易被智能体建模。有些情况下,与其绕开公共库那些不透明的上游行为,不如让智能体重写一部分功能更划算。比如,我们没有引入通用的 p-limit 类包,而是实现了自己的“带并发的 map”助手:它与我们的 OpenTelemetry 埋点紧密集成,测试覆盖率 100%,行为也完全符合我们的运行时预期。
把系统更多部分拉进一种智能体能直接检查、验证与修改的形态,会提升杠杆效应——不仅对 Codex 有利,也对同样在代码库上工作的其他智能体(例如 Aardvark)有利。
强制架构与“品味”
仅靠文档无法让一个完全由智能体生成的代码库保持一致性。**我们通过强制不变量,而非微观管理实现方式,让智能体能高速交付,同时不破坏地基。**例如,我们要求 Codex 在边界处 先解析数据形状再做业务处理,但并不规定必须怎么做(模型似乎偏好 Zod,但我们并未指定必须使用该库)。
智能体在具有严格边界与可预测结构的环境中最有效,因此我们用一个刚性的架构模型来构建应用。每个业务域都会被划分为固定的一组层次,并严格验证依赖方向,只允许有限的连接边。这些约束通过自定义 linter(当然也是 Codex 生成的!)与结构性测试以机械方式强制执行。
下图展示了规则:在每个业务域内(例如 App Settings),代码只能沿着固定的层次集合“向前”依赖(Types → Config → Repo → Service → Runtime → UI)。横切关注点(auth、connectors、telemetry、feature flags)只能通过一个明确的单一接口进入:Providers。其他方式一律禁止,并由工具强制执行。
这种架构通常要等到拥有数百名工程师时才会引入。而在编码智能体时代,它是更早的前置条件:正是这些约束,才允许高速而不腐化、不漂移。
实践中,我们通过自定义 linter 与结构性测试来执行这些规则,同时还定义了一小组“品味不变量”。例如,我们静态强制结构化日志、schema 与类型的命名规范、文件大小上限,以及面向平台的可靠性要求。由于这些 linter 是定制的,我们会把错误信息写得足够“可指导”,以便把补救动作的指令注入智能体上下文。
在人类优先的工作流里,这些规则可能显得教条或束缚;但对智能体来说,它们会产生倍增效应:一旦被编码,就能在所有地方同时生效。
与此同时,我们也会明确哪些地方必须严格约束,哪些地方则不必。这很像在带领一个大型工程平台组织:集中强制边界,局部放权自治。你会非常在意边界、正确性与可复现性;在这些边界内,你允许团队——或智能体——在表达方案时拥有很大的自由度。
最终产出的代码并不总符合人类的风格偏好,但这没关系。只要输出是正确的、可维护的,并且对未来的智能体运行仍然可读,它就达标。
人类的“品味”会持续回灌到系统中。评审意见、重构 PR,以及用户可见的 bug,都会被沉淀为文档更新或直接编码进工具里。当文档不够用时,我们会把规则升级为代码层面的硬约束。
吞吐量改变了合并哲学
随着 Codex 的吞吐量提升,许多传统工程规范反而变得适得其反。
这个仓库以最少的阻塞式合并门禁运行。pull request 生命周期很短。测试 flaky 往往通过后续重跑来解决,而不是无限期阻塞进度。在一个智能体吞吐量远超人类注意力的系统里,纠正错误很便宜,而等待很昂贵。
如果在低吞吐环境里这样做会很不负责任;但在这里,它往往是正确的取舍。
“智能体生成”到底意味着什么
当我们说这个代码库由 Codex 智能体生成时,我们指的是代码库里的所有东西。
智能体会产出:
- 产品代码与测试
- CI 配置与发布工具
- 内部开发者工具
- 文档与设计历史
- 评测/验证用的 harness
- 评审意见与回复
- 管理仓库本身的脚本
- 生产环境仪表盘定义文件
人类始终在回路之中,但工作在与过去不同的抽象层。我们做优先级、把用户反馈翻译成验收标准,并验证结果。当智能体卡住时,我们把它当作信号:找出缺少的东西——工具、护栏、文档——并把它回灌进仓库,而且始终让 Codex 自己来写出修复。
智能体会直接使用我们标准的开发工具:拉取评审反馈、行内回复、推送更新,甚至经常自己 squash 并合并自己的 pull request。
自主性不断提升
随着更多开发闭环被直接编码进系统——测试、验证、评审、反馈处理与恢复——这个仓库最近跨过了一个重要阈值:Codex 已经可以端到端驱动一个新特性。
给定一个提示词,智能体现在可以:
- 验证代码库当前状态
- 复现上报的 bug
- 录制展示故障的视频
- 实现修复
- 通过驱动应用来验证修复
- 录制展示修复结果的视频
- 发起 pull request
- 响应来自智能体与人类的反馈
- 发现并修复构建失败
- 仅在需要判断力时才升级给人类
- 合并变更
这种能力高度依赖这个仓库的具体结构与工具链;在没有类似投入的情况下,不应假设它能直接泛化——至少目前还不行。
熵与垃圾回收
**完全自主的智能体也会带来新的问题。**Codex 会复制仓库里已经存在的模式——包括那些不均匀或并不理想的模式。久而久之,这不可避免地导致漂移。
一开始,人类用手工方式来处理。我们团队过去常常每周五花一整天(占一周 20%)去清理“AI 泥沙(AI slop)”。这显然无法扩展。
于是我们开始把所谓的“黄金原则(golden principles)”直接编码进仓库,并建立了一个周期性的清理流程。这些原则是带立场的、可机械执行的规则,用于让代码库对未来的智能体运行保持可读与一致。比如:(1)我们偏好共享的工具包,而不是手写零散 helper,以便把不变量集中起来;(2)我们不做“YOLO 式”的数据探测——要么在边界验证,要么依赖有类型的 SDK,让智能体无法在猜测的数据形状上构建功能。在固定节奏下,我们会运行一组后台 Codex 任务来扫描偏差、更新质量评分,并发起有针对性的重构 PR。大多数 PR 只需不到一分钟就能审查并自动合并。
这很像垃圾回收。技术债就像高利贷:几乎总是更应该以小步、持续的方式偿还,而不是任其复利累积后再痛苦地集中偿还。人类的“品味”只需捕获一次,就能持续地在每一行代码上被强制执行。这样我们也能每日捕获并纠正坏模式,而不是让它们在代码库里扩散数天甚至数周。
仍在学习的部分
到目前为止,这套策略在 OpenAI 的内部上线与采用阶段运行良好。为真实用户构建真实产品,让我们的投入始终有现实锚点,并指引我们走向长期可维护性。
我们尚不清楚的是:在一个完全由智能体生成的系统里,架构一致性在多年尺度上会如何演化。我们仍在学习人类判断在哪些地方最具杠杆,以及如何把这种判断编码进去,使其产生复利效应。我们也不知道,随着模型能力持续提升,这个系统会如何随之演进。
越来越清晰的一点是:构建软件仍然需要纪律,但这种纪律更多体现在脚手架,而不是代码本身。让代码库保持一致性的工具、抽象与反馈回路变得愈发重要。
我们目前最棘手的挑战,集中在设计环境、反馈回路与控制系统上——它们要帮助智能体完成我们的目标:以规模化方式构建并维护复杂、可靠的软件。
随着像 Codex 这样的智能体接管软件生命周期中更大比例的工作,这些问题会变得更加重要。我们希望分享这些早期经验,能帮助你思考应该把精力投到哪里,从而更轻松地把东西做出来。
相关文档
- 深入解析 Codex 智能体循环;关联理由:上下游;说明:该文拆解了智能体循环与上下文管理机制,是本文工程实践的底层运行逻辑;
- 解锁 Codex 运行框架:我们如何构建 App Server;关联理由:解说;说明:该文展开了 harness 的协议与运行框架实现,补齐本文的系统层细节;
- 用 Evals 系统化测试 Agent Skills;关联理由:延伸思考;说明:该文把本文强调的反馈回路落到可执行评测方法,形成质量保障闭环;