工程技术:在智能体优先的世界中利用 Codex | OpenAI

过去我们谈到 AI 编程时,常常把它理解为一种“更强的代码补全”或“更聪明的结对程序员”:人类提出需求,AI 生成函数、测试或局部实现,工程师再负责检查、修改和合并。

但 OpenAI 在《Harness Engineering》这篇文章中描述的并不是这种工作流。

这篇文章真正值得关注的地方,不是 Codex 能不能写代码,而是当一个代码库几乎完全由智能体生成时,软件工程本身会发生什么变化。Codex 不只是写产品代码,也生成测试、CI、发布工具、内部开发者工具、文档、评估框架、审查评论、仓库管理脚本,甚至生产仪表盘定义文件。换句话说,智能体开始进入软件生命周期的更多环节。

这带来的关键变化是:人类工程师的价值不再主要体现为亲手写下每一行代码,而是体现在如何设计一个让智能体能够可靠工作的系统。

这套系统包括清晰的仓库上下文、稳定的架构边界、可执行的工程规范、自动化测试、可观测性、审查反馈循环,以及能够持续清理技术债的“垃圾回收”机制。工程师不只是使用 Codex,而是在为 Codex 构建一个可以理解、行动、犯错、修正并持续演化的工程环境。

因此,这篇文章表面上是在讲 Codex 如何生成代码,深层上其实是在讲一个更大的问题:

当软件越来越多地由智能体实现时,工程纪律应该从“人如何写代码”转移到“系统如何约束、引导和验证智能体”。

一、原文核心观点

OpenAI 团队做了一个实验:用 Codex 从空仓库开始构建一个真实软件产品,要求没有一行代码由人类手写;五个月后,这个仓库约有一百万行代码、约 1,500 个 PR,由一个很小的工程团队推动,并且产品已经有真实内部用户和外部 Alpha 测试者。

1. 人类掌舵。智能体执行。

人类仍然掌舵,但主要工作从写代码转向设计环境、明确目标、建立约束和反馈回路,从而使 Codex 智能体能够可靠地工作。

从一个空的 Git 代码仓库开始,初始架构 — 包括代码仓库结构、CI 配置、格式化规则、包管理器设置和应用框架 — 是在一小套现有模板的指导下,由 Codex CLI 使用 GPT‑5 生成的。就连指导智能体如何在代码仓库中工作的初始 AGENTS.md 文件本身也是由 Codex 编写的。

2. 重新定义工程师的角色:设计智能体能工作的系统

由于缺乏人工编码的实践,工程师工作的重点转向了系统、架构和杠杆作用

工程师的角色变了:从“亲自编码”变成“设计智能体能工作的系统”

这其实是一个很大的思维转变:
过去工程师问:“我要怎么实现?”
现在工程师问:“我要怎样让智能体可靠地实现?”

早期进展较慢,这并不是因为 Codex 不具备相应的能力,而是因为环境的规范不够明确。该智能体缺乏实现高级目标所需的工具、抽象层和内部结构,因而无法取得进展。OpenAI工程团队的主要任务成了协助智能体完成有用的工作。

在实践中,这意味着采用深度优先的工作方式:将更大的目标拆解为更小的构建模块(设计、代码、评审、测试等),提示智能体去构建这些模块,并使用它们去解锁更复杂的任务。

3. 智能体审查智能体

人类几乎完全通过提示与系统交互:工程师描述任务,运行智能体,并允许其打开一个 Pull Request。为了推动 PR 的完成,OpenAI 团队会指示 Codex 在本地审核其自身的更改,在本地和云端请求额外的特定智能体审查,对任何人工或智能体给出的反馈做出响应,并循环往复,直到所有智能体审核人员都满意为止(这实际上是一个 Ralph Wiggum 循环)。Codex 直接使用标准开发工具(gh、本地脚本和嵌入代码仓库的技能)来收集情境,而无需人工将内容复制粘贴到 CLI 中。

这里的 Ralph Wiggum 循环 是一个 AI 编程圈里的梗/术语,指的是:

