Skip to content

解释最近热门的 AI 新词:Harness Engineering #104

@coderPerseus

Description

@coderPerseus

标题:新兴的“Harness Engineering”指南

原文: https://x.com/charlierguo/status/2026009225663750512

作者:Charlie Guo

翻译官:Grok 4.2 beta (推荐使用「🥥 椰子翻译」浏览器插件,支持网页翻译,划词翻译,AI 翻译,youtube 字幕翻译等超多能力)

Gemini_Generated_Image_yzdvnqyzdvnqyzdv.png

这篇文章从 OpenAI 到 Stripe 到 OpenClaw,讲了构建编码 Agent 的最佳实践的汇聚。

本月早些时候,Greg Brockman 发布了一条线程,讨论 OpenAI 如何重组其工程团队,使其在使用代理时更有效率。这一举措的启动是因为内部情况发生了多大的变化:

昨天 OpenAI 的一些优秀工程师告诉我,自 12 月以来,他们的工作发生了根本变化。在此之前,他们可以使用 Codex 进行单元测试;现在,它几乎编写了所有代码,并完成了大量操作和调试工作。并非每个人都实现了这一飞跃,但通常是因为模型能力以外的因素。

之前映射了从 Copilot 到聊天机器人到代理到后台代理到代理舰队的进展。每一步都比上一步更快。但在过去几个月里,一些本质上不同的东西开始出现——是的,模型已经变得更好,同时我们也看到了当整个团队围绕它们重组时发生的具体证据。

考虑以下数据点:

OpenClaw 的创建者 Peter Steinberger 告诉 Pragmatic Engineer,他发布了自己没有阅读的代码。一个人,一个月内 6,600+ 次提交,同时运行 5-10 个代理。

一个 OpenAI 团队在五个月内用三名工程师构建了一个百万行内部产品。零行手写代码(按设计)。平均每个工程师每天 3.5 个 PR——并且随着团队的增长,吞吐量增加了。

Stripe 的内部编码代理,称为 Minions,现在每周产生超过一千个合并的拉取请求。一位开发者在 Slack 中发布任务;代理编写代码,通过 CI,并打开一个准备好人类审查的 PR,中间没有交互。

对我来说,很明显我们已经过了演示和副项目的阶段;这些是真实规模的生产系统。而且虽然具体细节不同——Steinberger 是一个独行者,OpenAI 团队是一个小队,Stripe 是一家 10,000 人的公司——他们汇聚的模式非常相似。1

这篇文章是我尝试映射这些模式的尝试。这些实践仍在出现,并无疑会演变,但它们汇聚得足够快,值得写下正在变得清晰的东西。

工程师的工作正在分裂成两部分

在这一刻,我看到 AI 领域反映并演变了我自己对从制造者日程到管理者日程的转变的观察:

我正在远离与 AI 聊天,转向管理它们。你可以看到这些工具的进展。今天,它们主要围绕编码设计,但将它们扩展到通用知识工作只需很短的一步。这意味着我们这些处于前沿的人将把我们的日程和工作流程从制造者的转变为管理者的。

这个框架仍然成立,但观看这些团队的工作使它变得更尖锐。工程师的工作不仅仅是成为泛泛意义上的“管理者”——它正在分裂成两个不同的部分,你需要两者。

第一部分是构建环境。OpenAI 团队直言不讳:瓶颈从来不是代理编写代码的能力,而是围绕它的结构、工具和反馈机制的缺乏。他们的重点从实现转向启用:当 Codex 卡住时,他们将其视为环境设计问题,并问代理可靠地继续需要缺少什么。而且这,我想,是我早期写的东西中缺少的关键部分。

第二部分是管理工作。这就是 Steinberger 在启动执行前与代理花费大量时间规划时所做的,或者当他作为 OpenClaw 架构的“仁慈独裁者”时发布他没有阅读的代码。这就是 Brockman 推荐每个团队指定一个“代理队长”时的意思——某人负责思考代理如何融入团队的工作流程。

这两个部分不是顺序的(至少目前不是)。你不是构建环境然后在其中管理代理。你同时做两者,每一个都告知另一个。代理的失败告诉你环境缺少什么;更好的环境让你以更少的摩擦进行管理。

构建 Harness

