deepagents-integration
deepagents framework integration patterns for agent creation, planning, filesystem operations, and subagent orchestration. Current version 0.2.5 with LangGraph 1.0.2+
When & Why to Use This Skill
This Claude skill provides expert integration patterns for the deepagents framework, enabling developers to build sophisticated AI agents with advanced planning, secure filesystem operations, and hierarchical subagent orchestration. It leverages LangGraph and LangChain to facilitate complex task decomposition and multi-agent coordination for enterprise-grade AI applications.
Use Cases
- Hierarchical Agent Orchestration: Creating a main coordinator agent that delegates specialized tasks to subagents (e.g., researchers, coders, or validators) while managing context isolation.
- Complex Task Planning: Implementing a robust planning system using the 'write_todos' pattern to decompose multi-step operations into actionable, trackable subtasks.
- Secure Filesystem Operations: Enabling agents to read, write, and list files within a restricted workspace using built-in security middleware that prevents path traversal attacks.
- MCP Server Integration: Extending agent capabilities by integrating Model Context Protocol (MCP) servers for browser automation, external memory, and advanced tool usage.
- Dynamic Platform Integration: Building scalable agent services that instantiate agents from database configurations and track execution states with persistent thread IDs.
| name | deepagents-integration |
|---|---|
| description | deepagents framework integration patterns for agent creation, planning, filesystem operations, and subagent orchestration. Current version 0.2.5 with LangGraph 1.0.2+ |
| keywords | ["deepagents", "DeepAgent", "langgraph", "planning", "write_todos", "subagent", "agent creation", "filesystem middleware", "mcp servers"] |
| file_patterns | ["**/deepagents_integration/**/*.py", "**/services/*_service.py", "**/api/v1/agents.py"] |
| context | ["creating AI agents", "agent configuration", "deepagents setup", "planning system", "agent orchestration"] |
deepagents Integration Skill
Expert patterns for integrating the deepagents framework (v0.2.5+) with LangGraph 1.0.2+ and LangChain 1.0.3+ for the DeepAgents Control Platform.
🎯 When to Use This Skill
Auto-activates when:
- Keywords mentioned:
deepagents,DeepAgent,langgraph,planning,subagent,write_todos - Working with files:
backend/deepagents_integration/,services/agent_service.py,api/v1/agents.py - Tasks: agent creation, planning configuration, filesystem operations, subagent orchestration
NOT for:
- FastAPI routing/dependencies → use
fastapi-patternsskill - Frontend components → use
react-enterpriseskill - Database models → use
fastapi-patternsskill (includes SQLAlchemy)
⚡ Quick Reference
Top 10 Essential Patterns
# 1. Simple Agent Creation (2025 API)
from deepagents import DeepAgent
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
planning=True,
filesystem=True,
system_prompt="You are an expert assistant..."
)
# 2. Async Agent Creation (for MCP servers)
from deepagents import async_create_deep_agent
agent = await async_create_deep_agent(
model="claude-sonnet-4-5-20250929",
mcp_servers=["playwright", "memory"],
planning=True
)
# 3. Execute Agent with Config
result = await agent.ainvoke(
"Your task here",
config={"configurable": {"thread_id": "session_123"}}
)
# 4. LangGraph State (TypedDict + Annotated)
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage
class AgentState(TypedDict):
messages: Annotated[list[BaseMessage], add_messages]
todos: Annotated[list[dict], lambda x, y: y] # Replace strategy
context: dict
# 5. Custom Tool Definition
from langchain_core.tools import tool
from pydantic import BaseModel, Field
class AnalysisInput(BaseModel):
query: str = Field(description="Analysis query")
@tool(args_schema=AnalysisInput)
def analyze_data(query: str) -> str:
"""Analyze data based on query."""
return f"Analysis result for: {query}"
# 6. Agent with Custom Tools
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
tools=[analyze_data],
planning=True
)
# 7. Subagent Creation
main_agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
subagents=[
Subagent(
name="researcher",
model="claude-haiku-4-20250508",
system_prompt="Research specialist",
tools=[search_tool]
)
]
)
# 8. File Operations (Security Built-in)
# ✅ Allowed - relative paths only
agent.file_read("data/report.txt")
agent.file_write("output/results.json", content)
# ❌ Blocked - path traversal prevention
agent.file_read("../../../etc/passwd") # Raises error
# 9. Planning Prompt Structure
system_prompt = """
You are a planning expert. Use write_todos for complex tasks.
## Planning Guidelines:
- Use write_todos for tasks requiring > 3 steps
- Create dependencies between tasks
- Update status: pending → in_progress → completed
"""
# 10. Error Handling Pattern
try:
result = await agent.ainvoke(task, config=config)
except Exception as e:
logger.error(f"Agent execution failed: {e}")
# Save partial results if available
await save_execution_state(agent.state)
📁 Project Structure
backend/
├── deepagents_integration/ # deepagents framework integration
│ ├── __init__.py
│ ├── factory.py # Agent creation from DB configs
│ ├── executor.py # Agent execution management
│ └── tools/ # Custom tool definitions
│ ├── __init__.py
│ ├── file_tools.py # File operation tools
│ └── data_tools.py # Data analysis tools
├── api/v1/
│ ├── agents.py # Agent CRUD endpoints
│ └── executions.py # Agent execution endpoints
├── services/
│ ├── agent_service.py # Agent business logic
│ └── execution_service.py # Execution tracking
├── models/
│ ├── agent.py # Agent SQLAlchemy model
│ └── execution.py # Execution SQLAlchemy model
└── schemas/
├── agent.py # Agent Pydantic schemas
└── execution.py # Execution Pydantic schemas
🔧 Core Patterns
1. Agent Creation Pattern (2025 API)
Use case: Creating agents from platform configuration
from deepagents import DeepAgent, Subagent
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
from langchain_core.messages import BaseMessage
# Type-safe state definition
class AgentState(TypedDict):
"""Agent state with type safety and reducers."""
messages: Annotated[list[BaseMessage], add_messages]
todos: Annotated[list[dict], lambda x, y: y] # Replace strategy
context: dict
error: str | None
# ✅ CORRECT: Agent with all features
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
planning=True, # Enables write_todos tool
filesystem=True, # Enables file_read/write/list
system_prompt="Expert assistant with planning capabilities",
state_schema=AgentState, # Type-safe state
temperature=0.7,
max_tokens=4096
)
# ❌ WRONG: Missing state_schema for complex state
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
# Missing state_schema - will use default MessagesState only
)
# 🔒 Security: Built-in path traversal prevention
# File operations automatically restricted to workspace
Troubleshooting:
- Error: "Model not found" → Check
ANTHROPIC_API_KEYorOPENAI_API_KEYenvironment variable - Planning not working → Ensure
planning=Trueand system prompt mentionswrite_todos - State not persisting → Add
config={"configurable": {"thread_id": "unique_id"}}
2. Planning System (write_todos)
Use case: Task decomposition for complex multi-step operations
# System prompt for planning-enabled agents
planning_prompt = """
You are an expert assistant with planning capabilities.
## When to Plan:
- Tasks requiring > 3 steps → use write_todos
- Complex workflows → break down into subtasks
- Long-running operations → track progress with todos
## Planning Structure:
{
"todos": [
{
"description": "Specific, actionable task",
"status": "pending", // or "in_progress", "completed"
"dependencies": [], // Array of task indices
"priority": "high" // Optional: high, medium, low
}
]
}
## Planning Best Practices:
1. Create clear, specific task descriptions
2. Use dependencies for sequential tasks
3. Update status as you progress
4. Revise plan when discovering new requirements
"""
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
planning=True, # Adds write_todos tool automatically
system_prompt=planning_prompt
)
# Agent will automatically use write_todos like this:
# {
# "tool": "write_todos",
# "input": {
# "todos": [
# {"description": "Analyze requirements", "status": "pending", "dependencies": []},
# {"description": "Design solution", "status": "pending", "dependencies": [0]},
# {"description": "Implement code", "status": "pending", "dependencies": [1]}
# ]
# }
# }
# ❌ WRONG: Vague todo descriptions
# {"description": "Do the thing"} # Too vague
# ✅ CORRECT: Specific todo descriptions
# {"description": "Extract user data from PostgreSQL users table"}
Troubleshooting:
- Todos not created → Check that
planning=Trueis set - Agent ignores todos → Add explicit planning instructions to system prompt
- Circular dependencies → Validate dependency graph before execution
3. Filesystem Middleware (Security-Enhanced)
Use case: File operations with built-in security
from deepagents import DeepAgent
# ✅ CORRECT: Enable filesystem with security
agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929",
filesystem=True, # Enables: file_read, file_write, file_list
system_prompt="Assistant with file access capabilities"
)
# Built-in tools when filesystem=True:
# - file_read(path: str) -> str
# - file_write(path: str, content: str) -> str
# - file_list(path: str) -> list[str]
# - file_delete(path: str) -> str # Optional, disabled by default
# 🔒 Security: Automatic path traversal prevention
# ✅ Allowed
agent.file_read("data/report.txt")
agent.file_read("./output/results.json")
# ❌ Blocked (raises SecurityError)
agent.file_read("../../../etc/passwd")
agent.file_read("/etc/hosts")
# Use case: Large file chunked reading
chunked_prompt = """
When reading large files:
1. Use file_list to check file size
2. Read in chunks if > 50KB
3. Process incrementally to avoid context overflow
"""
# Use case: Context offloading
offloading_prompt = """
For data exceeding token limits:
1. Analyze data incrementally
2. Write intermediate results to files
3. Provide summary in final response
Example:
- file_write("analysis_part1.json", results_1)
- file_write("analysis_part2.json", results_2)
- file_write("summary.txt", final_summary)
"""
Troubleshooting:
- Permission denied → Check file/directory permissions in filesystem
- Path traversal error → Use relative paths only (no
../or absolute paths) - File too large → Implement chunked reading pattern (see above)
Security Best Practices:
- ✅ Always use relative paths
- ✅ Validate file extensions if needed
- ✅ Set size limits for file operations
- ❌ Never expose sensitive system paths
4. Subagent Orchestration
Use case: Hierarchical agent systems with specialized subagents
from deepagents import DeepAgent, Subagent
# ✅ CORRECT: Main coordinator with specialized subagents
main_agent = DeepAgent.create(
model="claude-sonnet-4-5-20250929", # Powerful model for coordination
planning=True,
system_prompt="You coordinate specialized subagents for complex tasks",
subagents=[
Subagent(
name="researcher",
model="claude-haiku-4-20250508", # Fast, cost-effective
system_prompt="Research specialist - find and summarize information",
tools=[search_tool, web_scraper_tool],
context_isolation=False # Shares context with main agent
),
Subagent(
name="coder",
model="claude-sonnet-4-5-20250929", # Powerful for coding
system_prompt="Code generation specialist",
tools=[code_analyzer_tool],
context_isolation=True # Isolated context for security
),
Subagent(
name="validator",
model="claude-haiku-4-20250508",
system_prompt="Validate outputs for quality and correctness",
context_isolation=False
)
]
)
# Subagent delegation happens automatically based on task
result = await main_agent.ainvoke(
"Research Python best practices and generate example code"
)
# Main agent will:
# 1. Delegate research to "researcher" subagent
# 2. Delegate coding to "coder" subagent
# 3. Delegate validation to "validator" subagent
# ❌ WRONG: Using expensive model for simple tasks
Subagent(
name="simple_formatter",
model="claude-opus-4-20250514", # Overkill for formatting
system_prompt="Format text"
)
# ✅ CORRECT: Match model to task complexity
Subagent(
name="formatter",
model="claude-haiku-4-20250508", # Cost-effective for simple tasks
system_prompt="Format text output"
)
# 🔒 Security: Context isolation for sensitive operations
Subagent(
name="data_processor",
model="claude-sonnet-4-5-20250929",
tools=[database_tool],
context_isolation=True, # Prevents context leakage
system_prompt="Process sensitive user data"
)
Troubleshooting:
- Subagent not invoked → Ensure main agent's prompt mentions delegation
- Context not shared → Set
context_isolation=Falseif context sharing is needed - High costs → Use Haiku for simple subagents, Sonnet/Opus for complex ones
5. Platform Integration (DeepAgents Control Platform)
Use case: Creating agents from database configurations
# services/agent_service.py
from deepagents import DeepAgent, Subagent
from models.agent import Agent
from models.tool import Tool
from sqlalchemy.ext.asyncio import AsyncSession
class DeepAgentsFactory:
"""Factory for creating deepagents from platform configurations."""
@staticmethod
async def create_from_config(
db: AsyncSession,
agent_config: Agent
) -> DeepAgent:
"""
Create DeepAgent from database configuration.
Args:
db: Database session
agent_config: Agent model from database
Returns:
Configured DeepAgent instance
"""
# Load custom tools
tools = await db.scalars(
select(Tool).where(Tool.id.in_(agent_config.tool_ids))
)
custom_tools = [tool.to_langchain_tool() for tool in tools]
# Load subagents
subagents = []
for subagent_config in agent_config.subagents:
subagent = Subagent(
name=subagent_config.name,
model=subagent_config.model_name,
system_prompt=subagent_config.system_prompt,
context_isolation=subagent_config.context_isolation
)
subagents.append(subagent)
# Create agent
agent = DeepAgent.create(
model=agent_config.model_name,
planning=agent_config.planning_enabled,
filesystem=agent_config.filesystem_enabled,
system_prompt=agent_config.system_prompt,
tools=custom_tools,
subagents=subagents,
temperature=agent_config.temperature,
max_tokens=agent_config.max_tokens
)
return agent
# services/execution_service.py
from models.execution import Execution
from schemas.execution import ExecutionCreate
class AgentExecutionService:
"""Manage agent execution with tracking and tracing."""
async def execute_agent(
self,
db: AsyncSession,
agent_id: int,
task: str,
user_id: int
) -> dict:
"""
Execute agent and track execution.
Args:
db: Database session
agent_id: Agent ID from database
task: Task description
user_id: User ID initiating execution
Returns:
Execution result with metadata
"""
# Load agent config
agent_config = await db.get(Agent, agent_id)
# Create execution record
execution = Execution(
agent_id=agent_id,
user_id=user_id,
input_text=task,
status="pending"
)
db.add(execution)
await db.commit()
try:
# Create agent instance
agent = await DeepAgentsFactory.create_from_config(db, agent_config)
# Execute with thread ID for state persistence
config = {
"configurable": {
"thread_id": f"execution_{execution.id}"
}
}
execution.status = "running"
await db.commit()
result = await agent.ainvoke(task, config=config)
# Update execution record
execution.status = "completed"
execution.output_text = result.get("output", "")
execution.token_usage = result.get("token_usage", {})
execution.execution_time = result.get("execution_time", 0)
except Exception as e:
execution.status = "failed"
execution.error_message = str(e)
raise
finally:
await db.commit()
return {
"execution_id": execution.id,
"status": execution.status,
"result": execution.output_text
}
Troubleshooting:
- Agent not persisting state → Ensure unique
thread_idper execution - Tools not loading → Verify
tool.to_langchain_tool()method exists - High memory usage → Implement agent instance pooling
🔗 Custom Tool Development
Use case: Creating domain-specific tools for agents
from langchain_core.tools import tool
from pydantic import BaseModel, Field
import httpx
# ✅ CORRECT: Tool with Pydantic schema validation
class DatabaseQueryInput(BaseModel):
"""Input schema for database queries."""
query: str = Field(description="SQL query to execute")
limit: int = Field(default=100, ge=1, le=1000, description="Result limit")
@tool(args_schema=DatabaseQueryInput)
async def query_database(query: str, limit: int = 100) -> str:
"""
Execute database query with safety checks.
Args:
query: SQL query (SELECT only)
limit: Maximum rows to return
Returns:
JSON-formatted query results
Security:
- Only SELECT queries allowed
- Query timeout: 30 seconds
- Result limit enforced
"""
# 🔒 Security: Validate query type
if not query.strip().upper().startswith("SELECT"):
raise ValueError("Only SELECT queries allowed")
# Execute with timeout and limit
# ... implementation ...
return json.dumps(results)
# ❌ WRONG: No input validation
@tool
def unsafe_query(query): # No type hints, no validation
return execute_sql(query) # SQL injection risk!
# ✅ CORRECT: Async tool with error handling
@tool(args_schema=AnalysisInput)
async def fetch_external_data(url: str) -> str:
"""Fetch data from external API with timeout."""
async with httpx.AsyncClient(timeout=10.0) as client:
try:
response = await client.get(url)
response.raise_for_status()
return response.text
except httpx.TimeoutException:
return "Error: Request timed out"
except httpx.HTTPError as e:
return f"Error: {str(e)}"
Security Best Practices:
- ✅ Always use Pydantic schemas for input validation
- ✅ Set timeouts for external operations
- ✅ Validate and sanitize all inputs
- ✅ Use async for I/O operations
- ❌ Never execute arbitrary code from tool inputs
- ❌ Don't expose sensitive credentials in tool outputs
📊 MCP Server Integration
Use case: Using Model Context Protocol servers
from deepagents import async_create_deep_agent
# Async creation required for MCP servers
agent = await async_create_deep_agent(
model="claude-sonnet-4-5-20250929",
mcp_servers=["playwright", "memory", "filesystem"], # MCP server names
planning=True,
system_prompt="Assistant with browser automation and memory capabilities"
)
# MCP servers provide additional tools:
# - playwright: Browser automation (navigate, click, screenshot, etc.)
# - memory: Knowledge graph operations
# - filesystem: Enhanced file operations
# ❌ WRONG: Using sync creation with MCP servers
agent = DeepAgent.create( # Won't work with MCP!
mcp_servers=["playwright"]
)
# ✅ CORRECT: Async creation
agent = await async_create_deep_agent(
mcp_servers=["playwright"]
)
Troubleshooting:
- MCP server not found → Check MCP server configuration in environment
- Async context error → Use
await async_create_deep_agent, notDeepAgent.create - Tools not available → Verify MCP server is running and accessible
🎯 Best Practices Summary
DO ✅
- Use
async_create_deep_agentfor MCP server integration - Set
planning=Truefor multi-step tasks - Use
TypedDictwithAnnotatedfor complex state - Match model to task complexity (Haiku for simple, Sonnet/Opus for complex)
- Implement error handling and execution tracking
- Use
thread_idfor state persistence across conversations - Validate all tool inputs with Pydantic schemas
- Set timeouts for external operations
DON'T ❌
- Don't use absolute paths in filesystem operations
- Don't skip input validation in custom tools
- Don't use expensive models for simple subagents
- Don't ignore error handling in agent execution
- Don't expose sensitive data in tool outputs
- Don't create agents without proper configuration tracking
📚 See Also
- reference.md - Complete deepagents API documentation
- examples.md - Full working examples and use cases
- fastapi-patterns - Backend integration patterns
- react-enterprise - Frontend agent management UI