让 AI 智能体反复执行同一个任务 → 自查/跑测试/收集反馈 → 修复问题 → 再审查 → 再修复……直到检查条件全部通过。

名字来自《辛普森一家》里的 Ralph Wiggum,一个经常显得笨拙但很执着的角色。这个梗在 AI coding 场景里通常不是夸“聪明”,而是强调一种笨办法但有效的自动迭代:不用指望模型一次写对,而是让它不停循环、根据失败反馈继续改。相关解释通常把它描述为一个反复给 AI agent 输入任务、让它持续迭代直到完成的循环。

放回这段话里,它大概是这个意思:

  1. 工程师给 Codex 一个任务。
  2. Codex 修改代码并开 PR。
  3. Codex 自己先本地 review。
  4. 再让其他智能体 review。
  5. 收到人类或智能体反馈后继续改。
  6. 再次 review。
  7. 一直循环,直到所有 reviewer 都满意。

所以它不是一个正式算法名,更像是一个工程实践梗:把“写代码—检查—修复—再检查”变成 AI 可以自动跑的循环。

这也是文章想强调的重点:人的工作不再是每次亲手改代码,而是设计这个循环里的任务描述、审查标准、工具入口和退出条件

人类可以审核 Pull Request(合并请求),但并非必须这样做。随着时间的推移,团队已将几乎所有的审核工作调整为用智能体对智能体的方式来处理。

4. 提高应用程序的可读性:可观测性不只是给人看的,也要给智能体看

OpenAI 团队让 Codex 能启动应用、操作 UI、读取 DOM 快照、截图、通过 Chrome DevTools 观察运行时事件,从而复现 bug、验证修复和理解 UI 行为

他们还把日志、指标、追踪数据暴露给 Codex,让它能用 LogQL、PromQL 等方式查询系统状态。Codex 在该应用程序的一个完全独立的版本上运行,一旦任务完成,该版本的所有内容,包括日志和指标,都会被删除。智能体可以使用 LogQL 查询日志,使用 PromQL 查询指标。有了这些情境,像“确保服务启动在 800ms 内完成”“这四个关键用户旅程中的任何跨度都不得超过两秒”这样的提示就变得可行了。

这点很重要:AI 要可靠工作,不能只靠自然语言指令,还要能看到运行结果。

5.代码库要变成“智能体友好的工作环境”

让智能体能够直接从代码仓库推理出完整的业务领域

从智能体的角度来看,它在运行时无法在情境中访问的任何内容都是不存在的。存储在 Google Docs、聊天记录或人们头脑中的知识都无法被系统访问。代码仓库本地的、已版本化的工件(例如,代码、Markdown、模式、可执行计划)就是它所能看到的全部。

Agent无法访问 = 不存在

“更多情境”而不是“更多提示词”

少靠临时 prompt,多靠结构化文档、稳定抽象、清晰测试和透明工具

不要每次都在 prompt 里写:

“请遵守我们团队的编码规范、不要用某某库、错误日志要这样打、UI 文案要这样写、emoji 要这样用……”

这样会很脆弱,因为:

  • 提示词太长,模型容易遗漏;

  • 每个工程师写法不同,输出不稳定;

  • 同样的问题会反复解释;

  • 规范没有版本控制,也无法自动检查。

更好的做法是把这些东西沉淀到仓库里,比如:

  • docs/product-principles.md

  • docs/engineering-guidelines.md

  • AGENTS.md

  • 架构说明

  • lint 规则

  • 测试

  • 示例代码

  • 代码生成模板

  • 内部工具说明

这样 Codex 不是靠一次性的临时指令工作,而是能在仓库里读到稳定、结构化、可引用的项目上下文。

为 Codex 提供更多情境意味着要组织和展示正确的信息,好令智能体能够基于这些信息进行推理,而不是用临时指令使其不堪重负。就像你不会每天给新同事口头讲一遍团队规范,而是给他 onboarding 文档、代码规范、设计原则、项目结构、评审标准一样,将这些信息提供给智能体会带来更一致的输出。

