Skip to content
Blog

Deep Agents: Long-Horizon Task Execution with Durable Threads

Build agents that run for hours, pause for approval, and survive crashes. Learn durable execution, delta channels, and human-in-the-loop with LangChain Deep Agents.

Published on August 20, 2026

AI Assistant

Most production infrastructure assumes short-lived, stateless requests. Agents break both assumptions. A research agent runs for twenty minutes, spawning subagents and executing tool calls—and if the worker process dies, it can’t afford to restart from scratch. A coding agent pauses for a human to approve a draft, and nobody knows if the human will respond in thirty seconds or three days.

The infrastructure that handles this—durable execution, checkpointing, pause-and-resume, bounded memory—is what separates a demo agent from a production agent. Deep Agents is LangChain’s batteries-included answer: an open-source agent harness built on LangGraph that ships these production patterns out of the box.

In this tutorial, you will learn what durable execution actually requires, how Deep Agents delivers it, and how to build a long-horizon agent with human approval.

Prerequisites

  • Python 3.10+ (a JS/TS version, deepagentsjs, is also available)
  • pip install deepagents
  • A model provider with tool calling (frontier, open-weight, or local)

What Long-Horizon Work Means

Agents work by running a loop: given a prompt, the model reasons, calls tools, observes the results, and repeats until the task is complete. Unlike a web request that returns in milliseconds, this loop spans minutes or hours. A single run might make dozens of model calls, spawn subagents, or wait indefinitely for a human.

Three requirements follow:

  1. Reliability. A crash, deploy, or transient failure anywhere in the loop shouldn’t erase the work leading up to it. You want resumption from the last completed step with all prior state intact.
  2. Pausing. An agent that waits for human approval must truly stop: free resources, release workers, then pick up later exactly where it left off.
  3. Bounded memory. Long sessions grow context without bound, so history must be compressed and tool outputs offloaded.

The Harness: What You Get Out of the Box

Deep Agents is an opinionated harness with defaults tuned for long-horizon, multi-step work:

  • Planning — tools to decompose tasks, track progress, and adapt.
  • Sub-agents — delegate to agents with isolated context windows.
  • Filesystem — read, write, edit, or search over pluggable backends.
  • Context management — summarize long threads, offload large tool results to disk.
  • Shell access — run commands in your sandbox of choice.
  • Persistent memory — pluggable state and store backends for cross-session recall.
  • Human-in-the-loop — approve, edit, or reject tool calls before they run.
  • Skills and tools — reusable behaviors, your own functions, or any MCP server.

It’s model-agnostic and built on LangGraph, so it gets streaming, persistence, and checkpointing for free, with first-class tracing and evaluation via LangSmith.

Durable Execution: The Foundation

The runtime treats long runs as first-class. Agents run on a managed task queue with automatic checkpointing:

  • Each step of graph execution writes a checkpoint to the persistence layer (PostgreSQL by default), keyed by a thread_id that acts as a persistent cursor.
  • When a worker crashes, the run’s lease is released and another worker picks it up from the latest checkpoint.
  • When an agent waits for human input, the process hands off its slot and the run sleeps indefinitely until resumed.

Configure retry policies per node—backoff, max attempts, which exceptions trigger retries:

from deepagents import DeepAgent

agent = DeepAgent(
    name="researcher",
    model="anthropic/claude-sonnet-4",
    retry_policy={
        "max_attempts": 5,
        "backoff_factor": 2.0,
        "retry_on": ["TimeoutError", "RateLimitError"],
    },
)

Durability is what makes everything else possible. Because execution can pause and resume across process boundaries, agents can wait indefinitely for human input, run in the background, survive mid-run deploys, and handle concurrent inputs without corrupting state.

Human-in-the-Loop: interrupt() and Resume

The two primitives that power approval gates are interrupt() and Command(resume=...):

  • interrupt() pauses execution and surfaces a payload to the caller. It’s dynamic—place it anywhere in your code, wrap it in conditionals, or embed it inside a tool so approval logic travels with the tool.
  • Command(resume=...) continues execution with the human’s response. Because resume accepts any JSON-serializable value, the response isn’t limited to approve/reject: a reviewer can return an edited draft, a human can supply missing context, a downstream system can inject computed results.
from langgraph.types import Command, interrupt

def approval_gate(draft: dict) -> dict:
    verdict = interrupt({
        "kind": "draft_review",
        "payload": draft,
    })
    # resume value becomes the return value of interrupt()
    return {"approved": verdict["approved"], "note": verdict.get("note", "")}

When parallel branches each call interrupt(), all pending interrupts are surfaced together and can be resumed in a single invocation or one at a time as responses come back.

Delta Channels: Memory That Doesn’t Cost a Fortune

Long agents grow message histories and filesystem-backed context across dozens or hundreds of steps. Under the default full-snapshot model, checkpoint storage grows at O(N²)—for a simulated 200-turn coding session, that’s 5.3 GB of checkpoint storage.

DeltaChannel (a new LangGraph channel type) stores only the diff each step, writing full snapshots periodically. The same 200-turn session drops to 129 MB—a 41× reduction—with no config required:

  • messages and files are delta-backed by default in Deep Agents v0.6.
  • snapshot_frequency bounds resume latency (deepagents default: 50 steps).
  • The full LangGraph API surface (interrupts, time-travel, tooling) is unchanged.

For long-horizon agents, delta channels aren’t a nicety—they’re the difference between a database you can afford and one that grows quadratically with every session.

Async Subagents: Don’t Block the Supervisor

Inline subagents block the supervisor’s execution loop while they run. For work that takes minutes rather than seconds—deep research, large-scale code analysis—that’s a bottleneck. Deep Agents’ async subagents let the supervisor launch background work and continue:

ToolPurpose
start_async_taskLaunch a task on a remote agent, returns a task ID immediately
check_async_taskPoll a task’s status and retrieve its result
update_async_taskSend follow-up instructions mid-task
cancel_async_taskCancel a running task
list_async_tasksList all tracked tasks and statuses

The supervisor launches several subagents in parallel, continues talking to the user, and collects results as they arrive.

Putting It All Together

A complete, runnable deep agent with planning, subagents, filesystem, and HITL is available in the official docs and quickstart:

For production deployment, deepagents deploy packages your agent (configured in deepagents.toml) as a LangSmith Deployment with durable threads, memory, sandboxes, channels, schedules, and evals.

Conclusion & Next Steps

You now know what it takes to run long-horizon agents: durable execution so runs survive crashes, interrupt()/resume for human approval, and delta channels to keep checkpoint storage flat.

Next steps:

  • Add interrupt() gates to a coding or research agent and test resume across restarts.
  • Benchmark delta channels on a long session and compare storage before/after.
  • Explore async subagents for background research workflows.

Long-running agents are where the field is heading. Durable execution is the foundation everything else depends on.

References