找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4200

积分

0

好友

557

主题
发表于 2 小时前 | 查看: 2| 回复: 0

Harness概念形象图:一只立于原野的长角羚

自2026年初以来,“Harness工程”一词的热度不断攀升。OpenAI在二月发布的一份详细的内部实验报告中使用了这个术语,而ThoughtWorks首席科学家Martin Fowler也在X上表示,Harness工程是AI赋能软件开发的关键组成部分。

Martin Fowler关于Harness工程的推文截图

OpenAI文章链接:https://openai.com/index/harness-engineering/

近日,一位资深全栈工程师在X上发布了一篇名为《Harness 就是一切:Cursor、Claude Code 和 Perplexity 到底构建了什么》的文章。他将Harness之于智能体,类比于应用商店和开发工具之于移动端、搜索引擎和浏览器之于互联网,认为这是目前应用AI领域最核心的工程问题。

《Harness就是一切》文章推文截图

有评论写道:“这是AI领域的下一个千亿级的机会,大多数人会错失,它就是Harness工程。”

关于Harness工程价值的激烈评论截图

无独有偶,MiniMax在3月18日发布其首个深度参与迭代自身M2.7模型的报告时,也着重强调了M2.7能够自主构建Agent Harness,完成高度复杂的生产力任务。

M2*模型迭代系统与Agent Harness架构流程图

以下为对Harness概念的详细技术阐述:

AI用得不好,是因为环境没构建对

你之所以觉得AI用得不对,并不是因为还没找到正确的模型。你用错AI的原因是,你没有构建正确的环境

这就是为什么有些团队仅凭三名工程师就能交付数百万行代码,而其他团队甚至连让智能体流水线完成一次连贯的重构都困难重重。

这种差距不在于GPT-5与Claude Opus的区别,也不在于温度设置或最大Token数。甚至不在于提示词,尽管每个人都为了提示词争论不休,浪费了数月的人生。

真正的区别在于Harness。

这篇文章将探讨这个词在技术和哲学上的真正含义,因为业界已经养成了一种随意使用它的坏习惯。Harness不是系统提示词,不是API调用的包装器。它不是评测框架、提示词模板,也不是带记忆的聊天机器人。

Harness是语言模型运行的完整设计环境,包括:它可以调用的工具、它接收信息的格式、它历史记录的压缩与管理方式、在错误级联前拦截错误的护栏,以及允许它将工作移交给“未来的自己”而又不丢失连贯性的脚手架。

当你审视Anthropic为使Claude Code真正落地而构建的内容、OpenAI如何通过Codex交付数百万行零人工编写的代码,以及普林斯顿NLP小组在里程碑式的SWE-agent论文中发表的关于“智能体-计算机接口(ACI)”的研究时,你会发现所有严肃对待这一领域的团队都在呈现同一种模式。

模型几乎无关紧要,Harness就是一切。

这是关于该理念如何成为2025和2026年应用AI工程定义类洞察的详细技术分解。它涵盖了研究、实际实现、驱动设计决策的失败模式,以及无论你是在构建编码智能体、研究智能体还是长期运行的自主软件工程师时都会重复出现的模式。

读完本文,你不仅会理解什么是Harness,还会明白为什么正确构建它已成为行业内最有价值的工程技能。

没人讨论的问题:为什么原始能力是不够的

2024年中期,AI基准测试中发生了一件奇怪的事。研究人员发现,同一个前沿模型在相同的编码任务上,由于任务呈现方式和可用工具的不同,会产生截然不同的结果。模型没变,底层的智能没变,改变的是接口

这本不该让人感到惊讶。几十年来我们都知道,合适的工具能让工程师的生产力产生质的飞跃。一个拥有现代IDE、调试器、版本控制和CI/CD流水线的软件开发人员,其效率比仅在原始终端使用文本编辑器的同一人高出几个数量级。IDE并没有让开发人员变聪明,它只是减少了摩擦、在正确时刻呈现信息、及早发现错误并组织工作单元。

语言模型也是如此。它们并不是基于无限内部知识库工作的通用推理者。它们是运作在上下文窗口中的精密模式匹配引擎。它们在特定时刻所知道的一切,都取决于窗口中的内容;它们产出的一切,都受限于这些上下文的结构。输入格式不是装饰,它是智能体的认知架构。接口不是便利层;对于语言模型智能体来说,接口即思想

这是普林斯顿NLP小组2024年发表的SWE-agent论文的核心主张,且经受住了推敲。该论文引入了智能体-计算机接口 (Agent-Computer Interface, ACI) 的概念,并证明了精心设计的ACI与标准Linux Shell相比,能让同一模型在基准测试中的性能产生 64% 的相对提升。相同的模型,相同的任务,相同的计算预算,变量只有接口。

64%不是边际收益,而是工具“能用”与“不能用”的区别。而这完全源于环境设计,而非底层模型的改进。

上下文窗口不是内存条

关于AI智能体的一种原生模型是将上下文窗口视为RAM(随机存取存储器)。你加载数据,模型处理,然后输出。这种观点认为:更多的上下文等于更好的性能,更长的提示词等于更深的理解。这种观点是错误的,如果你围绕它构建智能体,它会毁了你的工作。

上下文窗口更像是智能体在给定会话中的整个工作意识。窗口中的每个Token都有计算成本。每一条无关信息都会与关键信息争夺注意力。模型并没有一种能干净利落地忽略噪音的选择性注意力机制。噪音就在房间里,它会影响推理。

这对智能体设计有具体且可衡量的后果。当你从智能体循环内部在大型代码库运行grep并返回一万行匹配项时,你并没有给智能体更多信息,而是用无关数据淹没了它的工作记忆,这将降低其后每一步的质量,直到上下文被清除。当你因为智能体想看两个函数就用cat倾倒整个文件时,你是在它需要一杯水的时候给了它一支高压水枪。