“枯燥技术”反而更适合智能体

OpenAI团队倾向于选择那些可以完全内化于在仓库中进行推理的依赖项和抽象

对智能体来说,通常被称为“枯燥”的技术,由于其可组合性、API 稳定性和在训练集里的表现,往往更容易建立模型。

这里的“枯燥技术”大概指成熟、稳定、常见、不花哨的技术,比如:

  • 普通 REST API

  • SQL

  • React 常规模式

  • TypeScript 常规类型

  • Node 标准库

  • 简单清晰的工具函数

  • 成熟稳定的库

这些东西对 AI 友好,因为它们:

  • 文档多;
  • 训练数据里出现频率高;
  • 行为稳定;
  • API 不经常变;
  • 抽象简单;
  • 容易组合;
  • 错了也容易通过测试发现。

相反,一些“聪明”的、新潮的、黑盒的、隐式行为很多的抽象,对人类高级工程师可能很优雅,但对智能体可能很难推理。

例如某个库内部做了很多魔法:

doSomethingSmart(config)

人类可能知道这个库的坑,但 Codex 未必知道。它只能看到调用方式,看不到内部运行逻辑,也不一定理解所有边界情况。

所以OpenAI团队的意思是:
AI 时代的好技术选型,不只是看人类写起来爽不爽,还要看智能体能不能读懂、预测、测试和修改。

为什么有时宁愿自己实现,也不用公共库

在某些情况下,让智能体重新实现部分功能子集比绕过公共库中不透明的上游行为更便宜。

例如,OpenAI团队没有引入通用的 p-limit 风格包,而是投入使用了他们自己的带并发的 map 辅助函数:它与他们的 OpenTelemetry 仪表紧密集成,具备 100% 的测试覆盖率,并且其行为完全符合他们的运行时预期。

p-limit 这一类包通常用于控制并发数量。比如你有 1,000 个异步任务,但不想一次全跑,只想每次最多跑 5 个。

普通做法可能是:

import pLimit from "p-limit";

const limit = pLimit(5);

await Promise.all(
  items.map(item => limit(() => processItem(item)))
);

这本身没问题。但 OpenAI 这篇文章说,他们有时会选择自己写一个类似的内部工具函数,比如:

await mapWithConcurrency(items, 5, async item => {
  await processItem(item);
});

为什么?

不是因为他们觉得公共库不好,而是因为对 Codex 来说,自己仓库里的实现更透明。

他们自己的 helper 具备几个优势:

第一,行为完全可见。
Codex 可以直接打开源码,看这个函数到底怎么处理错误、取消、重试、并发、日志。

第二,和内部观测系统集成。
文中提到它和 OpenTelemetry 紧密集成。也就是说,这个并发 map 函数不只是“跑任务”,还会记录 tracing、metrics、耗时、失败情况等。

第三,有 100% 测试覆盖率。
Codex 改代码时可以跑测试,知道这个 helper 的预期行为是什么。

第四,符合他们自己的运行时预期。
公共库的边界行为可能不完全符合他们的系统要求。比如:

  • 任务失败时是否立刻停止?
  • 是否保留结果顺序?
  • 是否支持 abort signal?
  • 是否记录 span?
  • 是否暴露指标?
  • 并发任务抛错时怎么聚合错误?
  • 是否适配他们自己的 runtime?

如果用公共库,Codex 可能要绕过一堆“不透明的上游行为”。但如果是内部实现,AI 可以直接读代码、读测试、读文档,然后更可靠地使用它。

这段话真正想表达的工程原则

它不是在鼓励“不要用第三方库,全部自己造轮子”。

它真正想说的是:

在智能体主导代码生成的环境里,技术选型要考虑“可推理性”。

也就是说,一个依赖或抽象是否适合,不只看:

  • 人类是否熟悉;
  • npm 下载量高不高;
  • 功能是不是强大;
  • 写起来是不是短。

