@bibryam:这篇 OpenAI 文章对于测试工程师来说简直就是一座金矿。其中的洞见不是“AI 写代码”,而是:→ 如何……

X AI KOLs Timeline 工具

摘要

OpenAI 分享了其团队如何利用 Codex 代理构建一个完整的软件产品,完全不编写任何手动代码,重点在于设计环境与反馈循环,以确保代理的可靠运行。

这篇 OpenAI 文章对于测试工程师来说简直就是一座金矿。 其中的洞见不是“AI 写代码”,而是: → 如何构建代理能够可靠运行的环境 → 如何将工程品味机械化编码 → 如何通过反馈循环进行扩展而非增加人力 → 如何将可观测性转变为代理可读的基础设施 https://openai.com/index/harness-engineering/…
查看原文
查看缓存全文

缓存时间: 2026/05/25 18:56

这篇 OpenAI 文章对于 harness 工程师来说简直是一座金矿。

其洞察力不在于“AI 编写代码”,而在于: → 如何构建智能体能够可靠运行的环境 → 如何将工程品味机械性地编码 → 如何扩展反馈循环,而非增加人手 → 如何使可观测性成为智能体可读的基础设施

https://openai.com/index/harness-engineering/…


Harness 工程:在智能体优先的世界中利用 Codex

来源:https://openai.com/index/harness-engineering/ 在过去的五个月里,我们的团队一直在进行一项实验:构建并交付一个软件的内部测试版,该版本包含 0 行手动编写的代码

该产品拥有内部日常用户和外部 Alpha 测试人员。它能够发布、部署、崩溃和修复。不同之处在于,每一行代码——应用程序逻辑、测试、CI 配置、文档、可观测性以及内部工具——都是由 Codex 编写的。我们估计,构建此产品所花费的时间大约是手动编写代码所需时间的十分之一。

人类掌舵。智能体执行。

我们有意选择这一约束条件,以便构建出能够将工程速度提升数个数量级所需的一切。我们只有几周时间来交付最终达到一百万行代码的产品。为此,我们需要理解当软件工程团队的主要工作不再是编写代码,而是设计环境、指定意图并构建反馈循环,使 Codex 智能体能够可靠工作时,会发生怎样的变化。

本文将分享我们通过使用智能体团队构建全新产品所学到的东西——哪些环节出了问题,哪些环节产生了复合效应,以及如何最大化我们唯一真正稀缺的资源:人的时间和注意力。

我们从空的 git 仓库开始

对空仓库的首次提交是在 2025 年 8 月下旬。

初始脚手架——仓库结构、CI 配置、格式化规则、包管理器设置和应用程序框架——由 Codex CLI 使用 GPT-5 生成,并基于一小套现有模板进行指导。甚至最初的 AGENTS.md 文件(用于指导智能体如何在仓库中工作)也是由 Codex 编写的。

没有预先存在的人工编写的代码来锚定系统。从一开始,仓库就由智能体塑造。

五个月后,该仓库包含大约一百万行代码,涵盖应用程序逻辑、基础设施、工具、文档和内部开发者工具。在此期间,大约有 1500 个拉取请求已被打开并合并,而驱动 Codex 的工程师团队最初只有三人。这相当于每位工程师每天平均处理 3.5 个 PR,令人惊讶的是,随着团队现在扩展到七名工程师,吞吐量反而增加了。重要的是,这并非为了产出而产出:该产品已在内部被数百名用户使用,包括日常活跃的内部重度用户。

在整个开发过程中,人类从未直接贡献任何代码。这成为了团队的核心理念:不手动编写任何代码

重新定义工程师的角色

缺乏人工编码引入了一种不同类型的工程工作,专注于系统、脚手架和杠杆效应

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

在实践中,这意味着深度优先地工作:将较大的目标分解为较小的构建块(设计、代码、审查、测试等),提示智能体构建这些块,并使用它们来解锁更复杂的任务。当出现故障时,修复方案几乎从来不是“再努力一点”。因为取得进展的唯一方法是让 Codex 完成工作,所以人类工程师总是介入任务并询问:“缺少什么能力?我们如何使其对智能体既清晰又可执行?”