SWE-agent的研究人员详细记录了这些失败模式。标准Bash接口会导致智能体“空转”:它们会发布返回数千行的grep命令,忘记自己要找什么,接着发布更多grep,导致上下文充满噪音,最终产生错误答案或停滞不前。问题不在于模型智能,而在于接口没有保护智能体免受其自身伤害的机制。

ACI的解决方案是构建一个有返回上限且能总结的搜索工具。如果搜索返回超过50个匹配项,工具会抑制输出并告诉智能体缩小查询范围。这个回想起来简单得近乎受辱的设计决策,是论文中杠杆率最高的变化之一。它将“上下文淹没”这种失败模式转化为了自然的改进循环。

SWE-Agent论文与ACI的诞生

智能体-计算机接口(ACI)究竟是什么?

在SWE-agent论文中,ACI被定义为位于语言模型智能体与计算机环境之间的抽象层。将其类比于人机交互(HCI)是刻意为之的。正如HCI研究如何设计符合人类认知架构的接口一样,ACI研究则探讨如何设计符合语言模型(LM)认知架构的接口

人类的认知架构涉及视觉模式识别、空间记忆、屏幕上的并行注意,以及略读和选择性关注的能力。LM的认知架构则根本不同:它涉及序列化的Token处理、对上下文顺序和格式的敏感性、有限的工作记忆,以及倾向于锚定在提示词中最显著信息的倾向。设计一个好的ACI意味着理解这些约束并围绕它们进行构建,而不是与其对抗。

用于编码任务的SWE-agent ACI包含四个主要组件,每一个都反映了关于语言模型在获得原始计算机访问权限时如何失败的特定洞察。

搜索与导航

搜索组件用专门构建的工具(find_filesearch_filesearch_dir)取代了标准的grepfind命令。关键区别不在于语法,而在于输出管理。结果被限制在50条以内。如果查询超过该限制,工具会返回一条消息,解释结果过多并提示智能体细化搜索。这听起来微不足道,但在实践中,它是该论文中最重要的决策之一。

其之所以重要,是因为智能体和处于认知负荷下的人类一样,当感到不确定时,往往会不断重复正在做的事情。当人类迷失在庞大的代码库中时,他们会搜索得越来越宽泛,产生越来越多的噪音。受限搜索工具通过创造一个“强制函数”中断了这种模式:你不能通过模糊不清来推进工作,你必须变得精确。这推动了智能体采取更深思熟虑、更有针对性的行为。

文件查看器

文件查看器是论文中关于认知架构的洞察变得最具体的地方。研究人员测试了多种查看器配置,发现一次显示100行是一个“恰到好处(Goldilocks)”的数字。显示行数更少(他们测试了30行)会导致智能体丢失周围代码的上下文并产生编辑错误;显示更多行(或全量文件)则会导致智能体迷失所在位置并遗漏重要细节。

查看器是有状态的。它在交互过程中保持在文件中的位置。关键在于,它在每个可见行前都添加了明确的行号。这最后一个细节听起来像是装饰性的,其实不然。当智能体需要发布针对第47到52行的编辑命令时,它需要能够直接从视图中读取这些数字,而不是去数行数或进行算术运算。从智能体的工作记忆中移除这项认知任务,为实际的后续问题解决腾出了空间。

带有Lint检查的文件编辑器

文件编辑器的关键创新是带有护栏的即时反馈。edit命令接受起始行、结束行和替换文本作为单一操作。每次编辑后,工具会自动对修改后的文件运行Linter(静态代码检查)并报告结果。如果编辑引入了语法错误,编辑会在应用前被拒绝,智能体将收到一条清晰的错误消息,同时显示原始代码和失败的编辑内容。

这闭合了在原生智能体实现中导致级联故障的反馈循环。如果没有Linter,智能体可能会引入语法错误,然后运行测试套件,看到一个似乎不相关的失败(因为真正的错误在别处),花费多个步骤追查错误的问题,最后在追逐幻影中耗尽其上下文窗口。通过将Linter直接集成到编辑器中,语法错误在引入瞬间就被捕获,修复工作在问题传播前就被局部化了。

对比智能体使用原始bash工具时的情况:使用sed或输出重定向时,没有集成反馈,编辑静默执行。多行更改需要复杂的参数格式化,极其容易出错。智能体可能成功运行了命令却引入了细微的格式错误(本可以被Linter捕获),然后接下来的十个步骤都在疑惑为什么测试会失败。

上下文管理

第四个组件解决了一个在长会话中不断恶化的问题:陈旧上下文的累积。随着智能体执行任务,其历史记录充满了旧的观察结果、中间状态和探索步骤,这些已不再反映环境的当前状态。所有这些历史记录都占据了上下文窗口的空间,并可能通过提供过时信息来误导智能体。

ACI的上下文管理系统将较旧的观察结果(最后五轮之前的)折叠成单行摘要。这使活跃上下文聚焦于最近的相关信息,同时保留了整体轨迹的压缩记录。智能体始终能看到它最近做了什么以及当前状态是什么,而不会被它运行过的每个命令的完整未压缩历史所淹没。

基准测试结果及其真实含义

SWE-agent论文针对SWE-bench数据集(来自流行Python仓库的真实GitHub Issue集合)对其ACI进行了基准测试。任务是接收一个自然语言错误报告并产出一个解决它的代码补丁。这是一个艰巨的实践任务,需要导航不熟悉的代码库、理解错误消息、编写正确的代码并验证修复。

使用带有标准bash shell接口的GPT-4,系统解决了3.97%的问题。使用带有专门构建的ACI的GPT-4,系统解决了12.47%的问题。这就是之前提到的64%的相对提升,且这完全来自于接口设计。

