真正决定 Agent 上限的,往往不是模型本身,而是包在模型外面的 harness:编排循环、工具、记忆、上下文管理、状态持久化、容错、验证与安全控制。理解这层系统,才真正接近生产级 Agent。
你已经做出了一个 chatbot。也许你还接上了一个带少量工具的 ReAct 循环。做 demo 的时候,一切都挺顺。等你真正开始做 production-grade 的东西,问题就全冒出来了:模型会忘掉三步前自己做过什么,tool call 会静默失败,context window 会被垃圾塞满。
问题不在模型本身。
问题在模型周围的一切。
LangChain 已经把这件事证明得很清楚了。他们只改了包在 LLM 外面的基础设施,同一个模型、同一组权重,TerminalBench 2.0 的排名就从前 30 名之外直接跳到第 5。另一项研究甚至让 LLM 去优化这层基础设施本身,最后做到 76.4% 的 pass rate,超过了人工设计的系统。
现在,这层基础设施有了一个名字:agent harness。
什么是 Agent Harness
这个术语在 2026 年初被正式明确下来,但概念本身早就存在了。Harness 就是包在 LLM 外面的整套软件基础设施:orchestration loop、tools、memory、context management、state persistence、error handling 和 guardrails。
Anthropic 的 Claude Code 文档说得很直接:SDK 就是“the agent harness that powers Claude Code”。OpenAI 的 Codex 团队也用同样的表述,明确把“agent”和“harness”放在同一个讨论框架里,指向那层让 LLM 真正变得有用的非模型基础设施。
LangChain 的 Vivek Trivedy 有一句我特别喜欢的公式:
“If you're not the model, you're the harness.”
这里最容易让人混淆的,是 agent 和 harness 的区别。
“Agent”是最终呈现出来的涌现行为:一个以目标为导向、会用工具、能自我修正的实体。用户与之交互,感知到的是 agent。
“Harness”是把这种行为生产出来的整套机制。
所以当有人说“我做了一个 agent”,真正的意思通常是:我做了一套 harness,再把它接到某个模型上。
Beren Millidge 在 2023 年的文章《Scaffolded LLMs as Natural Language Computers》里把这个类比讲得非常准确:原始 LLM 像一颗没有 RAM、没有磁盘、没有 I/O 的 CPU。Context window 像 RAM,快,但很有限。外部数据库像磁盘,容量大,但慢。Tool integrations 像设备驱动。Harness 就是操作系统。
他说得很到位:我们其实重新发明了一次冯·诺依曼架构,因为对于任何计算系统来说,这都是一种非常自然的抽象。
工程分成三层
围绕模型的工程,可以分成三个同心层:
- Prompt engineering:设计模型收到的指令。
- Context engineering:管理模型在什么时刻看到什么内容。
- Harness engineering:把前两者都包含进来,再加上整套应用基础设施:tool orchestration、state persistence、error recovery、verification loops、safety enforcement 和 lifecycle management。
Harness 不是 prompt 外面的一层薄包装。
Harness 是让 autonomous agent behavior 成为可能的完整系统。
生产级 Harness 的 12 个组件
综合 Anthropic、OpenAI、LangChain 以及更广泛的实践者讨论,一个生产级 agent harness 里,至少有 12 个清晰可辨的组件。
1. Orchestration Loop
这是心跳。
它实现的是 Thought-Action-Observation,也就是 TAO cycle,通常也叫 ReAct loop。整个循环的运行方式是:组装 prompt,调用 LLM,解析输出,执行 tool calls,把结果喂回去,重复,直到完成。
从机械结构上看,它经常只是一个 while loop。
真正复杂的地方不在 loop 本身,而在 loop 需要管理的那一切。Anthropic 甚至把自己的 runtime 形容成一个“dumb loop”:所有 intelligence 都在模型里,harness 只负责管理 turn。
2. Tools
Tools 是 agent 的手。
它们通常以 schema 的形式定义:名字、描述、参数类型。然后这些 schema 会被注入到 LLM 的上下文里,让模型知道自己能调用什么。
Tool layer 负责的事情包括:注册工具、校验 schema、提取参数、在 sandbox 里执行、捕获结果、再把结果格式化成 LLM 可以继续消费的 observation。
Claude Code 把工具分成六类:文件操作、搜索、执行、网页访问、代码智能和 subagent spawning。OpenAI Agents SDK 则支持 function tools、hosted tools(像 WebSearch、CodeInterpreter、FileSearch)和 MCP server tools。
3. Memory
Memory 按时间尺度分层工作。
短期记忆,是单个 session 里的 conversation history。长期记忆,会跨 session 持续存在。Anthropic 用的是 CLAUDE.md project files 和自动生成的 MEMORY.md;LangGraph 用 namespace-organized JSON Stores;OpenAI 则支持基于 SQLite 或 Redis 的 Sessions。
Claude Code 的实现非常有代表性:
- 一个很轻量的索引层,大概每条 150 个字符,始终加载。
- 更详细的主题文件,需要时按需拉取。
- 原始 transcript 只通过 search 去访问。
这里有一个很关键的设计原则:agent 会把自己的 memory 当成“hint”,然后在真正行动前再去和实际状态核对。
4. Context Management
很多 agent 都是在这里无声失败的。
核心问题是 context rot:当关键内容落在上下文中部时,模型性能会明显恶化。Chroma 的研究给出了 30% 以上的退化,Stanford 的 “Lost in the Middle” 也给出了相同方向的证据。就算你有 million-token 窗口,随着上下文变长,instruction-following 依然会开始下降。
生产环境里常见的策略包括:
- Compaction:快接近上限时,对对话历史做总结。Claude Code 会保留架构决策和未解决 bug,同时丢掉冗余 tool outputs。
- Observation masking:JetBrains 的 Junie 会隐藏旧的工具输出,但保留工具调用本身。
- Just-in-time retrieval:维护轻量 ID,需要时动态加载。Claude Code 会大量使用 grep、glob、head、tail,而不是整份文件直接灌进去。
- Sub-agent delegation:让每个 subagent 自己广泛探索,再只返回 1000 到 2000 token 的压缩摘要。
Anthropic 的 context engineering 指南把目标说得很清楚:找到最小、但信号最强的一组 tokens,把它们摆出来,让 desired outcome 的概率最大化。
5. Prompt Construction
这一层决定模型每一步实际看见什么。
典型结构是分层的:system prompt、tool definitions、memory files、conversation history、当前 user message。
OpenAI 的 Codex 用的是一套非常严格的优先级堆栈:最高优先级是 server-controlled system message,然后是 tool definitions,再往下是 developer instructions、user instructions、级联 AGENTS.md 文件,最后才是 conversation history。
6. Output Parsing
现代 harness 基本都依赖 native tool calling。
模型返回的不再是必须靠正则硬拆的自由文本,而是结构化的 tool_calls 对象。Harness 的判断逻辑也因此很清楚:
- 有 tool calls,就执行,再继续 loop。
- 没有 tool calls,就是 final answer。
如果要 structured outputs,OpenAI 和 LangChain 都支持基于 Pydantic model 的 schema-constrained response。旧式方案像 RetryWithErrorOutputParser 依然存在,但更多属于边缘补充。
7. State Management
LangGraph 把 state 建模成类型化 dictionary,在 graph nodes 之间流动,再通过 reducers 合并更新。Checkpoint 会在 super-step 边界发生,因此可以在中断之后恢复,也可以做 time-travel debugging。
OpenAI 给出了四种互斥策略:application memory、SDK sessions、服务端 Conversations API,以及更轻量的 previous_response_id chaining。
Claude Code 走的是另一条路:git commits 当 checkpoint,progress files 当结构化 scratchpads。
8. Error Handling
这一层为什么重要,可以用一个很简单的算式看出来:一个 10 步流程,如果每一步成功率是 99%,最后端到端成功率也只有大约 90.4%。错误会很快复利。
LangGraph 会把错误分成四类:
- transient:用 backoff 重试。
- LLM-recoverable:把错误作为 ToolMessage 返回,让模型自己调整。
- user-fixable:中断,等人类输入。
- unexpected:直接抛出,进入 debug 流程。
Anthropic 会在 tool handler 内部捕获失败,并把失败当作 error result 返回,这样 loop 还能继续。Stripe 的生产 harness 则把 retry cap 设成两次。
9. Guardrails and Safety
OpenAI 的 SDK 在这一层给了三层机制:
- input guardrails:跑在第一个 agent 上
- output guardrails:跑在最终输出上
- tool guardrails:跑在每一次 tool invocation 上
其中一个关键机制是 tripwire:一旦触发,agent 会立刻停下来。
Anthropic 在架构上把 permission enforcement 和 model reasoning 分开。模型决定想做什么;tool system 决定什么被允许。Claude Code 会对大约 40 种离散工具能力独立做 gating,并拆成三段:项目加载时建立信任、每次 tool call 前做 permission check、高风险操作再要求明确确认。
10. Verification Loops
这层是 toy demo 和 production agent 的分水岭。
Anthropic 推荐三类验证:
- rules-based feedback:测试、linter、type checker
- visual feedback:例如 Playwright 截图,用在 UI 任务上
- LLM-as-judge:再启一个 subagent,专门评估输出
Claude Code 的创建者 Boris Cherny 说得很直接:只要给模型一个验证自己工作的办法,质量往往就能提升 2 到 3 倍。
11. Subagent Orchestration
Claude Code 支持三种执行模型:
- Fork:把父上下文原样拷贝过去
- Teammate:单独终端 pane,通过文件邮箱通信
- Worktree:独立 git worktree,每个 agent 一条隔离 branch
OpenAI Agents SDK 则支持两种常见模式:
- agents-as-tools: specialist 处理边界明确的子任务
- handoffs: specialist 接管控制权
LangGraph 把 subagents 实现成嵌套 state graphs。
12. 运行时整合
单独列每个组件还不够。真正的 harness 价值,来自这些组件如何在同一个 runtime 里配合运转。Loop、tools、memory、state、verification、safety 和 subagents 不是分开的功能块,而是一台机器里的相互啮合件。
把 Loop 真正走一遍
知道了组件以后,再把一次实际循环走完,很多东西就更具体了。
Step 1:Prompt Assembly
Harness 先把完整输入组出来:system prompt + tool schemas + memory files + conversation history + 当前 user message。
关键内容会尽量放在开头和结尾,因为 “Lost in the Middle” 已经告诉我们,中部位置最容易掉信息。
Step 2:LLM Inference
组好的 prompt 送进模型 API。模型会吐出 output tokens:可能是文本,可能是 tool call request,也可能两者都有。
Step 3:Output Classification
如果模型只返回文本,没有 tool call,loop 结束。
如果模型请求 tool calls,就进入执行阶段。
如果发生 handoff,就更新当前 agent,再重新开始。
Step 4:Tool Execution
Harness 会针对每个 tool call:校验参数、检查权限、在 sandbox 里执行、捕获结果。
只读操作可以并发跑;会改状态的操作通常串行跑。
Step 5:Result Packaging
Tool results 会被打包成 LLM 可读的 message。错误也不会直接炸掉整个系统,而是会被捕获,并以 error result 的形式返回,让模型有机会自我修正。
Step 6:Context Update
结果被追加进 conversation history。
如果快撞上 context window 上限,harness 就触发 compaction。
Step 7:Loop
回到 Step 1,继续,直到结束。
终止条件通常是多层叠加的:
- 模型给出没有 tool calls 的响应
- 最大 turn limit 超了
- token budget 用光了
- guardrail tripwire 被触发
- 用户中断
- 安全拒绝返回
一个简单问题也许只要 1 到 2 个 turn。复杂的 refactoring 任务,可能会串起几十次 tool calls,跨越很多轮。
如果任务会跨越多个 context windows,Anthropic 还发展出一个两阶段的 Ralph Loop:先让 Initializer Agent 建环境,包括 init script、progress file、feature list、初始 git commit;之后每个新的 Coding Agent session 都先读 git log 和 progress file 来定位当前状态,再挑最高优先级的未完成项去做,做完 commit,写总结。这样一来,filesystem 本身就变成跨 context window 的连续性载体。
真实框架是怎么落地这套模式的
Anthropic 的 Claude Agent SDK 通过一个 query() 函数把 harness 暴露出来:它创建 agentic loop,然后以 async iterator 的方式流式返回消息。它的 runtime 很薄,近似就是“dumb loop”,核心智能在模型里。Claude Code 则围绕 Gather-Act-Verify 这个节奏运转:先 gather context,再 take action,然后 verify results,最后继续下一轮。
OpenAI Agents SDK 通过 Runner 类实现 harness,支持 async、sync 和 streamed 三种模式。它是 code-first 的:workflow logic 写在原生 Python 里,而不是图 DSL。Codex harness 在这上面又叠了一层三段架构:Codex Core、App Server、以及 CLI / VS Code / Web app 这些 client surfaces。也正因如此,Codex 模型在 Codex 自己的 surface 上,体验往往比通用聊天框更好。
LangGraph 把 harness 明确建模成 state graph。最简形式下,就是两个节点:llm_call 和 tool_node,中间通过条件边连接:如果有 tool calls,就去 tool_node;没有,就到 END。LangGraph 本身是从 LangChain 的 AgentExecutor 演化出来的,因为后者太难扩展,也缺少 multi-agent support。LangChain 的 Deep Agents 已经明确使用了 “agent harness” 这个术语:它把 built-in tools、planning、filesystem-based context management、subagent spawning 和 persistent memory 都纳进来。
CrewAI 走的是 role-based multi-agent 路线:Agent、Task、Crew 三层清晰分工。它的 Flows 层则提供“deterministic backbone with intelligence where it matters”:路由和验证由确定性流程管理,自主协作交给 Crew。
AutoGen,后来演化成 Microsoft Agent Framework,则更早就把 conversation-driven orchestration 做了出来。它的三层结构——Core、AgentChat、Extensions——支持五种 orchestration pattern:sequential、concurrent、group chat、handoff 和 magentic,其中 magentic 是由一个 manager agent 维护动态 task ledger,再去协调 specialists。
为什么 Scaffold 这个比喻特别准
Scaffolding 这个比喻不是装饰性的,它非常精确。
施工脚手架本身不完成建筑,但没有脚手架,工人就上不去,也碰不到那些本来够不着的地方。
更关键的一点是:建筑完成以后,脚手架是要被拆掉的。
这直接指向一个核心判断:随着模型能力继续增强,harness 的复杂度应该下降。Manus 在六个月里重写了五次,每次都在删复杂度。复杂工具定义慢慢收缩成更通用的 shell execution。“管理 agent”这类结构,也被更简单的 structured handoff 取代。
这又引出另一个原则:harness 和模型正在协同进化。模型已经开始在特定 harness 环境里接受后训练。Claude Code 的模型,学会的是使用它所配套的那套 harness。工具实现一旦变化,性能反而可能下降,因为两者之间已经耦合得很紧。
一个很好的 future-proofing test 是:如果模型更强以后,不需要继续增加 harness complexity,性能还能往上走,那这套 harness 设计就站住了。
每一套 Harness 都逃不开的 7 个设计抉择
每个 harness architect 都得回答七个问题。
1. 单 Agent 还是多 Agent
Anthropic 和 OpenAI 的建议都很接近:先把单 agent 压到极限。
多 agent 会带来额外开销:路由多一次 LLM call,handoff 带来上下文损失。只有当 tool overload 真的超过大约 10 个重叠工具,或者任务域明显分裂时,再去拆。
2. ReAct 还是 Plan-and-Execute
ReAct 在每一步交织 reasoning 和 action,灵活,但 per-step cost 更高。
Plan-and-execute 则把规划和执行拆开。LLMCompiler 报告过,相比顺序 ReAct,它能带来 3.6 倍加速。
3. 怎么管理 Context Window
生产环境里大致有五类办法:按时间清空、对话总结、observation masking、结构化 note-taking、sub-agent delegation。
ACON 的研究给出过一个很有意思的结果:只要优先保留 reasoning traces,而不是原始 tool outputs,就能减少 26% 到 54% 的 tokens,同时保住 95% 以上的准确率。
4. Verification Loop 怎么设计
计算型验证——测试、linter——能给出确定性的 ground truth。
推断型验证——LLM-as-judge——能抓语义问题,但会增加 latency。
Thoughtworks 团队把它归纳成 guides 和 sensors:前者是 feedforward,在行动前引导;后者是 feedback,在行动后感知。
5. 权限和安全放在哪一层
可以更 permissive,更快,但风险也更高;也可以更 restrictive,更慢,但更安全。
具体怎么取,要看部署语境。
6. 工具怎么收口
工具越多,效果往往越差。
Vercel 在 v0 里砍掉了 80% 的 tools,结果反而更好。Claude Code 借助 lazy loading,把上下文负担压掉了 95%。
原则很简单:只暴露当前这一步真正需要的最小工具集。
7. Harness 到底应该多厚
多少逻辑放在 harness,多少交给模型,这是最根本的架构选择。
Anthropic 更押注薄 harness,把更多能力留给模型内化。Graph-based frameworks 则押注显式控制。Claude Code 随着模型版本升级,也在持续删除 harness 里的 planning steps,因为模型已经能自己完成它们了。
Harness 本身就是产品
两个产品,用完全相同的模型,最后表现也可能天差地别,差异全来自 harness 设计。
TerminalBench 的证据已经足够清楚:只改 harness,就能让 agent 的排名前进 20 多个名次。
Harness 不是已经解决的问题,也不是一层 commodity。
真正艰难的工程,就在 harness 里:
- 把 context 当稀缺资源来管理
- 设计 verification loops,在错误复利之前把问题拦下来
- 构造 memory systems,既维持连续性,又不引入幻觉
- 决定该搭多少脚手架,该把多少事情留给模型自己完成
这个领域正在朝更薄的 harness 移动,因为模型在变强。
但 harness 本身不会消失。
再强的模型,也需要有人替它管理 context window、执行 tool calls、持久化 state、验证工作结果。
下次你的 agent 失败时,先别怪模型。
先看看 harness。