人类几乎完全通过提示与系统交互:工程师描述任务,运行智能体,并允许它打开拉取请求。为了推动 PR 完成,我们指示 Codex 在本地审查自己的更改,请求额外的特定智能体审查(本地和云端),响应任何人类或智能体的反馈,并在循环中迭代,直到所有智能体审查者满意(实际上,这是一个Ralph Wiggum 循环)。Codex 直接使用我们的标准开发工具(gh、本地脚本和仓库内嵌的技能)来收集上下文,无需人类复制粘贴到 CLI 中。

人类可以审查拉取请求,但不是必须的。随着时间的推移,我们已将几乎所有审查工作推向智能体之间的处理。

提高应用程序的可读性

随着代码吞吐量的增加,我们的瓶颈变成了人工 QA 能力。由于固定约束是人的时间和注意力,我们致力于通过使应用程序 UI、日志和应用指标等事物直接对 Codex 可读,来为智能体增加更多能力。

例如,我们使应用程序能够按 git worktree 启动,这样 Codex 可以每次变更启动并驱动一个实例。我们还将 Chrome DevTools 协议集成到智能体运行时中,并创建了用于处理 DOM 快照、截图和导航的技能。这使得 Codex 能够复现 bug、验证修复,并直接推理 UI 行为。

我们对可观测性工具也做了同样处理。日志、指标和跟踪通过本地可观测性栈暴露给 Codex,该栈对于任何给定的 worktree 都是临时的。Codex 在应用程序的完全隔离版本上工作——包括其日志和指标,这些在任务完成时会被销毁。智能体可以使用 LogQL 查询日志,使用 PromQL 查询指标。有了这些上下文,诸如“确保服务启动在 800ms 内完成”或“这四个关键用户旅程中没有 span 超过两秒”之类的提示就变得可行了。

我们经常看到单个 Codex 运行处理单个任务长达六小时以上(通常在人类睡觉时)。

我们将仓库知识作为真理之源

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

  • 上下文是稀缺资源。 巨大的指令文件会挤占任务、代码和相关文档——因此智能体要么错过关键约束,要么开始优化错误的目标。
  • 过多的指导会变成非指导**。** 当一切都是“重要”的时候,就没有什么是重要的了。智能体会陷入局部模式匹配,而不是有目的地导航。
  • 它会瞬间腐烂。 一个庞大的手册会变成一堆过时规则的坟墓。智能体无法判断什么是仍然正确的,人类停止维护它,文件悄然变成一个诱人的麻烦。
  • 难以验证。 单一的 blob 不利于机械检查(覆盖率、新鲜度、所有权、交叉链接),因此漂移是不可避免的。

因此,我们不是将 AGENTS.md 视为百科全书,而是将其视为目录

仓库的知识库位于结构化的 docs/ 目录中,被视为真理之源。一个简短的 AGENTS.md(大约 100 行)被注入到上下文中,主要作为一张地图,指向其他地方更深层次的事实来源。

仓库内知识存储布局。

设计文档被分类和索引,包括验证状态和一组定义智能体优先操作原则的核心信念。架构文档提供了领域和包层次结构的顶层映射。一个质量文档对每个产品领域和架构层进行评分,并随时间跟踪差距。

计划被视为一类元素。临时轻量级计划用于小变更,而复杂工作则被捕获在执行计划中,并带有进度和决策日志,这些日志被检入仓库。活动计划、已完成计划和已知技术债务都被版本化并共同定位,使智能体能够无需依赖外部上下文进行操作。

这实现了渐进式披露:智能体从一个小的、稳定的入口点开始,并被教导下一步应该看哪里,而不是一开始就被淹没。

我们在机械层面强制执行这一点。专用的 linter 和 CI 作业验证知识库是否最新、交叉链接且结构正确。一个定期的“文档维护”智能体会扫描那些不反映实际代码行为的陈旧或过时文档,并打开修复拉取请求。

