Module 11: Deep Agents

Introduction: The Highest Level of Abstraction

Overview

You've reached Module 11. Across this guide you built everything by hand: tools from scratch (M2), agents with ReAct loops (M3), graphs with nodes and edges (M5-M7), persistence with checkpointers (M8), interrupts for human oversight (M9), and multi-agent systems with supervisors, handoffs, and subagents (M10). You understand the guts of every piece because you assembled them yourself.

Now you're going to see what happens when someone packages all of that into a framework that does it for you.

Deep Agents is the highest layer of abstraction in the LangChain ecosystem. It's a harness that includes automatic planning (write_todos), a virtual filesystem for reading and writing files, subagent spawning to delegate tasks on demand, and long-term memory with swappable backends — all out of the box, without you having to build the infrastructure.

The value of this module isn't learning "the right way." Deep Agents is not better than LangGraph — it's more convenient for certain use cases and less configurable for others. The value is that you now have the judgment to choose: you already know what each piece does under the hood, so you can evaluate when it pays off to let the framework handle it and when you need manual control.


Where are we in the guide?

This is Module 11 of the guide LangChain & LangGraph: From Chains to Agents. It's the first module of Block 4 (Production).

Block 1: LangChain Core (Modules 1-4)           ✅ Complete
Block 2: LangGraph Fundamentals (Modules 5-7)   ✅ Complete
Block 3: Advanced LangGraph (Modules 8-10)      ✅ Complete
Block 4: Production (Modules 11-12)              ← YOU ARE HERE (Module 11)
Your progress:

Block 1 — LangChain Core                    ✅ Complete
    │
    │  Module 1: Models and Providers        ✅
    │  Module 2: Tools and Tool Calling      ✅
    │  Module 3: Agents (create_agent)       ✅
    │  Module 4: Middleware and Customization ✅
    │
    ▼
Block 2 — LangGraph Fundamentals            ✅ Complete
    │
    │  Module 5: Introduction to LangGraph   ✅
    │  Module 6: Functional API              ✅
    │  Module 7: Advanced Flows              ✅
    │
    ▼
Block 3 — Advanced LangGraph                ✅ Complete
    │
    │  Module 8: Memory and Persistence      ✅
    │  Module 9: Human-in-the-Loop           ✅
    │  Module 10: Multi-Agent Systems        ✅
    │
    ▼
Block 4 — Production
    │
    │  Module 11: Deep Agents                ← YOU ARE HERE
    │  Module 12: LangSmith and Production   🔒 Next

Block 3 gave you the advanced capabilities: persistence, human oversight, and multi-agent. Block 4 takes you to production: first with the batteries-included layer (this module), then with observability and deployment (M12).


The three levels of abstraction

Everything you learned in this guide organizes into three levels. Understanding these levels is the most important decision framework you take away from this module.

Level 1: create_agent — simple, 80% of cases

from langchain.agents import create_agent

agent = create_agent(
    "openai:gpt-4.1-mini",
    tools=[web_search, calculator],
    prompt="You are a research assistant.",
)

result = agent.invoke({"messages": [{"role": "user", "content": "What is 2+2?"}]})
  • ✅ One function, done
  • ✅ Automatic tool calling with a ReAct loop
  • ✅ Enough for chatbots, simple assistants, Q&A
  • ❌ No control over the decision flow
  • ❌ No built-in persistence (you need to add a checkpointer)
  • ❌ No multi-agent

Level 2: LangGraph — custom workflows, full control

from langgraph.graph import StateGraph, START, END

builder = StateGraph(ResearchState)
builder.add_node("search", search_node)
builder.add_node("analyze", analyze_node)
builder.add_node("report", report_node)
builder.add_edge(START, "search")
builder.add_conditional_edges("search", route_by_quality)
builder.add_edge("analyze", "report")
builder.add_edge("report", END)

graph = builder.compile(checkpointer=MemorySaver())
  • ✅ Full control over nodes, edges, and flow
  • ✅ Persistence, HITL, multi-agent — all configurable
  • ✅ Retry, branching, error handling built to your spec
  • ❌ More code: you design every decision
  • ❌ Planning, filesystem, subagent spawning — you build them by hand

Level 3: Deep Agents — autonomous, batteries-included

from deep_agents import create_deep_agent

agent = create_deep_agent(
    "openai:gpt-4.1",
    tools=[web_search],
    name="Research Assistant",
    instructions="Research complex topics. Break the task down into steps, "
                 "write the results to files, and delegate subtasks "
                 "to specialized subagents when needed.",
)