还没有官方术语,但我欣赏 Mitchell Hashimoto(Terraform、Ghostty 和许多其他软件工具的创建者)使用的名称:“harness engineering。” Harness 是约束、工具、文档和反馈循环的集合,这些保持代理高效并在轨道上。将它想象成将新员工扔进没有入职的公司与有清晰架构文档、linting 规则、快速 CI 管道和明确模块边界的公司之间的区别。

根据 Hashimoto 的说法,“这是每次你发现代理犯错时,你花时间设计一个解决方案,使代理再也不会犯那个错的想法。” 在我看到的例子中,四种实践不断出现。

架构作为护栏

OpenAI 团队强制执行严格的分层架构,其中每个域内的代码具有非常严格的依赖和接口。架构外的任何东西都被禁止并机械执行:

代理在具有严格边界和可预测结构的环境中最有效⁠,所以我们围绕一个严格的架构模型构建了应用程序。每个业务域被分成固定层集,具有严格验证的依赖方向和有限的允许边缘。这些约束通过自定义 linter(当然是 Codex 生成的!)和结构测试机械执行。
...
在人类优先的工作流程中,这些规则可能感觉迂腐或限制性。但对于代理,它们成为倍增器:一旦编码,它们立即适用于所有地方。

正如 Birgitta Böckeler 在 Martin Fowler 的网站上指出,这暗示了一个反直觉的未来:增加对 AI 生成代码的信任和可靠性需要约束解决方案空间而不是扩展它。我们最终可能选择技术栈和代码库结构不是因为它们最灵活,而是因为它们最适合 harness。

Stripe 采取了不同但互补的方法。他们的 Minions 在隔离的、预热“devboxes”中运行——与人类工程师使用的相同开发环境,但与生产和互联网沙盒化。代理通过 MCP 服务器访问超过 400 个内部工具。关键洞察:代理需要与人类工程师相同的上下文和工具,而不是事后整合。

工具作为基础和反馈

Brockman 对团队的推荐是直接的:“维护你的团队依赖的工具列表,并确保有人负责使其代理可访问(例如通过 CLI 或 MCP 服务器)。” 如果代理无法访问你的工具,它们就无法帮助。

Stripe 的实现可以说是这个的最成熟例子。他们的 Minions 通过称为 Toolshed 的集中 MCP 集成连接到 400+ 个内部工具。代理在与人类工程师相同的开发环境中运行——相同的工具、相同的上下文、相同的访问。

但使工具可访问只是开始。更重要的是,正确的工具不仅仅扩展代理能做什么——它们改善它已经做的一切的可靠性。

在我自己的经验中,在提交前为 Codex 提供运行哪些 linter 和测试套件的清晰指令增加了我对每个 diff 的信心。没有这些工具,我就是在盲目飞行,依靠自己手动审查捕获东西。类似于 OpenAI 和 Anthropic 的团队,我发现提示代理使用浏览器自动化工具进行端到端测试极大地提高了彻底性和准确性——代理可以捕获仅从代码中不可见的 bug。

OpenAI 团队更进一步,提出了可能是这些文章中最聪明的想法:自定义 linter 错误消息兼作补救指令。当代理违反架构约束时,错误消息不仅仅标记违反——它告诉代理如何修复它。工具在工作时教导代理。用 Brockman 的话说:“编写快速运行的测试,并创建组件之间的高质量接口。”

文档作为记录系统

但你如何将这些过程变成可重复的系统?再次,Brockman 的线程包括一个具体推荐:“为任何你工作的项目创建并维护一个 AGENTS.md;每当代理做错事或在任务中挣扎时更新 AGENTS.md。” 这将文档变成反馈循环而不是静态工件。

对于不熟悉的人:AGENTS.md 是一个新兴的开放约定——本质上是 AI 代理的 README 2。它是仓库根目录下的 Markdown 文件,编码代理在每个会话开始时自动阅读。它告诉代理关于你的项目需要知道的东西:构建步骤、测试命令、编码约定、架构约束和常见陷阱。

但使 AGENTS.md 成为负载轴承基础设施而不是另一个腐烂的文档的是 Brockman 和 Hashimoto 描述的使用模式。你不是写一次就忘记它。你在代理每次做错事时更新它。