还要看:

  • Codex 能不能从仓库里理解它;
  • 行为是不是明确;
  • 有没有测试;
  • 有没有文档;
  • 出问题时能不能定位;
  • 它是否和内部日志、指标、追踪系统打通;
  • 它是否减少智能体的不确定性。

将系统的更多部分转化为智能体可以检查、验证并直接修改的形式,可以直接提高杠杆效应

6. 将代码仓库设为记录系统

要给 Codex 的是一张地图,而不是一本 1,000 页的说明书

大型的 AGENTS.md 存在以下问题:

  • 情境是一种稀缺资源。一个巨大的指令文件会挤掉任务、代码和相关文档 — 因此智能体要么会错过关键约束条件,要么开始针对错误的约束条件进行优化。
  • 过多的指导反而变得无效当一切都 "重要"时,一切都不重要了。智能体最终会在本地进行模式匹配,而不是有意识地进行导航。
  • 它会立即腐烂。一本庞杂的手册会变成陈旧规则的坟场。智能体无法判断哪些信息仍然有效,一旦人类停止维护它,此文件就会悄然成为一个颇具吸引力的麻烦源头。
  • 这很难核实。单个 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

design-docs/包括验证状态和一套核心理念,定义了智能体优先的操作原则。

ARCHITECTURE.md提供域和包分层的顶层地图。一份高质量的文档会对每个产品领域和架构层进行评分,并随着时间的推移追踪差距。

临时轻量计划用于小幅变更,而复杂工作则记录在exec-plans/中,并附带进度和决策日志,这些日志会被提交到代码仓库。活跃计划(active/)、已完成计划(completed/)和已知的技术债务(tech-debt-tracker.md)都已进行版本控制并集中存放,使智能体能够在不依赖外部情境的情况下运行

渐进式披露:智能体从一个小而稳定的切入点开始,并被指导下一步该去哪里查看,而不是一开始就被淹没。

专职的 linter 和 CI 作业会验证知识库的更新状况、是否已交叉链接且结构正确。一个定期运行的“doc-gardening”智能体会扫描那些不再反映真实代码行为的过时或废弃文档,并发起修复用的 Pull Request。

7. 架构约束比以往更重要

仅靠文档本身,是没法保持完全由智能体生成的代码库的连贯性的。

当代码主要由智能体生成时,工程团队不能只靠“写文档”和“人工 review”来保持代码质量,而要把架构原则、工程品味和质量要求变成自动化规则。

不要一条条教 Codex 怎么写代码;要给它明确边界,并用工具强制执行边界。

强制执行不变量,而非对实施过程进行微观管理

通过强制执行不变量,而非对实施过程进行微观管理,我们令智能体能够快速交付,而且不会削弱基础。例如,OpenAI团队要求 Codex 在边界处解析数据形状,但不规定具体实现方式(模型似乎偏好 Zod,但OpenAI团队没有指定特定库)。

“不变量”就是无论谁写代码,都必须始终成立的规则。

例如:

  • 数据进入系统边界时必须被解析和校验;

  • 业务层不能直接依赖 UI 层;

  • 日志必须结构化;

  • 文件不能无限变大;

  • 类型、schema、model 命名必须一致;

  • 某些平台可靠性要求必须满足。

他们不会对 Codex 说:

你必须用 Zod,函数必须这样写,文件必须这样拆。

而是说:

外部数据进入边界时,必须经过 shape validation。

也就是说,他们规定结果和边界条件,但不规定每一步具体实现

这很像管理一个工程团队:你不应该管每个工程师每一行代码怎么写,但你要规定系统不能违反哪些底线。

为什么要严格的分层架构?

智能体在具有严格边界和可预测结构的环境中最为高效,因此OpenAI团队围绕一个严格的架构模型构建了该应用。每个业务域都划分为一组固定的层,依赖方向经过严格验证,并且仅允许有限的一组边。这些约束是通过自定义的 linter(当然是由 Codex 生成的!)和结构测试机械地强制执行的。