result = agent.run("Research the state of AI safety in 2025 and generate a report")
  • ✅ Automatic planning: the agent breaks tasks down with write_todos
  • ✅ Virtual filesystem: writes and reads files without filling the context window
  • ✅ Subagent spawning: creates specialized agents on demand
  • ✅ Long-term memory with swappable backends
  • ❌ Less control: the framework decides much of the flow
  • ❌ More opaque: you don't see every decision in the graph
  • ❌ Overhead for simple tasks

The metaphor

Level 1 — create_agent:    Driving an automatic car
                            Simple, fast, works for 80% of trips

Level 2 — LangGraph:       Driving a stick shift
                            More control, better for specific situations,
                            takes more skill

Level 3 — Deep Agents:     Getting into a self-driving taxi
                            You give it the destination, it picks the route, the
                            detours, and the stops. You arrive. But you're not
                            holding the wheel.

The question isn't "which one is better?" — it's "which one do I need for this task?"


The bridge: from manual to batteries-included

What you built by hand

Across modules 6-10, your Research Assistant grew piece by piece:

M6:  Research Agent v1 — basic search with the Functional API
M7:  Research Agent v2 — retry, branching, error handling
M8:  Research Agent v3 — checkpointing, crash recovery, memory
M9:  Research Agent v4 — HITL, approvals before expensive actions
M10: Research Agent v5 — multi-agent with a supervisor and subagents

Every version added a capability you had to design and implement: you wrote the retry with backoff, you configured persistence, you orchestrated the subagents. Roughly 150+ lines of code for the full system.

What Deep Agents provides out of the box

Deep Agents takes those same capabilities and packages them:

CapabilityWhat you builtWhat Deep Agents provides
PlanningYou designed the workflow in M6-M10: which node follows which, what conditions to evaluatewrite_todos: the agent breaks the task down on its own, tracks progress, re-plans
PersistenceYou configured checkpointers in M8: MemorySaver, PostgresSaver, thread_idVirtual filesystem: the agent writes outputs to files, reads only what it needs
Multi-agentYou implemented supervisor, handoffs, subagents in M10Subagent spawning: the agent decides when and what to delegate at runtime
MemoryInMemoryStore, namespaces, cross-session in M8Long-term memory with pluggable backends (filesystem, LangGraph Store)

The mapping is direct:

  • write_todos abstracts the planning you did in M6-M10 — instead of designing the workflow, the agent designs it itself
  • The virtual filesystem abstracts the persistence from M8 — instead of configuring checkpointers, the agent writes to files
  • Subagent spawning abstracts the multi-agent work from M10 — instead of designing who does what at build time, the agent decides at runtime

That's the reason this module comes after 10 modules of manual construction. Without having built each piece, you couldn't evaluate what you gain and what you lose when the framework does it for you.


When to use Deep Agents

Ideal cases

  • Long-running tasks: research that takes minutes, multi-source report generation, complex analyses that require multiple steps
  • Autonomous research: the agent needs to plan, search, analyze, and synthesize without constant supervision
  • Code generation: projects where the agent writes multiple files, tests them, and fixes them
  • Complex analyses: comparisons, due diligence, market research where there are multiple dimensions to explore
  • Fast prototypes: you want a working autonomous agent without building the whole infrastructure

When NOT to use Deep Agents

  • Simple Q&A: question-answer doesn't need planning or a filesystem — use create_agent
  • Fine-grained control needed: if you need to decide exactly which node runs at each step — use LangGraph
  • Custom workflows: flows with specific business rules, approvals at exact points — use LangGraph
  • Latency sensitive: Deep Agents has planning overhead; if you need answers in under 2s — use create_agent
  • Tight budget: planning and subagent spawning mean more LLM calls = more cost

Decision tree

Is your task simple (Q&A, direct search)?
  └─ YES → create_agent
  └─ NO ↓

Do you need full control over the decision flow?
  └─ YES → LangGraph (StateGraph or Functional API)
  └─ NO ↓

Is the task autonomous, long-running, multi-step?
  └─ YES → Deep Agents
  └─ NO → LangGraph (more flexible, no overhead)

What Deep Agents includes

1. Planning with write_todos

The agent receives a complex task — "Research AI safety and generate a report" — and breaks it into manageable steps:

1. [pending]     Define the scope of the research
2. [pending]     Search for recent academic papers
3. [pending]     Search for industry reports
4. [pending]     Analyze and synthesize findings
5. [pending]     Generate the final report

As it goes, it updates its progress. If it discovers something unexpected, it re-plans: adds, removes, or reorders steps. Capsule 02 covers this in detail.

2. Virtual Filesystem

Instead of stuffing the entire research effort into the context window (expensive, capped at 128K tokens), the agent writes outputs to files:

workspace/
├── research/
│   ├── papers.md          ← Academic search results
│   └── industry_reports.md ← Industry reports
├── analysis/
│   └── synthesis.md       ← Cross-source analysis
└── output/
    └── report.md          ← Final report