每当您发现代理犯了错误时,您都会花时间设计解决方案,以便代理不再犯同样的错误。

对于简单的事情 - 代理运行错误的命令或找到错误的 API - 这意味着需要更新 AGENTS.md了。 Hashimoto 指出 来自他的终端模拟器 Ghostty 的示例,其中文件中的每一行对应于现在已被阻止的特定过去代理故障。

但 OpenAI 团队更进一步。他们不是维护一个单一的巨型指令文件,而是构建了一个小的 AGENTS.md,指向更深层的真理来源——设计文档、架构地图、执行计划、质量等级——所有都在仓库中版本化和维护。一个后台代理定期扫描过时的文档并打开清理 PR:代理的文档,由代理创建。

Anthropic 的工程团队,在一篇关于长运行代理的有效 harness 的帖子中,从相反方向发现了类似模式。他们的核心问题是每个新代理会话开始时没有之前发生的事的记忆。解决方案是结构化的进度文件和特征列表,让新代理快速理解工作状态,类似于从未见面的工程师之间的轮班交接。他们甚至发现使用 JSON 进行特征跟踪比 Markdown 更好,因为代理不太可能不适当地编辑或覆盖结构化数据。

成为 AI 管理者

但是当然,安全带只是等式的一半。另一半是指导代理工作的日常实践——我称之为 人工智能经理的日程 。在这里,前沿的实践者也正在采取类似的方法。

规划是新的编码

此时,许多开发者强调在使用 AI 时进行广泛的前期规划——以至于大多数 AI 编码工具此时包括一个专用的“更多计划”。只有当他们满意时,工程师才会启动执行并移动到下一个任务。

Cloudflare 的 Workers 可观察性负责人 Boris Tane,有一整篇博客文章致力于这个原则:永远不要让代理编写代码,直到你审查并批准书面计划。用他的话说:

这种规划和执行的分离是我做的唯一最重要的事。它防止了浪费努力,让我控制架构决策,并以最少的 token 使用产生显著更好的结果,而不是直接跳到代码。

Anthropic 对长期运行代理的方法进一步将这一点正式化。他们的“初始化代理”根据高级提示生成全面的功能列表 - 单个 Web 应用程序的 200 多个单独功能,每个功能都有明确的测试步骤,所有功能最初都标记为“失败”。这种预先分解可以防止智能体尝试一次性完成整个项目或过早地宣布胜利。

自己经历了这种转变。当 Codex App 颠覆我的日常工作流程时,我停止花费时间实现,开始花费它范围界定、指导和审查。现在最重要的工作发生在任何代码编写之前。

对 Slop 说不

Brockman 的推荐 #5 是直率的:

确保某些人为任何合并的代码负责。作为代码审查者,保持至少与人类编写代码相同的标准,并确保作者理解他们提交的内容。

这是“对 slop 说不”的原则,它与速度的诱惑相反。当代理可以产生 PR 比你审查更快时,本能是降低标准。我读过的每个来源都反对这个。

Steinberger,尽管发布了自己没有逐行阅读的代码,但深深关心架构和可扩展性。他作为 OpenClaw 的架构守门人。在他的 Discord 与贡献者,他不谈代码——只谈架构和大决策。Pragmatic Engineer 的 Gergely Orosz 观察到 Steinberger “给我印象是一个软件架构师,他将项目的高级结构保持在头脑中。”

已经为此挣扎一段时间,但随着模型变得足够好,我发现更容易将它们视为经验丰富的分包商:

我喜欢用木工或木匠来比喻。对于初级木匠(即“学徒”)来说,这项工作可能只是关于输出——将设计或想法制作成成品。但对于更资深的人(“熟练工”或“工匠”)来说,他们的工作通常是了解客户想要什么,了解材料的实际情况,并设计出符合要求的东西。

最终,如果我与一位高级木匠一起帮助我设计一些东西,我并不特别关心他们是否是真正进行锯切和粘合的人。我正在与他们合作完成最终产品,而不是具体的机械步骤。

这就是 Steinberger 正在做的。他是大师木匠。代理在做锯和胶。他的工作是知道好的看起来像什么,并拒绝不符合标准的东西——有些人可能称之为“品味”。

