deepagents requires Python 3.11 or newer.
Installation
Setup
We recommend using UUIDs for session_id and user_id so traces can be grouped reliably across runs.
Usage
create_deep_agent returns a LangGraph compiled graph that respects LangChain’s config={"callbacks": [...]}. A single handler instance captures the parent agent and every sub-agent dispatched via the built-in task tool — sub-agent invocations forward callbacks / tags / configurable through automatically.
The handler must be passed in config["callbacks"] for each invocation. There is no global instrument() step.
What gets traced
| LangChain Callback | Span Kind | Description |
|---|
on_chain_start / on_chain_end | CHAIN (root) or AGENT (nested) | Root chain creates the trace boundary; LangGraph nodes (agent, tools, <middleware>.*) and sub-agent roots nest as AGENT |
on_chat_model_start / on_llm_end | LLM | Model, parameters, token usage, reasoning |
on_tool_start / on_tool_end | TOOL | Built-in tools (write_todos, ls, read_file, write_file, edit_file, glob, grep, task) and your custom tools |
Sub-agent span tree
DeepAgents’ built-in task tool synchronously dispatches a declared sub-agent inside its tool body. The resulting trace tree reflects this faithfully — color-coded by SpanKind below:
The task tool is recorded as TOOL (faithful to the LLM’s view: task is a tool call) with the sub-agent’s root chain nested inside as an AGENT. This makes “tool dispatched a sub-agent” obvious in the trace tree — note the task TOOL node leads directly into the sub-agent’s AGENT subtree — without breaking the universal schema.
Trace name remapping
DeepAgents wraps a LangGraph compiled graph, so the root run reports name="LangGraph". The handler rewrites this to "DeepAgents" for the trace name. Custom user-given graph names are preserved.
Token usage
Token usage is extracted from LangChain’s usage_metadata (primary) or legacy llm_output.token_usage (fallback). The mapping is: input_tokens → prompt_tokens, output_tokens → completion_tokens. Reasoning tokens are subtracted from output_tokens when present.
Example with sub-agents
This example declares a researcher sub-agent alongside the main deep agent. When the model decides to delegate research, it calls the built-in task tool, which dispatches the sub-agent — the handler captures the entire nested run as one trace:
This produces one trace where the parent agent’s task tool span contains the entire nested researcher sub-agent run, including its internal tools chain and tool calls.