您现在的位置:kastop>> Kas信息 Web3信息>>正文内容

搞懂Harness你的AI代理才算真正开始干活

作者:@rohit4verse

你并非因为没找到正确的模型而用错了 AI

你用错 AI,是因为你没有构建正确的环境。

有些团队用三名工程师交付了百万行代码,另一些团队却连 agent 流水线里一次稳定的重构都难以实现——原因不在于 GPT-5 还是Claude Opus 的差别,不在于 temperature 设置或 max tokens,甚至不在于提示词,尽管大家为提示词争论耗费了无数岁月。

差别在于 harness

本文要讲的,就是这个词在技术层面和观念层面究竟意味着什么——因为整个行业已经养成了一个坏习惯:把这个词用得漫不经心。

harness 不是系统提示词,不是对 API 调用的封装,不是评估框架、提示词模板,也不是带记忆功能的聊天机器人。

harness 是语言模型运作其中的完整设计环境,包括它可以调用的工具、它所接收信息的格式、它的历史记录如何被压缩和管理、在错误级联之前捕获它的护栏,以及让它能够将工作移交给未来的自己而不失去连贯性的脚手架。

当你审视 Anthropic 为使Claude Code 真正奏效而构建的东西,OpenAI 为通过 Codex 以零手写代码交付百万行代码而构建的东西,以及普林斯顿 NLP 组在其关于 agent-计算机接口的里程碑论文 SWE-agent 中所发表的内容,你会开始看到一个相同的模式从每一个认真工作于这一领域的团队中浮现出来。

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

这是一份关于这一理念如何成为 2025  2026 年应用 AI 工程核心洞察的详细技术分析。它涵盖了相关研究、真实的实现案例、驱动设计决策的失败模式,以及无论你在构建编程 agent、研究 agent 还是长期运行的自主软件工程师时都会反复出现的那些模式。

读完之后,你不仅会理解 harness 是什么,更会明白为何正确地构建一个 harness,已经成为当今行业中最有价值的工程技能。

第一部分:无人谈论的问题

为什么原始能力还不够

2024 年中,AI 基准测试领域发生了一件奇怪的事。研究人员开始注意到,同一个前沿模型在完全相同的编程任务上,会因任务呈现方式和可用工具的不同而产生截然不同的结果。模型没有变,底层智能没有变,变的只是接口。

这本不应令人惊讶。几十年来我们早已知晓,合适的工具能让工程师的效率大幅提升。一名拥有现代 IDE、调试器、版本控制和 CI/CD 流水线的软件开发者,其效能数量级地高于同一个人只用文本编辑器在纯终端中工作。IDE 并未让开发者变得更聪明,它减少了摩擦,在恰当的时机浮现信息,尽早捕获错误,并将工作组织成可导航的单元。

语言模型亦然。它们不是从某个无限内部知识库进行推理的通用推理机,而是在上下文窗口中对token 进行操作的精密模式匹配引擎。它们在某一时刻所知道的一切,由上下文窗口中的内容决定;它们产出的一切,以该上下文的结构为条件。输入的格式不是装饰,它是 agent 的认知架构。

接口不是便利层。对于语言模型 agent 而言,接口就是心智本身。

这是普林斯顿 NLP  2024 年发表的 SWE-agent 论文的核心主张,经得起推敲。该论文引入了 Agent-计算机接口(ACI)的概念,并证明一个精心设计的 ACI 与同一模型通过标准 Linux shell 交互相比,可在基准测试性能上产生 64% 的相对提升

相同的模型,相同的任务,相同的计算预算,唯一的变量是接口。

让这个数字沉淀片刻。64% 不是边际收益,这是有效工具与无效工具之间的差距。而它完全来自环境设计,而非来自底层模型的任何改进。

上下文窗口不是内存插槽

 AI agent 的朴素认知模型,将上下文窗口视为内存。你加载数据,模型处理,你得到输出。上下文越多等于性能越好,提示词越长等于理解越深。这个心智模型是错误的,而且错误的方式会毁掉你以此为基础构建的 agent

上下文窗口实际上更接近于 agent 在特定会话中的整个工作意识。窗口中的每个 token 都有计算成本。每一条无关信息都在与相关信息争夺注意力。模型没有能够干净地忽略噪声的选择性注意机制——噪声在场,就会影响推理。

这对 agent 设计有具体的、可测量的后果。当你在 agent 循环内部对大型代码库运行 grep 并返回一万行匹配结果时,你并没有给 agent 更多可以利用的信息,你是在用无关数据淹没它的工作记忆,这将降低后续每一个步骤的质量,直到上下文被清空。

当你因为 agent 想看两个函数就用 cat 把整个文件倾倒出来时,你在它需要一杯水的时候递给了它一根消防水管。

SWE-agent 的研究者详细记录了这些失败模式。标准 bash 接口会导致 agent 陷入反复横跳:它们会发出返回数千行结果的 grep 命令,迷失于自己在寻找什么,再发出更多 grep 命令,逐渐用噪声填满上下文,最终要么给出错误答案,要么彻底停止进展。

问题不在于模型智能,而在于接口没有任何机制来保护 agent 免于被自身淹没。

ACI 的解决方案是构建一个返回有上限、经过汇总的结果列表的搜索工具。如果你的搜索返回超过 50 条匹配,工具会抑制输出并告知 agent 缩小查询范围。

