Deep agent¶
A deep agent performs hierarchical task decomposition — it asks the LLM
whether the input can be solved directly, and if not, breaks it into
subtasks and recurses. Leaf subtasks (or anything at max_depth) are
solved through a ReAct sub-loop, then the agent synthesises the subtask
results into a final answer. Pick this for open-ended tasks where the
depth of decomposition isn't known up front — research-heavy questions,
"do the whole thing" requests, multi-part analyses.
Type identifier¶
YAML form:
What it does¶
runDeep in pkg/agent/adk/run_orchestration.go is a thin entry
point — deepDecompose(ctx, task, depth=0, maxDepth) does the work:
- At
depth >= maxDepth— short-circuit and solve directly withrunReAct(ctx, task). No more decomposition attempts. - Below max depth — issue a
Model.Generatecall with this decision prompt:
Analyze this task and decide: can it be solved directly, or
should it be broken into subtasks?
If it can be solved directly, respond with: {"direct": true}
If it needs decomposition, respond with:
{"direct": false, "subtasks": ["subtask1", "subtask2", ...]}
Task: <input>
- Parse the JSON. If the response is
{"direct": true}, the JSON is malformed, orsubtasksis empty → solve directly viarunReAct. - Otherwise recurse: for each subtask call
deepDecompose(ctx, subtask, depth+1, maxDepth). Collect results into a markdown digest:
- After all subtasks complete, synthesise a final answer by calling
runReActwith:
The ReAct sub-loop may itself call tools to refine / verify the synthesis.
Every recursion level emits a decompose debug event with the depth
and task preview so a tracer can render the full tree.
Configuration¶
Deep accepts every ReAct field (see react) plus:
| Field | Type | Default | Description |
|---|---|---|---|
deep_max_depth |
int | 3 | Maximum recursion depth. At depth >= this value, the agent solves with runReAct directly instead of decomposing further. Zero is coerced to 3 by New. |
max_iterations |
int | 10 | Per-ReAct cap for every leaf and synthesis call — applies inside each runReAct invocation, not across the recursion. |
All other ReAct-shaped fields (tools, memory, guardrails,
budget, approval_*, tool_retry, governance) apply to the
inner ReAct sub-loops and synthesis calls.
Behavior notes¶
- The decomposition phase is a single
Model.Generatecall — fast, but if it returns malformed JSON the agent just solves directly. There is no re-prompt or fallback parser. - Token consumption can blow up exponentially: at
max_depth=3with three subtasks per level you'll see up to 1 + 3 + 9 + 9 ≈ 22 ReAct sub-loops, each up tomax_iterationsLLM calls plus their tool calls. Always set abudget:for production. - The final synthesis is itself a ReAct loop, so tool calls happen there too — useful for verification ("re-fetch the most recent number before finalising").
- The decomposition prompt is prepended to the agent's system prompt verbatim. Customise the system prompt to bias what "subtask" means in your domain.
- Sub-agents (
sub_agents:) are NOT used by deep. Everything is the same agent recursing on itself. - Streaming is not supported —
RunStreamfalls back to non-streaming and replays the final text as word chunks.
Example¶
A deep research agent producing a structured report:
agents:
- id: deep-researcher
type: deep
deep_max_depth: 2
max_iterations: 8
model:
provider: anthropic
model: claude-sonnet-4-7
system_prompt: |
You are a research analyst. Break complex questions into the
smallest meaningful sub-questions, gather sources, then write
a citation-rich synthesis.
tools:
- { name: web-fetch, type: function, function: web.fetch }
- { name: read-file, type: function, function: fs.read }
budget:
max_tool_calls: 60
max_input_tokens: 800000
Source¶
pkg/agent/adk/run_orchestration.go—runDeepanddeepDecompose(the recursion).pkg/agent/adk/agent.go—Rundispatch onTypeDeep,DeepMaxDepthfield onAgentConfig, default-3 coercion inNew.pkg/workflow/definition.go—AgentDefinition.DeepMaxDepth.
See also¶
- plan-execute — flat plan-then-execute (one level of decomposition).
- react — the leaf executor that solves each subtask.
- loop — single-LLM iterative refinement.