AI技术·2026年4月27日·12 分钟

LLM 怎么变成 Agent:Harness 全景拆解

深入解析 Agent Harness——包裹在 LLM 之外的完整软件基础设施,拆解生产级 Agent Harness 的 12 个核心组件,从编排循环、工具层、记忆系统到验证循环和多 Agent 架构。

这是一篇关于 Anthropic、OpenAI、Perplexity 和 LangChain 实际在构建什么的研究。涵盖编排循环、工具、记忆、上下文管理,以及将无状态 LLM 转化为能干 Agent 的所有要素。

你搭过一个聊天机器人。也许还接了个 ReAct 循环,挂了几个工具。Demo 跑得挺顺。然后你试着做一个生产级系统,轮子开始掉了:模型忘了三步前做了什么,工具调用悄悄失败,上下文窗口塞满了垃圾。

问题不在你的模型。在于模型周围的一切。

LangChain 用事实证明了这一点:他们只改了包裹 LLM 的基础设施(同样的模型、同样的权重),就从 TerminalBench 2.0 的前 30 名之外跃升到第 5 名。另一个研究项目让 LLM 自行优化基础设施,达到了 76.4% 的通过率,超越了手工设计的系统。

这套基础设施现在有了一个名字:Agent Harness(Agent 驾驭框架)。

这个词在 2026 年初被正式命名,但概念早已存在。Harness 是包裹 LLM 的完整软件基础设施:编排循环、工具、记忆、上下文管理、状态持久化、错误处理和护栏。Anthropic 的 Claude Code 文档说得很直接:SDK 是"驱动 Claude Code 的 Agent Harness。" OpenAI 的 Codex 团队使用了同样的表述,明确将"agent"和"harness"等同起来,指代那些让 LLM 变得可用的非模型基础设施。

我很喜欢 LangChain 的 Vivek Trivedy 给出的经典公式:"如果你不是模型,你就是 harness。"

这里有一个容易让人混淆的区分。"Agent"是涌现出来的行为:目标驱动、使用工具、自我纠错、用户与之交互的实体。Harness 是产生这种行为的机器。当有人说"我搭了一个 Agent"时,他的意思是搭了一个 Harness,然后把它指向了一个模型。

图片

Beren Millidge 在他 2023 年的文章中把这个类比讲得非常精确。一个原始 LLM 就是一块没有内存、没有硬盘、没有 I/O 的 CPU。上下文窗口充当内存(快但有限),外部数据库充当硬盘(大但慢),工具集成充当设备驱动程序,而 Harness 就是操作系统。正如 Millidge 所写:"我们重新发明了冯·诺依曼架构",因为这是任何计算系统的自然抽象。

围绕模型有三层同心圆的工程:

prompt 工程为模型精心编排收到的指令。

上下文工程管理模型看到什么、什么时候看到。

Harness 工程涵盖前两者,加上整个应用基础设施:工具编排、状态持久化、错误恢复、验证循环、安全执行和生命周期管理。

Harness 不是 prompt 的包装器。它是使自主 Agent 行为成为可能的完整系统。

综合 Anthropic、OpenAI、LangChain 以及更广泛的实践者社区的经验,一个生产级 Agent Harness 包含十二个独立组件。让我们逐一拆解。

图片

编排循环

这是心脏。它实现了思维-行动-观察(TAO)循环,也叫 ReAct 循环。循环流程是:组装 prompt、调用 LLM、解析输出、执行工具调用、将结果喂回、重复直到完成。

从机械角度看,它通常就是一个 while 循环。复杂性不在于循环本身,而在于循环所管理的一切。Anthropic 把他们的运行时描述为一个"笨循环",所有智能都在模型里。Harness 只是管理轮次。

工具层

工具是 Agent 的手。它们被定义为 schema(名称、描述、参数类型),注入到 LLM 的上下文中,让模型知道有什么可用。工具层负责注册、schema 验证、参数提取、沙盒执行、结果捕获,以及将结果格式化为 LLM 可读的观察信息。

Claude Code 提供六个类别的工具:文件操作、搜索、执行、Web 访问、代码智能和子 Agent 生成。OpenAI 的 Agents SDK 支持函数工具(通过 OpenAI Functions)、托管工具(WebSearch、CodeInterpreter、FileSearch)以及 MCP server 工具。

