Deep Agents Architecture Decisions
When to Use Deep Agents
Use Deep Agents When You Need:
- - Long-horizon tasks - Complex workflows spanning dozens of tool calls
- Planning capabilities - Task decomposition before execution
- Filesystem operations - Reading, writing, and editing files
- Subagent delegation - Isolated task execution with separate context windows
- Persistent memory - Long-term storage across conversations
- Human-in-the-loop - Approval gates for sensitive operations
- Context management - Auto-summarization for long conversations
Consider Alternatives When:
| Scenario | Alternative | Why |
|---|
| Single LLM call | Direct API call | Deep Agents overhead not justified |
| Simple RAG pipeline |
LangChain LCEL | Simpler abstraction |
| Custom graph control flow | LangGraph directly | More flexibility |
| No file operations needed |
create_react_agent | Lighter weight |
| Stateless tool use | Function calling | No middleware needed |
Backend Selection
Backend Comparison
| Backend | Persistence | Use Case | Requires |
|---|
| INLINECODE1 | Ephemeral (per-thread) | Working files, temp data | Nothing (default) |
| INLINECODE2 |
Disk | Local development, real files |
root_dir path |
|
StoreBackend | Cross-thread | User preferences, knowledge bases | LangGraph
store |
|
CompositeBackend | Mixed | Hybrid memory patterns | Multiple backends |
Backend Decision Tree
CODEBLOCK0
CompositeBackend Routing
Route different paths to different storage backends:
CODEBLOCK1
Subagent Architecture
When to Use Subagents
Use subagents when:
- - Task is complex, multi-step, and can run independently
- Task requires heavy context that would bloat the main thread
- Multiple independent tasks can run in parallel
- You need isolated execution (sandboxing)
- You only care about the final result, not intermediate steps
Don't use subagents when:
- - Task is trivial (few tool calls)
- You need to see intermediate reasoning
- Splitting adds latency without benefit
- Task depends on main thread state mid-execution
Subagent Patterns
Pattern 1: Parallel Research
CODEBLOCK2
Best for: Research on multiple topics, parallel analysis, batch processing.
Pattern 2: Specialized Agents
CODEBLOCK3
Best for: Domain-specific expertise, different tool sets per task type.
Pattern 3: Pre-compiled Subagents
CODEBLOCK4
Best for: Reusing existing LangGraph graphs, complex custom workflows.
Middleware Architecture
Built-in Middleware Stack
Deep Agents applies middleware in this order:
- 1. TodoListMiddleware - Task planning with
write_todos/ INLINECODE8 - FilesystemMiddleware - File ops:
ls, read_file, write_file, edit_file, glob, grep, INLINECODE15 - SubAgentMiddleware - Delegation via
task tool - SummarizationMiddleware - Auto-summarizes at ~85% context or 170k tokens
- AnthropicPromptCachingMiddleware - Caches system prompts (Anthropic only)
- PatchToolCallsMiddleware - Fixes dangling tool calls from interruptions
- HumanInTheLoopMiddleware - Pauses for approval (if
interrupt_on configured)
Custom Middleware Placement
CODEBLOCK5
Middleware vs Tools Decision
| Need | Use Middleware | Use Tools |
|---|
| Inject system prompt content | ✅ | ❌ |
| Add tools dynamically |
✅ | ❌ |
| Transform requests/responses | ✅ | ❌ |
| Standalone capability | ❌ | ✅ |
| User-invokable action | ❌ | ✅ |
Subagent Middleware Inheritance
Subagents receive their own middleware stack by default:
- - TodoListMiddleware
- FilesystemMiddleware (shared backend)
- SummarizationMiddleware
- AnthropicPromptCachingMiddleware
- PatchToolCallsMiddleware
Override with default_middleware=[] in SubAgentMiddleware or per-subagent middleware key.
Architecture Decision Checklist
Before implementing:
- 1. [ ] Is Deep Agents the right tool? (vs LangGraph directly, vs simpler agent)
- [ ] Backend strategy chosen?
- [ ] Ephemeral only → StateBackend (default)
- [ ] Need disk access → FilesystemBackend
- [ ] Need cross-thread persistence → StoreBackend or CompositeBackend
- 3. [ ] Subagent strategy defined?
- [ ] Which tasks benefit from isolation?
- [ ] Custom subagents with specialized tools/prompts?
- [ ] Parallel execution opportunities identified?
- 4. [ ] Human-in-the-loop points defined?
- [ ] Which tools need approval?
- [ ] Approval flow (approve/edit/reject)?
- 5. [ ] Custom middleware needed?
- [ ] System prompt injection?
- [ ] Request/response transformation?
- 6. [ ] Context management considered?
- [ ] Long conversations → summarization triggers
- [ ] Large file handling → use references
- 7. [ ] Checkpointing strategy? (for persistence/resume)
Deep Agents 架构决策
何时使用 Deep Agents
在以下情况下使用 Deep Agents:
- - 长周期任务 - 跨越数十次工具调用的复杂工作流
- 规划能力 - 执行前的任务分解
- 文件系统操作 - 读取、写入和编辑文件
- 子代理委派 - 使用独立上下文窗口的隔离任务执行
- 持久化记忆 - 跨对话的长期存储
- 人在回路中 - 敏感操作的审批关卡
- 上下文管理 - 长对话的自动摘要
考虑替代方案时:
| 场景 | 替代方案 | 原因 |
|---|
| 单次 LLM 调用 | 直接 API 调用 | Deep Agents 开销不合理 |
| 简单 RAG 流水线 |
LangChain LCEL | 更简单的抽象 |
| 自定义图控制流 | 直接使用 LangGraph | 更灵活 |
| 无需文件操作 | create
reactagent | 更轻量 |
| 无状态工具使用 | 函数调用 | 无需中间件 |
后端选择
后端对比
| 后端 | 持久性 | 使用场景 | 要求 |
|---|
| StateBackend | 临时(每线程) | 工作文件、临时数据 | 无(默认) |
| FilesystemBackend |
磁盘 | 本地开发、真实文件 | root_dir 路径 |
| StoreBackend | 跨线程 | 用户偏好、知识库 | LangGraph store |
| CompositeBackend | 混合 | 混合记忆模式 | 多个后端 |
后端决策树
需要真实磁盘访问?
├─ 是 → FilesystemBackend(root_dir=/path)
└─ 否
└─ 需要跨对话持久化?
├─ 是 → 需要混合临时+持久化?
│ ├─ 是 → CompositeBackend
│ └─ 否 → StoreBackend
└─ 否 → StateBackend(默认)
CompositeBackend 路由
将不同路径路由到不同存储后端:
python
from deepagents import createdeepagent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
agent = createdeepagent(
backend=CompositeBackend(
default=StateBackend(), # 工作文件(临时)
routes={
/memories/: StoreBackend(store=store), # 持久化
/preferences/: StoreBackend(store=store), # 持久化
},
),
)
子代理架构
何时使用子代理
使用子代理时:
- - 任务复杂、多步骤且可独立运行
- 任务需要大量上下文,会膨胀主线程
- 多个独立任务可并行运行
- 需要隔离执行(沙箱化)
- 只关心最终结果,不关心中间步骤
不使用子代理时:
- - 任务简单(少量工具调用)
- 需要查看中间推理过程
- 拆分增加延迟而无收益
- 任务在执行过程中依赖主线程状态
子代理模式
模式 1:并行研究
┌─────────────┐
│ 编排器 │
└──────┬──────┘
┌──────────┼──────────┐
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│任务A │ │任务B │ │任务C │
└──┬───┘ └──┬───┘ └──┬───┘
└──────────┼──────────┘
▼
┌─────────────┐
│ 综合合成 │
└─────────────┘
最适合:多主题研究、并行分析、批量处理。
模式 2:专业化代理
python
research_agent = {
name: 研究员,
description: 对复杂主题进行深度研究,
system_prompt: 你是一位专家研究员...,
tools: [web
search, documentreader],
}
coder_agent = {
name: 编码员,
description: 编写和审查代码,
system_prompt: 你是一位专家程序员...,
tools: [code_executor, linter],
}
agent = createdeepagent(subagents=[researchagent, coderagent])
最适合:领域特定专业知识、按任务类型使用不同工具集。
模式 3:预编译子代理
python
from deepagents import CompiledSubAgent, create
deepagent
使用现有 LangGraph 图作为子代理
custom
graph = createreact_agent(model=..., tools=...)
agent = createdeepagent(
subagents=[CompiledSubAgent(
name=自定义工作流,
description=运行专业化工作流,
runnable=custom_graph
)]
)
最适合:复用现有 LangGraph 图、复杂自定义工作流。
中间件架构
内置中间件栈
Deep Agents 按以下顺序应用中间件:
- 1. TodoListMiddleware - 使用 writetodos/readtodos 进行任务规划
- FilesystemMiddleware - 文件操作:ls、readfile、writefile、editfile、glob、grep、execute
- SubAgentMiddleware - 通过 task 工具进行委派
- SummarizationMiddleware - 在约 85% 上下文或 170k 令牌时自动摘要
- AnthropicPromptCachingMiddleware - 缓存系统提示(仅限 Anthropic)
- PatchToolCallsMiddleware - 修复中断导致的悬空工具调用
- HumanInTheLoopMiddleware - 暂停等待审批(如果配置了 interrupton)
自定义中间件放置
python
from langchain.agents.middleware import AgentMiddleware
class MyMiddleware(AgentMiddleware):
tools = [mycustomtool]
def transform_request(self, request):
# 修改系统提示,注入上下文
return request
def transform_response(self, response):
# 后处理、记录、过滤
return response
自定义中间件添加在内置栈之后
agent = create
deepagent(middleware=[MyMiddleware()])
中间件与工具决策
| 需求 | 使用中间件 | 使用工具 |
|---|
| 注入系统提示内容 | ✅ | ❌ |
| 动态添加工具 |
✅ | ❌ |
| 转换请求/响应 | ✅ | ❌ |
| 独立能力 | ❌ | ✅ |
| 用户可调用的操作 | ❌ | ✅ |
子代理中间件继承
子代理默认接收自己的中间件栈:
- - TodoListMiddleware
- FilesystemMiddleware(共享后端)
- SummarizationMiddleware
- AnthropicPromptCachingMiddleware
- PatchToolCallsMiddleware
可通过 SubAgentMiddleware 中的 default_middleware=[] 或每个子代理的 middleware 键覆盖。
架构决策清单
实施前:
- 1. [ ] Deep Agents 是否是合适的工具?(对比直接使用 LangGraph、更简单的代理)
- [ ] 后端策略是否已选择?
- [ ] 仅临时 → StateBackend(默认)
- [ ] 需要磁盘访问 → FilesystemBackend
- [ ] 需要跨线程持久化 → StoreBackend 或 CompositeBackend
- 3. [ ] 子代理策略是否已定义?
- [ ] 哪些任务受益于隔离?
- [ ] 具有专业化工具/提示的自定义子代理?
- [ ] 是否识别出并行执行机会?
- 4. [ ] 人在回路中的节点是否已定义?
- [ ] 哪些工具需要审批?
- [ ] 审批流程(批准/编辑/拒绝)?
- 5. [ ] 是否需要自定义中间件?
- [ ] 系统提示注入?
- [ ] 请求/响应转换?
- 6. [ ] 是否考虑了上下文管理?
- [ ] 长对话 → 摘要触发
- [ ] 大文件处理 → 使用引用
- 7. [ ] 检查点策略?(用于持久化/恢复)