我称之为“胡说检测”,随着输出量的增加,它变得更关键,而不是更少。你现在在更高的抽象水平审查。代码感觉太聪明,还是太重复?这里有模式会在六个月内引起维护头痛吗?抽象在正确的水平吗?

编排,而不仅仅是委托

最终的管理技能是并行化,但需要明确的是,并不是每个人都能做到(或需要)。 Steinberger 同时运行 5-10 个代理。 Stripe 工程师从 Slack 并行启动多个 Minion。我对 Codex 应用程序中的工作树也做了同样的事情 - 三个会话同时讨论不同的功能,作为审阅者而不是实现者在它们之间进行上下文切换

但在两种并行工作模式之间出现了一个重要的区别。Steinberger 和我做的是参与并行化——你积极管理几个代理会话,检查每个会话,并在需要时进行重定向。 Stripe 的 Minions 代表的是更接近于无人值守的并行化——开发人员发布一个任务然后走开。代理通过 CI 处理一切,而人类仅在审查阶段重新进入循环

这些是真正不同的管理风格,有不同的权衡。有人值守的并行化给你更多控制并更早捕获问题,但认知上要求高。无人值守的并行化扩展更好,但需要对环境的大量投资——harness 必须足够好,你信任代理从任务到 PR 而无需监督。Stripe 可以这样做是因为他们构建了 Toolshed、预热 devboxes 和紧密 CI 集成。大多数团队还没有到那里。

您的团队在该范围内的位置取决于两件事:您的 harness 的成熟程度,以及您对代码库的代理的信任程度。随着安全带的改进和模型能够更好地维持更长的任务而不脱轨,我预计平衡将转向无人值守的工作。但就目前而言,我们大多数人都处于中间状态——参与复杂的任务,无人参与范围广泛的任务。

什么仍然困难

上面的实践代表了真正的汇聚。但有几个开放问题,没有人有说服力的答案。

第一个是布罗克曼的结束语:如何防止“功能正确但难以维护的代码”渗入代码库? 《Harness Engineering》帖子将这种现象称为“熵”——代理生成的代码与人类编写的代码的累积方式不同。他们已经开始运行定期的“垃圾收集”代理来发现不一致和违规行为,但他们承认这仍然是一种新兴做法。

第二个是大规模验证。伯克勒对 Harness 帖子的批评是尖锐的:该文章缺乏对功能和行为的验证。 Anthropic 的长期运行的代理研究也发现了同样的差距——代理会在没有适当的端到端测试的情况下将功能标记为完整,并且如果没有明确的提示,他们将无法认识到某些东西不起作用。即使有了浏览器自动化,视觉和工具访问的限制也意味着一些错误会被忽略。

第三个是改造问题。所有这些成功故事涉及新建项目或从头开始构建 harness 的团队。将这些技术应用到十年旧的代码库,没有架构约束、不一致测试和零散文档是一个更复杂的问题。Böckeler 将其比作在从未有过静态分析工具的代码库上运行它——你会淹没在警报中。Harness engineering 如何适用于老旧存量项目是一个开放问题。

第四个,或许最大的,是文化采用。

阅读所有这些例子,一件事变得清楚:没有什么是偶然发生的。某人必须构建这些东西。每个组织的某人必须做找出代理如何融入他们团队工作流程的工作——创建 harness,定义过程,并基于有效的东西更新。

好消息是投资复合。每个 AGENTS.md 更新防止一类未来的失败。每个自定义 linter 教导每个未来的代理会话。你通过 MCP 暴露的每个工具使每个后续任务更快。前期成本显著,但回报加速。

事物的形状

Steinberger 观察到喜欢解决算法谜题的工程师努力转向代理原生,而喜欢发布产品的工程师快速适应 5。这与我亲眼看到的东西一致——当我不再用自己的双手编写代码时,我必须学会放弃软件工程的技巧。

但是尽管有 苦乐参半的方面 ,我还是对这里发生的事情着迷。这是一门真正实时形成的新学科——它借鉴了软件架构和团队管理中的经典挑战,同时将上下文工程融入其中。剧本仍在编写中,但我第一次认为它的形状正在变得清晰。

Metadata

Metadata

Assignees

No one assigned

    Labels

    AI这是 人工智能Agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions