OpenAI 用 Codex 写到百万行代码后,真正遇到的 9 个工程问题

OpenAI 用 Codex 写到百万行代码后,真正遇到的 9 个工程问题

——从 Harness Engineering 看 AI 开发为什么不能只靠 Prompt

最近我在学习 OpenAI 的《Harness Engineering》。

一开始我以为这篇文章讲的会是:

  • 怎么写 Prompt;
  • 怎么让 Codex 一次写更多代码;
  • 怎么选模型;
  • 怎么让 Agent 更聪明。

但读完以后,我发现它真正讨论的其实是另一件事:

当 AI 已经很会写代码以后,怎样让它在一个越来越大的项目里长期、稳定、可控地工作。

OpenAI 在文章里介绍了一个内部实验:他们从一个空 Git 仓库开始,用 Codex 构建一个真实的软件产品。五个月后,仓库大约有一百万行代码,期间大约打开并合并了 1500 个 Pull Request。应用代码、测试、CI、文档、可观测性和内部工具都由 Codex 编写,人类主要负责方向、环境、意图和反馈机制。

真正值得学习的不是“一百万行代码”这个数字,而是:

代码量上去以后,他们连续遇到了一系列新的工程问题。

这些问题并不是换一个更强模型就会自动消失。

相反,他们需要不断改造整个开发环境。

我把这篇文章里的核心问题,加上整篇方法论最终形成的闭环,整理成 9 个问题。


问题一:Codex 明明会写代码,但项目就是推进得很慢

这是文章一开始就遇到的问题。

OpenAI 发现,早期进展比预期慢。

直觉上,我们可能会认为:

Codex能力不够

但他们发现真正的问题是:

环境不够明确
缺工具
缺抽象
缺内部结构

也就是说,模型可能完全有能力写出某个函数,却不知道:

应该从哪里开始?
应该改哪个模块?
项目里已有哪个能力可以复用?
完成以后该怎么验证?

一个简单例子

假设你告诉 AI:

给后台增加“删除用户”功能。

人类开发者可能会自然想到:

权限检查
↓
Service
↓
Repository
↓
Soft Delete
↓
Audit Log
↓
测试

但 Agent 不一定知道这些隐含信息。

它可能搜索到一个 UserTable.tsx,然后直接在 UI 里调用删除接口。

功能能跑。

但是整个项目结构可能已经被破坏。

OpenAI 怎么解决?

他们采用一种深度优先的方式,把大目标拆成更小的构建块:

设计
↓
代码
↓
Review
↓
测试

然后每次 Agent 推进不下去时,不再只说:

再试一次。

而是问:

到底还缺什么能力?

缺浏览器,就补浏览器。

缺内部工具,就补内部工具。

缺架构可读性,就补架构文档。

缺验证能力,就补测试和可观测性。

我认为这是整篇文章最重要的思维变化之一:

Agent 失败,不一定说明模型不够强,也可能说明环境没有给它足够的杠杆。


问题二:代码吞吐量提高以后,人工 QA 反而成了瓶颈

当 Codex 开始快速产出代码以后,新的问题出现了。

以前:

写代码

是慢的。

现在 AI 把写代码的速度提高以后:

验证代码

开始变慢。

比如每次修改 UI,人类都要:

启动应用
↓
打开页面
↓
点按钮
↓
复现 Bug
↓
检查修复
↓
查看日志

AI 一天能改很多东西。

但人的注意力是固定的。

于是:

人类 QA 成为了新的瓶颈。

OpenAI 怎么解决?

他们开始让应用本身对 Codex “可读”。

比如让 Agent 可以:

  • 启动自己的应用实例;
  • 使用 Chrome DevTools 相关能力;
  • 获取 DOM 快照;
  • 截图;
  • 导航页面;
  • 查询日志;
  • 查询 Metrics;
  • 查看 Trace。

于是流程变成:

Agent写代码
↓
Agent启动应用
↓
Agent复现问题
↓
Agent观察真实运行结果
↓
Agent修改
↓
Agent再次验证

这让我理解了一个很重要的区别。

错误做法:

Prompt:
“完成以后请仔细验证。”

更好的做法:

真的给Agent验证能力。

“提醒它验证”和“让它具备验证能力”不是同一回事。


问题三:AGENTS.md 越来越大,最后反而不好用了

项目做大以后,很自然会出现这种想法:

把所有规则都写进 AGENTS.md。

比如:

架构
编码规范
测试规范
安全规则
目录说明
工具说明
注意事项
历史经验

一开始可能很好用。

但随着项目增长:

100行
↓
500行
↓
2000行
↓
5000行

最后开始出现问题。