记忆系统

记忆在多个时间尺度上运作。短期记忆是单个会话内的对话历史。长期记忆跨会话持久化:Anthropic 使用项目文件和自动生成的 CLAUDE.md 文件;LangGraph 使用命名空间组织的 JSON Store;OpenAI 支持以 SQLite 或 Redis 为后端的 Sessions。

Claude Code 实现了三层层级结构:轻量级索引(每条约 150 字符,始终加载)、按需拉取的详细主题文件、以及仅通过搜索访问的原始记录。一个关键设计原则:Agent 把自己的记忆当作"提示",在行动前对照实际状态进行验证。

上下文管理

这是很多 Agent 悄悄翻车的地方。核心问题是上下文腐烂(context rot):当关键内容落在窗口中间位置时,模型性能下降 30% 以上(Chroma 研究,斯坦福"Lost in the Middle"发现也印证了这一点)。即使是百万 token 窗口,随着上下文增长也会出现指令遵循能力的退化。

生产级策略包括:

压缩(Compaction):在接近限制时摘要对话历史(Claude Code 保留架构决策和未解决的 bug,丢弃冗余的工具输出)

观察遮蔽(Observation masking):JetBrains 的 Junie 隐藏旧的工具输出,但保留工具调用可见

即时检索(Just-in-time retrieval):维护轻量级标识符,动态加载数据(Claude Code 使用 grep、glob、head、tail 而非加载完整文件)

子 Agent 委派:每个子 Agent 广泛探索,但只返回 1,000 到 2,000 token 的压缩摘要

Anthropic 的上下文工程指南陈述了目标:找到最小的、高信号 token 集合,最大化产生期望结果的概率。

Prompt 组装

这在每一步组装模型实际看到的内容。它是层级化的:系统 prompt、工具定义、记忆文件、对话历史和当前用户消息。

OpenAI 的 Codex 使用严格的优先级栈:服务器控制的系统消息(最高优先级)、工具定义、开发者指令、用户指令(级联的 CLAUDE.md 文件,32 KiB 限制),然后是对话历史。

输出解析与现代工具调用

现代 Harness 依赖原生工具调用,模型返回结构化的 tool_calls 对象,而非需要解析的自由文本。Harness 检查:有工具调用吗?执行并循环。没有工具调用?那就是最终答案。

对于结构化输出,OpenAI 和 LangChain 都支持通过 Pydantic 模型进行 schema 约束响应。遗留方案如 RetryWithErrorOutputParser(将原始 prompt、失败的完成结果和解析错误一起喂回给模型)仍可用于边界情况。

状态持久化

LangGraph 将状态建模为在图节点间流动的类型化字典,通过 reducer 合并更新。检查点发生在超级步骤边界,支持中断后恢复和时间旅行调试。OpenAI 提供四种互斥策略:应用内存、SDK Sessions、服务端 Conversations API,或轻量级的 previous_response_id 链式传递。Claude Code 采用了不同的方式:用 git commit 作为检查点,用进度文件作为结构化草稿区。

错误处理

这很重要:一个 10 步流程,每步 99% 的成功率,端到端成功率也只有约 90.4%。错误会快速叠加。

LangGraph 区分四种错误类型:瞬态错误(用退避重试)、LLM 可恢复错误(将错误作为 ToolMessage 返回让模型自行调整)、用户可修复错误(中断等待人工输入)、意外错误(上抛供调试)。Anthropic 在工具处理器内捕获失败,将其作为错误结果返回以保持循环运行。Stripe 的生产级 Harness 将重试次数上限设为两次。

护栏与安全

OpenAI 的 SDK 实现了三个层级:输入护栏(在首个 Agent 上运行)、输出护栏(在最终输出上运行)、工具护栏(在每次工具调用上运行)。一个"绊线"(tripwire)机制在触发时立即停止 Agent。

Anthropic 在架构上将权限执行与模型推理分离。模型决定尝试做什么;工具系统决定允许什么。Claude Code 独立控制约 40 项离散的工具能力,分三个阶段:项目加载时建立信任、每次工具调用前进行权限检查、高风险操作需要用户明确确认。

验证循环

