🎛️ DeepAgents Harness 系统
生产级 Agent 运行时框架,提供文件系统管理、上下文优化、 子代理委派、人工介入等企业级特性,让 Agent 可靠、高效地运行。
📚 什么是 Harness?
Harness(代理框架)是 DeepAgents 的运行时环境, 它不是一个简单的框架,而是一个完整的生产级 Agent 执行引擎。
| 特性 | 说明 | 应用场景 |
|---|---|---|
| 文件系统工具 | 6 个内置文件操作工具 | 文档处理、代码工作 |
| 大结果驱逐 | 自动管理超大工具输出(20,000 Token) | 避免上下文溢出 |
| 存储抽象 | 4 种可插拔存储后端 | 临时数据 + 持久化 |
| 子代理委派 | 通过 task 工具创建专门化 Agent | 任务分解、并行执行 |
| 历史摘要 | 170,000 Token 自动压缩对话历史 | 长期运行 Agent |
| 工具调用修复 | 检测并修复悬空工具调用 | 保证对话连贯性 |
| 待办列表 | write_todos 工具追踪任务进度 | 复杂工作流管理 |
| 人工介入 | 特定工具调用前暂停等待审批 | 安全门控、成本控制 |
| 提示词缓存 | Anthropic 模型缓存系统提示词 | 10 倍加速和成本降低 |
Harness 实现了"标准工具调用循环 + 生产级增强"的理念:
- 核心循环:标准的请求 → 工具调用 → 结果处理
- 增强层:自动结果监控、Token 管理、上下文优化、错误恢复
- 存储抽象:可插拔的后端策略,无需改代码即可切换
🏗️ Harness 架构
Harness 采用分层架构,在标准 Agent 执行循环之上 添加了多个增强层:
Agent 执行引擎"] Core --> Enhance["增强层"] Enhance --> FileTools["文件系统工具
ls, read, write, edit, glob, grep"] Enhance --> ResultEviction["大结果驱逐
>20K Token 自动写入存储"] Enhance --> History["历史摘要
170K Token 自动压缩"] Enhance --> Repair["工具调用修复
悬空调用处理"] FileTools --> Storage["存储抽象层"] ResultEviction --> Storage Storage --> State["StateBackend
内存存储"] Storage --> FS["FilesystemBackend
磁盘存储"] Storage --> Store["StoreBackend
持久化存储"] Storage --> Composite["CompositeBackend
混合路由"] Core --> Advanced["高级特性"] Advanced --> Subagents["子代理委派
task 工具"] Advanced --> HITL["人工介入
审批门控"] Advanced --> Caching["提示词缓存
Anthropic 加速"] Advanced --> Todos["待办列表
write_todos"] style Core fill:#3b82f6,color:#fff style Enhance fill:#10b981,color:#fff style Storage fill:#f59e0b,color:#fff style Advanced fill:#8b5cf6,color:#fff
📁 文件系统工具
Harness 提供6 个内置文件操作工具,让 Agent 可以 像操作本地文件系统一样管理数据:
| 工具 | 功能 | 典型用途 |
|---|---|---|
ls |
列出目录内容(带元数据) | 浏览文件结构、查看大小和修改时间 |
read_file |
读取文件内容(带行号和偏移) | 加载已保存的搜索结果、读取中间数据 |
write_file |
创建新文件 | 保存大量工具输出、临时数据 |
edit_file |
精确字符串替换(支持全局替换) | 修改配置、更新已保存数据 |
glob |
基于模式的文件发现 | 查找特定类型的文件(*.txt, **/*.json) |
grep |
内容搜索(多种输出模式) | 在文件中搜索关键字、提取信息 |
"""
文件系统工具 - Agent 自动使用示例
"""
from deepagents import create_deep_agent
# 创建 Agent(文件系统工具自动可用)
agent = create_deep_agent(
model="gpt-4o",
system_prompt="""你是数据分析助手。你可以:
1. 使用 write_file 保存大量搜索结果
2. 使用 read_file 加载已保存的数据进行分析
3. 使用 ls 查看已保存的文件
4. 使用 edit_file 更新数据
5. 使用 glob 查找特定文件
6. 使用 grep 搜索文件内容
工作流程:
- 收集数据 → write_file 保存
- 分析数据 → read_file 读取
- 更新数据 → edit_file 修改
"""
)
# Agent 会自动使用文件工具管理数据
result = agent.invoke({
"messages": [{
"role": "user",
"content": "收集 2024 年 AI 研究的最新进展,保存到文件,然后分析趋势"
}]
})
# Agent 执行流程:
# 1. 使用网络搜索收集信息
# 2. 使用 write_file 保存大量数据(避免上下文溢出)
# 3. 使用 read_file 逐步读取和分析
# 4. 生成最终报告
💾 存储后端
Harness 提供4 种可插拔的存储后端, 支持不同的数据持久化策略:
1. StateBackend(内存存储)
临时内存存储,数据保存在 Agent 状态中, 随对话一起 checkpoint。
"""
StateBackend - 内存存储(默认)
"""
from deepagents import create_deep_agent
from deepagents.harness import StateBackend
agent = create_deep_agent(
model="gpt-4o",
storage_backend=StateBackend() # 数据保存在内存中
)
# 特点:
# - 数据随对话状态一起 checkpoint
# - 对话结束后数据消失
# - 适用于临时工作空间
2. FilesystemBackend(磁盘存储)
真实磁盘访问,支持路径验证、大小限制、 symlink 防护等安全特性。
"""
FilesystemBackend - 磁盘存储
"""
from deepagents.harness import FilesystemBackend
agent = create_deep_agent(
model="gpt-4o",
storage_backend=FilesystemBackend(
root_path="/data/agent_workspace", # 根目录
max_file_size=10 * 1024 * 1024, # 10MB 限制
allow_symlinks=False # 禁止符号链接
)
)
# 特点:
# - 数据持久化到磁盘
# - 跨对话数据共享
# - 路径验证和安全检查
# - 适用于需要真实文件操作的场景
3. StoreBackend(持久化存储)
跨对话持久化,使用 LangGraph 的 BaseStore, 支持数据库存储。
"""
StoreBackend - 持久化存储
"""
from deepagents.harness import StoreBackend
from langgraph.store.memory import InMemoryStore
# 创建持久化 store
store = InMemoryStore() # 可替换为 PostgresStore 等
agent = create_deep_agent(
model="gpt-4o",
storage_backend=StoreBackend(store=store)
)
# 特点:
# - 跨对话数据持久化
# - 支持数据库后端
# - 适用于知识库、长期记忆
4. CompositeBackend(混合路由)
最灵活的方案,根据路径前缀将不同路径路由到 不同的后端。
"""
CompositeBackend - 混合路由策略
"""
from deepagents.harness import (
CompositeBackend,
StateBackend,
StoreBackend,
FilesystemBackend
)
# 创建混合后端
composite = CompositeBackend(
backends={
"/tmp": StateBackend(), # 临时数据 → 内存
"/knowledge": StoreBackend(store), # 知识库 → 持久化
"/workspace": FilesystemBackend(root_path="/data") # 工作区 → 磁盘
},
default_backend=StateBackend() # 默认使用内存
)
agent = create_deep_agent(
model="gpt-4o",
storage_backend=composite
)
# 使用示例:
# - write_file("/tmp/search_results.txt", ...) → 内存
# - write_file("/knowledge/faq.txt", ...) → 持久化
# - write_file("/workspace/report.pdf", ...) → 磁盘
# - write_file("other.txt", ...) → 默认内存
| 后端 | 适用场景 | 数据生命周期 |
|---|---|---|
StateBackend |
临时工作空间、单次对话 | 对话结束后消失 |
FilesystemBackend |
真实文件操作、代码工作 | 持久化,手动删除 |
StoreBackend |
知识库、跨对话共享 | 永久持久化 |
CompositeBackend |
混合场景(推荐) | 按路径分类 |
🔄 大结果驱逐
当工具输出超过20,000 Token时,Harness 会 自动将结果写入存储,并用文件引用替换原始输出。
返回大量数据"] --> Check{"结果大小
> 20K Token?"} Check -->|否| Direct["直接返回
结果"] Check -->|是| Evict["驱逐到存储
write_file(data)"] Evict --> Replace["替换为引用
'结果已保存到 file.txt'"] Replace --> Agent["Agent 继续执行
需要时 read_file()"] Direct --> Agent style Tool fill:#3b82f6,color:#fff style Check fill:#f59e0b,color:#fff style Evict fill:#ef4444,color:#fff style Replace fill:#10b981,color:#fff
"""
大结果驱逐 - 自动管理
"""
from deepagents import create_deep_agent
# 场景:搜索工具返回大量结果
def massive_search(query: str) -> str:
"""搜索工具,可能返回超大结果"""
# 假设返回 50,000 Token 的结果
results = search_api(query, max_results=1000)
return "\n".join([f"{i}. {r}" for i, r in enumerate(results)])
agent = create_deep_agent(
model="gpt-4o",
tools=[massive_search]
)
result = agent.invoke({
"messages": [{
"role": "user",
"content": "搜索所有关于 LangChain 的文档"
}]
})
# 执行过程:
# 1. Agent 调用 massive_search 工具
# 2. 工具返回 50,000 Token 的结果
# 3. Harness 检测到超过 20,000 Token 阈值
# 4. 自动执行 write_file("search_results.txt", data)
# 5. 将工具消息替换为:"搜索结果已保存到 search_results.txt"
# 6. Agent 看到文件引用,可以后续使用 read_file 读取
# 优势:
# - 避免上下文窗口溢出
# - Agent 可以选择性地读取部分数据
# - 自动化,无需手动管理
👥 子代理委派
主 Agent 可以使用内置的task 工具创建 独立的子代理来执行专门化任务。
"""
子代理委派 - task 工具使用
"""
from deepagents import create_deep_agent
# 主 Agent 的系统提示词
main_prompt = """你是项目经理 Agent。你可以:
1. 使用 task 工具委派专门化任务给子 Agent
2. 子 Agent 会独立执行,返回压缩的结果
3. 你可以并行创建多个子 Agent
示例:
- task("研究 LangChain 架构", agent_type="researcher")
- task("编写代码示例", agent_type="coder")
- task("生成测试用例", agent_type="tester")
每个子 Agent 都有独立的上下文,不会污染主 Agent 的对话历史。
"""
agent = create_deep_agent(
model="gpt-4o",
system_prompt=main_prompt
)
# 使用 Agent
result = agent.invoke({
"messages": [{
"role": "user",
"content": """创建一个完整的 LangChain RAG 项目:
1. 研究 RAG 最佳实践
2. 编写代码实现
3. 生成测试用例
"""
}]
})
# Agent 执行流程:
# 1. 主 Agent 分析任务
# 2. 调用 task("研究 RAG 最佳实践", agent_type="researcher")
# → 子 Agent 1 独立执行研究任务
# → 返回压缩的研究报告
# 3. 调用 task("编写 RAG 代码", agent_type="coder", context="研究结果...")
# → 子 Agent 2 独立编写代码
# → 返回代码
# 4. 调用 task("生成测试用例", agent_type="tester", code="...")
# → 子 Agent 3 生成测试
# → 返回测试用例
# 5. 主 Agent 整合所有子 Agent 的结果,生成最终输出
# 优势:
# - 上下文隔离:每个子 Agent 有独立的对话历史
# - 并行执行:可以同时运行多个子 Agent
# - 专门化:每个子 Agent 专注于特定任务
# - Token 效率:子 Agent 返回压缩结果,节省主 Agent 上下文
- 独立任务:适合可以独立完成的任务(研究、编码、测试)
- 上下文隔离:子 Agent 不会污染主 Agent 的对话历史
- 并行执行:多个子 Agent 可以同时运行,提升效率
- 压缩返回:子 Agent 只返回关键结果,节省 Token
📝 对话历史摘要
当对话历史超过170,000 Token时,Harness 会 自动压缩旧消息,保留最近 6 条消息不变。
"""
历史摘要 - 自动压缩
"""
from deepagents import create_deep_agent
agent = create_deep_agent(
model="gpt-4o",
system_prompt="你是长期运行的助手"
)
# 长期运行的对话
for i in range(100):
result = agent.invoke({
"messages": [{
"role": "user",
"content": f"任务 {i}: 执行一些复杂的操作"
}]
})
# 执行过程:
# 1. 对话不断积累消息
# 2. 当达到 170,000 Token 时,Harness 触发摘要
# 3. 保留最近 6 条消息不变
# 4. 旧消息被压缩成摘要:"前 94 个任务的总结..."
# 5. 继续执行,上下文保持可控
# 配置(可选):
# - 摘要触发阈值:170,000 Token(默认)
# - 保留最近消息数:6 条(默认)
# - 摘要由模型生成,确保关键信息不丢失
🔧 悬空工具调用修复
Harness 会检测AIMessage 包含 tool_calls 但没有对应的 ToolMessage 的情况,并自动创建合成响应。
"""
工具调用修复 - 自动处理
"""
# 场景:Agent 中断或错误导致工具调用没有响应
# 错误的对话序列:
# 1. HumanMessage: "搜索 LangChain"
# 2. AIMessage: tool_calls=[search("LangChain")]
# 3. [中断,没有 ToolMessage]
# 4. HumanMessage: "继续"
# Harness 自动修复:
# 1. 检测到 AIMessage 有 tool_calls 但没有响应
# 2. 创建合成 ToolMessage: "工具调用被中断,请重试"
# 3. 对话序列变为完整:
# - HumanMessage: "搜索 LangChain"
# - AIMessage: tool_calls=[search("LangChain")]
# - ToolMessage: "工具调用被中断,请重试" [合成]
# - HumanMessage: "继续"
# 4. Agent 可以正常继续执行
# 优势:
# - 保证对话序列的完整性
# - 避免模型混淆
# - 自动恢复错误状态
✅ 待办列表追踪
Agent 可以使用write_todos 工具维护结构化的 任务列表,追踪复杂工作流的进度。
"""
待办列表 - write_todos 工具
"""
from deepagents import create_deep_agent
agent = create_deep_agent(
model="gpt-4o",
system_prompt="""你是项目管理助手。使用 write_todos 工具追踪任务进度。
任务状态:
- pending: 待处理
- in_progress: 进行中
- completed: 已完成
工作流程:
1. 收到任务后,使用 write_todos 创建任务列表
2. 开始任务时,更新状态为 in_progress
3. 完成任务后,更新状态为 completed
"""
)
result = agent.invoke({
"messages": [{
"role": "user",
"content": "创建一个完整的 Web 应用:前端、后端、数据库、部署"
}]
})
# Agent 执行过程:
# 1. 调用 write_todos:
# [
# {"task": "设计数据库 schema", "status": "pending"},
# {"task": "实现后端 API", "status": "pending"},
# {"task": "开发前端界面", "status": "pending"},
# {"task": "配置部署", "status": "pending"}
# ]
#
# 2. 开始第一个任务,更新:
# [
# {"task": "设计数据库 schema", "status": "in_progress"},
# ...
# ]
#
# 3. 完成第一个任务,更新:
# [
# {"task": "设计数据库 schema", "status": "completed"},
# {"task": "实现后端 API", "status": "in_progress"},
# ...
# ]
#
# 4. 循环执行,直到所有任务完成
# 优势:
# - 结构化追踪复杂工作流
# - 用户可见任务进度
# - Agent 可以根据任务状态决策
👤 人工介入(HITL)
配置 Harness 在特定工具调用前暂停并等待人工审批, 实现安全门控和成本控制。
"""
人工介入 - HITL 配置
"""
from deepagents import create_deep_agent
# 定义需要审批的工具
def delete_file(path: str) -> str:
"""删除文件(危险操作)"""
import os
os.remove(path)
return f"已删除文件:{path}"
def expensive_api_call(query: str) -> str:
"""调用昂贵的 API"""
# 假设这是一个每次调用花费 $10 的 API
return external_api.query(query)
agent = create_deep_agent(
model="gpt-4o",
tools=[delete_file, expensive_api_call],
# 配置人工介入
interrupt_before=["delete_file", "expensive_api_call"],
system_prompt="你是文件管理和数据查询助手"
)
# 使用 Agent
result = agent.invoke({
"messages": [{
"role": "user",
"content": "清理临时文件,并查询最新数据"
}]
})
# 执行流程:
# 1. Agent 决定调用 delete_file("/tmp/cache")
# 2. Harness 检测到 interrupt_before 配置
# 3. 暂停执行,返回中断信号
# 4. 用户审批或拒绝:
# - 审批:agent.resume() 继续执行
# - 拒绝:agent.cancel() 取消操作
# 5. 继续执行后续任务
# 审批示例:
if result.get("interrupt"):
print(f"Agent 请求执行:{result['next_tool_call']}")
approval = input("是否批准?(y/n): ")
if approval.lower() == "y":
result = agent.resume()
else:
result = agent.cancel("用户拒绝操作")
# 应用场景:
# - 危险操作(删除、修改生产数据)
# - 昂贵的 API 调用
# - 需要人工判断的决策
⚡ 提示词缓存(Anthropic)
对于 Anthropic 模型,Harness 会自动缓存系统提示词, 实现10 倍加速和成本降低。
"""
提示词缓存 - 自动启用(Anthropic)
"""
from deepagents import create_deep_agent
# 使用 Anthropic 模型时自动启用缓存
agent = create_deep_agent(
model="claude-sonnet-4-5-20250929", # Anthropic 模型
system_prompt="""你是专业的代码审查助手...
[非常长的系统提示词,包含详细的审查标准、代码规范、输出格式等]
总共 5000+ Token 的系统提示词
"""
)
# 第一次调用:系统提示词被缓存
result1 = agent.invoke({
"messages": [{"role": "user", "content": "审查这段代码..."}]
})
# 第二次调用:直接使用缓存,10 倍加速
result2 = agent.invoke({
"messages": [{"role": "user", "content": "审查另一段代码..."}]
})
# 效果:
# - 第一次调用:正常速度和成本
# - 后续调用:
# - 延迟降低 ~90%(10 倍加速)
# - 成本降低 ~90%(系统提示词不重复计费)
# 注意:
# - 仅适用于 Anthropic Claude 模型
# - 缓存有效期:5 分钟(Anthropic 限制)
# - 系统提示词必须保持不变才能使用缓存
✨ Harness 最佳实践
1. 存储策略选择
- 推荐使用 CompositeBackend:灵活路由不同类型的数据
- 临时数据 → StateBackend(内存)
- 知识库 → StoreBackend(持久化)
- 真实文件操作 → FilesystemBackend(磁盘)
2. Token 管理
- 信任大结果驱逐:让 Harness 自动管理超大输出
- 使用子代理:隔离上下文,避免主 Agent 污染
- 历史摘要:对长期运行的 Agent 自动生效
3. 安全和成本控制
- 配置 interrupt_before:为危险/昂贵操作添加人工审批
- FilesystemBackend 安全:设置 max_file_size、禁用 symlinks
- 监控 Token 使用:配合 LangSmith 追踪
4. 性能优化
- Anthropic 模型:启用提示词缓存,10 倍加速
- 并行子代理:使用 task 工具并行执行独立任务
- 适时使用文件工具:避免重复传输大量数据
❓ 常见问题
Q1: Harness 和普通 Agent 有什么区别?
| 特性 | 普通 Agent | Harness(DeepAgent) |
|---|---|---|
| 文件操作 | 需要手动定义工具 | 6 个内置工具 |
| 大结果处理 | 上下文溢出风险 | 自动驱逐到存储 |
| 子代理 | 不支持 | 内置 task 工具 |
| 历史管理 | 手动处理 | 自动摘要压缩 |
| 错误恢复 | 需要手动处理 | 自动修复悬空调用 |
Q2: 如何选择存储后端?
推荐使用 CompositeBackend,根据数据类型路由:
# 推荐配置
composite = CompositeBackend({
"/tmp": StateBackend(), # 临时数据
"/knowledge": StoreBackend(), # 永久知识库
"/workspace": FilesystemBackend() # 真实文件
})
Q3: 大结果驱逐的阈值可以调整吗?
当前为固定值 20,000 Token。如需调整, 需要自定义 Harness 配置(高级用法)。
Q4: 子代理会消耗更多成本吗?
会,每个子代理都是独立的模型调用。但由于:
- 子代理上下文隔离,避免主 Agent 上下文膨胀
- 子代理返回压缩结果,节省 Token
- 可以并行执行,提升效率
总体上成本效益更高。
Q5: 人工介入会阻塞 Agent 执行吗?
是的。配置 interrupt_before 的工具调用会暂停执行,
需要调用 agent.resume() 或 agent.cancel() 才能继续。
这是设计行为,用于安全门控。