Home / Articles

LangChain Deep Agents: Planning, Files and Subagents Built In

LangChain Deep Agents on top of LangGraph: write_todos planning, a virtual filesystem, subagents, auto-summarization and memory, plus when to skip the harness.

Publisher: REACTAPP.TOP8 min read1742 words

This article is published in English.

Sources: LangChain Deep Agents AI Systems

Teams that get serious about agents tend to walk the same road. They start with LangChain chains, which handle simple pipelines nicely. Then the task grows: it needs tool calls, loops, outputs of unpredictable length. Chains stop being enough, so they move to LangGraph, and now they're writing state schemas, conditional edges and graph compilation code before they've touched the actual problem.

LangGraph isn't the issue. It's powerful. But it's a runtime, a low-level primitive, and people often treat it like an application framework. deepagents is LangChain's response to that mismatch.

What it is

"Deep agents" could mean almost anything, so to be precise: deepagents is a standalone Python package, installed with pip install deepagents, that sits on top of LangChain and LangGraph. LangChain's docs call it an agent harness. It runs the same core tool-calling loop as other frameworks but ships with extra capabilities built in, so you don't rebuild them each time.

The entry point is create_deep_agent(). Import it first:

from deepagents import create_deep_agent

Then pass in a tool and a prompt:

def get_weather(city: str) -> str:
    """Get 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 assistant",
)
agent.invoke(
    {"messages": [{"role": "user", "content": "What is the weather in Mumbai?"}]}
)

That's the whole thing. The library takes care of the LangGraph graph, state, streaming and context window management, and you never touched any of it. The more interesting part is what comes included.

Five built-in capabilities

Planning through write_todos

Each deep agent gets a write_todos tool automatically. Given a complicated task, it breaks the work into steps, marks each as pending, in progress or completed, and revises the plan as things change. This isn't a prompt trick. The list lives in agent state, so the agent can return to it, update it and refer to it throughout a session. Nobody has to tell the model to think step by step, because the structure is part of the harness.

A virtual filesystem

This one may be the biggest surprise. By default the agent has ls, read_file, write_file, edit_file, glob and grep. Why would an agent need files? Context management.

Context windows are finite, and long research runs, code execution or large tool results make history balloon quickly. Deep agents push bulky content into the virtual filesystem instead of keeping it all in the prompt. When a tool result goes past 20,000 tokens, the library saves it to the configured backend and leaves a file path plus a 10-line preview in the context. When the agent needs the full content, it calls read_file or grep. That's neither chunking nor truncation, it's deliberate offloading with retrieval on demand.

The filesystem backend is pluggable: in-memory state by default, local disk, LangGraph Store for persistence across threads, or sandboxes like Modal and Daytona.

Subagents

A built-in task tool lets the main agent spawn specialized subagents for isolated subtasks. It matters more than it sounds. In a long research job, one agent handling everything fills its context with intermediate steps, search results and partial output. With subagents, the main agent hands a subtask to a fresh instance with a clean context. That instance works on its own, finishes, and sends back one summary, so the main agent's context stays tidy.

You can define custom subagents with their own tools and system prompts. Start with the import:

from deepagents import create_deep_agent, Subagent

Then define a reviewer and attach it:

code_reviewer = Subagent(
    name="code-reviewer",
    system_prompt="You are an expert code reviewer. Analyze code for bugs, style, and performance.",
    tools=[read_file_tool],
)
agent = create_deep_agent(
    tools=[internet_search],
    subagents=[code_reviewer],
    system_prompt="You are a research and engineering assistant.",
)

A general-purpose subagent with filesystem tools is always there without any setup.

Automatic summarization

For long tasks, this is where the library earns its place. Once context reaches 85% of the model's window and there's nothing left to offload to files, the harness triggers summarization. An LLM writes a structured summary covering the session's intent, the artifacts created and the next steps, and that summary replaces the full history in working memory. The original messages are saved to the filesystem as the canonical record, so specifics can be recovered later. In effect, deep agents can keep going on complex tasks without hitting context limits, something you'd otherwise engineer by hand on raw LangGraph.

Memory across conversations

Normally state stays inside one thread. Configure a CompositeBackend with a LangGraph Store, though, and the agent can keep memory across sessions and threads. Files stored under the /memories/ path, or any path you choose, survive restarts and can be read from any conversation. Use it to give an agent a recall of your preferences, your repo's coding habits, or where a research effort that spans several days left off. Imports first:

from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore

Then the wiring:

store = InMemoryStore()
backend = CompositeBackend(
    routes={"/memories/": StoreBackend(store=store)},
    default=StateBackend(),
)
agent = create_deep_agent(
    tools=[...],
    backend=backend,
    memory=["path/to/AGENTS.md"],  # persistent context file
)

How the pieces relate

People mix these up, so it's worth being explicit.

  • LangChain provides the building blocks: models, tools, prompts and chains. It's the foundation.
  • LangGraph is a runtime for durable, stateful, graph-based execution, handling persistence, streaming, interrupts and complicated conditional flows. It's the engine.
  • Deep Agents is a harness over both. It doesn't replace LangGraph. It uses LangGraph for everything and adds a higher-level API with opinionated defaults, so you don't have to build the planner, filesystem layer, context compression and subagent infrastructure yourself.

A way to picture it: LangGraph gives you an engine and a transmission, and Deep Agents hands you a car.

For simple agents, LangChain's create_agent is probably plenty. When tasks are complex, long-running and need lots of context, that's where deepagents repays its abstraction cost.

A realistic quickstart: a research agent

Here's a research agent that searches the web and writes a structured report. Setup comes first:

import os
from typing import Literal
from tavily import TavilyClient
from deepagents import create_deep_agent

Then the tool, the instructions and the agent itself:

tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
def internet_search(
    query: str,
    max_results: int = 5,
    topic: Literal["general", "news", "finance"] = "general",
    include_raw_content: bool = False,
):
    """Run a web search and return results."""
    return tavily_client.search(
        query,
        max_results=max_results,
        include_raw_content=include_raw_content,
        topic=topic,
    )
research_instructions = """You are an expert researcher.
Your job is to conduct thorough research and then write a polished report.
Use internet_search to gather information.
Write your findings to files as you go to avoid losing context.
Use write_todos to plan your research steps before starting.
"""
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",  # default model
    tools=[internet_search],
    system_prompt=research_instructions,
)
result = agent.invoke({
    "messages": [{
        "role": "user",
        "content": "Research the current state of agentic AI frameworks in 2025 and write a structured report."
    }]
})
print(result["messages"][-1].content)

Running it sets off a sequence. The agent calls write_todos to plan the research. It runs searches and automatically offloads large results to the virtual filesystem. If the work is big, it launches a subagent for one section. It reads files back when needed and pulls everything into a final report. All the while, the harness manages context so the model never runs into its window limit. You wrote none of that infrastructure, since it arrived with the harness.

The command-line agent

The package also includes a terminal agent built on the same SDK:

pip install deepagents
deepagents  # launches the interactive CLI agent

It's a coding agent along the lines of Claude Code or Aider, but running on the Deep Agents SDK. It offers an interactive mode, a non-interactive pipe mode for scripting (the -n flag), custom skills and persistent memory. Teach it your project conventions and it'll remember them from one session to the next. So the SDK that drives a production research agent also gives you a usable developer tool right away.

When to reach for it

deepagents suits you when:

  • The task needs planning and many steps.
  • Tool results are large and must be managed over a long session.
  • You want subagent delegation without building the plumbing.
  • You need memory that persists across conversation threads.
  • You're building a coding agent or an autonomous research system.

Stay with create_agent or plain LangGraph when:

  • The agent is simple, with one or two tool calls and short replies.
  • You need fine control over graph topology.
  • You're already far into a custom LangGraph workflow and don't want opinionated defaults.

The docs themselves say as much: simple agents call for simpler tools.

Why it matters

The timing says something. Basic agent patterns, tool calling, ReAct loops and simple RAG, are well understood by now. What the field is still figuring out is reliability on long-horizon work, tasks that demand planning, big context, persistence and delegation. Every team shipping production agents has had to solve those same problems from scratch, and context strategies, subagent patterns and memory designs keep getting reinvented in slightly different forms.

deepagents is LangChain's wager that those solutions are common enough to standardize. A harness with opinionated defaults, built-in infrastructure and pluggable backends tries to move the question from "how do we build the plumbing?" to "what should the agent actually do?" Whether it succeeds depends on whether the defaults survive production. As a direction, though, it makes sense.

Getting started

Install the package and the search client:

pip install deepagents tavily-python

Then set your keys:

export ANTHROPIC_API_KEY="your-key"
export TAVILY_API_KEY="your-key"
export LANGSMITH_TRACING=true  # optional, for debugging
export LANGSMITH_API_KEY="your-key"

The Deep Agents overview in the LangChain docs covers backends, subagents, sandboxes, human-in-the-loop and the CLI. If you're building anything serious with agents, give yourself an afternoon to see where it fits in your stack, even if you don't adopt it straight away.