这个设计决策回头看来几乎简单得令人发笑,却是整篇论文中杠杆效益最高的改变之一。它将一个上下文淹没的失败模式,转化为一个自然的精炼循环。

第二部分:SWE-Agent 论文与 ACI 的诞生

Agent-计算机接口究竟是什么

ACI  SWE-agent 论文中被定义为位于语言模型 agent 与计算机环境之间的一个抽象层。与人机接口(HCI)的类比是有意为之的。正如 HCI 研究追问如何设计契合人类认知架构的接口,ACI 研究追问如何设计契合语言模型认知架构的接口。

人类认知架构涉及视觉模式识别、空间记忆、跨屏幕的并行注意力,以及略读和选择性聚焦的能力。

语言模型的认知架构根本不同——它涉及顺序 token 处理、对上下文顺序和格式的敏感性、有限的工作记忆,以及倾向于锚定在提示词中最突出信息的特性。设计一个好的 ACI,意味着理解这些约束并围绕它们构建,而非与之对抗。

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

搜索与导航

搜索组件用专门构建的工具取代了标准的 grep  find 命令:find_filesearch_file search_dir。关键差异不在于语法,而在于输出管理。结果上限为 50 条。

如果查询超出该限制,工具会返回一条说明结果过多的消息,并提示 agent 精炼其搜索。这听起来微不足道,实际上却是论文中最具影响力的决策之一。

它之所以重要,是因为 agent 与认知负荷下的人类一样,在感到不确定时往往会延续既有行为。当一个人在大型代码库中迷失时,会越搜越广,产生越来越多的噪声。带上限的搜索工具通过创造一个强制函数打断了这个模式:你无法靠模糊来推进,你必须精确。这推动 agent 朝着更审慎、更有针对性的行为方向发展。

文件查看器

文件查看器是论文对认知架构洞察最为具体的体现。研究人员测试了多种查看器配置,发现每次显示 100 行是一个恰到好处的数字。行数更少(他们测试了 30 行)会导致 agent 失去对周边代码的上下文,从而出现编辑错误;行数更多(或显示完整文件)会导致agent 迷失方向,遗漏重要细节。

查看器是有状态的,在多次交互之间保持文件中的位置。更重要的是,它在每一个可见行前面加上了明确的行号。这最后一个细节看似纯属表面,实则不然。

 agent 需要发出一条针对第 47  52 行的编辑命令时,它需要能够直接从视图中读取这些数字,而不是数行数或做算术。将这个认知任务从 agent 的工作记忆中移除,为真正的问题求解释放了认知容量。

 Linting 的文件编辑器

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

这封闭了在朴素 agent 实现中导致级联失败的反馈回路。没有 linter 时,agent 可能引入一个语法错误,运行测试套件,看到一个看似不相关的失败(因为真正的错误在别处),花费多个步骤追逐错误的问题,最终耗尽上下文窗口追踪一个幽灵。

 linter 直接集成到编辑器中,语法错误就能在引入的那一刻被捕获,修复被本地化,问题无法传播。

对比使用原始 bash 工具时的情况:使用 sed 或输出重定向,没有集成反馈,编辑静默执行,多行修改需要极易出错的复杂参数格式化。Agent 可能成功运行了命令,却引入了 linter 本可捕获的细微格式错误,然后花接下来的十个步骤纳闷测试为何失败。

上下文管理

第四个组件解决了一个在长会话中不断累积的问题:过时上下文的堆积。随着 agent 推进任务,其历史记录充满了旧的观察、中间状态以及不再反映当前环境状态的探索步骤。

所有这些历史记录占用上下文窗口的空间,并可能通过提供过时信息而主动误导 agent

ACI 的上下文管理系统将较早的观察记录——最后五轮之前的内容——压缩为单行摘要。这使活跃上下文聚焦于近期的相关信息,同时保留了整体轨迹的压缩记录。

Agent 随时能看到自己最近做了什么、当前状态是什么,而不会被自己曾经运行过的每一条命令的完整未压缩历史所淹没。

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

SWE-agent 论文在SWE-bench 数据集上对其 ACI 进行了基准测试,该数据集收录了来自热门 Python 代码库的真实 GitHub Issue。任务是接收一份自然语言的 bug 报告,并产出一个解决它的代码补丁。这是一项困难的实际任务,需要在陌生的代码库中导航、理解错误消息、编写正确的代码并验证修复效果。

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

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

性能差异与模型智能无关,而与认知负荷管理有关。ACI 减少了模型追踪状态所需的工作量,为真正重要的工作腾出了空间。

这些启示远远超出了编程 agent 的范畴。任何长期 agent 任务都涉及相同的根本挑战:在大型信息空间中导航、在多个步骤中保持连贯的状态、捕获错误并从中恢复,以及管理上下文窗口注意力这一有限资源。ACI 的设计原则是可泛化的,具体工具会变,底层问题的架构不会变。

第三部分:Anthropic  Harness 工程(长期运行的 Agent 问题)

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

SWE-agent 论文解决的是如何为单个 agent 会话设计接口的问题。Anthropic 的工程团队在开发 Claude Agent SDK  Claude Code 的过程中,遭遇了一个不同的问题:如果一项任务过于庞大,无法在单个上下文窗口内完成,该怎么办?

