一文深度解析 Agent Harness
一文深度解析 Agent Harness
一文深度解析 Agent Harness 一文深度解析 Agent Harness Modified April 8 Step 6:上下文更新 结果会被追加进对话历史。 如果接近上下文窗口上限,harness 会触发 compaction。 Step 7:循环 回到 Step 1。 重复,直到终止。 终止条件是分层的: • 模型返回一个没有工具调用的响应 • 超过最大轮次限制 • token 预算耗尽 • guardrail tripwire 触发 • 用户中断 • 返回安全拒绝 一个简单问题可能只需要 1 到 2 轮。 而复杂重构任务则可能在许多轮里串起几十次工具调用。 接下来是一个典型模式: 一个 Initializer Agent 先建立环境(初始化脚本、进度文件、功能列表、初始 git commit); 然后在后续每个 session 里,一个 Coding Agent 都会读取 git log 和进度文件来建立上下文,挑选最高优先级、尚未完成的功能,开始工作,提交代码,并写下总结。文件系统本身在上下文窗口之外提供了连续性。 真实框架如何实现该模式 Anthropic 的 Claude Agent SDK 通过一个 query() 函数暴露 harness。这个函数会创建 agentic loop,并返回一个流式消息的异步迭代器。 这个 runtime 是一个“dumb loop”。 所有智能都在模型里。 Claude Code 使用 Gather Act Verify 循环: • gather context搜索文件、读取代码 • take action编辑文件、运行命令 • verify results运行测试、检查输出 • 然后重复 OpenAI 的 Agents SDK 通过 Runner 类实现 harness,有三种模式: • async • sync • streamed 这个 SDK 是 “code first” 的:工作流逻辑直接写在原生 Python 里,而不是依赖图 DSL。 Codex harness 在此基础上扩展为三层结构: • Codex Coreagent 代码 + runtime • App Server双向 JSON RPC API • client surfacesCLI、VS Code、Web App 所有端面共用同一个 harness。 这也是为什么:Codex models feel better on Codex surfaces than a generic chat window. LangGraph 把 harness 建模成显式状态图。 两个节点: • llm call • tool node 它们通过条件边连接: • 如果存在 tool calls,就路由到 tool node • 如果没有,就路由到 END LangGraph 是从 LangChain 的 AgentExecutor 演化来的。后者在 v0.2 被弃用,因为它难以扩展,也缺少多 agent 支持。 LangChain 的 Deep Agents 明确使用了 agent harness 这个说法: • 内建工具 • 规划(write todos 工具) • 用文件系统管理上下文 • 子 agent 生成 • 持久记忆 CrewAI 实现的是角色驱动型多 agent 架构: • Agent包裹 LLM 的 harness,由 role、goal、backstory 和 tools 定义 • Task工作单元 • Crewagent 的集合 CrewAI 的 Flows 层增加了一条“在需要的地方加入智能、而在其余部分保持确定性骨架”的路径:它负责路由和校验,而 Crew 负责自主协作。 AutoGen(后来演化成 Microsoft Agent Framework)最早推动了 conversation driven orchestration。 它的三层架构: • Core • AgentChat • Extensions 支持五种编排模式: • sequential • concurrent(fan out / fan in) • group chat • handoff • magentic由一个 manager agent 维护动态任务账本并协调专家 agent 脚手架隐喻 “脚手架”这个比喻不是装饰性的。它是精确的。 建筑工地上的脚手架,是一种临时性基础设施,让工人能接触到原本够不着的地方。 它不会替工人建楼。 但没有它,工人就到不了高层。 这里的关键洞见是: 脚手架会在建筑完成后被拆掉。 随着模型变强,harness 的复杂度应该下降。 Manus 在六个月里重写了五次,每次重写都在删除复杂性。 • 复杂工具定义变成了通用 shell 执行 • “管理 agent” 变成了简单结构化 handoff 这指向了一个共同演化原则: 模型现在是在特定 harness 在环的情况下被后训练的。 Claude Code 的模型学会的是使用它所配套训练过的那套特定 harness。 正因为这种紧耦合,单纯更换工具实现都可能导致性能下降。 对于 harness 设计来说,一个 “future proofing test” 是: 如果随着模型能力变强,性能能够随之提升,而不需要继续增加 harness 的复杂度,那么这个设计就是健康的。 决定每一套工具执行框架的七大关键抉择 每一个 harness 架构师都要面对 7 个选择: 1. 单 agent 还是多 agentAnthropic 和 OpenAI 都给出了同样建议:先把单 agent 做到极致。多 agent 系统会引入额外开销,比如用于路由的额外 LLM 调用、handoff 过程中的上下文损失。只有当工具负载超过大约 10 个相互重叠的工具,或者任务域之间存在清晰边界时,才值得拆分。 2. ReAct 还是 plan and executeReAct 在每一步交替进行推理和行动,灵活,但每一步成本更高。Plan and execute 把规划和执行分开。LLMCompiler 报告显示,相比顺序 ReAct,它速度提升了 3.6x。 3. 上下文窗口管理策略五种生产级做法: ◦ 基于时间清理 ◦ 对话摘要 ◦ observation masking ◦ 结构化记笔记 ◦ sub agent delegationACON 的研究表明,通过优先保留 reasoning traces 而非原始工具输出,可以在保持 95%+ 准确率的同时减少 26% 到 54% 的 token 使用。 4. 验证循环设计计算式验证(测试、lint)能提供确定性的真值。推断式验证(LLM as judge)能捕捉语义问题,但会增加延迟。Martin Fowler 的 Thoughtworks 团队把这区分成: ◦ guides(feedforward,在行动前引导) ◦ sensors(feedback,在行动后观察) 5. 权限与安全架构宽松式:快,但风险高,默认自动批准大多数动作。保守式:安全,但慢,几乎每个动作都要求审批。该如何选,取决于部署场景。 6. 工具范围策略工具越多,往往性能越差。Vercel 从 v0 中移除了 80% 的工具,结果效果反而更好。Claude Code 通过 lazy loading 实现了 95% 的上下文缩减。原则是:只暴露当前步骤所需的最小工具集。 7. Harness 的“厚度”多少逻辑应该写在 harness 里,多少留给模型本身。Anthropic 押注轻 harness 和模型持续进化。图式框架押注显式控制。随着新模型版本把某些能力内化,Anthropic 会定期把 Claude Code harness 里的规划步骤删掉。 工具框架本身就是核心产品 Step 6:上下文更新 结果会被追加进对话历史。 如果接近上下文窗口上限,harness 会触发 compaction。 Step 7:循环 回到 Step 1。 重复,直到终止。 终止条件是分层的: • 模型返回一个没有工具调用的响应 • 超过最大轮次限制 • token 预算耗尽 • guardrail tripwire 触发 • 用户中断 • 返回安全拒绝 一个简单问题可能只需要 1 到 2 轮。 而复杂重构任务则可能在许多轮里串起几十次工具调用。 接下来是一个典型模式: 一个 Initializer Agent 先建立环境(初始化脚本、进度文件、功能列表、初始 git commit); 然后在后续每个 session 里,一个 Coding Agent 都会读取 git log 和进度文件来建立上下文,挑选最高优先级、尚未完成的功能,开始工作,提交代码,并写下总结。文件系统本身在上下文窗口之外提供了连续性。 真实框架如何实现该模式 Anthropic 的 Claude Agent SDK 通过一个 query() 函数暴露 harness。这个函数会创建 agentic loop,并返回一个流式消息的异步迭代器。 这个 runtime 是一个“dumb loop”。 所有智能都在模型里。 Claude Code 使用 Gather Act Verify 循环: • gather context搜索文件、读取代码 • take action编辑文件、运行命令 • verify results运行测试、检查输出 • 然后重复 OpenAI 的 Agents SDK 通过 Runner 类实现 harness,有三种模式: • async • sync • streamed 这个 SDK 是 “code first” 的:工作流逻辑直接写在原生 Python 里,而不是依赖图 DSL。 Codex harness 在此基础上扩展为三层结构: • Codex Coreagent 代码 + runtime • App Server双向 JSON RPC API • client surfacesCLI、VS Code、Web App 所有端面共用同一个 harness。 这也是为什么:Codex models feel better on Codex surfaces than a generic chat window. LangGraph 把 harness 建模成显式状态图。 两个节点: • llm call • tool node 它们通过条件边连接: • 如果存在 tool calls,就路由到 tool node • 如果没有,就路由到 END LangGraph 是从 LangChain 的 AgentExecutor 演化来的。后者在 v0.2 被弃用,因为它难以扩展,也缺少多 agent 支持。 LangChain 的 Deep Agents 明确使用了 agent harness 这个说法: • 内建工具 • 规划(write todos 工具) • 用文件系统管理上下文 • 子 agent 生成 • 持久记忆 CrewAI 实现的是角色驱动型多 agent 架构: • Agent包裹 LLM 的 harness,由 role、goal、backstory 和 tools 定义 • Task工作单元 • Crewagent 的集合 CrewAI 的 Flows 层增加了一条“在需要的地方加入智能、而在其余部分保持确定性骨架”的路径:它负责路由和校验,而 Crew 负责自主协作。 AutoGen(后来演化成 Microsoft Agent Framework)最早推动了 conversation driven orchestration。 它的三层架构: • Core • AgentChat • Extensions 支持五种编排模式: • sequential • concurrent(fan out / fan in) • group chat • handoff • magentic由一个 manager agent 维护动态任务账本并协调专家 agent 脚手架隐喻 “脚手架”这个比喻不是装饰性的。它是精确的。 建筑工地上的脚手架,是一种临时性基础设施,让工人能接触到原本够不着的地方。 它不会替工人建楼。 但没有它,工人就到不了高层。 这里的关键洞见是: 脚手架会在建筑完成后被拆掉。 随着模型变强,harness 的复杂度应该下降。 Manus 在六个月里重写了五次,每次重写都在删除复杂性。 • 复杂工具定义变成了通用 shell 执行 • “管理 agent” 变成了简单结构化 handoff 这指向了一个共同演化原则: 模型现在是在特定 harness 在环的情况下被后训练的。 Claude Code 的模型学会的是使用它所配套训练过的那套特定 harness。 正因为这种紧耦合,单纯更换工具实现都可能导致性能下降。 对于 harness 设计来说,一个 “future proofing test” 是: 如果随着模型能力变强,性能能够随之提升,而不需要继续增加 harness 的复杂度,那么这个设计就是健康的。 决定每一套工具执行框架的七大关键抉择 每一个 harness 架构师都要面对 7 个选择: 1. 单 agent 还是多 agentAnthropic 和 OpenAI 都给出了同样建议:先把单 agent 做到极致。多 agent 系统会引入额外开销,比如用于路由的额外 LLM 调用、handoff 过程中的上下文损失。只有当工具负载超过大约 10 个相互重叠的工具,或者任务域之间存在清晰边界时,才值得拆分。 2. ReAct 还是 plan and executeReAct 在每一步交替进行推理和行动,灵活,但每一步成本更高。Plan and execute 把规划和执行分开。LLMCompiler 报告显示,相比顺序 ReAct,它速度提升了 3.6x。 3. 上下文窗口管理策略五种生产级做法: ◦ 基于时间清理 ◦ 对话摘要 ◦ observation masking ◦ 结构化记笔记 ◦ sub agent delegationACON 的研究表明,通过优先保留 reasoning traces 而非原始工具输出,可以在保持 95%+ 准确率的同时减少 26% 到 54% 的 token 使用。 ◦ 基于时间清理 ◦ 对话摘要 ◦ observation masking ◦ 结构化记笔记 ◦ sub agent delegationACON 的研究表明,通过优先保留 reasoning traces 而非原始工具输出,可以在保持 95%+ 准确率的同时减少 26% 到 54% 的 token 使用。 4. 验证循环设计计算式验证(测试、lint)能提供确定性的真值。推断式验证(LLM as judge)能捕捉语义问题,但会增加延迟。Martin Fowler 的 Thoughtworks 团队把这区分成: ◦ guides(feedforward,在行动前引导) ◦ sensors(feedback,在行动后观察) ◦ guides(feedforward,在行动前引导) ◦ sensors(feedback,在行动后观察) 5. 权限与安全架构宽松式:快,但风险高,默认自动批准大多数动作。保守式:安全,但慢,几乎每个动作都要求审批。该如何选,取决于部署场景。 6. 工具范围策略工具越多,往往性能越差。Vercel 从 v0 中移除了 80% 的工具,结果效果反而更好。Claude Code 通过 lazy loading 实现了 95% 的上下文缩减。原则是:只暴露当前步骤所需的最小工具集。 7. Harness 的“厚度”多少逻辑应该写在 harness 里,多少留给模型本身。Anthropic 押注轻 harness 和模型持续进化。图式框架押注显式控制。随着新模型版本把某些能力内化,Anthropic 会定期把 Claude Code harness 里的规划步骤删掉。 工具框架本身就是核心产品 两个使用相同模型的产品,仅仅因为 harness 设计不同,就可能有极大的性能差异。 TerminalBench 的证据已经很明确:只改变 harness,就能让 agent 在排名上前后移动 20+ 个位置。 Harness 不是一个已经解决的问题,也不是一个无差别商品层。 真正难的工程都在这里: • 把上下文当作稀缺资源来管理 • 设计验证循环,在错误累积之前发现问题 • 构建记忆系统,在维持连续性的同时避免幻觉 • 在“搭更多脚手架”与“把更多能力留给模型”之间做架构押注 随着模型能力增强,这个领域正在走向更薄的 harness。 但 harness 本身不会消失。 即便是最强的模型,也需要某种东西来: • 管理它的上下文窗口 • 执行它的工具调用 • 持久化它的状态 • 验证它的工作 所以下次当你的 agent 失败时,不要先怪模型。 先看看 harness。 就到这里! 如果你喜欢这篇内容: 找到我 →@akshay pachaar✔️ @akshay pachaar 我每天都会分享关于 AI、机器学习,以及 vibe coding 最佳实践的教程和洞见。 原帖链接:https://x.com/akshay pachaar/status/2041146899319971922 作者:Akshay 🚀 一篇深入解析,讲清 Anthropic、OpenAI、Perplexity 和 LangChain 实际上在构建什么。涵盖编排循环、工具、记忆、上下文管理,以及其他一切能把一个无状态 LLM 变成有能力的 agent 的部分。 或许你已经做出了一个聊天机器人。也许你还接上了一个带几个工具的 ReAct 循环。拿来做 demo 没问题。然后你开始尝试构建一个生产级系统,结果整个东西就开始散架:模型会忘记三步之前自己做过什么,工具调用会静默失败,上下文窗口里塞满垃圾内容。 问题不在你的模型。 问题在模型之外的所有东西。 LangChain 证明了这一点:他们只改了包裹 LLM 的那层基础设施(同一个模型、同一组权重),就在 TerminalBench 2.0 上从前 30 名之外跳到了第 5 名。另一个独立研究项目让一个 LLM 去优化这层基础设施本身,结果达到了 76.4% 的通过率,超过了人工设计的系统。 现在,这层基础设施有了一个名字:agent harness。 什么是 Agent Harness? 这个术语是在 2026 年初被正式化的,但这个概念早就存在。Harness 是包裹 LLM 的整套软件基础设施:编排循环、工具、记忆、上下文管理、状态持久化、错误处理和护栏。Anthropic 的 Claude Code 文档说得很直接:SDK 就是“驱动 Claude Code 的 agent harness”。OpenAI 的 Codex 团队也使用同样的表述,明确把 “agent” 和 “harness” 这两个词对应用来指代那层让 LLM 变得有用的非模型基础设施。 我非常喜欢 LangChain 的 Vivek Trivedy 给出的那个经典公式:If you're not the model, you're the harness. 这里有一个很容易让人搞混的区分。 “Agent” 是一种涌现出来的行为:它是用户交互到的那个目标导向、会用工具、会自我修正的实体。“Harness” 是产生这种行为的那套机械结构。当有人说“我构建了一个 agent”,他的实际意思是:他构建了一套 harness,然后把它接到一个模型上。 Beren Millidge 在他 2023 年的一篇文章里把这个类比讲得非常精确。 "Scaffolded LLMs as Natural Language Computers." Scaffolded LLMs as Natural Language Computers. 一个原始 LLM 就像是一颗没有 RAM、没有磁盘、没有 I/O 的 CPU。 • 上下文窗口像 RAM:速度快,但容量有限 • 外部数据库像磁盘存储:容量大,但速度慢 • 工具集成像设备驱动 • Harness 就像操作系统 正如 Millidge 所写:We have reinvented the Von Neumann architecture 因为这对任何计算系统来说,都是一种自然抽象。 工程设计的三个层级 围绕模型有三层同心工程结构: • Prompt engineering负责设计模型接收到的指令 • Context engineering负责管理模型在什么时间看到什么内容 • Harness engineering包含前两者,以及整套应用基础设施:工具编排、状态持久化、错误恢复、验证循环、安全约束和生命周期管理 Harness 不是包在 prompt 外面的一层壳。它是让自主 agent 行为成为可能的完整系统。 生产级Agent Harness的12个组成部分 综合 Anthropic、OpenAI、LangChain 以及更广泛实践者社区的做法,一个生产级 agent harness 有 12 个清晰可分的组成部分。下面逐个来看。 1. 编排循环 这是心跳。它实现的是 Thought Action Observation(TAO)循环,也叫 ReAct loop。这个循环这样运行:组装 prompt 调用 LLM 解析输出 执行工具调用 把结果回填 重复 从机械角度看,它通常不过就是一个 while 循环。复杂性不在循环本身,而在于循环需要管理的所有事情。Anthropic 把他们的 runtime 描述成一个“愚蠢的循环(dumb loop)”,所有智能都在模型里。Harness 只是负责管理轮次。 2. 工具 工具是 agent 的手。它们被定义成 schema(名字、描述、参数类型),并注入到 LLM 的上下文里,让模型知道自己可以用什么。 工具层负责: • 注册工具 • 校验 schema • 提取参数 • 在沙箱中执行 • 捕获结果 • 把结果格式化回 LLM 可读的 observation Claude Code 提供了六类工具: • 文件操作 • 搜索 • 执行 • Web 访问 • 代码智能 • 子 agent 生成 OpenAI 的 Agents SDK 支持: • function tools • hosted tools(WebSearch、CodeInterpreter、FileSearch) • MCP server tools 3. 记忆 记忆运行在多个时间尺度上。短期记忆是单次 session 内的对话历史。 长期记忆跨 session 持久存在: • Anthropic 使用项目文件和自动生成的记忆文件 • LangGraph 使用按 namespace 组织的 JSON Stores • OpenAI 支持由 SQLite 或 Redis 支撑的 Sessions Claude Code 实现了三层层级: • 一个轻量索引(每条约 150 个字符,始终加载) • 按需拉取的详细主题文件 • 仅通过搜索访问的原始对话记录 一个关键设计原则是: agent 把自己的记忆当作“提示”,而不是事实本身;在真正行动前,它会再次核验实际状态。 4. 上下文管理 很多 agent 就是在这里无声失败的。 核心问题叫 context rot:当关键内容落在上下文中间位置时,模型表现会下降 30%+(Chroma 的研究,Stanford 的 “Lost in the Middle” 也得出了类似结论)。 即使是百万 token 的上下文窗口,随着内容增多,指令遵循能力依旧会下降。 生产级策略包括: • Compaction在接近上限时压缩对话历史Claude Code 会保留架构决策和未解决 bug,丢弃冗余工具输出 • Observation maskingJetBrains 的 Junie 会隐藏旧工具输出,但保留工具调用本身 • Just in time retrieval维护轻量标识并动态加载数据Claude Code 常用 grep、glob、head、tail,而不是整文件载入 • Sub agent delegation每个子 agent 可以做大量探索,但最终只返回 1,000 到 2,000 token 的压缩总结 Anthropic 的 context engineering 指南把目标说得很明确:找到尽可能小、但高信号密度最高的 token 集合,以最大化得到目标结果的概率。 5. 提示词构建 这一步决定模型在每个步骤里究竟能看到什么。 它是分层组装的: • system prompt • tool definitions • memory files • conversation history • 当前用户消息 OpenAI Codex 使用严格的优先级栈: • 服务器控制的 system message(最高优先级) • 工具定义 • developer instructions • user instructions(逐级级联的说明文件,32 KiB 上限) • conversation history 6. 输出解析 现代 harness 依赖原生 tool calling,也就是模型返回结构化的 tool calls 对象,而不是返回自由文本后再去解析。 Harness 会检查: • 有 tool calls 吗?有的话就执行并继续循环 • 没有 tool calls 吗?那就是最终回答 对于结构化输出,OpenAI 和 LangChain 都支持通过 Pydantic 模型来约束 schema。 像 RetryWithErrorOutputParser 这种旧方法也仍然可用:把原始 prompt、失败输出和解析错误一起再喂回模型,让模型修正。 7. 状态管理 LangGraph 把状态建模成流经图节点的类型化字典,并通过 reducer 来合并更新。Checkpoint 发生在 super step 边界上,因此可以在中断后恢复,也能进行 time travel 调试。 OpenAI 提供四种互斥策略: • application memory • SDK sessions • 服务端 Conversations API • 更轻量的 previous response id 串接 Claude Code 采取的是另一种方式: • 用 git commit 作为 checkpoint • 用进度文件作为结构化 scratchpad 8. 错误处理 这里的重要性在于: 一个 10 步流程,即便每一步成功率是 99%,端到端成功率也只有大约 90.4%。 错误会很快累积。 LangGraph 把错误分成四类: • transient用 backoff 重试 • LLM recoverable作为 ToolMessage 返回给模型,让它自行调整 • user fixable中断并等待人类输入 • unexpected向上抛出,供调试使用 Anthropic 会在 tool handler 内捕获失败,并把它们作为错误结果返回,从而保持主循环继续运行。 Stripe 的生产 harness 把最大重试次数限制为 2 次。 9. 防护机制与安全保障 OpenAI SDK 实现了三层 guardrails: • input guardrails运行在第一个 agent 上 • output guardrails运行在最终输出上 • tool guardrails运行在每次工具调用上 一旦 tripwire 被触发,agent 会立即停止。 Anthropic 从架构上把权限控制与模型推理解耦: • 模型负责决定“要尝试什么” • 工具系统负责决定“什么是允许的” Claude Code 对大约 40 个离散工具能力分别做门控,并分为三个阶段: • 项目加载时建立信任 • 每次工具调用前检查权限 • 对高风险操作要求显式用户确认 10. 验证循环 这正是把玩具 demo 和生产 agent 区分开的关键。 Anthropic 推荐三类验证方式: • 规则式反馈测试、lint、类型检查 • 视觉反馈通过 Playwright 截图验证 UI 任务 • LLM as judge用另一个子 agent 来评估输出 Claude Code 的创建者 Boris Cherny 提到:给模型一个验证自己工作的办法,质量会提升2到3倍。 11. 子智能体编排 Claude Code