OpenAI 自己也试过“大型 AGENTS.md”,并明确说这是一次失败尝试。

主要有几个原因。

第一:Context 是有限资源

规则占得越多:

真正的任务
代码
相关文档

能占的空间就越少。

第二:所有东西都重要,就等于什么都不重要

如果文件里到处都是:

IMPORTANT
MUST
CRITICAL

Agent 反而不知道:

当前任务真正应该关注什么。

第三:文档会腐烂

项目已经变了。

旧规则还在。

新规则又不断加进去。

最后:

Agent无法判断哪条还是有效的。

第四:巨大文本很难机械检查

比如:

是否过期?
是否有Owner?
是否正确链接?
是否遗漏?

都很难自动检查。

OpenAI 怎么解决?

他们把:

AGENTS.md

从:

百科全书

改成:

地图

真正详细的知识放到结构化目录中,例如:

ARCHITECTURE.md
docs/design-docs/
docs/exec-plans/
docs/product-specs/
SECURITY.md
RELIABILITY.md
...

Agent 先看到一个小入口。

需要什么,再去读取什么。

这就是:

Progressive Disclosure,渐进式披露。


问题四:新的 Session 根本不知道以前发生过什么

如果你经常用 AI 开发,一定遇到过这个问题。

昨天你和 AI 讨论了两个小时。

终于确定:

以后这个模块只能这样调用。

今天开了一个新 Session。

新的 Agent:

完全不知道。

因为这些知识可能只存在于:

聊天记录
Slack
Google Docs
人的脑子

对于 Agent 来说:

它当前无法访问的信息,实际上就等于不存在。

OpenAI 怎么解决?

他们把 Repository 变成:

System of Record

真正重要的长期信息进入仓库:

代码
Markdown
Architecture
Design Docs
Execution Plans
Product Specs
Technical Debt
Schema

而且全部版本控制。

这样一个新的 Agent Session 进来以后:

不需要过去聊天历史
↓
读取Repository
↓
重新理解项目

这对 AI-first 开发非常重要。

因为未来很可能:

今天Codex
明天OpenCode
后天Claude Code

模型会换。

Session 会换。

但是:

Repository不能丢失项目记忆。

问题五:文档写得再好,Agent 还是会破坏架构

这是我认为整篇文章最关键的部分之一。

假设 ARCHITECTURE.md 里写:

UI不能直接调用Repo。

但 Agent 为了快速完成任务,还是写出了:

UI
↓
Repo

代码:

能编译
能运行
功能正常

这时候你不能再说:

AI不知道规则。

它可能知道。

真正的问题是:

系统允许它违反这个规则。

OpenAI 怎么解决?

他们建立严格的架构层级。

例如文章里的方向:

Types
↓
Config
↓
Repo
↓
Service
↓
Runtime
↓
UI

然后规定:

只能按照允许方向依赖。

再用:

Custom Linter
Structural Test
CI

机械执行。

于是:

文档:
“不要这样做。”

升级成:

这样做
↓
FAIL

这就是一个非常重要的升级:

Guideline
↓
Invariant
↓
Machine Enforcement

问题六:规则太多,又会把 Agent 束缚死

看到前面的内容以后,很容易走到另一个极端:

既然AI会乱写,
那我把所有事情全部规定死。

比如:

必须用这个库
必须用这种函数
必须建这个目录
必须写成这个模式

最后 Agent 可能变成一个非常笨的机械执行器。

OpenAI 没有这么做。

他们强调的是:

强制 Invariant,而不是微观管理 Implementation。

例如:

进入边界的数据必须验证

这是:

Invariant

但具体:

用Zod?
用自定义Parser?
用其他Schema工具?

可以让 Agent 自己决定。

我现在会把它理解成一句很简单的话:

WHAT
强约束

HOW
尽量给自由

也就是:

规定什么必须成立,不要过度规定具体怎么实现。


问题七:AI 写得太快,传统 Merge / Review 开始变成阻塞

传统软件开发流程通常是:

开发
↓
PR
↓
人工Review
↓
CI
↓
批准
↓
Merge

在人工开发速度下,这套流程很合理。

但是当 Agent 的代码吞吐量越来越高:

Agent一天能产生很多PR

人的注意力却没有增加。

于是:

Review队列

开始成为瓶颈。

OpenAI 怎么解决?

他们逐渐把大量 Review 变成:

Agent Review Agent

Codex 可以:

检查自己的修改
↓
请求其他Agent Review
↓
读取Review反馈
↓
继续修改
↓
处理Build失败
↓
重新验证
↓
推进PR

人类依然可以 Review。

但不再要求:

每一个PR都必须由人逐行检查。

人的角色逐渐变成:

决定目标
制定验收标准
处理异常
提供判断