这不是小众的边缘情况。大多数真实的软件项目都太大,无法装进任何上下文窗口。一个生产级 Web 应用包含数百个文件、数千个函数、测试套件、配置、文档和依赖项。

即便拥有 20  token 的上下文窗口,你也无法同时将完整项目装进脑海。人类工程师通过外部记忆、文档、版本控制,以及数周乃至数月在代码库中积累的理解来解决这个问题。而一个开启全新会话的 agent,什么都没有。

朴素的解决方案是压缩(compaction),它在一定程度上有效。Claude Agent SDK 内置了压缩能力,能够在窗口填满时对旧上下文进行摘要。但仅靠压缩是不够的。

Anthropic 的内部实验表明,即使有压缩机制,像 Opus 4.5 这样的前沿编程模型在跨多个上下文窗口循环运行时,也会持续失败,无法仅凭高层提示词构建出生产级质量的 Web 应用。

失败呈现出两种模式,两者都颇具启发意义。

第一种失败模式是试图一次性完成太多。当给定"构建一个 claude.ai 克隆"这样的提示词时,agent 会尝试一次性完成整个应用。

它会不断实现一个又一个功能,但每一个都未完成或测试,便在实现过程中耗尽上下文窗口,留给下一个会话的是一个半成品应用——没有已完成内容的文档,也没有关于代码当前状态的任何明确说明。

下一个 agent 实例会将其大部分上下文预算消耗在理解这团乱麻上,而不是推进工作。

第二种失败模式出现在项目后期。在某些功能已经构建完毕之后,后续的 agent 实例会环顾四周,看到已经取得了进展,便得出"工作已完成"的结论。它会在应用只完成了一半的情况下宣告胜利并停止工作。

这不是愚蠢,而是从不完整信息中做出的合理推断。Agent 没有结构化的方式来了解这个项目的"完成"究竟意味着什么。

两种失败都有一个共同的根源:agent 没有持久的、结构化的项目状态理解,这种理解无法在上下文窗口边界处存活下来,也无法为后续会话提供方向。

 Agent 架构:初始化 Agent 与编程 Agent

Anthropic 的解决方案是一套两部分架构,此后已成为认真对待长期 agentic 工作的团队所采用的模板。

第一部分是初始化 Agent这是一个具有专属系统提示词的特化初始会话,其全部目的是搭建好所有后续编程 agent 将在其中运作的环境。它不编写功能,它创建使得跨多个后续会话的功能开发成为可能的脚手架。

初始化 Agent 产出三个关键输出。

首先,它创建一个能够可靠启动开发环境的init.sh 脚本。这听起来平淡无奇,但具有显著的杠杆效益。

后续每一个编程agent 会话都可以通过运行 init.sh 来开始,而不必花费 token 去摸索如何启动服务器、配置数据库、将应用调整到可测试状态。在每次会话中节省的这部分开销,积累起来不容忽视。

其次,初始化 Agent 创建一个全面的功能列表文件。在 Anthropic 内部运行的 claude.ai 克隆实验中,这意味着超过 200 条具体的端到端功能描述,例如"用户可以打开一个新对话,输入查询,按下回车,并看到 AI 的回复"。每个功能最初都被标记为失败。

这个文件是项目的基准事实。一个开启新会话的编程agent 读取这个文件,就能立刻确定无疑地知道哪些东西已经构建完成、哪些尚未完成。它无法环顾四周,看到一些代码,就得出工作已完成的结论——功能列表会告诉它真相。

第三,初始化 Agent 创建一个 claude-progress.txt 文件并进行初始的 git 提交。进度文件是一个人类可读的日志,agent 在每次会话结束时更新它,记录自己处理了什么、完成了什么、以及将事情留在了什么状态。结合 git 历史记录,每一个后续编程 agent 都能快速定向,而无需将上下文预算耗费在考古工作上。

第二部分是编程 Agent初始化之后的每次会话使用不同的提示词:一次只处理一个功能,将环境留在干净的状态,并在会话结束前更新进度文件和 git 历史。增量推进,记录状态,干净交接。

功能列表作为认知锚点

功能列表值得特别关注,因为它解决了一个容易被低估的问题。没有它,在复杂代码库中运作的 agent 必须从代码本身推断项目的完成度。这种推断是不可靠的。

代码可能存在但并不可用;功能可能存在但并不完整。一个阅读代码并推断完成情况的 agent,会频繁得出错误答案,严重到足以构成问题。

功能列表使完成度变得明确无歧义。每个功能都有一个passes 字段,值为 true  falseAgent 要么在端到端验证某功能可用后更新这个字段,要么不更新。没有歧义,不需要推断,基准事实就在文件里。

Anthropic 有意将这个列表存储为 JSON 而非 Markdown。原因是行为层面的。从经验来看,模型对 JSON 文件的不当修改或覆写概率,低于对 Markdown 文件的概率。

JSON 具有抵制随意编辑的刚性结构。这是一个细节,但后果真实存在:你希望功能列表是agent 谨慎更新的东西,而不是它心血来潮随意改写的东西。

{"category": "functional",

"description": "新建对话按钮创建一个全新的会话",

"steps": ["导航到主界面",

"点击"新建对话"按钮",

"验证新会话已创建",

"检查对话区域显示欢迎状态",

"验证对话出现在侧边栏中"],

"passes": false}