研究人员还进行了消融实验,每次移除一个组件以隔离每个设计决策的贡献。Linter集成始终是杠杆作用最高的组件之一。受限搜索对于防止上下文泛滥至关重要。带有行号的有状态文件查看器表现显著优于原始cat命令和更简单的查看器设计。

性能差异不在于模型的智能程度,而在于认知负荷管理。ACI减少了模型跟踪状态所需的工作,为真正重要的工作留出了空间。

其影响远超编码智能体。任何长程(long-horizon)智能体任务都涉及相同的根本挑战:在庞大的信息空间中导航、在多个步骤中保持连贯的状态、捕获错误并从中恢复,以及管理有限的上下文窗口注意力资源。ACI的设计原则是普适的,具体的工具会变,问题的底层架构不会变。对这类问题的系统性思考,可以参考社区内关于RAG的讨论。

Anthropic的Harness工程:长程运行智能体问题

为什么上下文窗口边界是难题

SWE-agent论文解决了如何为单次智能体会话设计接口。而Anthropic的工程团队在开发Claude Agent SDK和Claude Code时遇到了另一个问题:当任务大到无法在单个上下文窗口中完成时,会发生什么?

这并不是一个冷门的边缘案例。大多数真实的软件项目都太大,无法放入任何上下文窗口。一个生产环境的Web应用拥有数百个文件、数千个函数、测试套件、配置、文档和依赖项。即使拥有200K Token的上下文窗口,你也无法同时在大脑中保留整个项目。人类工程师通过外部记忆、文档、版本控制以及在代码库中工作数周甚至数月积累的理解来解决这个问题。而一个开启新会话的智能体完全没有这些。

原生的解决方案是压缩,它在某种程度上有效。Claude Agent SDK包含压缩功能,当窗口填满时会总结旧的上下文。但仅靠压缩是不够的。Anthropic的内部实验表明,即使有压缩,像Opus 4.5这样处于前沿的编码模型,如果在多个上下文窗口中循环运行,仍然无法根据一个高层次提示词构建出一个生产级质量的Web应用。

失败主要集中在两种模式上,这两种模式都极具启发性。

第一种失败模式是试图一次做太多事情。当收到“构建一个claude.ai的克隆版”之类的提示词时,智能体会尝试“一站式”完成整个应用。它会在不完成或不测试任何功能的情况下开始实现一个又一个功能,在实现过程中耗尽上下文窗口,导致下一次会话开始时面对的是一个只实现了一半的应用、没有任何已完成工作的文档,也没有明确的代码状态指示。下一个智能体实例将花费大部分上下文预算去理解这一团糟,而不是取得进展。

第二种失败模式出现在项目后期。在构建了一些功能后,随后的智能体实例会观察四周,看到已经取得了进展,便断定工作已经完成。它会针对一个仅完成部分的应用宣布胜利并停止工作。这不是愚蠢,而是基于不完整信息的合理推论。智能体没有结构化的方式来了解该项目真正的“完成”意味着什么。

这两个失败都有一个共同的根源:智能体对项目状态没有持久的、结构化的理解,这种理解无法跨越上下文窗口边界并引导未来的会话。

双智能体架构:初始化智能体与编码智能体

Anthropic的解决方案是一个由两部分组成的架构,这已成为严肃团队处理长程智能体化工作的模板。

第一部分是初始化智能体。这是一个专门的首次会话,带有独特的系统提示词,其全部目的是设置未来所有编码智能体都将在其中操作的环境。它不编写功能代码,而是创建让跨多个后续会话的功能开发成为可能的脚手架。

初始化智能体产出三个关键输出。首先,它创建一个 init.sh脚本,可以可靠地启动开发环境。这听起来很平凡,但它具有巨大的杠杆作用。此后的每一次编码智能体会话都可以通过运行init.sh开始,而不是花费Token去摸索如何启动服务器、设置数据库以及让应用进入可测试状态。在每次会话中节省的这些开销累积起来非常可观。

其次,初始化智能体创建一个全面的功能列表文件。在Anthropic内部进行的claude.ai克隆实验中,这意味着超过200个具体的、端到端的功能描述,例如“用户可以打开新聊天、输入查询、按回车并看到AI响应”。每个功能最初都标记为失败。该文件作为项目的“唯一真相”。开启新会话的编码智能体读取此文件,立即就能确定哪些已经构建、哪些尚未构建。它不会因为看到一些代码就断定工作已完成,功能列表会告诉它真相。

第三,初始化智能体创建一个claude-progress.txt文件并进行初始git提交。进度文件是一个人类可读的日志,智能体在每次会话结束时更新它,记录它们处理了什么、完成了什么以及留下的状态。结合git历史记录,这让未来的每个编码智能体都能快速定位,而无需在“考古”上耗费上下文预算。

第二部分是编码智能体。初始化之后的每一次会话都使用不同的提示词:一次只处理一个功能,保持环境状态干净,并在会话结束前更新进度文件和git历史。增量的进展,文档化的状态,干净的交接。

功能列表作为认知锚点

功能列表值得特别关注,因为它解决了一个极易被低估的问题。如果没有它,在复杂代码库中操作的智能体必须从代码本身推断项目的完成情况。这种推论是不可靠的。可能存在不可用的代码,也可能存在不完整的功能。智能体阅读代码并推理已完成的工作,其出错频率足以构成严重问题。

功能列表使完成情况变得明确且无歧义。每个功能都有一个passes字段,要么为true,要么为false。智能体要么在验证功能端到端运行后更新此字段,要么不更新。这里没有歧义,不需要推论。真相就在文件里。

