# Agent Harness 解剖：生产级智能体外壳的 12 个组件

> 来源：Akshay Pachaar，《The Anatomy of an Agent Harness》（2026-04-06） 推文：[https://x.com/akshay\_pachaar/status/2041146899319971922](https://x.com/akshay_pachaar/status/2041146899319971922) 本仓库归档：`Agent/design/harness.pdf`

---

## 一、什么是 Agent Harness

你已经搭过 chatbot，也许还接了几个工具的 ReAct 循环——demo 跑得很好。可一旦要上生产，问题立刻浮现：模型忘掉三步前做过的事、工具调用静默失败、上下文窗口被垃圾塞满。

> **问题不在模型，而在模型周围的一切。**

LangChain 在 TerminalBench 2.0 上做过一个"反事实"实验：**模型不变（同权重），只改外围基础设施**，排名从 30 名开外飙到第 5。另一项研究让 LLM 自己优化基础设施，pass rate 达到 76.4%，超过人手设计的系统。

**这套基础设施有了正式名字：Agent Harness（智能体外壳）。**

### 1.1 定义

> **Harness 是包裹 LLM 的完整软件基础设施**：编排循环、工具、记忆、上下文管理、状态持久化、错误处理、护栏。

- Anthropic 的 Claude Code 文档：SDK 就是"the agent harness that powers Claude Code"
- OpenAI 的 Codex 团队明确把 "agent" 与 "harness" 当同义词使用
- LangChain 的 Vivek Trivedy 给出了**经典口径**：

> **"If you're not the model, you're the harness."** （不是模型的部分，就都是 harness。）

### 1.2 容易混淆的"Agent" vs "Harness"

- **Agent**：用户感知到的"涌现行为"——目标导向、会用工具、会自我纠错的实体
- **Harness**：产生这种行为的**机器**

> 当有人说"我做了个 agent"，本质上是：**做了个 harness，把它指向某个模型**。

### 1.3 类比：冯·诺依曼架构（Beren Millidge, 2023）

裸 LLM = 一颗没有 RAM、没有硬盘、没有 I/O 的 CPU：

| 计算机 | LLM Agent |
| --- | --- |
| RAM（快但小） | Context window |
| 磁盘（大但慢） | 外部数据库 |
| 设备驱动 | Tool 集成 |
| **操作系统** | **Harness** |

---

## 二、三层工程

围绕模型的三层同心圆：

1. **Prompt Engineering**：雕琢喂给模型的指令
2. **Context Engineering**：管理模型在何时看到什么
3. **Harness Engineering**：包含上面两者，再加上**完整的应用基础设施**——工具编排、状态持久化、错误恢复、校验回路、安全约束、生命周期管理

> Harness 不是 prompt 的包装。它是让自主 agent 行为成为可能的**完整系统**。

---

## 三、生产级 Harness 的 12 个组件

> 综合 Anthropic、OpenAI、LangChain 与广泛实践者社区的工程经验。

---

### 1. Orchestration Loop（编排循环）

整个心脏。实现 **TAO 循环（Thought-Action-Observation）**，也叫 ReAct loop：

```
组装 prompt → 调 LLM → 解析输出 → 执行 tool calls → 喂回结果 → 循环至完成

```

机制上往往**只是一个 while 循环**。复杂度全在循环管理的东西，而不在循环本身。

> Anthropic 把自家 runtime 称为 **"dumb loop"**：循环越笨越好，**所有智能都留在模型里**，harness 只管轮次。

---

### 2. Tools（工具）

工具是 agent 的"手"。以 Schema 形式声明（name、description、parameter types），注入到 LLM 上下文中告诉模型有哪些能力可用。Tool 层负责：

- 注册（registration）
- Schema 校验（validation）
- 入参提取（argument extraction）
- 沙箱执行（sandboxed execution）
- 结果捕获（result capture）
- 把结果格式化回模型可读的 observation

**典型实现**：

- **Claude Code**：6 大类工具——文件操作、搜索、执行、Web 访问、代码智能、subagent 派生
- **OpenAI Agents SDK**：function tools（`@function_tool`）+ hosted tools（WebSearch / CodeInterpreter / FileSearch）+ MCP server tools

---

### 3. Memory（记忆）

记忆按时间尺度分两层：

- **Short-term memory**：单会话内的对话历史
- **Long-term memory**：跨会话持久化
    - Anthropic：`CLAUDE.md` 项目文件 + 自动生成的 `MEMORY.md`
    - LangGraph：namespace 组织的 JSON Stores
    - OpenAI：SQLite/Redis 支持的 Sessions

**Claude Code 的三层结构**：

1. 轻量索引（每条 ~150 字符，**始终常驻**）
2. 主题详情文件（按需取入）
3. 原始 transcript（**只能搜索访问**）

> **关键原则**：**agent 把自己的记忆只当作"提示"，行动前必须先去验证真实状态。**

---

### 4. Context Management（上下文管理）

很多 agent 在这里**静默失败**。根本问题是 **Context Rot**：

- **关键内容落在窗口中段时，模型性能下降 30%+**（Chroma 研究，与 Stanford "Lost in the Middle" 互证）
- **百万 token 窗口**也照样会随上下文增长发生指令遵循退化

**生产策略**：

| 策略 | 做法 |
| --- | --- |
| **Compaction** | 临近上限时摘要历史（Claude Code 保留架构决策与未解 bug，丢弃冗余工具输出） |
| **Observation Masking** | 屏蔽老的工具输出但保留工具调用本身（JetBrains Junie） |
| **Just-in-time Retrieval** | 只持有轻量标识符，按需加载（Claude Code 用 grep / glob / head / tail，而不是直接读全文件） |
| **Sub-agent Delegation** | 子 agent 充分探索，但只返回 1k–2k token 的浓缩摘要 |

> Anthropic context engineering 指南的目标：**找到使期望结果概率最大化的"最小高信号 token 集合"**。

---

### 5. Prompt Construction（Prompt 装配）

每一步模型实际看到的东西。**层级化拼装**：

```
System Prompt → Tool Definitions → Memory Files → Conversation History → Current User Message

```

**OpenAI Codex** 采用**严格优先级栈**：

- Server-controlled system message（最高）
- Tool definitions
- Developer instructions
- User instructions（级联的 AGENTS.md，**32 KiB 上限**）
- Conversation history

---

### 6. Output Parsing（输出解析）

现代 harness 普遍依赖**原生 tool calling**：模型直接返回结构化的 `tool_calls` 对象，**不再需要解析自由文本**。

```
有 tool calls？ → 执行 + 循环
没 tool calls？ → 这就是最终回答

```

**结构化输出**：OpenAI 与 LangChain 均通过 Pydantic 模型做 schema 约束。

老式的 `RetryWithErrorOutputParser`（把原 prompt + 失败补全 + 解析错误一并喂回模型）作为兜底仍然可用。

---

### 7. State Management（状态管理）

四种代表性流派：

| 框架 | 做法 |
| --- | --- |
| **LangGraph** | 类型化字典在图节点间流动，reducer 合并更新；super-step 边界打 checkpoint，可断点恢复、时间旅行调试 |
| **OpenAI** | 四种**互斥**策略：应用内存 / SDK Sessions / 服务端 Conversations API / 轻量的 `previous_response_id` 链式拼接 |
| **Claude Code** | 用 **git commit 当 checkpoint**，**progress 文件当结构化草稿本** |

---

### 8. Error Handling（错误处理）

**为什么这件事至关重要**：

> 10 步流程，每步成功率 99% → 端到端只剩 **~90.4%**。**错误会快速复利**。

**LangGraph 的四类错误**：

| 类型 | 处理 |
| --- | --- |
| Transient（瞬时） | retry + backoff |
| LLM-recoverable（模型可自纠） | 错误以 `ToolMessage` 形式回传，让模型自我调整 |
| User-fixable（需要人介入） | 中断（interrupt）等待人类输入 |
| Unexpected（意外） | 向上冒泡，便于调试 |

- Anthropic：在 tool handler 内部捕获失败，作为 error result 返回，**保持循环不中断**
- Stripe 生产 harness：**最多重试 2 次**

---

### 9. Guardrails and Safety（护栏与安全）

**OpenAI SDK 的三层**：

- **Input guardrails**：在第一个 agent 上运行
- **Output guardrails**：在最终输出上运行
- **Tool guardrails**：在每次工具调用上运行
- **Tripwire** 机制：触发即立刻停机

**Anthropic 的核心理念**：**把权限执行从模型推理中架构性分离**。

- 模型决定**想做什么**
- 工具系统决定**允许做什么**

**Claude Code** 把约 **40 个独立工具能力**分别上闸，分三阶段：

1. 项目加载时建立信任（trust establishment）
2. 每次调用前检查权限（permission check）
3. 高风险操作要求显式用户确认

---

### 10. Verification Loops（校验回路）

**这是把玩具 demo 与生产 agent 区分开的关键。**

Anthropic 推荐三种：

- **Rules-based feedback**：测试、Linter、类型检查
- **Visual feedback**：UI 任务用 Playwright 截图比对
- **LLM-as-judge**：另一个 subagent 来评估输出

> Claude Code 作者 **Boris Cherny**：**给模型一个能验证自己工作的方式，质量提升 2 到 3 倍。**

---

### 11. Subagent Orchestration（子 agent 编排）

**Claude Code 的三种执行模型**：

| 模式 | 含义 |
| --- | --- |
| **Fork** | 字节级完整副本（复制父上下文） |
| **Teammate** | 独立终端面板 + 文件邮箱通信 |
| **Worktree** | 自己的 git worktree，每个 agent 独立分支 |

- **OpenAI SDK**：agents-as-tools（专家处理有界子任务）+ handoffs（专家完全接管）
- **LangGraph**：subagent 实现为嵌套 state graph

---

### 12. Long-Horizon Execution（长程执行 / Ralph Loop）

> 原文标题说 12 个组件、正文显式编号到 11；这里把"跨上下文窗口的长程执行"列为第 12 项——它在 PDF 中以独立模式 **"Ralph Loop"** 详细展开。

**问题**：单次会话可能跑 1–2 轮就结束，但**复杂重构任务可能跨多个上下文窗口**——简单的循环根本撑不到完成。

**Anthropic 的两阶段 Ralph Loop**：

1. **Initializer Agent**：搭好环境
    - init 脚本
    - progress 文件
    - feature 列表
    - 初始 git commit
2. **Coding Agent**（之后每个会话循环）：
    - 读 git log + progress 文件**自我定位**
    - 挑优先级最高的未完成 feature
    - 干活 → commit → 写摘要

> **文件系统在跨上下文窗口的场景里提供连续性。**

**终止条件**是分层的：模型给出无 tool call 的回答 / 达到最大轮次 / token 预算耗尽 / guardrail tripwire 触发 / 用户中断 / 安全拒绝。

---

## 四、单次循环的 7 个步骤

把 12 个组件串起来跑一圈：

| 步骤 | 内容 |
| --- | --- |
| **1. Prompt Assembly** | 装配：system prompt + tool schemas + memory files + conversation history + 当前消息。**重要内容放在 prompt 的开头和结尾**（Lost in the Middle） |
| **2. LLM Inference** | 送进模型 API，生成 text / tool call requests / 两者都有 |
| **3. Output Classification** | 文本无 tool call → 结束；有 tool call → 执行；handoff → 切换当前 agent 重启 |
| **4. Tool Execution** | 校验入参 → 检查权限 → 沙箱执行 → 捕获结果。**只读并发，写操作串行** |
| **5. Result Packaging** | 工具结果格式化为 LLM 可读消息；**错误也以 error result 形式回传，模型可自纠** |
| **6. Context Update** | 追加到对话历史；接近窗口上限就触发 compaction |
| **7. Loop** | 回到第 1 步直到终止 |

> 简单问题 1–2 轮即可；复杂重构可能跨数十次 tool call 与多轮上下文。

---

## 五、主流框架的实现

| 框架 | 关键抽象 | 特点 |
| --- | --- | --- |
| **Anthropic Claude Agent SDK** | 单一 `query()` 函数，返回流式异步迭代器 | "dumb loop"；Gather-Act-Verify 循环（gather context → take action → verify results → repeat） |
| **OpenAI Agents SDK** | `Runner` 类（async/sync/streamed） | **Code-first**：用原生 Python 写工作流，不用 graph DSL |
| **OpenAI Codex Harness** | 三层架构 | Codex Core（agent + runtime）+ App Server（双向 JSON-RPC）+ 客户端（CLI / VS Code / Web）。**"Codex 模型在 Codex 表面感觉更好"，因为共享同一 harness** |
| **LangGraph** | 显式 state graph：`llm_call` 与 `tool_node` + 条件边 | 从已废弃的 `AgentExecutor` 进化而来；原生支持多 agent |
| **LangChain Deep Agents** | 明确使用 "agent harness" 一词 | 内置工具 + 规划（`write_todos`）+ 文件系统 + subagent + 持久记忆 |
| **CrewAI** | Agent / Task / Crew + Flows | 角色制（role/goal/backstory/tools）；Flows 提供"intelligence where it matters"的确定性骨架 |
| **AutoGen → Microsoft Agent Framework** | Core / AgentChat / Extensions 三层 | 五种编排模式：sequential / concurrent (fan-out/fan-in) / group chat / handoff / **magentic**（manager agent 维护动态任务账本协调专家） |

---

## 六、定义每个 Harness 的 7 个架构决策

| \# | 决策 | 关键 trade-off |
| --- | --- | --- |
| **1** | **单 agent vs 多 agent** | Anthropic & OpenAI 都建议**先把单 agent 做到极致**。多 agent 增加额外的路由 LLM 调用、handoff 时的上下文丢失。**只在工具数量超过约 10 个重叠工具，或任务领域明显分离时才拆分** |
| **2** | **ReAct vs Plan-and-Execute** | ReAct 每步都交错推理与动作（灵活但每步成本高）；Plan-and-Execute 把规划与执行分离。**LLMCompiler 报告比顺序 ReAct 快 3.6×** |
| **3** | **上下文窗口管理策略** | 五种：time-based clearing / summarization / observation masking / structured note-taking / sub-agent delegation。**ACON 研究：26–54% token 削减 + 95%+ 准确率保留**（关键：reasoning trace 优先于 raw tool output） |
| **4** | **校验回路设计** | Computational（测试、linter）= 确定性 ground truth；Inferential（LLM-as-judge）= 抓语义问题但增加延迟。Martin Fowler / Thoughtworks 把它们框成 **guides**（feedforward，行动前引导）vs **sensors**（feedback，行动后观察） |
| **5** | **权限与安全架构** | Permissive（快但险，自动批准多数动作）vs Restrictive（安全但慢，每个动作都需批准）。**取决于部署场景** |
| **6** | **工具范围策略** | **更多工具往往意味着更差的性能**。Vercel 从 v0 删掉 80% 工具，结果反而更好；Claude Code 用懒加载实现 95% 上下文削减。**原则：只暴露当前步骤所需的最小工具集** |
| **7** | **Harness 厚度** | 多少逻辑放在 harness、多少放在模型里。**Anthropic 押注薄 harness 与模型进化**；图框架押注显式控制。**Anthropic 会随新模型版本，定期从 Claude Code 的 harness 里删掉规划步骤**（因为模型自己内化了） |

---

## 七、脚手架隐喻与协同进化

### 7.1 脚手架隐喻（不是修辞，是精确比喻）

- 建筑脚手架 = **临时基础设施**，让工人能去到原本到不了的位置
- 它**不做施工本身**；但**没有它，工人上不到顶层**
- **建筑完工时脚手架就被拆除**

> **核心洞见：模型变强 → harness 复杂度应该下降。**

**Manus** 6 个月内重写 5 次，**每次重写都在删复杂度**：

- 复杂的工具定义 → 通用 shell 执行
- "Management agents" → 简单的结构化 handoff

### 7.2 协同进化原则

模型现在是**带着特定 harness 一起做 post-train** 的：

- Claude Code 的模型学会了用它训练时配套的那套 harness
- **改工具实现可能因为这种紧耦合而降低性能**

### 7.3 "未来兼容性"测试

> **如果换用更强的模型时，性能能 scale up 而不需要追加 harness 复杂度，这个设计就是好的。**

---

## 八、Harness 即产品

两个用相同模型的产品，可以仅因 harness 设计的差异而**性能天差地别**。TerminalBench 的证据是清晰的：**只改 harness，agent 名次能跨越 20+ 位**。

Harness 不是已解决问题，也不是商品化层。**这里才是真正的硬工程：**

- 把上下文当稀缺资源管理
- 设计能在错误复利之前抓住失败的校验回路
- 构建能提供连续性又不幻觉的记忆系统
- 在"多搭脚手架"和"留给模型自己"之间做架构性押注

> 趋势是 **harness 在变薄**——但**它不会消失**。 即便最强的模型，也需要东西来管它的上下文窗口、执行它的工具、持久化它的状态、校验它的工作。

> **下一次你的 agent 出问题时，别怪模型，看 harness。**

---

## 九、对本仓库（AllData）的启发

对照仓库里现有 Agent 设计文档（`一种理想的智能体编排架构.md`、`基于关键词的知识树系统设计方案.md`）以及 WeaveAgent，建议的对齐方向：

| Harness 组件 | 与本仓库的映射 |
| --- | --- |
| **Memory 三层结构** | 与 MindStore 的多层级摘要（pyramid + MarkdownLogic）高度同构，可以把"轻量索引/详情/原文"模式直接落到 MindStore 上 |
| **Context Management — Compaction & Tool Output Offloading** | 直接对应 `project_chronicle_grain.md`：WeaveAgent Chronicle 只记"原因 + 结果"，不复述工具返回——这就是 PDF 里说的 **tool output offloading** |
| **Verification Loops（rules / visual / LLM-as-judge）** | 后续 Agent 输出质量评估的标准范式，Qwen3-Embedding 训练数据增强环节也可以接 LLM-as-judge |
| **Long-Horizon Execution / Ralph Loop** | Auto/ 流水线（PDF→MD→Logic→Embedding→MindStore）天然是长程任务，可以引入 progress 文件 + git checkpoint 的 Ralph Loop 模式 |
| **Harness 厚度原则** | 随着 Qwen3-Embedding checkpoint 持续训练增强，本地 Agent 的 harness 应**有意识地变薄**——删功能比加功能更重要 |
| **工具范围 — "少即是多"** | Vercel 砍 80% 工具反而更好的经验，对 Auto/ 中各 `gen_*.py` 也成立：合并语义重复步骤优于堆功能 |