伴随此格式的指令是明确的:删除或编辑测试是不可接受的,因为这可能导致功能缺失或存在缺陷。你提示模型将这个文件视为不可侵犯的。JSON 结构在架构层面强化了这一指令。

增量推进与干净状态要求

多会话 agentic 工作中最困难的问题之一,是确保每次会话结束时都处于一个下一次会话可以安全地在其上构建的状态。

若无明确的执行机制,agent 倾向于将工作留在上下文窗口填满时碰巧所处的状态:半成品功能、破损的测试、未记录的变更。下一个 agent 继承的是这团乱麻。

Anthropic 的解决方案是将干净状态作为一等要求,而非可有可无的附加项。每次编程 agent 会话以一次 git 提交(附有描述性信息)、对进度文件的更新以及在必要时回退到可工作状态为结尾。

他们所说的"干净状态",意味着代码适合合并到主分支:没有重大缺陷、有良好文档、处于一个开发者可以合理地开始新功能而无需先解开他人半成品工作的状态。

git 提交不只是一个检查点,它是一个恢复机制。当 agent 做出破坏某些东西的变更时,它可以用 git 回退到最后已知的良好状态并重试。这正是人类工程师的工作方式,事实证明对 agent 同样是正确的纪律。版本控制是认知脚手架,而不仅仅是源代码管理。

测试:无人愿意谈论的失败模式

Anthropic 记录了一种几乎在每个认真的 agentic 编程项目中都会出现的失败模式:agent 在没有端到端验证的情况下将功能标记为完成

Agent 会做出代码变更,对开发服务器运行单元测试或 curl 命令,看到通过结果,然后将功能标记为已完成。但当以用户方式通过浏览器测试时,该功能实际上并不可用。

单元测试成功与端到端功能可用之间的差距,是人类工程师通过切换上下文来跨越的——运行应用并尝试使用它。一个没有明确浏览器测试能力的 agent 无法完成这种切换。

它只能观察其工具所允许观察的内容,如果这些工具不包括浏览器自动化,它就会持续遗漏一类只在真实用户流程中显现的缺陷。

解决方案是为 agent 提供访问 Puppeteer MCP 服务器的能力——一个浏览器自动化工具,允许 Claude 实际导航应用、点击按钮、填写表单,并验证功能端到端可用。

性能提升是显著的。仅从代码中不可见的缺陷,当 agent 能够看到用户所见的内容时,变得一目了然。

这是一个通用原则的具体例证:agent 工作的质量受限于其反馈回路的质量。如果你的 agent 无法在真正重要的领域中观察到其行为的后果,它就会对代理指标进行优化,而这些指标可能与实际正确性并不相关。

启动流程:快速进入状态

Anthropic harness 中每次编程 agent 会话都以一套标准化的启动流程开始,其目的是在不浪费 token 的前提下尽快为 agent 定向。该流程如下:

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

只有完成所有这些步骤之后,agent 才会开始处理新功能。如果启动测试显示应用已损坏,agent 会在触碰任何新内容之前先修复已有问题。这防止了一种复合问题:agent 在破损的基础上开始新功能,使底层问题更难被隔离和修复。

启动流程还以一种具体的方式节省了 token:因为 init.sh 脚本精确记录了如何启动开发环境,agent 不需要从头摸索。每次会话在环境配置上节省的 token,在一个漫长项目中积累起来相当可观。