Anthropic刻意决定将此列表存储为JSON而不是Markdown。原因在于行为学。经验表明,与Markdown文件相比,模型不太可能不恰当地修改或覆盖JSON文件。JSON具有严密的结构,能够抵御随意的编辑。这是一个产生真实后果的小细节:你希望功能列表是智能体谨慎更新的东西,而不是它们兴起时就随手改写的东西。

{ "category": "functional", "description": "New chat button creates a fresh conversation", "steps": [ "Navigate to main interface", "Click the 'New Chat' button", "Verify a new conversation is created", "Check that chat area shows welcome state", "Verify conversation appears in sidebar" ], "passes": false }

伴随此格式的指令是明确的:移除或编辑测试是不可接受的,因为这可能导致功能缺失或产生Bug。你提示模型将此文件视为神圣不可侵犯的。JSON结构从架构上强化了这一指令。

增量进展与干净状态要求

多会话智能体工作中,最难的问题之一是确保每次会话结束时的状态能让下次会话安全地在其基础上构建。如果没有明确的强制执行,智能体往往会在上下文窗口填满时,将工作留在任何可能的状态:实现了一半的功能、损坏的测试、未记录的更改。下一个智能体继承了这一团糟。

Anthropic的解决方案是将“干净状态”作为一等公民的要求,而非“最好能有”。每次编码智能体会话都以git提交(带有描述性消息)、进度文件更新以及(如果需要的话)恢复到工作状态结束。所谓的“干净状态”,是指代码应当适合合并到主分支:没有重大Bug、文档完备、处于一个开发者可以合理地开始新功能而无需先清理前任留下的烂摊子的状态。

Git提交不仅是一个检查点,它还是一种恢复机制。当智能体做出的更改破坏了某些东西时,它可以利用git恢复到上一个已知的良好状态并重试。这就是人类工程师的工作方式,事实证明,这对智能体也是完全正确的纪律。版本控制是认知脚手架,而不仅仅是源码管理。

测试:没人喜欢谈论的失败模式

Anthropic记录了一种在几乎所有严肃的智能体化编码项目中都会出现的失败模式:智能体在没有进行正确的端到端验证的情况下就将功能标记为已完成。智能体会修改代码,针对开发服务器运行单元测试或curl命令,看到通过的结果,然后将功能标记为已完成。但当用户通过浏览器测试时,该功能实际上并不起作用。

单元测试成功与端到端功能之间的差距,是人类工程师通过切换上下文(运行应用并尝试使用它)来处理的。一个没有明确浏览器测试能力的智能体无法进行这种切换。它只能观察工具允许它观察到的东西,如果这些工具不包括浏览器自动化,它将一贯地遗漏那些仅在真实用户流程中表现出来的Bug。

解决方案是让智能体访问Puppeteer MCP服务器,这是一种浏览器自动化工具,允许Claude真正地导航应用、点击按钮、填写表单并验证功能是否端到端运行。性能提升是巨大的。Bug仅从代码看是隐形的,在智能体能真正看到用户所见内容时变得显而易见。

这是一个普适原则的具体例证:智能体工作的质量受限于其反馈循环的质量。如果你的智能体无法在其核心领域观察其行为的后果,它就会去优化那些可能与实际正确性无关的代理指标(proxy metrics)。对于如何构建更复杂、更长周期的智能体系统,可以参考这个关于智能体的技术话题。

启动序列:快速进入状态

Anthropic的Harness中每一次编码智能体会话都以标准化的启动序列开始,旨在尽可能快地引导智能体,而不浪费不必要的Token。序列如下:

  1. 运行pwd以确认工作目录。
  2. 读取进度文件和git日志以了解近期工作。
  3. 读取功能列表并选择优先级最高的未完成功能。
  4. 运行init.sh脚本以启动开发环境。
  5. 运行基础端到端测试以验证应用处于工作状态。

只有在完成所有这些步骤后,智能体才会开始处理新功能。如果启动测试显示应用已损坏,智能体会在触碰任何新东西之前先修复现有的损坏。这防止了问题的复合化——即智能体在破碎的基础上开始新功能,导致底层问题更难被隔离和修复。

启动序列还以特定方式节省了Token。因为init.sh脚本记录了启动开发环境的确切方法,智能体不需要从头摸索。在长周期项目中,每次会话在环境设置上节省的Token累积起来非常显著。

[Assistant] I'll start by getting my bearings and understanding the current state of the project. [Tool Use] <bash-pwd> [Tool Use] <read-claude-progress.txt> [Tool Use] <read-feature_list.json> [Assistant] Let me check the git log to see recent work. [Tool Use] <bash-gitlog--oneline-20> [Assistant] Now let me check if there's an init.sh script to restart the servers. <Startsthedevelopmentserver> [Assistant] Excellent! Now let me navigate to the application and verify that some fundamental features are still working. <Testsbasicfunctionality>

OpenAI的Harness工程:零行人工代码

实验背景

2025年8月下旬,OpenAI的Codex团队启动了一个git仓库,并设立了一个单一约束:禁止人工编写代码。仓库中的每一行代码,包括应用逻辑、测试、CI配置、文档、可观测性工具和内部开发工具,都必须由Codex智能体编写。人类负责掌舵,智能体负责执行。

五个月后,该仓库在所有类别中包含约100万行代码。大约有1,500个拉取请求(PR)被开启并合并。一支由三名工程师组成的小团队驱动了其中的大部分工作,平均每名工程师每天处理3.5个PR。随着团队扩大到七名工程师,人均吞吐量实际上还增加了。该产品每天有数百名内部用户和外部Alpha测试人员。

这不是一个Demo。这是一个完全通过智能体生成的代码构建并交付的真实内部产品。该团队在2026年2月撰写了描述这一经历的文章,核心信息与SWE-agent论文一致:瓶颈从来不在于模型能力,而始终在于环境设计。