这是区分玩具 Demo 和生产级 Agent 的关键。Anthropic 推荐三种方式:基于规则的反馈(测试、lint、类型检查)、视觉反馈(通过 Playwright 截图用于 UI 任务)、以及 LLM-as-judge(一个独立的子 Agent 评估输出)。

Claude Code 的创建者 Boris Cherny 指出,给模型一种验证自己工作的方法,可以将质量提升 2 到 3 倍。

多 Agent 架构

Claude Code 支持三种执行模型:Fork(父上下文的字节级拷贝)、Teammate(独立的终端面板,通过基于文件的邮箱通信)、Worktree(独立的 git worktree,每个 Agent 一个隔离分支)。OpenAI 的 SDK 支持 agents-as-tools(专家处理有界子任务)和 handoffs(专家接管完全控制权)。LangGraph 将子 Agent 实现为嵌套状态图。

了解了所有组件之后,让我们追踪它们在一个循环中是如何协同工作的。

图片

步骤 1(Prompt 组装):Harness 构建完整输入:系统 prompt + 工具 schema + 记忆文件 + 对话历史 + 当前用户消息。重要上下文被放置在 prompt 的开头和末尾("Lost in the Middle"发现)。

步骤 2(LLM 推理):组装好的 prompt 发送到模型 API。模型生成输出 token:文本、工具调用请求,或两者兼有。

步骤 3(输出分类):如果模型产生了没有工具调用的文本,循环结束。如果请求了工具调用,进入执行。如果请求了 handoff,更新当前 Agent 并重新开始。

步骤 4(工具执行):对每个工具调用,Harness 验证参数、检查权限、在沙盒环境中执行并捕获结果。只读操作可以并发运行;修改操作串行执行。

步骤 5(结果打包):工具结果被格式化为 LLM 可读的消息。错误被捕获并作为错误结果返回,让模型可以自我纠正。

步骤 6(上下文更新):结果被追加到对话历史。如果接近上下文窗口限制,Harness 触发压缩。

步骤 7(循环):返回步骤 1。重复直到终止。

终止条件是分层的:模型产生了没有工具调用的响应、超过最大轮次限制、token 预算耗尽、护栏绊线触发、用户中断、或安全拒绝被返回。一个简单问题可能只需 1 到 2 轮。一个复杂的重构任务可以链式执行数十个工具调用跨多轮。

图片

Claude Code 的实现方式:一个初始化 Agent 设置环境(初始化脚本、进度文件、功能列表、初始 git commit),然后在后续每个会话中,编码 Agent 读取 git 日志和进度文件来定位自己,选择最高优先级的未完成功能,进行开发,commit,并写摘要。文件系统在上下文窗口之间提供了连续性。

Anthropic 的 Claude Agent SDK 通过单一的 query() 函数暴露 Harness,创建 Agent 循环并返回一个异步迭代器流式传输消息。运行时是一个"笨循环"。所有智能都在模型里。Claude Code 使用 Gather-Act-Verify 循环:收集上下文(搜索文件、阅读代码)、采取行动(编辑文件、运行命令)、验证结果(运行测试、检查输出),重复。

OpenAI 的 Agents SDK 通过 Runner 类实现 Harness,有三种模式:async、sync 和 streamed。SDK 是"代码优先"的:工作流逻辑用原生 Python 表达,而非图 DSL。Codex 的 Harness 在此基础上扩展为三层架构:Codex Core(Agent 代码 + 运行时)、App Server(双向 JSON-RPC API)和客户端界面(CLI、VS Code、Web 应用)。所有界面共享同一个 Harness,这就是为什么"Codex 模型在 Codex 界面上的表现比通用聊天窗口更好。"

LangGraph 将 Harness 建模为显式状态图。两个节点(llm_call 和 tool_node)通过条件边连接:有工具调用则路由到 tool_node,没有则路由到 END。LangGraph 从 LangChain 的 AgentExecutor 演化而来,后者在 v0.2 中被废弃,因为难以扩展且缺乏多 Agent 支持。LangChain 的 Deep Agents 明确使用了"Agent Harness"这个词:内置工具、规划(write_todos 工具)、用于上下文管理的文件系统、子 Agent 生成和持久化记忆。

CrewAI 实现了基于角色的多 Agent 架构:Agent(包裹在 LLM 周围的 Harness,由角色、目标、背景故事和工具定义)、Task(工作单元)和 Crew(Agent 的集合)。CrewAI 的 Flows 层添加了"在关键之处注入智能的确定性骨架",管理路由和验证,而 Crew 处理自主协作。