注意,这不是:

人类不需要Review。

而是:

Review 的抽象层级发生了变化。


问题八:Agent 会复制代码库里的坏模式

Agent 有一个非常明显的特性:

它会模仿项目里已经存在的东西。

这是好事。

因为:

项目风格一致。

但也是坏事。

因为:

坏模式
也会被复制。

假设某一次为了赶进度写了:

一个临时helper

下一个 Agent:

看到这个模式
↓
继续复制

后来:

1个helper
↓
5个
↓
20个

技术债开始迅速扩散。

OpenAI 把这种现象称为:

Entropy

也就是代码库里的熵。

他们一开始怎么处理?

人类每周花时间清理所谓的:

AI slop

但很快发现:

不可扩展。

后来怎么解决?

他们建立:

Golden Principles

然后让后台 Codex 定期:

扫描偏差
↓
更新质量等级
↓
产生小型重构PR
↓
Review
↓
Merge

这更像:

Garbage Collection

不是:

几年后大重构一次。

而是:

不断偿还一点
不断偿还一点
不断偿还一点

不让坏模式积累成无法处理的大问题。


问题九:如果 Agent 每次失败都只修当前任务,同样的问题还会一直回来

这里我要特别说明:

这一条不是 OpenAI 原文单独列出的第九个章节标题,而是我从整篇文章的方法论中提炼出来的闭环。

文章里其实反复出现同一个模式:

Agent遇到困难
↓
人类判断缺了什么
↓
补工具 / 指导 / 约束 / 文档
↓
把它反馈到Repository
↓
以后Agent拥有新的能力

所以我认为整篇文章真正值得普通 AI 开发者学习的一条原则是:

不要只修 Agent 当前犯下的错误,还要研究为什么系统允许它犯这个错误。

例如:

Agent忘记验证UI

一次性处理:

提醒它“记得验证”。

Harness 处理:

给它浏览器和E2E。

再例如:

Agent绕过Scope。

一次性处理:

Prompt里加一句“不要越权”。

Harness 处理:

Runtime强制ScopeGuard。

再例如:

Agent又写了一套重复Graph流程。

一次性处理:

删掉重复代码。

Harness 处理:

Architecture Rule
+
Dependency Test

这个过程可以概括成:

Failure
↓
Root Cause
↓
Recurring?
↓
Harness Gap
↓
Docs / Tool / State / Guard / Test / CI
↓
Machine Verification

这其实把前面的 8 个问题全部串了起来。


这 9 个问题背后其实只有一条演化路线

把整个过程连起来以后,可以看到一个很有意思的模式:

Agent推进慢
↓
补工具和结构

Agent写快了
↓
人工QA跟不上

让Agent自己验证
↓
Context开始变复杂

巨大AGENTS.md失败
↓
Repository成为知识系统

知识有了
↓
Agent还是违反架构

架构规则机器化
↓
规则越来越多

只强制Invariant
↓
吞吐量继续上升

传统Review跟不上
↓
Agent Review Agent

代码越来越多
↓
Agent复制坏模式

持续Garbage Collection
↓
Agent仍然会暴露新问题

Failure → Harness

这让我意识到:

Harness Engineering 并不是第一天就设计出一套完美系统。

而是不断:

遇到真实问题
↓
分析根因
↓
把解决方案编码进环境
↓
获得更高自主性
↓
暴露新的瓶颈
↓
继续改Harness

对普通 AI 开发者来说,最应该学什么?

不是照抄 OpenAI 的:

目录结构
具体技术栈
具体Lint规则

因为你的项目和他们完全不同。

真正应该学的是他们的工作方式。

以后 AI 再做错时,不要只问:

这一次怎么修?

多问三句:

为什么会发生?

以后还会不会再发生?

如果会,
怎么让系统自动发现或阻止?

如果答案是:

以后很可能还会发生

那么这可能就不是一个普通 Bug。

它可能是:

Harness Gap

最终的解决方案可能不是 Prompt。

而是:

Documentation
Tool
State
Runtime
Guard
Test
E2E
Lint
CI
Observability

这就是我现在理解 Harness Engineering 最有价值的地方:

把 Agent 的失败,变成下一轮工程环境升级的输入。


参考资料

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

https://openai.com/zh-Hans-CN/index/harness-engineering/

注:本文按照初学者学习视角重新组织 OpenAI 原文。前 8 个问题对应原文明确讨论的工程问题;第 9 个“Failure → Harness”是作者基于原文多处方法论总结出的实践闭环,并非 OpenAI 原文单独列出的第九个问题标题。

posted @ 2026-10-04 21:10  0xMouise  阅读(19)  评论(0)    收藏  举报