工程工作的重新定义

OpenAI的Harness工程文章中最重要的观察是关于工程工作本身是如何演变的。当你的主要工作不再是编写代码时,你转而在做什么?

你在设计环境。你在指定意图。你在构建反馈循环。 你不再不断地问“我该如何修复这个Bug?”,而是问:“环境中缺少什么能力导致了这个Bug的出现?

当出现故障时,修复方法几乎从来不是“再努力一点”,而几乎总是:“环境中缺少或误配置了什么结构化组件,导致智能体在这里失败?”这是工程思维的一个深刻转变。你停止调试代码,转而开始调试生产代码的系统。

工程团队的主要工作变成了赋能智能体去完成有用的工作,而不是由人亲自去完成工作。

在实践中,这意味着将宏大目标分解为更小的构建块,构建让这些构建块可实现的工具和抽象,并将失败作为环境需要更好支持什么的信号。人类工程师的工作是“深度优先”的:当智能体卡住时,他们不会试图自己写代码,而是询问缺少了什么,将其构建到环境中,然后让智能体重试。

仓库知识作为记录系统

OpenAI的Harness中最重要的架构决策之一,是将仓库本身作为智能体需要了解的一切信息的权威来源。这一洞察简单却深远:从智能体的视角来看,任何它在运行时无法通过上下文访问的东西,实际上都不存在。存在于Google Docs、Slack对话或人们大脑中的知识,对系统来说是不可见的。

在项目早期,团队尝试过“一份超大的AGENTS.md”方案。这是一个单一的大型指令文件,包含智能体需要了解的关于项目、架构、约定和约束的一切。不出所料,它失败了,其失败模式有四点值得理解:

  1. 上下文是稀缺资源:巨型指令文件挤占了任务、代码和相关文档的空间。智能体要么遗漏关键约束,要么开始针对错误的目标进行优化。
  2. 过多的指导等于没有指导:当每件事都被标记为重要时,就没有什么是重要的了。智能体开始在局部进行模式匹配,而不是有意识地导航。
  3. 迅速腐烂:随着代码库的演进,单体手册会变成陈旧规则的坟墓。
  4. 难以验证:单一的大块内容不利于覆盖率检查、新鲜度追踪或交叉引用。偏差是不可避免的。

解决方案是一个结构化的 docs/目录,将其视为记录系统,并辅以一个简短的AGENTS.md文件(约100行)作为地图,指向别处更深层次的真理来源。设计文档被编目并索引;架构文档提供了领域和包分层的顶级地图;计划被视为一等资产,其进度和决策日志都签入仓库。

这实现了团队所称的“渐进式披露”:智能体从一个微小、稳定的入口点开始,并被教导接下来该去哪里查找,而不是预先被海量信息淹没。结果是,智能体可以直接从仓库中推理出完整的业务领域,而无需访问可能不可用或已过时的外部上下文。

应用的可读性:使系统对智能体可见

随着代码吞吐量的增加,瓶颈从“生成”转移到了“验证”。团队生成代码的速度超过了人类QA(质量保证)能力的验证速度。解决方案是让应用对Codex直接可读,从而让更多的验证工作可以由智能体自行完成

这涉及几项具体的投入。他们让应用可以按git工作树 (worktree) 启动,因此Codex可以在它正在处理的每个更改中,启动并驱动一个隔离的应用实例。他们将Chrome DevTools协议接入智能体运行时,并创建了处理DOM快照、屏幕截图和浏览器导航的工具。这使得Codex能够直接复现Bug、验证修复并推理UI行为,而无需人类与应用交互。

他们构建了一个完整的本地可观测性栈:通过LogQL、PromQL和TraceQL向Codex开放日志、指标和追踪。每个智能体任务都在一个完全隔离的应用版本上运行,并拥有自己的观测数据,任务完成后即销毁。这意味着智能体可以使用真实的可观测性工具(与人类工程师使用的工具相同)来调试生产级问题,而不是仅凭代码推测行为。

这里的原则与SWE-agent论文所证明的一致:智能体工作的质量受限于其反馈循环的质量。 如果智能体能看到用户所见,并能观察到人类工程师所观察的相同指标和日志,它就能捕捉并修复比仅操作代码的智能体多得多的问题。

在不进行微观管理的情况下强化架构

在全智能体生成的代码库中,最大的挑战之一是长期保持架构的连贯性。Codex会复制仓库中已有的模式,包括那些不均衡或次优的模式。久而久之,这会导致偏差:坏模式蔓延,不一致性累积,代码库变得越来越难让未来的智能体正确导航。

OpenAI的解决方案是机械化地强制执行不变性 (Invariants),而不是通过人工代码审查。应用围绕一个严苛的架构模型构建:每个业务领域被划分为一组固定的层级,具有严格验证的依赖方向和有限的允许边缘。这些约束由自定义的Linter(自然也是由Codex编写的)和结构化测试来强制执行。

核心洞察是在强化边界的同时,允许在边界内拥有巨大的自由。Linter检查代码是否在层级结构中按正确方向流动,但它们不干预特定功能在这些边界内是如何实现的。这与让平台团队在规模化时发挥作用的原则相同:强化基座,允许其上的自主权。

这些Linter是专门为生成对智能体有用的错误信息而编写的。当Linter捕捉到违规时,错误信息中包含了格式化的修复指令,以便注入智能体的上下文。这关闭了闭环:被违反的约束、被违反的规则以及修复步骤,都通过一条单一的、可操作的反馈信息送达。

他们还将所谓的“黄金原则 (Golden Principles)”直接编码进仓库:这些是武断的、机械的规则,旨在保持代码库对未来智能体运行的可读性和一致性。例如:优先使用共享工具包而非手写的助手函数;在边界处验证数据形状。这些原则由定期运行的清理后台任务强制执行,这些任务会扫描偏差、更新质量等级,并开启针对性的重构PR。其中大多数PR可以在一分钟内完成Review并自动合并。

