第04章 Harness 核心架构 —— 四层模型详解
目录
上一篇我们理解了 Harness 的五大组件。本章我们拆解 Harness 的四层架构——环环相扣,循环不息。
四层模型概述
一句话核心:Harness 由四层组成——Loop层(心跳)、工具层(手脚)、管理层(大脑辅助)、扩展层(外挂)。
图表
代码
graph TB
subgraph L4["第四层:扩展层"]
E1[Skills 按需加载]
E2[MCP 插件集成]
E3[Hooks 扩展点]
end
subgraph L3["第三层:管理层"]
M1[权限判断]
M2[上下文压缩]
M3[任务系统]
M4[子 Agent 派发]
end
subgraph L2["第二层:工具层"]
T1[Bash]
T2[Read/Write/Edit]
T3[Glob/Grep]
T4[Browser/MCP]
end
subgraph L1["第一层:Loop层"]
L1a[observe
观察环境]
L1b[think
推理决策]
L1c[act
执行行动]
L1d[feedback
收集反馈]
end
L4 --> L3
L3 --> L2
L2 --> L1
L1 -->|循环| L1agraph TB
subgraph L4["第四层:扩展层"]
E1[Skills 按需加载]
E2[MCP 插件集成]
E3[Hooks 扩展点]
end
subgraph L3["第三层:管理层"]
M1[权限判断]
M2[上下文压缩]
M3[任务系统]
M4[子 Agent 派发]
end
subgraph L2["第二层:工具层"]
T1[Bash]
T2[Read/Write/Edit]
T3[Glob/Grep]
T4[Browser/MCP]
end
subgraph L1["第一层:Loop层"]
L1a[observe
观察环境]
L1b[think
推理决策]
L1c[act
执行行动]
L1d[feedback
收集反馈]
end
L4 --> L3
L3 --> L2
L2 --> L1
L1 -->|循环| L1agraph TB
subgraph L4["第四层:扩展层"]
E1[Skills 按需加载]
E2[MCP 插件集成]
E3[Hooks 扩展点]
end
subgraph L3["第三层:管理层"]
M1[权限判断]
M2[上下文压缩]
M3[任务系统]
M4[子 Agent 派发]
end
subgraph L2["第二层:工具层"]
T1[Bash]
T2[Read/Write/Edit]
T3[Glob/Grep]
T4[Browser/MCP]
end
subgraph L1["第一层:Loop层"]
L1a[observe
观察环境]
L1b[think
推理决策]
L1c[act
执行行动]
L1d[feedback
收集反馈]
end
L4 --> L3
L3 --> L2
L2 --> L1
L1 -->|循环| L1agraph TB
subgraph L4["第四层:扩展层"]
E1[Skills 按需加载]
E2[MCP 插件集成]
E3[Hooks 扩展点]
end
subgraph L3["第三层:管理层"]
M1[权限判断]
M2[上下文压缩]
M3[任务系统]
M4[子 Agent 派发]
end
subgraph L2["第二层:工具层"]
T1[Bash]
T2[Read/Write/Edit]
T3[Glob/Grep]
T4[Browser/MCP]
end
subgraph L1["第一层:Loop层"]
L1a[observe<br/>观察环境]
L1b[think<br/>推理决策]
L1c[act<br/>执行行动]
L1d[feedback<br/>收集反馈]
end
L4 --> L3
L3 --> L2
L2 --> L1
L1 -->|循环| L1a分层原则:
- Loop层:Agent 的核心心跳,循环不息
- 工具层:具体行动的实现
- 管理层:辅助决策的管理机制
- 扩展层:动态增强的能力外挂
第一层:Agent Loop —— Harness 的心跳
Loop 的本质
一句话定义:observe → think → act → feedback 的持续循环。
图表
代码
flowchart LR
A[messages 数组
对话历史] --> B[Model 推理
Claude/GPT]
B --> C{stop_reason
判断}
C -->|tool_use
需要工具| D[执行工具
Bash/Read/Write]
D --> E[收集结果
工具输出]
E -->|append
追加| A
C -->|end_turn
结束对话| F[返回用户
最终结果]flowchart LR
A[messages 数组
对话历史] --> B[Model 推理
Claude/GPT]
B --> C{stop_reason
判断}
C -->|tool_use
需要工具| D[执行工具
Bash/Read/Write]
D --> E[收集结果
工具输出]
E -->|append
追加| A
C -->|end_turn
结束对话| F[返回用户
最终结果]flowchart LR
A[messages 数组
对话历史] --> B[Model 推理
Claude/GPT]
B --> C{stop_reason
判断}
C -->|tool_use
需要工具| D[执行工具
Bash/Read/Write]
D --> E[收集结果
工具输出]
E -->|append
追加| A
C -->|end_turn
结束对话| F[返回用户
最终结果]flowchart LR
A[messages 数组<br/>对话历史] --> B[Model 推理<br/>Claude/GPT]
B --> C{stop_reason<br/>判断}
C -->|tool_use<br/>需要工具| D[执行工具<br/>Bash/Read/Write]
D --> E[收集结果<br/>工具输出]
E -->|append<br/>追加| A
C -->|end_turn<br/>结束对话| F[返回用户<br/>最终结果]Loop 的四个阶段
| 阶段 | 动作 | 内容 |
|---|---|---|
| observe | 观察环境 | 接收 messages 数组、感知环境状态 |
| think | 推理决策 | Model 根据上下文推理下一步行动 |
| act | 执行行动 | 调用工具(Bash、Read、Write、Edit) |
| feedback | 收集反馈 | 工具输出追加到 messages,形成新上下文 |
关键机制:
- stop_reason 判断:Model 输出 stop_reason,决定是继续循环(tool_use)还是结束对话(end_turn)
- 消息数组管理:messages 数组持续追加,形成完整对话历史
- 上下文溢出:当 messages 数组超过模型上下文窗口时,触发压缩机制
最小 Agent Loop 实现
# 伪代码:最小 Agent Loop
messages = []
while True:
response = model.chat(messages)
if response.stop_reason == "end_turn":
return response.content
if response.stop_reason == "tool_use":
tool_name = response.tool_name
tool_args = response.tool_args
tool_result = execute_tool(tool_name, tool_args)
messages.append({"role": "assistant", "content": response})
messages.append({"role": "user", "content": tool_result})第二层:工具系统 —— Harness 的双手
工具的定义与注册
一句话定义:Agent 可以采取的具体行动。
| 工具类别 | 工具名称 | 功能描述 | 参数示例 |
|---|---|---|---|
| 文件操作 | Read | 读取文件内容 | file_path: "/path/to/file" |
| 文件操作 | Write | 写入文件内容 | file_path: "/path/to/file", content: "..." |
| 文件操作 | Edit | 编辑文件片段 | file_path, old_string, new_string |
| 搜索导航 | Glob | 搜索文件路径 | pattern: "**/*.py" |
| 搜索导航 | Grep | 搜索文件内容 | pattern: "function_name" |
| 命令执行 | Bash | 执行 Shell 命令 | command: "npm install" |
| 网络交互 | WebFetch | 网络请求 | url: "https://..." |
工具分发机制
图表
代码
sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant ToolRegistry as 工具注册表
participant ToolExec as 工具执行器
Loop->>Mgmt: 请求工具调用
Mgmt->>Mgmt: 权限检查
Mgmt->>ToolRegistry: 查询工具定义
ToolRegistry-->>Mgmt: 返回工具 schema
Mgmt->>ToolExec: 执行工具
ToolExec-->>Mgmt: 返回结果
Mgmt-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant ToolRegistry as 工具注册表
participant ToolExec as 工具执行器
Loop->>Mgmt: 请求工具调用
Mgmt->>Mgmt: 权限检查
Mgmt->>ToolRegistry: 查询工具定义
ToolRegistry-->>Mgmt: 返回工具 schema
Mgmt->>ToolExec: 执行工具
ToolExec-->>Mgmt: 返回结果
Mgmt-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant ToolRegistry as 工具注册表
participant ToolExec as 工具执行器
Loop->>Mgmt: 请求工具调用
Mgmt->>Mgmt: 权限检查
Mgmt->>ToolRegistry: 查询工具定义
ToolRegistry-->>Mgmt: 返回工具 schema
Mgmt->>ToolExec: 执行工具
ToolExec-->>Mgmt: 返回结果
Mgmt-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant ToolRegistry as 工具注册表
participant ToolExec as 工具执行器
Loop->>Mgmt: 请求工具调用
Mgmt->>Mgmt: 权限检查
Mgmt->>ToolRegistry: 查询工具定义
ToolRegistry-->>Mgmt: 返回工具 schema
Mgmt->>ToolExec: 执行工具
ToolExec-->>Mgmt: 返回结果
Mgmt-->>Loop: 返回工具输出工具设计原则
原子化:
- 每个工具只做一件事
- Read 只读文件,不编辑
- Edit 只编辑片段,不覆盖全文件
可组合:
- Glob + Grep = 搜索包含特定内容的文件
- Read + Edit = 读取并修改文件
- Bash + WebFetch = 执行命令并获取网络结果
描述清晰:
- 工具名称清晰(Read、Write、Edit)
- 参数描述详细(file_path、pattern、command)
- 输出格式明确(文本、JSON、错误信息)
第三层:管理层 —— Harness 的辅助系统
管理层的四大机制
图表
代码
graph TB
subgraph Management["管理层四大机制"]
M1[权限判断
deny→ask→allow]
M2[上下文压缩
防止溢出]
M3[任务系统
持久化目标]
M4[子 Agent 派发
团队协作]
endgraph TB
subgraph Management["管理层四大机制"]
M1[权限判断
deny→ask→allow]
M2[上下文压缩
防止溢出]
M3[任务系统
持久化目标]
M4[子 Agent 派发
团队协作]
endgraph TB
subgraph Management["管理层四大机制"]
M1[权限判断
deny→ask→allow]
M2[上下文压缩
防止溢出]
M3[任务系统
持久化目标]
M4[子 Agent 派发
团队协作]
endgraph TB
subgraph Management["管理层四大机制"]
M1[权限判断<br/>deny→ask→allow]
M2[上下文压缩<br/>防止溢出]
M3[任务系统<br/>持久化目标]
M4[子 Agent 派发<br/>团队协作]
end1. 权限判断
权限模式:
| 模式 | 行为 | 适用场景 |
|---|---|---|
| deny | ❌ 禁止执行 | 删除系统文件、访问密钥 |
| ask | ⚠️ 请求审批 | git push、npm install、删除文件 |
| allow | ✅ 自动执行 | Read、Grep、Glob |
权限流程:
图表
代码
graph LR
A[工具调用请求] --> B{权限规则匹配}
B -->|匹配 deny 规则| C[❌ 禁止执行
返回错误]
B -->|匹配 ask 规则| D[⚠️ 请求审批
等待用户确认]
B -->|匹配 allow 规则| E[✅ 自动执行]
B -->|无匹配规则| F[默认 ask
请求审批]graph LR
A[工具调用请求] --> B{权限规则匹配}
B -->|匹配 deny 规则| C[❌ 禁止执行
返回错误]
B -->|匹配 ask 规则| D[⚠️ 请求审批
等待用户确认]
B -->|匹配 allow 规则| E[✅ 自动执行]
B -->|无匹配规则| F[默认 ask
请求审批]graph LR
A[工具调用请求] --> B{权限规则匹配}
B -->|匹配 deny 规则| C[❌ 禁止执行
返回错误]
B -->|匹配 ask 规则| D[⚠️ 请求审批
等待用户确认]
B -->|匹配 allow 规则| E[✅ 自动执行]
B -->|无匹配规则| F[默认 ask
请求审批]graph LR
A[工具调用请求] --> B{权限规则匹配}
B -->|匹配 deny 规则| C[❌ 禁止执行<br/>返回错误]
B -->|匹配 ask 规则| D[⚠️ 请求审批<br/>等待用户确认]
B -->|匹配 allow 规则| E[✅ 自动执行]
B -->|无匹配规则| F[默认 ask<br/>请求审批]2. 上下文压缩
压缩策略:
| 策略 | 方法 | 效果 |
|---|---|---|
| 滚动窗口 | 只保留最近 N 条消息 | 减少历史 |
| 重要性过滤 | 只保留关键决策和结果 | 精简内容 |
| 摘要压缩 | 将历史消息摘要为摘要段 | 压缩信息 |
| 子 Agent 隔离 | 子 Agent 的消息不泄露到主 Agent | 防止污染 |
触发时机:
- messages 数组长度超过阈值
- 上下文窗口接近溢出
- 用户手动触发压缩
3. 任务系统
任务持久化:
| 任务状态 | 含义 | 操作 |
|---|---|---|
| pending | 等待执行 | 初始化任务 |
| in_progress | 正在执行 | 开始工作 |
| completed | 执行完成 | 标记完成 |
| blocked | 被阻塞 | 等待依赖任务 |
任务依赖:
图表
代码
graph LR
T1[任务1
创建目录] --> T2[任务2
克隆仓库]
T2 --> T3[任务3
安装依赖]
T3 --> T4[任务4
启动服务]
T2[blockedBy: T1]
T3[blockedBy: T2]
T4[blockedBy: T3]graph LR
T1[任务1
创建目录] --> T2[任务2
克隆仓库]
T2 --> T3[任务3
安装依赖]
T3 --> T4[任务4
启动服务]
T2[blockedBy: T1]
T3[blockedBy: T2]
T4[blockedBy: T3]graph LR
T1[任务1
创建目录] --> T2[任务2
克隆仓库]
T2 --> T3[任务3
安装依赖]
T3 --> T4[任务4
启动服务]
T2[blockedBy: T1]
T3[blockedBy: T2]
T4[blockedBy: T3]graph LR
T1[任务1<br/>创建目录] --> T2[任务2<br/>克隆仓库]
T2 --> T3[任务3<br/>安装依赖]
T3 --> T4[任务4<br/>启动服务]
T2[blockedBy: T1]
T3[blockedBy: T2]
T4[blockedBy: T3]4. 子 Agent 派发
子 Agent 隔离:
图表
代码
graph TB
Main[主 Agent
messages 数组A]
Main -->|派发| Sub1[子 Agent 1
messages 数组B
隔离上下文]
Main -->|派发| Sub2[子 Agent 2
messages 数组C
隔离上下文]
Sub1 -->|返回结果| Main
Sub2 -->|返回结果| Main
Sub1[上下文隔离
不污染主 Agent]
Sub2[上下文隔离
不污染主 Agent]graph TB
Main[主 Agent
messages 数组A]
Main -->|派发| Sub1[子 Agent 1
messages 数组B
隔离上下文]
Main -->|派发| Sub2[子 Agent 2
messages 数组C
隔离上下文]
Sub1 -->|返回结果| Main
Sub2 -->|返回结果| Main
Sub1[上下文隔离
不污染主 Agent]
Sub2[上下文隔离
不污染主 Agent]graph TB
Main[主 Agent
messages 数组A]
Main -->|派发| Sub1[子 Agent 1
messages 数组B
隔离上下文]
Main -->|派发| Sub2[子 Agent 2
messages 数组C
隔离上下文]
Sub1 -->|返回结果| Main
Sub2 -->|返回结果| Main
Sub1[上下文隔离
不污染主 Agent]
Sub2[上下文隔离
不污染主 Agent]graph TB
Main[主 Agent<br/>messages 数组A]
Main -->|派发| Sub1[子 Agent 1<br/>messages 数组B<br/>隔离上下文]
Main -->|派发| Sub2[子 Agent 2<br/>messages 数组C<br/>隔离上下文]
Sub1 -->|返回结果| Main
Sub2 -->|返回结果| Main
Sub1[上下文隔离<br/>不污染主 Agent]
Sub2[上下文隔离<br/>不污染主 Agent]隔离机制:
- 子 Agent 使用独立的 messages 数组
- 子 Agent 的历史不泄露到主 Agent
- 主 Agent 只接收子 Agent 的最终结果
第四层:扩展层 —— Harness 的外挂系统
扩展层三大机制
图表
代码
graph TB
subgraph Extension["扩展层三大机制"]
E1[Skills 按需加载
领域知识注入]
E2[MCP 插件集成
外部系统连接]
E3[Hooks 扩展点
生命周期拦截]
endgraph TB
subgraph Extension["扩展层三大机制"]
E1[Skills 按需加载
领域知识注入]
E2[MCP 插件集成
外部系统连接]
E3[Hooks 扩展点
生命周期拦截]
endgraph TB
subgraph Extension["扩展层三大机制"]
E1[Skills 按需加载
领域知识注入]
E2[MCP 插件集成
外部系统连接]
E3[Hooks 扩展点
生命周期拦截]
endgraph TB
subgraph Extension["扩展层三大机制"]
E1[Skills 按需加载<br/>领域知识注入]
E2[MCP 插件集成<br/>外部系统连接]
E3[Hooks 扩展点<br/>生命周期拦截]
end1. Skills 按需加载
Skills 定义:按需注入的领域知识 Markdown 文件。
| Skills 类型 | 内容 | 加载时机 |
|---|---|---|
| CLAUDE.md | 项目约定、架构、注意事项 | 自动注入 |
| skills/*.md | 技术知识、领域文档 | Model 判断需要时加载 |
| 规则文件 | 编码规范、测试要求 | 自动注入 |
加载流程:
图表
代码
graph LR
Model[Model 推理] -->|判断需要
领域知识| K[查询 Skills 列表]
K -->|读取| S[Skills Markdown 文件]
S -->|注入| C[上下文 messages]
C -->|增强推理| Modelgraph LR
Model[Model 推理] -->|判断需要
领域知识| K[查询 Skills 列表]
K -->|读取| S[Skills Markdown 文件]
S -->|注入| C[上下文 messages]
C -->|增强推理| Modelgraph LR
Model[Model 推理] -->|判断需要
领域知识| K[查询 Skills 列表]
K -->|读取| S[Skills Markdown 文件]
S -->|注入| C[上下文 messages]
C -->|增强推理| Modelgraph LR
Model[Model 推理] -->|判断需要<br/>领域知识| K[查询 Skills 列表]
K -->|读取| S[Skills Markdown 文件]
S -->|注入| C[上下文 messages]
C -->|增强推理| Model2. MCP 插件集成
MCP 定义:Model Context Protocol——连接 AI 和外部工具的开放协议。
| MCP 服务器 | 功能 | 提供的工具 |
|---|---|---|
| filesystem | 文件系统操作 | read_file、write_file、list_directory |
| database | 数据库连接 | query、insert、update |
| web | 网络访问 | fetch、search、browser_control |
| custom | 自定义系统 | 企业 API、云服务 |
集成流程:
图表
代码
sequenceDiagram
participant Loop as Agent Loop
participant MCP as MCP 服务器
participant External as 外部系统
Loop->>MCP: 调用 MCP 工具
MCP->>External: 执行操作
External-->>MCP: 返回结果
MCP-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant MCP as MCP 服务器
participant External as 外部系统
Loop->>MCP: 调用 MCP 工具
MCP->>External: 执行操作
External-->>MCP: 返回结果
MCP-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant MCP as MCP 服务器
participant External as 外部系统
Loop->>MCP: 调用 MCP 工具
MCP->>External: 执行操作
External-->>MCP: 返回结果
MCP-->>Loop: 返回工具输出sequenceDiagram
participant Loop as Agent Loop
participant MCP as MCP 服务器
participant External as 外部系统
Loop->>MCP: 调用 MCP 工具
MCP->>External: 执行操作
External-->>MCP: 返回结果
MCP-->>Loop: 返回工具输出3. Hooks 扩展点
Hooks 定义:生命周期拦截器——在特定事件触发时执行自定义逻辑。
| Hook 类型 | 触发时机 | 用途 |
|---|---|---|
| PreToolUse | 工具执行前 | 参数验证、权限增强 |
| PostToolUse | 工具执行后 | 自动格式化、结果处理 |
| Stop | 会话结束时 | 最终验证、清理工作 |
示例:
// PostToolUse Hook 示例
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": ["npm run format"] // 写入文件后自动格式化
}
]
}
}层间协作
层间调用序列图
图表
代码
sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant Tool as 工具层
participant Ext as 扩展层
Loop->>Mgmt: 请求工具执行
Mgmt->>Mgmt: 权限检查
Mgmt->>Ext: PreToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Tool: 执行工具
Tool-->>Mgmt: 返回结果
Mgmt->>Ext: PostToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Mgmt: 上下文压缩检查
Mgmt-->>Loop: 返回工具结果sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant Tool as 工具层
participant Ext as 扩展层
Loop->>Mgmt: 请求工具执行
Mgmt->>Mgmt: 权限检查
Mgmt->>Ext: PreToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Tool: 执行工具
Tool-->>Mgmt: 返回结果
Mgmt->>Ext: PostToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Mgmt: 上下文压缩检查
Mgmt-->>Loop: 返回工具结果sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant Tool as 工具层
participant Ext as 扩展层
Loop->>Mgmt: 请求工具执行
Mgmt->>Mgmt: 权限检查
Mgmt->>Ext: PreToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Tool: 执行工具
Tool-->>Mgmt: 返回结果
Mgmt->>Ext: PostToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Mgmt: 上下文压缩检查
Mgmt-->>Loop: 返回工具结果sequenceDiagram
participant Loop as Agent Loop
participant Mgmt as 管理层
participant Tool as 工具层
participant Ext as 扩展层
Loop->>Mgmt: 请求工具执行
Mgmt->>Mgmt: 权限检查
Mgmt->>Ext: PreToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Tool: 执行工具
Tool-->>Mgmt: 返回结果
Mgmt->>Ext: PostToolUse Hook
Ext-->>Mgmt: Hook 处理完成
Mgmt->>Mgmt: 上下文压缩检查
Mgmt-->>Loop: 返回工具结果协作流程
- Loop 层 → 管理层:请求工具执行
- 管理层 → 权限检查:判断 deny/ask/allow
- 管理层 → 扩展层:PreToolUse Hook(参数验证)
- 管理层 → 工具层:执行具体工具
- 工具层 → 管理层:返回执行结果
- 管理层 → 扩展层:PostToolUse Hook(结果处理)
- 管理层 → Loop 层:返回工具输出
本章小结
- 四层模型:Loop层、工具层、管理层、扩展层
- Loop层:observe → think → act → feedback 的持续循环
- 工具层:Bash/Read/Write/Edit/Glob/Grep/Browser/MCP
- 管理层:权限判断、上下文压缩、任务系统、子 Agent 派发
- 扩展层:Skills 按需加载、MCP 插件集成、Hooks 扩展点
- 层间协作:环环相扣,循环不息
预告:下一篇我们辨析 Model、Agent、Harness 三者的精确定义——你真的理解它们的关系吗?
相关内容
- 第01章 Agent 的 70 年简史 —— 从符号推理到深度学习
- 第02章 LLM 时代的 Agent 革命 —— 2023-2026 爆发期
- 第03章 Harness 概念溯源 —— "模型是大脑,Harness是身体"
- 第05章 Harness vs Agent vs Model —— 三者关系辨析
- 第06章 Claude Code Harness 架构剖析 —— 编程 Agent 的标杆实现
收录于 合集・01-AI 工具与智能体/07-Harness 27
如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
支付宝
微信