The context window stays lean: the agent reads only the file it needs for the current step. Capsule 03 covers this in detail.

3. Subagent Spawning

The main agent can create specialized subagents on demand:

Main Agent: "I need to search for papers about RAG"
  └─ spawn: paper_researcher("Find papers about RAG in 2025")
       └─ Runs in an isolated context
       └─ Returns: "I found 5 relevant papers..."

Main Agent: "Now I need to analyze these papers"
  └─ spawn: analysis_agent("Compare these 5 papers and rank by relevance")
       └─ Runs in an isolated context
       └─ Returns: "Ranking: 1) Paper X, 2) Paper Y..."

Unlike M10, where you designed the multi-agent structure, here the agent decides which subagents to create at runtime. Capsule 04 covers this in detail.

4. Long-term Memory

Swappable backends to persist information across sessions:

  • Filesystem backend: files on disk, simple, no external dependencies
  • LangGraph Store backend: uses LangGraph's Store system for consistency with the ecosystem
  • Composite backends: combines multiple backends

Covered in later capsules of the module.


Module map

#CapsuleWhat you'll learnType
01Introduction (this one)The three levels of abstraction, when to use Deep Agents, setupIntro
02Planning with write_todosBreaking tasks down, tracking progress, dynamic re-planningTechnical
03Virtual FilesystemContext offloading, reading/writing files, organizing outputsTechnical
04Subagent Spawning and DelegationCreating subagents on demand, isolated context, limits and controlsTechnical
05Long-term MemoryMemory backends, filesystem vs LangGraph Store, compositeTechnical
06Deep Agents CLIAutonomous agents from the terminal, configuration, daily useTechnical
07Decision tree: create_agent vs LangGraph vs Deep AgentsComplete decision framework, trade-offs, when to use whatTechnical
08Project: Research Assistant as a Deep AgentReimplementing the Research Assistant, side-by-side comparisonProject

Learning flow

You start with planning (capsule 02) — the most fundamental capability: how the agent breaks complex tasks down. Then you learn the virtual filesystem (capsule 03) — how the agent handles information without filling the context window. You add subagent spawning (capsule 04) — autonomous delegation of subtasks. With those three pieces, you understand the core of Deep Agents. Capsules 05-06 add long-term memory and the CLI. Capsule 07 consolidates everything into a complete decision tree. And capsule 08 pulls it all together in the module's final project.

The progression is: planning → filesystem → delegation → memory → CLI → decision framework → project.


Connection with the project

Research Assistant: from ~150 lines to ~40 lines

In Module 10, your Research Assistant runs about 150 lines of code: state definition, nodes, edges, conditionals, checkpointer, tools, supervisors, subagents. It works, it's robust, and you have full control.

In this module, you reimplement it as a Deep Agent:

from dotenv import load_dotenv
load_dotenv()

from deep_agents import create_deep_agent
from langchain_community.tools import TavilySearchResults

web_search = TavilySearchResults(max_results=5)

agent = create_deep_agent(
    "openai:gpt-4.1",
    tools=[web_search],
    name="Research Assistant",
    instructions=(
        "You are a research assistant. "
        "For each topic, break the research down into steps with write_todos. "
        "Write the findings from each source into separate files. "
        "Delegate specialized subtasks to subagents when needed. "
        "Generate a consolidated final report."
    ),
)

result = agent.run("Research the state of AI agents in production in 2025")

print(f"Files generated: {list(result.files.keys())}")
print(f"Todos completed: {sum(1 for t in result.todos if t['status'] == 'completed')}/{len(result.todos)}")
print(f"Subagents used: {len(result.subagents_spawned)}")
# Expected output (varies by model):
# Files generated: ['research/web_search.md', 'analysis/synthesis.md', 'output/report.md']
# Todos completed: 5/5
# Subagents used: 2

~40 lines. The same result. But with a clear trade-off: you lost control over every decision. The agent decided how to break the task down, which files to create, and when to delegate. If that's fine for your use case, Deep Agents saves you time. If you need control, LangGraph is the option.

The most important pedagogical moment of this module is that side-by-side comparison. You'll get to it in capsule 08.


Connection with Module 12: LangSmith and Production

Deep Agents generates a lot of LLM calls: planning, executing each step, subagent spawning, filesystem operations. Without observability, you have no visibility into what the agent is doing, how much it's costing, or why it made a decision.

Module 12 adds LangSmith to any of your agents — whether it's the LangGraph version or the Deep Agents version:

M11: Deep Agents (the agent does more for you)
  ↓
M12: LangSmith (you see everything the agent does)
  ↓
  Result: an autonomous agent you can observe, evaluate, and deploy

