Last month, I was building an automated research pipeline for my team. The idea was simple: give the system a topic, have it search for information, synthesize findings, and produce a structured report. I started with a basic ReAct agent, and it worked fine for simple queries. But the moment I gave it something like "Compare the regulatory approaches to AI governance in the EU, US, and China," everything fell apart. The agent would lose track of what it had already researched, run out of context window halfway through, and produce reports that contradicted themselves across sections.
I kept running into the same three walls: context management for long tasks, the inability to break down complex objectives into trackable steps, and no way to parallelize independent research threads. That's when I stumbled across Deep Agents from LangChain. It's an open-source agent harness specifically built for long-running, complex tasks—and it handles planning, context management, and multi-agent orchestration out of the box. After spending a couple of weekends with it, here's what I learned.
What Deep Agents Actually Gives You
Deep Agents isn't just another agent wrapper. It's a harness with three core primitives that address exactly the problems I was hitting:
- Planning tools that let agents decompose tasks, track progress, and adapt as they learn
- Subagents that can be spawned for independent subtasks, each with isolated context
- A virtual filesystem that persists knowledge, system prompts, skills, and long-term memory across sessions
The context management piece is the real differentiator. The harness includes middleware that compresses conversation history, offloads large tool results, isolates context with subagents, and uses prompt caching to reduce latency and cost. For long-running tasks, this is the difference between an agent that works and one that crashes into context limits.
Step 1: Installation
I went with uv because I like isolated project environments, but pip works just as well:
# Using uv
uv init
uv add deepagents tavily-python
uv sync
# Or using pip
pip install deepagents tavily-python
You'll need a search provider for the research agent. The docs use Tavily as the default, but you can swap in DuckDuckGo, SerpAPI, or Brave Search. I stuck with Tavily since it's designed for agent use cases and returns cleaner results.
Step 2: Set Up API Keys
Deep Agents is model-neutral—it works with any LangChain chat model that supports tool calling. I used Anthropic's Claude, but you can use Google Gemini, OpenAI, OpenRouter, Fireworks, Baseten, or even Ollama for local inference.
export ANTHROPIC_API_KEY="your-api-key"
export TAVILY_API_KEY="your-tavily-api-key"
One thing that caught me off guard: the model must support tool calling. I initially tried pointing it at an older local model via Ollama that didn't support function calling, and the agent just silently failed to use any tools. Check your model's capabilities before you start debugging.
Step 3: Create a Search Tool
Here's where we wire up the search capability. The Tavily integration is straightforward:
import os
from typing import List
from langchain_community.tools.tavily_search import TavilySearchResults
def create_search_tool():
"""Create a web search tool using Tavily."""
search = TavilySearchResults(
max_results=5,
tavily_api_key=os.environ["TAVILY_API_KEY"],
)
return search
search_tool = create_search_tool()
If you want to use a different provider, you just need to wrap it in a tool interface that Deep Agents can call. The key is that whatever tool you create needs to return structured results the agent can parse.
Step 4: Build the Research Agent
Now for the main event. Deep Agents provides a create_deep_agent function that wires together the planning, filesystem, and subagent capabilities:
from deepagents import create_deep_agent
# Create the deep agent with research capabilities
agent = create_deep_agent(
tools=[search_tool],
prompt="""You are a thorough research agent. When given a research topic:
1. Break the topic into sub-questions using the planning tool
2. Research each sub-question systematically
3. Store findings in the virtual filesystem as you go
4. Synthesize all findings into a coherent report
5. Write the final report to the filesystem
Always track your progress using the plan. Update the plan as you
discover new information or need to adjust your approach.""",
)
# Run the agent on a research task
result = agent.invoke({
"messages": [{"role": "user", "content": "Research the current state of quantum computing and write a 2000-word report covering hardware approaches, key milestones, and near-term applications."}]
})
The first time I ran this, I was surprised by how differently it behaved compared to a basic ReAct agent. Instead of immediately jumping into searches, it first created a plan with sub-questions. Then it worked through each one, storing intermediate findings in the virtual filesystem. When it found something that changed its understanding, it went back and updated the plan.
Step 5: Understanding What Happens Under the Hood
Let me walk through what actually happens when you run that agent, because understanding the flow helps when things go wrong.
Planning phase: The agent receives the task and uses the planning tool to decompose it. For my quantum computing example, it created sub-questions like "What are the main hardware approaches to quantum computing?", "What milestones have been achieved in 2024?", and "What near-term applications are being explored?"
Research phase: For each sub-question, the agent searches, reads results, and stores summaries in the virtual filesystem. This is where the context management middleware kicks in—large search results get offloaded so they don't eat up the context window.
Subagent spawning: For truly independent subtasks, the agent can spawn subagents. Each subagent gets its own isolated context, which means they can work in parallel without stepping on each other's findings. This was the game-changer for my multi-country regulatory comparison—the agent spawned separate subagents for EU, US, and China research.
Synthesis phase: Finally, the agent reads back all the stored findings and synthesizes them into a coherent report, writing it to the filesystem.
Real Results and Surprises
I ran the quantum computing research task, and the output was genuinely impressive. The report was well-structured, covered all the angles the agent had planned, and—most importantly—was internally consistent. No more contradicting itself across sections.
But there were surprises along the way:
Surprise #1: The agent sometimes over-plans. On simpler tasks, it would still create elaborate plans when a direct approach would have been faster. I learned to adjust the prompt to tell it to "plan only when the task has multiple distinct sub-questions."
Surprise #2: Subagent context isolation is a double-edged sword. When subagents work in isolation, they can't share discoveries in real-time. If one subagent finds information that would change another subagent's approach, there's no mechanism for that mid-research. The agent handles this at the synthesis phase, but it means some work might be redundant.
Surprise #3: Cost adds up fast. Long-running agents with planning, multiple search calls, and subagent spawning burn through tokens quickly. My quantum computing research task cost about $0.85 with Claude. That's reasonable for a one-off, but if you're running these in production at scale, pay attention to costs.
Using the CLI
One thing I didn't expect is that Deep Agents also comes with a CLI. If you just want to run an agent from your terminal without writing Python:
deepagents run "Research the environmental impact of lithium mining"
This is handy for quick tasks or testing, but for anything production-grade, you'll want the SDK for control over tools, prompts, and configuration.
Practical Tips
After a few weeks of working with Deep Agents, here's what I'd recommend:
Be specific in your prompts about when to plan. Without guidance, the agent will plan everything. Tell it "Plan for tasks with 3+ distinct sub-questions; handle simple questions directly."
Use the filesystem actively. Encourage the agent to store intermediate findings. This is what makes long-running tasks possible without context overflow.
Set max iterations. Without a cap, a determined agent can loop for a very long time. Set a reasonable limit based on your task complexity.
Check your model's tool calling support. This is the most common silent failure mode. If your model doesn't support tool calling, the agent will just... not use tools, and you'll get garbage output.
Monitor with LangSmith. Deep Agents integrates natively with LangSmith for tracing. Turn it on from the start—debugging a long agent run without traces is a nightmare.
Honest Limitations
Deep Agents isn't perfect. The planning can be rigid—once the agent creates a plan, it follows it even if early findings suggest a different approach would be better. The subagent model works well for independent tasks but struggles when subtasks have dependencies. And the virtual filesystem, while essential for context management, adds complexity that can make debugging harder.
For simple tasks—single questions, short conversations, straightforward tool use—Deep Agents is overkill. A basic ReAct agent will be faster and cheaper. Deep Agents shines when you have genuinely complex, multi-step work that requires tracking progress over time.
The framework is also relatively new, and I hit a few rough edges. The documentation covers the happy path well, but when things go wrong, you'll find yourself reading source code. The error messages could be more helpful, especially around tool calling failures.
That said, for the specific problem I had—long-running research tasks that need planning, context management, and parallel execution—Deep Agents is the first framework I've used that actually handles it without me having to build all that infrastructure myself. It's not a silver bullet, but it's a solid step forward for agents that need to do real work over extended time horizons.