AutoGen(正在演变为 Microsoft Agent Framework)开创了对话驱动编排。它的三层架构(Core、AgentChat、Extensions)支持五种编排模式:顺序、并发(扇出/扇入)、群聊、交接和 magnet(一个管理 Agent 维护一个动态任务账本,用于协调专家)。

图片

脚手架这个比喻不是装饰性的。它是精确的。建筑脚手架是临时基础设施,让工人能够建造他们够不到的结构。脚手架本身不施工。但没有它,工人就够不到上层。

关键洞见:建筑完工后,脚手架会被拆除。随着模型的改进,Harness 的复杂度应该降低。Manus 在六个月内重建了五次,每次重写都减少了复杂度。复杂的工具定义变成了通用 shell 执行。"管理 Agent"变成了简单的结构化交接。

这指向了协同进化原则:模型现在是与特定 Harness 一起进行后训练的。Claude Code 的模型学会了使用它被训练时使用的特定 Harness。改变工具实现可能会降低性能,因为这种紧密耦合。

Harness 设计的"未来验证测试":如果性能随着更强大的模型提升而不需要增加 Harness 复杂度,这个设计就是合理的。

图片

每个 Harness 架构师都面临七个选择:

图片

1. 单 Agent vs 多 Agent。 Anthropic 和 OpenAI 都说:先最大化单 Agent。多 Agent 系统会增加开销(路由的额外 LLM 调用、交接时的上下文丢失)。只有在工具过载超过约 10 个重叠工具,或存在明显不同的任务领域时,才进行拆分。

2. ReAct vs 计划-执行。 ReAct 在每一步交替推理和行动(灵活但单步成本更高)。计划-执行将规划和执行分离。LLMCompiler 报告了比顺序 ReAct 快 3.6 倍的加速。

3. 上下文窗口管理策略。 五种生产级方法:基于时间的清除、对话摘要化、观察遮蔽、结构化笔记、子 Agent 委派。ACON 研究显示,通过优先保留推理轨迹而非原始工具输出,实现了 26% 到 54% 的 token 减少同时保持 95% 以上的准确率。

4. 验证循环设计。 计算验证(测试、lint)提供确定性的真实依据。推断验证(LLM-as-judge)能捕获语义问题但增加延迟。Martin Fowler 的 Thoughtworks 团队将其表述为引导器(前馈,在行动前引导)vs 传感器(反馈,在行动后观察)。

5. 权限与安全架构。 宽松模式(快但有风险,自动批准大多数操作)vs 严格模式(安全但慢,每次操作都需要批准)。选择取决于部署场景。

6. 工具范围策略。 更多工具往往意味着更差的表现。Vercel 从 v0 中移除了 80% 的工具,结果反而更好了。Claude Code 通过延迟加载实现了 95% 的上下文缩减。原则:暴露当前步骤所需的最小工具集。

7. Harness 厚度。 多少逻辑放在 Harness 中 vs 模型中。Anthropic 押注薄 Harness 和模型改进。基于图的框架押注显式控制。Anthropic 定期从 Claude Code 的 Harness 中删除规划步骤,因为新模型版本已经内化了这些能力。

两个使用相同模型的产品,可能仅因 Harness 设计不同而表现天差地别。TerminalBench 的证据很明确:只改 Harness 就让排名移动了 20 多个位次。

Harness 不是一个已解决的问题,也不是一个可商品化的通用层。这里才是真正的工程挑战所在:将上下文管理为稀缺资源,设计在错误累积之前捕获它们的验证循环,构建提供连续性而不产生幻觉的记忆系统,以及做出"搭多少脚手架 vs 留多少给模型"的架构决策。

整个领域正在随着模型改进而走向更薄的 Harness。但 Harness 本身不会消失。即使是最强大的模型,也需要有东西来管理它的上下文窗口、执行工具调用、持久化状态并验证工作。

下次你的 Agent 出了问题,别怪模型。看看 Harness。

以上就是全部内容!如果你喜欢这篇文章,可以在 X 上找到我:@akshay_pachaar。我每天分享关于 AI、机器学习和 vibe coding 最佳实践的教程和洞见。