下图展示了规则:在每个业务领域内(例如应用设置),代码只能“向前”依赖于一组固定的层(Types → Config → Repo → Service → Runtime → UI)。横切关注点(认证、连接器、遥测、功能标志)通过一个单一的显式接口进入:Providers。其他任何内容都不被允许,并将通过自动化方式强制执行。

“横切关注点”就是很多业务模块都会用到的公共能力,如果没有约束,Codex 可能会在任何地方直接 import 这些东西。短期看很方便,长期看会导致每个模块都和全局系统耦合。

对于编码智能体来说,这是一个早期的先决条件:有了约束,速度才不会下降,架构才不会漂移。

对 AI 智能体来说,这些规则很重要,因为智能体会快速生成大量代码。如果没有边界,它可能今天在一个地方写一个快捷实现,明天在另一个地方复制类似模式,最后架构迅速漂移。

自定义 linter 和结构测试的作用是什么?

在实践中,OpenAI团队通过自定义的代码检查器和结构测试来强制执行这些规则,并辅以一小组“品味不变式”。例如,OpenAI团队通过自定义 lint 静态地强制执行结构化日志记录、模式和类型的命名约定、文件大小限制,以及特定平台的可靠性要求。

约束不是靠人记住,而是用工具机械执行。

这点非常关键。

如果只是写在文档里:

请不要让 Service 依赖 UI。

Codex 可能会忘,人类 reviewer 也可能漏看。

但如果有自定义 linter:

Error: Service layer cannot import from UI layer.
Fix: Move UI-specific logic into the UI layer, and expose only domain behavior from Service.

那 Codex 一跑检查就会知道错在哪里,还能根据错误信息修复。

由于这些 lint 是自定义的,OpenAI团队编写错误信息时会在智能体情境中注入修复指令。

把错误信息写成适合智能体理解的“修复指令”。
以前 lint 错误主要是写给人看的;现在 lint 错误也要写给 AI agent 看。

也就是说,linter 不只是检查器,还是给智能体的教学反馈机制

在以人为本的工作流程中,这些规则可能会让人感到迂腐或束缚。有了智能体,它们就成了倍增器:一旦编码,它们就能立即应用于所有地方。

对智能体来说,规则越明确,它越不容易跑偏。

原因是智能体有两个特点:

第一,它生成代码很快。
所以错误模式也会扩散得很快。

第二,它很擅长遵守明确的、可检测的规则。
只要规则写进工具,它就可以不断修,直到通过。

所以这些规则不是为了限制速度,而是为了让高速生成不会破坏系统结构。

在中央层面强制执行边界,在本地层面允许自主权

同时,OpenAI团队还明确指出了哪些地方需要限制,哪些地方不需要限制。这类似于领导一个大型工程平台组织:在中央层面强制执行边界,在本地层面允许自主权。你非常重视界限、正确性和可重复性。在这些边界内,你允许团队或智能体在解决方案的表达方式上拥有很大的自由。

必须统一的东西:

  • 架构边界;
  • 依赖方向;
  • 数据校验;
  • 日志结构;
  • 可观测性;
  • 正确性;
  • 可重复性;
  • 安全和可靠性规则。

可以自由发挥的东西:

  • 函数内部怎么组织;
  • 局部实现细节;
  • 具体算法表达;
  • 某些代码风格;
  • 小范围的结构选择。

也就是说,中央平台只管会影响长期健康的边界,不管每个局部细节。

这对智能体尤其重要。你不能让它完全自由,否则系统会漂移;但你也不能规定得太死,否则它无法高效解决问题。

人的品味如何进入系统

生成的代码不总是符合人类的风格偏好,这也没关系。只要输出是正确的、可维护的,并且对未来的智能体运行而言清晰易读,就可以算作达标。

人类的品味会不断反馈到系统中。审查评论、重构的 Pull Request 和面向用户的 Bug 会被记录为文档更新,或直接编码到工具中。当文档不够完善时,OpenAI团队会将规则转化为代码

比如 reviewer 发现 Codex 总是写出一种不好的日志:

console.log("failed");

人类不会每次都评论:

请使用 structured logging。