The combination of Deep Agents + LangSmith is powerful: the agent operates autonomously while you monitor cost, quality, and behavior in production.


Technical setup

Prerequisites

  • Module 10 completed — you have a working multi-agent Research Assistant
  • Python 3.11+ installed
  • ✅ At least one API key from a provider (OpenAI recommended, GPT-4.1 for the best planning results)

Installation

pip install deep-agents langchain-openai python-dotenv

Deep Agents installs LangGraph as a transitive dependency. If you already have LangGraph installed, there's no conflict.

Verify the installation:

import deep_agents
print(f"deep-agents version: {deep_agents.__version__}")
# Expected output:
# deep-agents version: 0.2.x

Environment variables

Your .env from earlier modules still works:

# .env
OPENAI_API_KEY=sk-...

# Optional: for web search in the exercises
TAVILY_API_KEY=tvly-...

Quick check

from dotenv import load_dotenv
load_dotenv()

from deep_agents import create_deep_agent

agent = create_deep_agent(
    "openai:gpt-4.1-mini",
    tools=[],
    name="test-agent",
    instructions="Answer simple questions.",
)

result = agent.run("What is the capital of France?")
print(result.output)
# Expected output (varies by model):
# The capital of France is Paris.

If you see a coherent answer, your setup is ready.


What this module does NOT cover

  • Building your own agent framework — you're not recreating Deep Agents, you're using it. If you want to build something similar, modules 5-10 gave you the tools
  • RAG and vector stores — the virtual filesystem stores the agent's outputs, not indexed knowledge bases
  • Model fine-tuning — Deep Agents works with general-purpose models via API
  • Cloud deployment — how to deploy your agent is covered in Module 12 with LangSmith

Evidence of success

By the end of this module, you'll know you succeeded if:

  • ✅ You can create a Deep Agent with planning, filesystem, and subagent spawning enabled
  • ✅ You understand what write_todos does internally: decomposition, tracking, re-planning
  • ✅ You can explain why the virtual filesystem cuts costs: context offloading
  • ✅ You know when subagent spawning is useful and when it's overkill
  • ✅ You have a clear decision tree: create_agent vs LangGraph vs Deep Agents
  • ✅ You reimplemented your Research Assistant as a Deep Agent and can articulate the trade-offs
  • ✅ You can use the Deep Agents CLI to run agents from the terminal

Self-assessment test

If you can answer these questions, you're on the right track:

  1. What are the three levels of abstraction in the LangChain ecosystem, and when would you use each one?
  2. What does write_todos do that goes beyond a simple task list?
  3. Why does the virtual filesystem cut costs compared to stuffing everything into the context window?
  4. What's the difference between designing multi-agent in M10 and subagent spawning in Deep Agents?
  5. What do you lose when you use Deep Agents instead of LangGraph?

Summary

  • You're in Module 11, Block 4 (Production). You built everything by hand in modules 1-10: tools, graphs, persistence, HITL, multi-agent. Now you see the batteries-included layer
  • The ecosystem has three levels of abstraction: create_agent (simple, 80% of cases), LangGraph (full control, custom workflows), and Deep Agents (autonomous, batteries-included). There's no "better" — there's "right for your case"
  • Deep Agents includes four main capabilities: planning with write_todos, a virtual filesystem for context offloading, subagent spawning for autonomous delegation, and long-term memory with swappable backends
  • The Deep Agents abstractions map directly to what you built: write_todos = the planning from M6-M10, filesystem = the persistence from M8, subagent spawning = the multi-agent work from M10. Now that you know the guts, you can appreciate how much the framework does for you
  • When to use Deep Agents: long-running autonomous tasks, research, code generation, complex analyses. When NOT to: simple Q&A, fine-grained control needed, latency sensitive
  • The module project is reimplementing the Research Assistant as a Deep Agent: ~150 lines → ~40 lines, with explicit trade-offs you'll be able to articulate

Additional resources

  1. Deep Agents — Documentation — Official documentation, API reference, and examples
  2. LangChain — Agent Architectures — Overview of the different agent architectures in the ecosystem
  3. LangGraph — Overview — LangGraph documentation, to compare against Deep Agents
  4. Building Autonomous Agents — LangChain Blog — Article on designing autonomous agents and when to use each level of abstraction
  5. Cognitive Architectures for Language Agents — Academic paper on cognitive architectures for agents (planning, memory, tool use)
  6. The Landscape of Emerging AI Agent Architectures — LangChain — Landscape of agent architectures and where each abstraction fits

Module 11 — LangChain & LangGraph: From Chains to Agents

Next capsule: Planning with write_todos — you'll learn how the agent breaks complex tasks into steps, tracks progress, and re-plans dynamically when results change.