吞吐量改变了合并哲学

当智能体的吞吐量大幅超过人类的注意力容量时,传统的工程规范就会产生反作用。等待Review的PR会阻塞智能体的工作;被逐一调查的测试闪烁(Test flakes)会消耗本可以投入到更高杠杆任务上的人类注意力。

OpenAI团队做出了一个深思熟虑的决定:以最小化的阻塞式合并门禁来运行。 PR保持短生命周期。测试闪烁通过后续运行来处理,而不是无限期阻塞进度。当智能体吞吐量远超人类注意力时,纠错是廉价的,而等待是昂贵的。 这种权衡在低吞吐量环境下看起来是不负责任的,但在高吞吐量环境下却是显而易见的。

对于正在转向智能体驱动开发的团队来说,这是一个真正重要的洞察。当人类工程师编写每一行代码时合理的合并哲学,在智能体每人每天生成3.5个PR时,并不一定自动合理。 瓶颈转移了,流程也需要随之转变。

Awesome Agent Harness分类法:描绘生态系统版图

由GitHub上的AutoJunjie项目维护的Awesome Agent Harness代码仓库,试图描绘新兴的harness工程工具的生态系统版图。在深入探讨该分类法之前,其核心论点值得明确陈述:人工智能编写代码的能力实际上已成为一种商品(commodity)。基础模型能够生成具有功能性的代码。这已不再是产生差异化的能力。真正产生差异化的能力在于协调与环境设计

该代码仓库将一个严肃的智能体Harness生态系统所需的完整技术栈进行了目录化整理,分为七个截然不同的层级。理解这些层级有助于解释为什么“构建一个AI编码助手”实际上是许多个独立的工程问题,而不是单一的问题。

第一层:人类监督

位于最顶层的是人类监督层,人类在这里批准提案、审查拉取请求(pull requests)并设定优先级。这不是传统意义上的技术层。它是人类判断与智能体执行之间的接口。这里的关键设计原则是,工程师应该是在设计环境和审查结果,而不是直接编写代码。他们的杠杆作用(影响力)来自于引导(steering),而不是执行。

第二层:规划与需求(规约工具)

这一层将人类的想法转化为结构化的规约和任务有向无环图(DAG),以便智能体能够可靠地使用。其潜在的深刻见解是,智能体是盲目执行的。如果规约模糊或存在歧义,智能体将生成满足其对该规约理解的内容,而这可能并非人类的本意。规约工具在编写任何代码之前,在需求阶段就强制要求精确性。

该领域的一个项目Chorus,试图解决代码仓库中所称的“反向对话鸿沟(reversed conversation gap)”。Chorus并没有让自然缺乏智能体所需精确度的人类去编写详细的规约工单(这是一个主要的失败点),而是让AI提出任务DAG并详细阐述需求,人类在执行开始前仅扮演严格的验证和批准角色。在根据部分意图生成完整规约方面,AI比人类从零开始编写要擅长得多。

第三层:全生命周期平台

这些工具管理从初始需求到交付的端到端流程,将AI提案与人类验证关卡以及子智能体编排整合在一起。它们是规约层和执行层之间的粘合剂,处理贯穿整个开发生命周期的状态管理。

第四层:任务运行器

任务运行器弥合了问题跟踪器(如GitHub Issues、Linear)与编码智能体之间的鸿沟。流程如下:人类或产品经理(PM)智能体创建一个问题,任务运行器生成一个工作区,智能体交付一个PR,然后人类进行审查。此类别的工具包括不断轮询任务队列、决定何时生成智能体并交付已完成工作的系统,而无需人类参与执行循环。

第五层:智能体编排器

编排器通过实现多个智能体的并行执行,同时将它们的工作隔离在独立的git工作树(worktrees)中,从而解决吞吐量问题。这至关重要,因为如果共享同一个工作区,在同一代码库上并行工作的智能体会相互冲突。Git工作树隔离为每个智能体提供了自己的沙箱,允许许多智能体同时工作而不会互相踩踏(干扰)。

诸如Vibe Kanban、Emdash和Composio之类的工具实现了这种模式。每个智能体任务都会获得自己的git工作树。更改在合并之前会在隔离状态下进行验证。持续集成(CI)反馈、合并冲突以及智能体之间的协调都由编排层处理,无需人工干预。

第六层:智能体Harness框架与运行时

框架(Frameworks)为构建自定义环境提供了可组合的基础:渐进式披露机制、子智能体生成、结构化的上下文交付。运行时(Runtimes)提供持久的基础设施:长期运行的内存、计划(定时)执行、会话之间的多渠道通信。

框架与运行时之间的区别非常重要。框架是你构建的基础。运行时是持续运行的实体。 Claude Agent SDK主要是一个框架。一个按cron计划运行智能体、在会话之间保持持久内存、并处理智能体实例之间多渠道协调的系统,则是一个运行时。对于严肃的、长期运行的智能体化工作来说,两者都是必不可少的。了解和选择这些框架与工具,可以关注开源实战板块的讨论。

第七层:编码智能体

位于最底层的是执行层:Claude Code、Codex以及类似编写、测试和调试代码的系统。该代码仓库的核心洞察是,这一层已成为一种商品(基础大宗品)。智能体的有效性主要由其在技术栈上方的所有事物决定,而不是由智能体本身决定。

这是一个具有颠覆性的主张,但有证据支持。SWE-agent论文通过经验验证了这一点:相同的模型,仅仅通过界面设计就获得了64%的性能提升。OpenAI的Codex团队在实际操作中证明了这一点:真正重要的工程工作是环境设计,而不是执行。Anthropic的框架工程工作在实践中证明了这一点:初始化智能体的设置决定了编码智能体究竟能否取得任何进展。