智能体可读性是目标

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

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

从智能体的角度来看,任何它在运行时上下文中无法访问的东西,实际上都不存在。存在于 Google Docs、聊天线程或人类头脑中的知识,系统无法访问。仓库本地的、版本化的工件(例如,代码、markdown、模式、可执行计划)是它唯一能看到的东西。

我们学到,我们需要随着时间的推移将越来越多的上下文推入仓库。那个让团队在架构模式上达成一致的 Slack 讨论?如果智能体无法发现它,那么它就像三个月后加入的新员工一样不可读。

给 Codex 更多上下文意味着组织和暴露正确的信息,以便智能体能够对其进行推理,而不是用临时的指令淹没它。就像你引入一位新队友,介绍产品原则、工程规范和团队文化(包括 emoji 偏好)一样,给智能体这些信息会导致更一致的结果。

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

将系统更多部分拉入智能体可以直接检查、验证和修改的形式,会增加杠杆效应——不仅对 Codex,也对其他正在代码库上工作的智能体(例如 Aardvark)。

强制执行架构和品味

文档本身并不能保持完全由智能体生成的代码库的一致性。通过强制执行不变性,而不是微观管理实现,我们让智能体快速发布而不破坏基础。 例如,我们要求 Codex 在边界处解析数据类型,但对于具体如何实现则不做规定(模型似乎喜欢 Zod,但我们并未指定具体库)。

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

下面的图表显示了规则:在每个业务领域内(例如,应用设置),代码只能通过一组固定的层(类型 → 配置 → 存储库 → 服务 → 运行时 → UI)“向前”依赖。横切关注点(认证、连接器、遥测、功能标志)通过一个单一的显式接口进入:提供者(Providers)。其他任何方式都是不允许的,并通过机械方式强制执行。

这种架构通常是在你拥有数百名工程师之后才会考虑的。而对于编码智能体来说,这是一个早期的先决条件:约束是允许速度而不衰减或架构漂移的关键。

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

在人类优先的工作流程中,这些规则可能显得书呆子气或限制过多。但对于智能体来说,它们变成了倍增器:一旦编码,它们就会立即应用于所有地方。

同时,我们明确说明哪些地方需要约束,哪些地方不需要。这类似于领导一个大型工程平台组织:集中执行边界,允许本地自治。你深切关注边界、正确性和可重现性。在这些边界内,允许团队——或智能体——在如何表达解决方案方面拥有显著的自由。

生成的代码有时并不符合人类的风格偏好,这没关系。只要输出正确、可维护且对未来的智能体运行可读,它就达到了标准。

人类的品味会持续反馈回系统。审查评论、重构拉取请求和面向用户的 bug 会被捕获为文档更新,或直接编码到工具中。当文档不足时,我们会将规则提升为代码。

吞吐量改变了合并哲学

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

仓库以最小的阻塞合并门禁运行。拉取请求生命周期短。测试不稳定通常通过后续运行解决,而不是无限期地阻塞进展。在一个智能体吞吐量远超人类注意力的系统中,纠正是廉价的,而等待是昂贵的。

这在低吞吐量环境中是不负责任的。但在这里,这通常是一个正确的权衡。

“智能体生成”的真正含义

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

智能体生成:

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

人类始终在循环中,但在与以往不同的抽象层上工作。我们确定优先级,将用户反馈转化为验收标准,并验证结果。当智能体遇到困难时,我们将其视为一个信号:识别缺少什么——工具、护栏、文档——然后将其反馈回仓库,并且总是让 Codex 自己编写修复。

智能体直接使用我们的标准开发工具。他们提取审查反馈,内联回复

相似文章

驾驭工程:在智能体优先的世界中利用Codex

OpenAI Blog

OpenAI描述了一项内部实验,使用Codex智能体构建了一个零手动编写代码的生产软件产品,在五个月内由AI编写了150万行代码,开发速度提升了约10倍。团队认识到,有效的智能体驱动开发要求工程师专注于系统设计、脚手架和反馈循环,而不是直接编写代码。