而是把这个反馈沉淀成:

  • 文档更新:说明日志规范;
  • lint 规则:禁止裸 console.log
  • 自动修复提示:告诉 Codex 应该怎么改;
  • 测试规则:验证关键路径日志字段。

这就是从“人肉纠错”变成“系统纠错”。

所以人类的作用不是消失了,而是变成:

把一次性的判断,提炼成长期有效的规则。

总结

文档只能提供方向,真正稳定代码库的是自动化规则:linter、结构测试、依赖边界、命名规范、日志规范和可重复的质量检查。

更直白地说:

对人类团队来说,严格架构可能是规模变大后的补救措施;
对 AI 编码团队来说,严格架构是从一开始就必须有的基础设施。

这段背后的核心理念是:
不要试图通过不断提醒 Codex 来维持质量,而要把你的工程品味写进系统,让 Codex 每次生成代码时都被这些规则自动约束。

8. 吞吐量改变了合并的理念

随着 Codex 的吞吐量增加,许多传统的工程规范变得不再有效。

该代码仓库在运行过程中尽量减少阻塞合并门。Pull Request 的生命周期很短。测试偶发失败通常通过后续重跑来解决,而不是无限期地阻碍进展。在一个智能体吞吐量远超人类注意力的系统中,纠错成本低,而等待成本高

在低吞吐量环境中,这样做是不负责任的。而在这里,这通常是正确的选择。

9. “智能体生成”实际上意味着什么

代码库是由 Codex 智能体生成的,指的是整个代码库。

智能体的产出包括:

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

人类始终参与其中,但工作的抽象层次与过去不同。OpenAI团队优先处理工作,将用户反馈转化为验收标准,并对结果进行验证。当智能体遇到困难时,OpenAI团队将其视为一个信号:识别缺失的内容 — 工具、指导与约束、文档 — 并将其反馈到代码仓库中,始终由 Codex 自己编写修复。

每次 Codex 失败,都会变成一次“增强代码库可被智能体操作能力”的机会。

智能体可以直接使用OpenAI团队的标准开发工具。智能体会拉取审查反馈、在行内回复、推送更新,并且经常压缩并合并智能体自己的 Pull Request(合并请求)。

10. 不断提高的自主水平

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

给定一个提示,智能体现在可以:

  • 验证代码库的当前状态
  • 重现已报告的漏洞
  • 录制一个演示故障的视频
  • 实施修复措施
  • 通过运行应用程序来验证修复
  • 录制第二个视频,演示解决方案
  • 打开 Pull Request
  • 回应智能体和人类反馈
  • 检测并修复构建故障
  • 仅在需要判断时才交由人工处理
  • 合并更改

Codex 可以从一个提示开始,完成一个比较完整的新功能或修复周期。

这里的重点是自主性提高了,不是完全无人监督。

它仍然会在“需要判断时”交给人类。比如:

  • 产品取舍;
  • 用户体验判断;
  • 风险接受;
  • 是否真的符合需求;
  • 多个方案该选哪个;
  • 是否可以合并。

所以更准确地说,它是:

高度自动化的工程执行流,人类保留判断权。

此行为在很大程度上取决于此代码仓库的具体结构和工具,不应在没有类似投入的情况下假定它可以泛化 — 至少目前还不行。

智能体的自主性不是凭空来的,而是建立在专门为智能体设计的代码库结构、工具链和规则系统之上。

11. 熵与垃圾收集

完全自主的智能体也引入了新的问题——漂移

Codex 会复现代码仓库中已存在的模式 — 甚至包括那些不均衡或不够理想的模式。随着时间的推移,这不可避免地导致漂移。

这里的“熵”可以理解成:代码库随着时间自然变乱、变不一致、变难维护的趋势。

Codex 会学习和复现仓库里已有的模式。如果仓库里有一个不太理想的写法,Codex 可能会认为:

既然这里已经这样写了,那我也照着写。

于是问题会被复制。

这就是文中说的 漂移:代码库慢慢偏离原本想要的架构、质量标准和风格。

