| name | deepagents-overview |
| description | Understanding Deep Agents framework - what they are, how to create them with create_deep_agent/createDeepAgent, and the agent harness architecture with built-in middleware for planning, filesystems, and subagents. |
| language | python |
deepagents-overview (Python)
What are Deep Agents?
Deep Agents are an opinionated agent framework built on top of LangChain and LangGraph, designed for complex, multi-step tasks. They come "batteries included" with built-in capabilities:
- Task Planning: TodoListMiddleware for breaking down complex tasks
- Context Management: Filesystem tools with pluggable backends
- Task Delegation: SubAgent middleware for spawning specialized agents
- Long-term Memory: Persistent storage across threads via Store
- Human-in-the-loop: Approval workflows for sensitive operations
Deep Agents use an "agent harness" architecture - the same core tool-calling loop as other frameworks, but with pre-configured middleware and tools.
When to Use Deep Agents
| Use Deep Agents When | Use LangChain's create_agent When |
|---|
| Multi-step tasks requiring planning | Simple, single-purpose tasks |
| Large context requiring file management | Context fits in a single prompt |
| Need for specialized subagents | Single agent is sufficient |
| Persistent memory across sessions | Ephemeral, single-session work |
| CLI or coding assistant use cases | Simple API or chat applications |
Creating a Deep Agent
Basic Agent Creation
from deepagents import create_deep_agent
agent = create_deep_agent()
result = agent.invoke({
"messages": [
{"role": "user", "content": "What's the weather in Tokyo?"}
]
})
Agent with Custom Tools
from deepagents import create_deep_agent
from langchain.tools import tool
@tool
def get_weather(city: str) -> str:
"""Get the weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_deep_agent(
tools=[get_weather],
system_prompt="You are a helpful weather assistant"
)
result = agent.invoke({
"messages": [
{"role": "user", "content": "What's the weather in Tokyo?"}
]
})
Agent with Custom Model
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
agent = create_deep_agent(
model="openai:gpt-4"
)
model = ChatOpenAI(model="gpt-4", temperature=0)
agent = create_deep_agent(
model=model
)
The Agent Harness Architecture
Deep Agents automatically attach middleware when created:
from deepagents import create_deep_agent
agent = create_deep_agent()
Built-in Tools
Every deep agent has access to:
- Planning Tool:
write_todos - Track multi-step tasks
- Filesystem Tools:
ls, read_file, write_file, edit_file, glob, grep
- Subagent Tool:
task - Delegate work to specialized agents
Configuration Options
from deepagents import create_deep_agent
from langgraph.checkpoint.memory import MemorySaver
agent = create_deep_agent(
name="my-assistant",
model="claude-sonnet-4-5-20250929",
tools=[custom_tool1, custom_tool2],
system_prompt="Custom instructions",
middleware=[custom_middleware],
subagents=[research_agent, code_agent],
backend=FilesystemBackend(root_dir="."),
interrupt_on={"write_file": True},
skills=["/path/to/skills/"],
checkpointer=MemorySaver(),
store=InMemoryStore()
)
Decision Table: Which Middleware to Customize
| If you need to... | Use this middleware | When to customize |
|---|
| Track complex multi-step tasks | TodoListMiddleware | Default works; customize prompt if needed |
| Manage file context | FilesystemMiddleware | Change backend or tool descriptions |
| Delegate specialized work | SubAgentMiddleware | Add custom subagents with specific tools |
| Prevent context overflow | SummarizationMiddleware | Default works; customize summarization strategy |
| Cache prompts (Anthropic) | AnthropicPromptCachingMiddleware | Default works automatically |
| Add human approval | HumanInTheLoopMiddleware | Configure which tools require approval |
| Load skills on-demand | SkillsMiddleware | Provide skill directories |
| Access persistent memory | MemoryMiddleware | Provide a Store instance |
Boundaries
What Agents CAN Configure
✅ Model selection and parameters
✅ Additional custom tools
✅ System prompt customization
✅ Backend storage strategy
✅ Which tools require approval
✅ Custom subagents with specialized tools
✅ Skill directories and content
✅ Middleware order and configuration
What Agents CANNOT Configure
❌ Core middleware removal (TodoList, Filesystem, SubAgent are always present)
❌ The write_todos, task, or filesystem tool names
❌ The fundamental tool-calling loop
❌ LangGraph's runtime execution model
❌ The Agent Skills protocol format
Gotchas
1. Checkpointer Required for Interrupts
agent = create_deep_agent(
interrupt_on={"write_file": True}
)
from langgraph.checkpoint.memory import MemorySaver
agent = create_deep_agent(
interrupt_on={"write_file": True},
checkpointer=MemorySaver()
)
2. Store Required for Persistent Memory
from deepagents.backends import StoreBackend
agent = create_deep_agent(
backend=lambda rt: StoreBackend(rt)
)
from langgraph.store.memory import InMemoryStore
agent = create_deep_agent(
backend=lambda rt: StoreBackend(rt),
store=InMemoryStore()
)
3. Skills Require Backend Setup
agent = create_deep_agent(
skills=["/path/to/skills/"]
)
from deepagents.backends import FilesystemBackend
agent = create_deep_agent(
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
skills=["./skills/"]
)
4. Thread ID Required for Stateful Conversations
agent.invoke({"messages": [{"role": "user", "content": "Hi"}]})
agent.invoke({"messages": [{"role": "user", "content": "What did I say?"}]})
config = {"configurable": {"thread_id": "user-123"}}
agent.invoke({"messages": [{"role": "user", "content": "Hi"}]}, config=config)
agent.invoke({"messages": [{"role": "user", "content": "What did I say?"}]}, config=config)
5. Default Model is Anthropic Claude
agent = create_deep_agent()
import os
os.environ["ANTHROPIC_API_KEY"] = "your-key"
Full Documentation