重复出现的设计模式

在所有这些系统和组织中,几种设计模式反复出现。这并非巧合,而是每当试图大规模可靠地部署智能体时,针对出现的工程问题所提出的解决方案。

模式1:渐进式披露

不要预先给智能体提供它可能需要的所有信息。只给它定位自身所需的最小值,以及在需要时寻找更多信息的指针。 这种模式出现在SWE-agent的限制性搜索(不返回所有结果,强制智能体细化搜索)、OpenAI的docs/架构(一个指向更深层次事实的简短地图)、Anthropic的启动序列(先读取进度文件,然后是功能列表),以及实现结构化上下文分层的利用工具框架中。

这种模式的认知原因是上下文是有限资源,且智能体的注意力在其上并非均匀分布。提示词开头呈现的信息具有不成比例的影响力。一个简短、聚焦的切入点并指向其他地方更丰富的上下文,比一个会稀释注意力的全面信息转储更有效。

实践上的原因是维护。一个作为深度文档地图的简短切入点,你可以保持其准确性。而一个包含所有内容的庞大文档很快就会过时并产生负面影响。

模式2:Git工作树隔离

一个智能体,一个工作树。 这种模式出现在每个严肃的编排系统中。理由很简单:当你有多个智能体并行工作(或单个智能体按顺序运行任务)时,你需要工作流之间的隔离。如果没有隔离,并行的智能体会互相踩踏对方的更改。 即使是顺序执行的智能体,你也希望在更改影响主代码库之前,能够在隔离的环境中验证它们。

Git工作树在文件系统层级提供了这种隔离。每个智能体都有自己的工作目录、自己的分支和自己的环境。更改在隔离中进行,在隔离中测试,并且只有在通过验证时才进行合并。这就是现代CI/CD系统为人类工程师工作的方式,事实证明,这对于智能体编排也是完全正确的模型。

模式3:规约优先,仓库作为唯一事实来源

智能体对非正式知识是盲目的。 任何存在于Slack讨论串、Google文档或某人脑海中的东西对智能体来说都是不可见的。智能体唯一能处理的是其上下文窗口中的内容,而该上下文唯一可靠的来源是代码仓库。

这种模式表现为Anthropic利用工具中的功能列表文件、OpenAI系统中的结构化docs/目录、各种开源框架中的AGENTS.md文件,以及awesome-agent-harness分类法中的规约工具层。共同点是,在执行开始之前,规约、需求、架构决策和约束必须编码到仓库中机器可读的文件中。如果智能体不能从仓库中读取它,它就不存在。

这对工程团队如何记录其工作具有重要意义。文档不再仅仅是给人类读者看的。它是人类意图变得对智能体可读的机制。 模糊、陈旧或存储在仓库之外的文档,是会主动损害智能体性能的文档。

模式4:机械化架构强制执行

人工代码审查无法扩展到智能体驱动的开发。当一个智能体每天能为每个工程师开启3.5个拉取请求时,审查不能作为维护代码质量和架构完整性的主要机制。解决方案是将架构约束编码为自动运行的机械化检查。

自定义静态代码分析工具(Linters)、结构化测试和CI流水线取代了人类驱动开发中代码审查的大部分工作。其优势在于机械化检查是一致的、快速的,并在违规点立即提供反馈。一个捕获到架构违规并在错误消息中返回修复指令的Linter,比三天后在拉取请求评论中发现相同违规的代码审查员更有效。

关键的设计原则是强制执行“不变性”,而非具体实现。你深度关注依赖方向、边界跨越、接口处的数据验证以及命名和结构的一致性。你并不关心智能体使用哪个特定的库或函数究竟如何拆解,只要它满足行为契约即可。这赋予了智能体在明确定义的结构内显著的自主权。编写和维护这类高质量的规则和检查,本身就是一门学问,相关的技术文档值得深入研究。

模式5:集成反馈循环

每一个高性能的Harness架构都尽可能紧密地闭合反馈循环。 语法错误由Linters在编辑时捕获。运行时错误通过智能体可以查询的可观测性工具浮现。UI缺陷通过智能体可以驱动的浏览器自动化捕获。测试失败返回时带有关于哪里出了问题以及出在何处的上下文。

另一种选择——智能体编写代码,代码在外部进行测试并产生失败消息,并在随后的会话中反馈——则更慢、Token成本更高,并且更有可能产生级联故障。反馈循环中任何可以缩小行动与后果之间差距的点,都是可以提高智能体性能的点。

这是经典软件工程中“尽早发现错误”原则在利用工具上的体现。发现错误越早,修复成本越低。对于智能体来说,这一点更为有力,因为未能立即捕获的错误会在上下文中累积,并降低后续推理的质量。

这对工程师而言究竟意味着什么?

可迁移的技能

Harness工程原则的核心,是将系统思维应用于智能体环境。它要求你足够深入地理解语言模型的认知架构,从而设计出与其协作而非对抗的环境。它要求你以分布式系统工程中熟悉的方式去思考状态管理、反馈循环、错误恢复和上下文优化,并将其应用于一个全新的领域。

在这个新兴范式中,最有效的工程师并不是那些拥有最强提示词技巧的人(尽管提示词也很重要)。而是那些理解整个系统如何运作的人:上下文如何流动、在哪里会被污染、反馈循环如何收紧、状态如何跨会话保存,以及如何在不微观管理智能体行为的情况下强制执行约束。

从抽象角度看,这些并不是新技能。它们是优秀软件工程师已有技能的延伸:系统设计、API设计、错误处理、测试策略。新的是领域:为语言模型智能体设计环境,而不是为人类设计接口。