人类手动处理这个问题不具备可扩展性。

OpenAI团队将“黄金原则”的直接编码到代码仓库中,并建立了一个循环清理流程。这些原则是带有主观意见的机械规则,旨在保持代码库的可读性和一致性,以便将来运行智能体。

“黄金原则”:人类工程品味沉淀成的一组规则

“主观意见”是指这些规则来自人类团队的判断和偏好

“机械规则”是指这些品味不是停留在口头上,而是变成可以自动检查、自动执行的规则。

也就是说,人的品味被编码进系统里。

例如:

(1) OpenAI团队更倾向于使用共享的实用程序包,而不是手工编写的辅助工具,以便将不变式集中管理;

如果 Codex 每次遇到小问题都自己写一个辅助函数,代码库会很快出现一堆类似但不同的工具:

parseDate()
safeParseDate()
parseDateOrNull()
tryParseTimestamp()

这些函数可能行为略有不同,未来会很难维护。

所以他们更倾向于使用共享 utility 包。这样规则、边界行为和测试都集中在一个地方。

这对智能体也更友好,因为 Codex 下次只需要学会:

这种情况应该用这个共享工具。

而不是在每个业务模块里重新发明一遍。

(2) OpenAI团队不会使用“YOLO 式”探测数据 — 他们会验证边界,或依赖类型化的 SDK,这样智能体就不会意外地基于猜测的结构进行构建

“YOLO 式探测数据”就是不验证数据结构,直接凭感觉读取字段。

比如:

const value = payload.result.items[0].name;

这种写法的隐含假设很多:

  • result 一定存在;
  • items 一定是数组;
  • items[0] 一定存在;
  • name 一定是字符串。

如果这些假设不成立,运行时就会炸。

他们的原则是:
要么在边界处验证数据结构,要么使用类型化 SDK。不要让 Codex 基于猜测继续构建代码。

这其实和前文“边界处解析数据形状”是同一个思想。

循环清理流程

OpenAI团队会定期运行一组后台 Codex 任务,扫描偏差、更新质量等级,并发起有针对性的重构 Pull Request。其中大多数都可以在一分钟内完成审查并自动合并。

他们不是等技术债堆积很多后再集中重构,而是让 Codex 定期在后台做小规模清理。

流程大概是:

  1. 后台 Codex 任务扫描代码库;
  2. 找出偏离黄金原则的地方;
  3. 给相关区域打质量等级;
  4. 发起小范围重构 PR;
  5. 人类快速审查;
  6. 大部分可以自动合并。

其功能类似于垃圾回收。技术债务就像一笔高息贷款:不断地以小额贷款的方式偿还债务,总比让债务不断累积,再痛苦地一次解决要好得多。人类的品味一旦被捕捉,就会持续应用于每一行代码。这也使我们能够每天发现并解决不良模式,而不是让它们在代码库中传播数天或数周。

12. OpenAI团队仍在学习的内容

到目前为止,这一策略在 OpenAI 的内部发布和采纳过程中表现良好。为真实用户打造真实产品,帮助OpenAI将投资锚定在现实中,并引导他们实现长期的可维护性。

OpenAI团队尚不清楚的是,在一个完全由智能体生成的系统中,架构连贯性会如何随着时间的推移而演变。OpenAI团队仍在学习人类的判断力在哪些方面能发挥最大作用,以及如何对这种判断力进行编码,使其发挥更大作用。他们也不知道,随着时间的推移,模型的功能不断增强,这一系统将如何演变。

显而易见的是:构建软件仍然需要纪律,但纪律更多地体现在支撑结构上,而不是代码上。保持代码库一致性的工具、抽象和反馈回路变得越发重要。

OpenAI​​​​当前最棘手的挑战集中在设计环境、反馈回路和控制系统方面,帮助智能体实现人类的目标:大规模构建和维护复杂、可靠的软件。

设计环境:怎样让智能体看到正确上下文、使用正确工具、理解代码库结构;

反馈回路:怎样让智能体知道自己做得对不对,比如测试、日志、review、用户反馈;

控制系统:怎样确保智能体高速执行时不会偏离目标,比如架构约束、合并规则、质量等级、自动清理。

总结

OpenAI 的这篇文章想表达的不是“AI 将替代工程师”,而是一个更细微也更重要的判断:

软件工程的核心抽象层正在上移。

过去,工程师主要直接面对代码。我们通过写代码、改代码、review 代码来塑造系统。即使有 CI、lint、测试和代码规范,这些工具大多也是辅助人类工程师工作的。

而在 Codex 这样的智能体参与越来越深入之后,代码本身反而变成了智能体的产物。人类工程师要更多面对的是代码背后的生产系统:任务如何被描述,规范如何被表达,反馈如何被收集,错误如何被修正,技术债如何被持续清理,架构边界如何被机械地强制执行。

这意味着,未来高杠杆的工程能力,可能不再只是“我能写出优雅代码”,而是:

我能不能设计一套系统,让智能体持续写出正确、可维护、可验证、可演化的代码。

这篇文章中反复出现的几个关键词,其实构成了一套完整的方法论。

第一,是上下文工程
给 Codex 更多上下文,并不是把所有规则都塞进 prompt,而是把产品原则、工程规范、设计历史、架构说明、工具文档和团队偏好沉淀到仓库中。仓库不再只是代码存放处,而是智能体理解项目的工作环境。

第二,是架构约束
智能体生成代码的速度很快,因此坏模式扩散的速度也很快。仅靠文档和人工 review 无法保持系统连贯性。必须通过自定义 linter、结构测试、依赖方向检查、命名规范和文件大小限制,把架构品味转化为可执行的规则。对人类来说可能显得繁琐的规则,对智能体来说反而是速度放大的基础设施。

第三,是反馈回路
Codex 不能只被要求“写代码”,它还需要能够运行应用、复现 bug、查看日志、读取指标、录制视频、响应 PR 评论、修复构建失败。智能体要可靠工作,就必须能看到自己的行为结果,并根据反馈反复修正。所谓 Ralph Wiggum 循环,本质上就是把“实现—检查—反馈—修复”变成自动化迭代。

第四,是技术债的自动清理
完全自主的智能体会复现代码库中的既有模式,包括不理想的模式。如果没有治理,代码库会逐渐漂移。OpenAI 的做法不是让人类定期大扫除,而是把“黄金原则”编码进系统,让后台 Codex 任务持续扫描偏差、发起小型重构 PR,像垃圾回收一样不断偿还技术债。

第五,是人类判断力的重新定位
人类并没有退出软件工程,而是从执行层转向系统设计层。人类负责设定优先级,把用户反馈转化为验收标准,判断结果是否真的符合目标,并在智能体失败时分析系统缺了什么:是缺文档、缺工具、缺测试、缺边界,还是缺反馈机制。每一次失败都不是简单地“人类接手”,而是一次改善智能体工作环境的机会。

所以,这篇文章真正提供的不是一个 Codex 使用技巧,而是一种面向智能体时代的软件工程观:

未来的软件工程不是让 AI 在混乱的代码库里更努力地写代码,而是把代码库、工具链和组织规范改造成 AI 可以稳定推理和行动的环境。

AI 编程的瓶颈,可能不会长期停留在“模型会不会写代码”上。随着模型能力增强,更关键的问题会变成:

  • 代码库是否对智能体可理解;
  • 架构边界是否清晰;
  • 反馈是否足够及时;
  • 规则是否可执行;
  • 错误是否能自动暴露;
  • 人类品味是否能被编码进工具;
  • 技术债是否能被持续清理。

换句话说,AI 时代的软件工程纪律并没有消失,只是转移了位置。

过去纪律体现在工程师写代码时的自觉与经验;
未来纪律更多体现在系统本身的结构、约束、反馈和自动化治理中。

这正是《Harness Engineering》最重要的启发:
当智能体成为软件生产的主要执行者,工程师要打造的不只是产品,而是能够生产和维护产品的智能工程系统。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