Agent Harness 是什么:全面解析
发布于 2026-06-04 23:46
Agent Harness 是什么:全面解析
一、定义
Agent Harness( Agent 线束/框架)是指包裹在 AI Agent 外层的那层基础设施,它定义了 Agent 如何接收输入、调用工具、处理输出、管理状态,以及与外部系统交互的方式。
类比汽车制造:
- LLM = 发动机(核心动力)
- Agent = 整车设计(方向盘、刹车、传动系统)
- Harness = 生产线和检测线(把发动机装进整车,并确保它能跑起来、跑得安全)
更简单地说:Harness 是让 Agent 从"能聊天"变成"能干活"的那层工程代码。
二、Harness 能做什么
1. 工具调用编排
LLM 本身只能生成文本。Harness 负责:
- 解析 LLM 返回的 tool_calls
- 路由到对应的工具实现
- 处理工具返回结果
- 管理调用顺序和并行
用户: "帮我查下天气然后发条消息"
↓
LLM: [tool_call: get_weather("北京")]
↓
Harness: 调用 weather API → 拿到结果
↓
LLM: [tool_call: send_message("北京今天晴,25°C")]
↓
Harness: 调用 messaging API → 发送成功
2. 上下文管理
Agent 对话越来越长,Harness 负责:
- 压缩:把早期对话总结成摘要(Hermes 的 compression 就是做这个)
- 裁剪:丢弃不相关的工具输出
- 注入:把 AGENTS.md、Skill 等上下文塞进系统提示
- 缓存:利用 prompt caching 减少重复 token
3. 状态持久化
- 会话状态管理(当前在做什么、做了哪些步骤)
- 跨会话记忆(Memory、Session Search)
- 检查点/回滚(checkpoint/rollback)
- 后台进程管理(background process)
4. 安全和权限
- 命令审批:危险操作前先问用户(
rm -rf、git reset等) - 沙箱隔离:限制 Agent 能访问的文件系统范围
- 速率限制:防止 Agent 无限循环调用工具
- 超时控制:工具调用超时时自动终止
5. 错误处理和重试
- 工具调用失败时的重试逻辑
- LLM 返回格式不正确时的解析恢复
- 网络超时、API 限流等异常处理
- 子 Agent 失败时的降级策略
6. 评估和测试
- Benchmark 框架:标准化测试 Agent 能力
- 回归测试:Agent 升级后验证没有退化
- A/B 测试:比较不同 Agent 配置的效果
- 日志和追踪:记录每次工具调用和决策过程
三、Harness 的核心组件
一个完整的 Agent Harness 通常包含:
┌─────────────────────────────────────────────────┐
│ Agent Harness │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ System │ │ Tool │ │ State │ │
│ │ Prompt │ │ Router │ │ Manager │ │
│ │ Builder │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Context │ │ Safety │ │ Error │ │
│ │ Compress │ │ Guard │ │ Handler │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Memory │ │ Output │ │ Eval │ │
│ │ System │ │ Parser │ │ Engine │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘
各组件说明
| 组件 | 职责 | 示例 |
|---|---|---|
| System Prompt Builder | 构建系统提示 | 注入 AGENTS.md、Skill、personality |
| Tool Router | 路由工具调用 | 解析 tool_calls → 调用对应函数 |
| State Manager | 管理会话状态 | 当前步骤、已完成的操作、待办事项 |
| Context Compress | 压缩上下文 | 总结早期对话、裁剪冗余工具输出 |
| Safety Guard | 安全检查 | 命令审批、沙箱隔离、速率限制 |
| Error Handler | 错误处理 | 重试、降级、超时恢复 |
| Memory System | 持久化记忆 | Memory、Session Search、Skill |
| Output Parser | 解析输出 | 提取结构化数据、验证格式 |
| Eval Engine | 评估测试 | Benchmark、回归测试 |
四、主流 Harness 实现
1. Claude Code Harness
Anthropic 官方的 Agent Harness,特点是:
- 严格的工具权限模型(需要用户显式批准)
- CLAUDE.md 作为项目上下文入口
- 内置 Explore sub-agent 做代码探索
- 自动检查点支持回滚
2. Cursor Harness
Cursor IDE 内置的 Agent:
- 自动 codebase indexing(RAG)
- .cursorrules 作为全局规则
- 多模型支持(可切换 Claude/GPT/Gemini)
- 实时代码diff预览
3. Hermes Agent Harness
Nous Research 的 Agent 框架:
- Skills 系统(可复用的操作手册)
- Memory 系统(跨会话持久化记忆)
- 多平台 Gateway(Telegram/Discord/WeChat 等)
- Cron 定时任务
- 子 Agent 委派(delegate_task)
4. LangChain / LlamaIndex Harness
开源 Agent 框架:
- AgentExecutor:基础执行循环
- ToolRegistry:工具注册和管理
- MemoryBuffer:对话记忆
- AgentRunner:LangGraph 中的状态机
5. AutoGen Harness
微软的多 Agent 框架:
- GroupChat:多 Agent 协作
- ConversableAgent:可配置的 Agent 基类
- AssistantAgent + UserProxyAgent 模式
- 代码执行沙箱
6. OpenHands Harness
开源的 Agent 开发环境:
- 事件驱动的 Agent 循环
- 文件编辑、命令执行、代码搜索
- Docker 沙箱隔离
- 完整的评估框架(SWE-bench)
五、Harness vs Agent vs LLM
很多人混淆这三个概念:
| 概念 | 是什么 | 类比 |
|---|---|---|
| LLM | 大语言模型,核心推理引擎 | 发动机 |
| Agent | LLM + 工具调用能力,能感知环境并行动 | 整车设计 |
| Harness | Agent 的运行时基础设施,管理输入/输出/状态/安全 | 生产线和检测线 |
一个常见误区:很多人说"用 Agent",其实只是在用裸 LLM + 简单的 prompt。没有 Harness 的 Agent 就像没有生产线的发动机——能转,但装不进车里。
六、常见误区
误区 1:Harness 就是 Agent
错误:把 Harness 等同于 Agent。
正确:Harness 是 Agent 的运行时基础设施。Agent 是设计概念,Harness 是工程实现。同一个 Agent 设计可以有不同的 Harness 实现。
误区 2:Harness 越复杂越好
错误:认为 Harness 功能越多 Agent 越强。
正确:Harness 应该刚好够用。过度复杂的 Harness 会:
- 增加延迟(每多一层处理就多一次往返)
- 消耗更多 token(更复杂的系统提示)
- 引入更多 bug 点
- 降低可调试性
原则:从最简单的 Harness 开始,只在实际需要时增加功能。
误区 3:裸 LLM 就能做 Agent
错误:认为只要 prompt 写得好,LLM 就能完成复杂任务。
正确:没有 Harness 的 LLM:
- 无法调用工具(只能生成文本描述"我想调用工具")
- 无法持久状态(每次对话从零开始)
- 无法处理错误(工具调用失败时不知道怎么办)
- 无法保证安全(可能执行危险操作)
误区 4:Harness 可以替代 Prompt Engineering
错误:有了好的 Harness,就不用精心设计 prompt 了。
正确:Harness 和 Prompt Engineering 是互补的:
- Harness 解决"怎么做"(工具调用、状态管理)
- Prompt Engineering 解决"做什么"(任务定义、输出格式)
- 好的 Agent 需要两者配合
误区 5:一个 Harness 通吃所有场景
错误:认为通用的 Harness 可以适配所有 Agent 任务。
正确:不同场景需要不同的 Harness 侧重:
- 代码开发 Agent:需要代码分析、文件操作、测试运行(Hermes Agent 的 Skill 系统)
- 客服 Agent:需要知识库检索、多轮对话、工单系统集成
- 数据分析 Agent:需要数据查询、可视化、报告生成
- 运维 Agent:需要命令执行、日志分析、自动修复
误区 6:Harness 只在开发阶段需要
错误:Harness 是一次性的开发基础设施。
正确:Harness 需要持续维护:
- LLM 升级后,工具调用格式可能变化
- 新工具加入后,Router 需要更新
- 安全漏洞需要修补
- 性能瓶颈需要优化
误区 7:Harness 让 Agent 变得可信
错误:认为有了安全检查,Agent 就不会出错。
正确:Harness 可以降低风险,但不能消除风险:
- LLM 可能被 prompt injection 攻击
- 工具可能被滥用(如 Agent 被诱导读取敏感文件)
- 复杂的多步骤任务可能因为某一步出错而整体失败
- Harness 本身可能有 bug
七、最小可行 Harness
自己做 Agent 时,最小的 Harness 只需要四层:
1. Prompt Layer(提示层)
- 系统提示 + 工具描述 + 输出格式
2. Loop Layer(循环层)
- while not done:
- 调用 LLM
- 如果有 tool_calls → 执行工具 → 继续
- 如果有最终输出 → 返回
3. Tool Layer(工具层)
- 工具注册和路由
- 参数解析和验证
- 返回值格式化
4. Error Layer(错误层)
- 工具调用重试
- 超时处理
- 异常恢复
# 最简 Harness 伪代码
async def agent_loop(user_message, system_prompt, tools):
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
]
while True:
response = await llm.chat(messages)
if response.has_tool_calls:
for call in response.tool_calls:
result = await execute_tool(call.name, call.args)
messages.append({"role": "tool", "content": result})
continue
if response.is_final:
return response.content
上面的例子就是一个最简 Harness。所有复杂的 Harness(Claude Code、Cursor、Hermes)都是在这个基础上增加功能层。
八、Harness 选型的考量维度
如果要在现有 Harness 基础上做选择,考虑这些维度:
| 维度 | 问题 |
|---|---|
| 延迟 | 工具调用往返几次?每次多少毫秒? |
| Token 效率 | 系统提示多大?是否支持 prompt caching? |
| 可扩展性 | 添加新工具难不难?支不支持第三方工具? |
| 可观测性 | 能记录每次工具调用吗?出错好调试吗? |
| 安全 | 有没有命令审批?沙箱隔离?速率限制? |
| 记忆 | 跨会话记忆怎么管理?上下文压缩策略是什么? |
| 多 Agent | 支不支持子 Agent 委派?多 Agent 协作? |
| 平台 | 支持哪些部署方式?CLI/Web/API? |
九、总结
| 要点 | 说明 |
|---|---|
| 是什么 | 包裹在 Agent 外层的基础设施 |
| 核心能力 | 工具编排、上下文管理、状态持久化、安全控制、错误处理 |
| 必要性 | 没有 Harness,LLM 只是聊天机器人,不是 Agent |
| 常见误区 | 把 Harness 当 Agent、认为越复杂越好、忽视持续维护 |
| 最小实现 | Prompt + Loop + Tool + Error 四层 |
| 选型关键 | 根据场景选择刚好够用的复杂度 |
Harness 不性感,但没有它,Agent 就只是空中楼阁。好的 Harness 让 Agent 从"能聊天"变成"能干活"——这就是它存在的全部意义。
← 返回博客列表