你应该问的问题

当你构建一个智能体系统且某些环节失效时,运用Harness工程思维会产生与原生思维不同的一组问题。

你不再问“我该如何写出更好的提示词?”,而是问“智能体需要什么它目前无法访问的信息?”。你不再问“为什么模型会犯这个错误?”,而是问“缺少了什么样的反馈循环,才能在这个错误传播之前捕获它?”。你不再问“为什么智能体不按我说的做?”,而是问“环境中的什么约束阻碍了智能体执行我的指令?”。

这种转变不仅仅是语义上的。它改变了你投入工程精力的方向。投资于一个解决特定失败模式的更好提示词是局部的、暂时的。而投资于一个能防止一类失败模式的更好工具则是通用的、永久的。Harness正是这种永久性投资的所在地。

执行的商品化

在Awesome Agent Harness代码仓库的核心论点中,隐藏着一个值得坦白陈述的令人不安的含义:如果执行层是一种商品,那么AI驱动开发中的长期竞争护城河就不在模型中,而是在Harness中。

这意味着,那些投资于Harness工程——构建脚手架、反馈循环、可观测性、规约工具以及允许智能体大规模可靠工作的编排系统——的组织和个人,将比那些主要关注使用哪个模型或如何写提示词的人拥有更持久的优势。

OpenAI的Codex团队为他们特定的代码库和领域构建了相当于定制开发平台的系统。Anthropic构建了一个能够让复杂应用实现数月增量进展的Harness架构。SWE-agent团队构建了一个让相同模型产生64%性能提升的界面。这些优势没有一个来自模型,它们全部来自环境。

模型是“思考者”。Harness是“思考的对象”。 搞清楚这个区别就是这场游戏的全部。

构建你自己的Harness

最小可行Harness

你不需要构建OpenAI那样的可观测性技术栈或Anthropic完整的双智能体架构,也能从Harness思维中获益。对于一个真实项目中的编码智能体,最小有效的Harness包含少量核心组件。

首先,建立一个持久的进度文件。 智能体在每次会话开始时读取它以了解上次做了什么,在会话结束时写入它以记录所做的工作。这一个改变就能防止“过早宣布胜利”的失败模式,并确保跨上下文窗口边界的连续性。

增加一个结构化的任务列表。 不是对项目的模糊描述,而是一个具体的、列举出的、可验证的完成标准清单。每项都应描述一个可以进行端到端测试的用户可见行为。为每项标记状态,且智能体只有在验证后才能更新状态。这能防止“部分完成看起来像已完成”的失败模式。

将带有描述性提交消息的版本控制作为每次会话的一级部分。 每次会话都以一次提交结束。在代码提交且进度文件更新之前,智能体不应认为其工作已完成。这创造了清晰的交接,使多会话工作变得连贯。

如果你在构建Web应用,增加浏览器自动化。 一个只能读代码的智能体与一个能真正使用它所构建的应用的智能体之间的区别,就像一个只能读代码的开发者与一个能运行应用的开发者之间的区别。大多数重要的Bug只有在运行时才可见。

环境审计

如果你已经拥有一个智能体系统且其表现不佳,Harness工程方法建议进行特定的诊断流程。与其寻求更好的模型或更长的提示词,不如进行环境审计。

问:智能体需要哪些目前无法访问的信息?在任务流的哪些环节,智能体经常卡住或犯错?缺少了哪些反馈能让智能体自行捕获这些错误?上下文在哪里被无关信息污染了?有哪些约束需要强制执行,而目前却依赖于智能体的判断?

每一个问题都指向一个具体的Harness改进。 缺失的信息变成一个新工具或仓库中的新文档。缺失的反馈变成一个新的测试、Linter或可观测性集成。上下文污染变成一个新的上下文管理策略。未强制执行的约束变成新的机械化检查。

这就是利用工具开发的良性循环:每一次失败都是关于环境需要什么的信号,而对环境的每一次改进都会降低未来所有智能体会话中该失败发生的频率。

最后的一点思考

变革性技术在早期阶段如何被误解是有模式可循的。那些吸引公众注意力的东西——原生能力、令人印象深刻的演示、基准测试分数——很少是决定长期胜负的关键。基础设施层、Harness、环境,通常才是真正价值产生和被捕获的地方。

互联网具有变革性,不是因为HTML的存在,而是因为搜索引擎和浏览器让互联网变得可导航。移动端具有变革性,不是因为智能手机的存在,而是因为应用商店和开发工具使得在智能手机上进行大规模开发应用成为可能。在这两个案例中,组织底层能力的平台层才是持久价值的所在。

AI智能体正遵循同样的模式。能力已经存在。问题在于谁能构建出让这种能力变得可靠、可控且可持续改进的环境。SWE-agent的研究人员在2024年理解了这一点并进行了量化演示。Anthropic在构建Claude Code时理解了这一点并公开记录。OpenAI在构建其内部产品时理解了这一点并分享了教训。Awesome Agent Harness社区正在通过数十种工具和框架中对其进行归类。

Harness就是一切。 模型是推理引擎。Harness是上下文、约束、反馈循环、内存、工具和脚手架,它们决定了推理引擎究竟能成就什么。

搞好Harness不是一个提示词工程问题,它是一个系统工程问题。而且它是目前应用AI领域最重要的工程问题。

参考链接:

想了解更多关于AI工程化、智能体开发和前沿技术实践?欢迎访问 云栈社区 ,与广大开发者一同探索和构建未来。




上一篇:高并发游戏交易平台架构选型:RocketMQ保障核心交易,Kafka支撑实时风控
下一篇:Oracle数据库导出指定分区表实战指南:expdp命令详解
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-21 06:28 , Processed in 0.689280 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表