[助手我将首先确认方向,了解项目的当前状态。

[工具调用] <bash - pwd>

[工具调用] <read - claude-progress.txt>

[工具调用] <read - feature_list.json>

[助手让我检查 git log 以查看近期工作。

[工具调用] <bash - git log --oneline -20>

[助手现在让我检查是否有 init.sh 脚本来重启服务器。

<启动开发服务器>

[助手很好!现在让我导航到应用,验证一些基本功能仍然正常运行。

<测试基本功能>

第四部分:OpenAI  Harness 工程(零行手写代码)

这场实验

2025  8 月下旬,OpenAI Codex 团队以一个唯一的约束条件创建了一个 git 代码库:无人工编写代码。代码库中的每一行代码——包括应用逻辑、测试、CI 配置、文档、可观测性工具和内部开发者实用工具——都将由 Codex agent 编写。人类负责引导,agent 负责执行。

五个月后,该代码库在上述所有类别中共包含约一百万行代码。大约 1500  PR 已被提交并合并。一个由三名工程师组成的小团队推动了其中大部分工作,平均每名工程师每天提交 3.5  PR

随着团队扩充至七名工程师,每名工程师的吞吐量实际上还有所提升。该产品拥有数百名每日活跃的内部用户和外部 alpha 测试者。

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

工程工作的重新定义

OpenAI harness 工程文章中最重要的观察,是关于工程工作本身的变化。当你的主要工作不再是编写代码,你在做什么?

你在设计环境。你在明确意图。你在构建反馈回路。你在持续追问的不是"我如何修复这个缺陷?"而是"环境中缺少什么能力,导致这个缺陷反复出现?"

当某些东西失败时,修复方案几乎从来不是"更努力尝试",而几乎总是"环境中缺少或配置错误了什么结构性要素,导致 agent 在这里失败?"这是工程思维的深刻转变:你不再调试代码,你开始调试产生代码的系统

工程团队的首要工作变成了使 agent 能够完成有用的工作,而不是亲自完成这些工作。

在实践中,这意味着:将宏大目标分解为更小的构建模块,构建使这些模块可实现的工具和抽象,以及将失败作为信号,了解环境需要在哪些方面提供更好的支持。

人类工程师采用深度优先的工作方式:当 agent 卡住时,他们不会试图亲自编写代码,而是追问缺少什么,将其构建进环境,然后让agent 再次尝试。

代码库知识作为系统记录

OpenAI harness 中最重要的架构决策之一,是将代码库本身作为 agent 所需了解的一切内容的唯一真实来源。其洞察简单却意义深远:

agent 的视角来看,任何它在运行时无法在上下文中访问的内容,实际上都不存在。存在于 Google 文档、Slack 消息线程或某人脑海中的知识,对系统而言是不可见的。

在项目早期,团队尝试了"一个大 AGENTS.md"的方案——一个单一的大型指令文件,包含 agent 需要了解的关于项目、架构、规范和约束的一切。它以可以预见的方式失败了,且以四种值得理解的方式失败。

第一,上下文是稀缺资源。一个庞大的指令文件挤占了任务、代码和相关文档的空间。Agent 要么遗漏关键约束,要么开始为错误的目标优化。

第二,过多的指导变成了无指导。当一切都被标记为重要,就什么都不重要了。Agent 开始局部模式匹配,而不是有意识地导航。

第三,它会瞬间腐化。随着代码库的演进,一体化手册变成了过时规则的坟场。

第四,它难以验证。一个单一的文本块不适合进行覆盖率检查、新鲜度追踪或交叉链接,漂移是不可避免的。

解决方案是一个被视为系统记录的结构化docs/ 目录,配合一个简短的 AGENTS.md 文件(约 100 行)作为地图,指向其他地方更深层的真实来源。

设计文档经过了分类和索引;架构文档提供了领域和包层次的顶层地图;计划被视为第一等制品,其进度和决策日志被提交进代码库。

这实现了团队所称的渐进式披露agent 从一个小而稳定的入口点出发,被引导去知晓下一步该看哪里,而不是一开始就被淹没。结果是 agent 能够直接从代码库推断整个业务领域,无需访问可能不可用或可能已过时的外部上下文。

应用可读性:让系统对 Agent 可见

随着代码生成吞吐量的增加,瓶颈从生成转移到了验证。团队生成代码的速度超过了人工 QA 的验证能力。解决方案是通过让应用对 Codex 直接可读,使更多的验证工作成为 agent 能够自行完成的事情。

这涉及若干具体投入。他们使应用能够按 git worktree 启动,让 Codex 能够为它正在处理的每个变更启动并驱动一个应用的独立实例。

他们将 Chrome DevTools Protocol 接入 agent 运行时,并创建了处理 DOM 快照、截图和浏览器导航的工具。这使 Codex 能够直接复现缺陷、验证修复,并对 UI 行为进行推理,而不需要人类与应用交互。

他们构建了一套完整的本地可观测性技术栈:通过 LogQLPromQL TraceQL  Codex 暴露日志、指标和追踪。

每个agent 任务都运行在一个完全隔离的、拥有独立可观测性数据的应用版本上,任务完成后即被销毁。这意味着agent 可以使用真实的可观测性工具调试类生产环境问题——与人类工程师使用的工具相同——而不必仅凭代码推断行为。

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

在不微观管理的情况下执行架构

在一个完全由 agent 生成的代码库中,随着时间推移维护架构一致性是最有趣的挑战之一。Codex 会复制代码库中已存在的模式,包括不均匀或次优的模式。

久而久之,这会导致漂移:糟糕的模式扩散,不一致性积累,代码库对未来的 agent 运行变得更难正确导航。

OpenAI 的解决方案是机械化地执行不变量,而非依赖人工代码审查。应用围绕一个刚性的架构模型构建:每个业务领域划分为固定的层次集合,具有经过严格验证的依赖方向和有限的允许边界集合。

这些约束由自定义 linter(自然是由 Codex 编写的)和结构测试来执行。

核心洞察是执行边界,同时允许边界内的充分自由Linter 检查代码是否沿正确方向流经层次结构,但不规定边界内特定功能如何实现。这与平台团队在规模化时保持有效性的原则相同:执行基础,在其上允许自主。

这些 linter 是专门为 agent 生成有用错误消息而定制编写的。当 linter 捕获到一个违规时,错误消息包含格式化为可注入 agent 上下文的修复指令。这形成了闭环:被违反的约束、被违反的规则,以及修复步骤,全部在单一的可操作反馈消息中一并传递。

他们还将所谓的"黄金原则"直接编码进代码库:有主见的、机械化的规则,使代码库对未来的 agent 运行保持可读性和一致性。优先使用共享工具包而非手写辅助函数,在边界处验证数据形状。

这些原则通过周期性运行的后台清理任务来执行——扫描偏差、更新质量评级、提交针对性的重构 PR。其中大多数可在一分钟内完成审查并自动合并。

吞吐量改变了合并哲学

 agent 吞吐量大幅超过人类注意力容量时,传统工程规范会变得适得其反。等待审查的PR 阻塞了 agent 的工作;逐一调查的测试偶发性失败消耗了本可用于更高杠杆任务的人类注意力。

OpenAI 的团队做出了一个有意为之的决定:以最小的阻塞合并门控来运作。PR 保持短生命周期,测试偶发性失败通过重新运行来处理,而非无限期阻塞进度。

agent 吞吐量远超人类注意力时,纠错是廉价的,等待是昂贵的。这个权衡在低吞吐量环境中看起来不负责任,在高吞吐量环境中则显而易见。

这对向 agent 驱动开发转型的团队而言是一个真正重要的洞察。当人类工程师亲自编写每一行代码时合理的合并哲学,在 agent 每名工程师每天生成 3.5  PR 时并不自动适用。瓶颈发生了转移,流程也需要随之转移。

第五部分:Awesome Agent Harness 分类体系

生态系统图谱

 GitHub AutoJunjie 项目维护的 Awesome Agent Harness 代码库,试图绘制 harness 工程工具链这一新兴生态系统的全景图。在深入分类体系之前,有必要先明确其核心论点:AI 编写代码的能力实际上已经是一种商品。

基础模型可以生成可运行的代码,这不再是差异化能力。真正的差异化能力在于协调机制与环境设计

该代码库将一个严肃的 agent harness 生态系统所需的完整技术栈划分为七个不同层次。理解这些层次,有助于解释为何"构建一个 AI 编程助手"实际上是许多相互独立的工程问题,而非一个单一问题。

第一层:人类监督

位于最顶层的是人类监督层,由人类负责审批提案、审查 PR、设定优先级。这在传统意义上并非一个技术层,而是人类判断与 agent 执行之间的接口。

此处的核心设计原则是:工程师应当负责设计环境、审查产出,而非直接编写代码。他们的杠杆来自于引导,而非执行。

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

这一层将人类的想法转化为结构化规格说明和任务 DAG(有向无环图),供 agent 可靠地消费执行。

其底层洞察在于:agent 是盲目执行的。如果规格说明模糊或存在歧义,agent 会按其自身的理解来产出结果,而这往往与人类的真实意图相悖。Spec 工具在代码编写之前的需求阶段强制要求精确性。

该领域中的一个项目 Chorus,试图解决代码库所称的"反向对话缺口"。它并非让人类来撰写详细的规格工单(这是一个重大故障点,因为人类在 agent 所需的精确程度上并不擅长),而是让 AI 来提出任务 DAG 并细化需求,人类则在执行开始前扮演严格的验证与审批角色。

AI 从局部意图生成完整规格说明的能力,强于人类从零开始撰写的能力。

第三层:全生命周期平台

这类工具管理从初始需求到最终交付的端到端流程,将 AI 提案与人类验证关卡及子 agent 编排整合为一体。它们是规格层与执行层之间的粘合剂,负责处理整个开发生命周期中的状态管理。

第四层:任务运行器(Task Runners

任务运行器弥合了问题追踪系统(GitHub IssuesLinear)与编程 agent 之间的鸿沟。其工作流如下:

由人类或 PM agent 创建 Issue,任务运行器生成工作空间,agent 交付 PR,人类进行审查。

这一类别中的工具包括:持续轮询任务队列、决定何时启动 agent、以及在无需人工介入执行循环的情况下完成工作交付的各类系统。

第五层:Agent 编排器

编排器通过在独立的 git worktree 中隔离各 agent 的工作,实现多 agent 并行执行,从而解决吞吐量问题。

这一点至关重要——如果多个 agent 并行工作时共享同一工作空间,彼此之间必然会产生冲突。Git worktree 隔离为每个 agent 提供了独立的沙箱,使多个 agent 能够同时工作而互不干扰。

Vibe KanbanEmdashComposio 等工具均实现了这一模式。每个 agent 任务拥有独立的 git worktree,变更在隔离环境中得到验证后方可合并。

CI 反馈、合并冲突以及 agent 间的协调,均由编排层统一处理,无需人工干预。

第六层:Agent Harness 框架与运行时

框架提供用于构建自定义环境的可组合原语:渐进式披露机制、子 agent 生成、结构化上下文分发。运行时则提供持久化基础设施:长期记忆、定时执行、会话间多通道通信。

框架与运行时的区别至关重要。框架是你在其上构建的东西,运行时是持续运行的东西。

Claude Agent SDK 主要是一个框架。而一个按 cron 计划运行 agent、跨会话维护持久记忆、处理 agent 实例间多通道协调的系统,则是一个运行时。两者对于严肃的长期 agentic 工作而言缺一不可。

第七层:编程 Agent

位于最底层的是执行层:Claude CodeCodex 及类似系统,负责编写、测试和调试代码。代码库的核心洞察在于:这一层是商品化的Agent 的有效性主要由技术栈中其上方的所有层级决定,而非 agent 本身。

这一颇具挑战性的论断有充分的证据支撑。SWE-agent 论文通过实验验证了这一点:相同的模型,仅凭界面设计改进便带来了 64% 的性能提升。

OpenAI Codex 团队从实际操作层面验证了这一点:真正重要的工程工作是环境设计,而非执行本身。Anthropic  harness 工程实践从实操层面验证了这一点:初始化 agent 的配置决定了编程 agent 能否顺利推进工作。

第六部分:反复出现的设计模式

纵观所有这些系统和组织,若干设计模式反复出现。这并非巧合,而是在尝试大规模可靠部署agent 时涌现出的问题所对应的工程解决方案。

模式一:渐进式披露(Progressive Disclosure

不要预先将 agent 可能需要的所有信息一次性提供。给它定向所需的最小信息量,并提供必要时获取更多信息的指引。这一模式在以下场景中均有体现:

SWE-agent 的搜索结果上限(不返回全部结果,迫使 agent 进行精炼)、OpenAI  docs/ 架构(简短的地图指向更深层的内容)、Anthropic 的启动流程(先读进度文件,再读功能列表),以及实现结构化上下文分层的harness 框架。

采用这一模式的认知原因在于:上下文是有限资源,agent 的注意力并非均匀分布其间。位于提示词开头的信息具有不成比例的影响力。一个简短、聚焦的入口点,指向更丰富的上下文,比稀释注意力的大而全的信息堆砌更为有效。

实践原因在于可维护性。一个作为更深层文档地图的简短入口点,是可以保持准确的;而一个包罗万象的单体文档则会迅速变得陈旧,并产生反效果。

模式二:Git Worktree 隔离

一个 agent,一个worktree。这一模式出现在每一个严肃的编排系统中。其逻辑是直接的:当多个 agent 并行工作(或单个 agent 按序执行任务)时,需要在工作流之间保持隔离。若无隔离,并行 agent 会相互覆盖彼此的变更。

即便是顺序执行的 agent,也需要能够在隔离环境中验证变更,再将其影响扩散到主代码库。

Git worktree 在文件系统层面提供这种隔离。每个 agent 拥有独立的工作目录、独立的分支和独立的环境。

变更在隔离环境中产生、在隔离环境中测试,仅在通过验证后才被合并。这正是现代 CI/CD 系统为人类工程师所采用的模式,同时也被证明是 agent 编排的正确模型。

模式三:规格优先,代码库作为系统记录

Agent 对非正式知识是盲目的。任何存在于 Slack 消息、Google 文档或某人脑海中的信息,对 agent 而言都是不可见的。Agent 能够处理的只有其上下文窗口中的内容,而该上下文的唯一可靠来源就是代码库。

这一模式体现为:Anthropic harness 中的功能列表文件、OpenAI 系统中结构化的 docs/ 目录、各开源框架中的 AGENTS.md 文件,以及 awesome-agent-harness 分类体系中的 spec 工具层。

共同主线是:规格说明、需求、架构决策和约束条件,必须在执行开始前编码为代码库中的机器可读文件。如果 agent 无法从代码库中读取,它便不存在。

这对工程团队的文档工作方式具有重要含义。文档不再仅仅是为人类读者服务。它是人类意图对agent 可见的机制。模糊、陈旧或存储在代码库之外的文档,是积极损害 agent 性能的文档。

模式四:机械化架构执行

人工代码审查无法扩展到 agent 驱动的开发场景。当 agent 每名工程师每天能够提交 3.5  PR 时,审查不能成为维护代码质量和架构完整性的主要机制。解决方案是将架构约束编码为自动运行的机械化检查。

自定义 linter、结构测试和 CI流水线,取代了人工驱动开发中代码审查所承担的大部分功能。

机械化检查的优势在于:一致性强、速度快,并能在违规发生点提供即时反馈。一个捕捉到架构违规并在错误信息中返回修复指令的 linter,比三天后在 PR 评论中才捕捉到同一问题的代码审查者更为有效。

核心设计原则是执行不变量,而非实现细节。你深切关注的是依赖方向、边界跨越、接口处的数据校验以及命名与结构的一致性。

 agent 使用哪个具体库、如何分解某个函数,只要满足行为契约,你并不在意。这在定义良好的结构内给予了 agent 充分的自主空间。

模式五:闭合的反馈回路

所有高性能的 harness 架构都将反馈回路收紧到极致。linter 在编辑时捕获语法错误;运行时错误通过 agent 可查询的可观测性工具浮现;UI 缺陷通过 agent 可驱动的浏览器自动化工具发现;测试失败则附带上下文信息,说明哪里出了问题。

与之相对的另一种方式——agent 编写代码,在外部进行测试,在后续会话中才获得失败反馈——速度更慢、token 消耗更多,也更容易产生级联失败。反馈回路中每一个能够缩短行动与结果之间间隔的节点,都是可以提升 agent 性能的节点。

这是 harness 对于经典软件工程原则"尽早捕获错误"的具体演绎。错误发现得越早,修复成本越低。对 agent 而言,这一原则更具强制性——未被即时捕获的错误会在上下文中累积,并降低后续推理的质量。

第七部分:这对工程师究竟意味着什么

可迁移的技能

harness 工程这一学科,本质上是将系统思维应用于 agent 环境。它要求你对语言模型的认知架构有足够深入的理解,从而能够设计出顺应其运作机制而非与之对抗的环境。

它要求你以分布式系统工程中熟悉的方式来思考状态管理、反馈回路、错误恢复和上下文优化,只不过将其应用于一个全新的领域。

在这一新兴范式中最为高效的工程师,并不是那些拥有最佳提示词技巧的人——尽管提示词确实重要。

他们是那些理解整个系统运作方式的人:上下文如何流动、在哪里遭到污染、如何收紧反馈回路、如何跨会话保持状态,以及如何在不微观管理 agent 行为的前提下执行约束。

抽象地看,这些并非全新的技能,而是优秀软件工程师已有技能的延伸:系统设计、API 设计、错误处理、测试策略。真正新颖之处在于领域的转换:从为人类设计接口,转变为为语言模型 agent 设计环境。

你应该追问的问题

当你构建的 agent 系统出现问题时,harness 工程思维会引导出一套与朴素思维截然不同的问题。

与其问"我怎么写出更好的提示词?"不如问"agent 当前无法获取哪些它所需要的信息?

"与其问"为什么模型会犯这个错误?"不如问"缺少哪个反馈回路,导致这个错误在传播之前未能被捕获?

"与其问"agent 为什么没有按我说的去做?"不如问"环境中存在什么约束,阻止了 agent 执行我的指令?"

这种转变不只是语义层面的。它改变了你投入工程精力的方向。为某个特定故障模式设计更好的提示词,是局部的、临时的。构建能够预防一类故障模式的更好工具,是通用的、永久的。harness 正是这种永久性投资的载体。

执行层的商品化

awesome-agent-harness 代码库核心论点中有一个令人不安的含义,值得直白地说出来。如果执行层是商品化的,那么 AI 驱动开发中的长期竞争壁垒就不在于模型本身,而在于 harness

这意味着,那些投资于 harness 工程——构建脚手架、反馈回路、可观测性、规格工具以及使 agent 能够大规模可靠工作的编排系统——的组织和个人,将相较于那些主要专注于选择何种模型或如何提示的人,拥有持久的优势。

OpenAI  Codex 团队为其特定代码库和领域构建了相当于自定义开发平台的东西。Anthropic 构建了一套 harness 架构,使其能够在复杂应用上实现数月的持续进展。SWE-agent 团队构建了一套界面,使相同模型产出提升了 64% 的结果。这些优势没有一个来自模型本身,它们全部来自环境。

模型负责思考,harness 决定思考什么。把这个区别理解清楚,才是真正理解了这场游戏的全部。

第八部分:构建你自己的 Harness

最小可用 Harness

你不需要构建 OpenAI 的可观测性技术栈,也不需要 Anthropic 完整的双 agent 架构,就能从 harness 思维中获益。一个真实项目中针对编程 agent 的最小有效 harness,只需要少数几个核心组件。

持久化进度文件开始。让 agent 在每次会话开始时读取它,以了解上次做了什么;在每次会话结束时写入它,以记录本次的工作。这一个单一改变,就能防止"过早宣告完成"的失败模式,并确保跨上下文窗口边界的工作连续性。

添加结构化任务列表。不是对项目的模糊描述,而是具体的、可枚举的、可验证的完成标准列表。每一项都应描述一个可端到端测试的用户可见行为,并标注状态——agent 只有在完成验证后才能更新该状态。这能防止"做了一半看起来像做完了"的失败模式。

带有描述性提交信息的版本控制作为每次会话的一等公民。每次会话以一次提交结束。在代码提交且进度文件更新之前,agent 不应认为工作已完成。这创造了干净的交接,使多会话工作具有连贯性。

如果你在构建 Web 应用,请添加浏览器自动化。一个只能读取代码的 agent 与一个能够实际使用所构建应用的 agent,其差距,等同于一个只能读代码的开发者与一个能够运行应用的开发者之间的差距。大多数真正重要的 bug,只有在运行时才能显现。

环境审计

如果你已有一套 agent 系统但表现欠佳,harness 工程方法建议采用一套特定的诊断流程。不要急于寻找更好的模型或更长的提示词,而是做一次环境审计

追问:agent 需要哪些它目前无法获取的信息?在任务流程中,agent 经常在哪些节点卡住或犯错?缺少什么反馈,导致 agent 无法自行捕获这些错误?上下文在哪里被无关信息污染?有哪些约束目前依赖 agent 的自我判断来执行,而应当被强制检查所取代?

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

这是 harness 开发的良性循环:每一次失败都是环境需要改进的信号,而每一次环境改进都会降低该失败在未来所有 agent 会话中出现的频率。

最后一件事

变革性技术在早期阶段被误读,往往存在一个共同的规律。吸引公众眼球的东西——原始能力、令人印象深刻的演示、跑分成绩——鲜少是决定长期胜负的因素。基础设施层、harness、环境,通常才是真正价值被创造和捕获的地方。

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

AI agent 正在遵循同样的规律。能力已然存在。问题是谁来构建让这种能力变得可靠、可控、持续可改进的环境。

SWE-agent 的研究者在 2024 年理解了这一点,并用数据加以证明。Anthropic 在构建 Claude Code 时理解了这一点,并公开记录了下来。

OpenAI 在构建其内部产品时理解了这一点,并分享了相关经验。awesome-agent-harness社区正在数十种工具和框架中对此进行系统性整理。

harness 就是一切。 模型是推理引擎,harness 是上下文、约束、反馈回路、记忆、工具和脚手架——它们共同决定推理引擎究竟能够完成什么。

 harness 做对,不是一个提示词工程问题,而是一个系统工程问题。这是当前应用 AI领域最重要的工程问题。

请以此为指引,去构建。



感动 同情 无聊 愤怒 搞笑 难过 高兴 路过
【字体: 】【收藏】【打印文章】 【 打赏 】 【查看评论

相关文章

    没有相关内容