skip to content

How do you decide the shape of a large Google ADK agent tree as it grows?

level: principalimportance: should knowfreq 36%

answer

  1. decide per node: judgment or known step
  2. routing quality falls as siblings multiply
  3. every hop is another model call
  4. fence what a leaf is allowed to do
  5. subtrees you can run alone, you can test alone

basics

~20 s

Decide per node whether the next step is a judgment or a known fact. Known steps become workflow agents; genuine judgment becomes a small set of sub_agents with sharply distinct descriptions. Every extra transfer hop is another model call, another failure point, and another thing to evaluate.

solid answer

~50 s

There is no single right shape, but there is a defensible method. First, push determinism upward: the top of a mature ADK tree is usually `SequentialAgent`s and `ParallelAgent`s, because the coarse pipeline is something the business already knows, and workflow agents cost nothing and never mis-route. Second, keep LLM-driven transfer local and narrow — an `LlmAgent` coordinator routing over three to five well-differentiated `sub_agents` routes reliably; one routing over fifteen overlapping ones does not, and the descriptions of all fifteen sit in its context on every turn. Third, prefer breadth over depth where you can, because each nested transfer is another model round trip on the critical path; where depth is genuine, fence it with `disallow_transfer_to_parent` and `disallow_transfer_to_peers` so a bad hop cannot bounce around the tree. Then match the `model` per agent — routers and formatters do not need your most expensive model — and make each subtree independently runnable so it can be evaluated on its own.

go deeper

for a junior

Focus first on knowing what a sub_agents list does and that descriptions drive transfer; tree-shaping judgment is not expected of you yet, but recognising that deep trees add model calls is a good instinct to voice.

for a middle

Be able to argue that a known ordering belongs in a workflow agent rather than an LlmAgent's instruction, and that a routing tier should have few, clearly distinct siblings.

for a senior

Show that you reason about hops as latency and spend, fence leaf transfers so a bad hop cannot wander, and keep subtrees independently runnable so each can be evaluated without the whole tree.

for a principal

Own the policy: where non-determinism is permitted at all, the ceiling on routing fan-out, per-node model tiering as a cost lever, state-key namespacing across subtrees, and an evaluation strategy that tests subtrees rather than only end-to-end runs.

## The question behind the question An interviewer asking this is not looking for "use a coordinator pattern". They want to know whether you have a rule for deciding where non-determinism is allowed, and whether you understand what each structural choice costs in latency, spend, reliability and testability once the tree is bigger than a demo. ## Rule one: determinism migrates upward In a mature ADK application the top of the tree is usually not an `LlmAgent`. The coarse-grained flow — intake, enrich, analyse, review, respond — is business process, and business process is already known. Encoding it as `SequentialAgent` and `ParallelAgent` costs zero tokens, cannot mis-route, produces one execution path per configuration, and shows up in code review as readable structure. The LLM decisions that remain are the ones that genuinely depend on content the model just read: which specialist owns this ticket, is this draft acceptable, does this request need a human. Those become `LlmAgent`s, usually near the leaves. The anti-pattern is the inverse — a root `LlmAgent` whose sub-agents are the pipeline stages and whose instruction says "do these in order". It works in a demo and degrades in production, because you have converted a guaranteed ordering into a probabilistic one and paid a model call for the privilege. ## Rule two: routing accuracy degrades with sibling count An `LlmAgent` with `sub_agents` routes by having its model choose a target from the siblings' `name` and `description`. Two forces work against you as that list grows: - **Discrimination.** Three specialists with crisply disjoint charters are easy to choose between. Fifteen, several of which plausibly cover the same request, are not — and the errors are not random, they concentrate on exactly the ambiguous requests you most care about. - **Context cost.** Every sibling's description is in the router's context on every turn. Fifteen verbose descriptions is a standing tax on each routing decision. So the practical ceiling for a single routing tier is small — think a handful, not dozens. Past that, group: route to a domain, and let the domain route within itself. That is where a second tier earns its place. ## Rule three: depth costs a round trip per hop Every LLM-driven transfer is a model call before any useful work happens. A three-tier tree can spend two full inference round trips deciding who should act. Breadth is cheaper than depth for the same number of leaves, so add a tier only when a tier genuinely reduces the number of choices each router must discriminate between. When you do go deep, constrain it. `LlmAgent` exposes `disallow_transfer_to_parent` and `disallow_transfer_to_peers`; setting them on leaf specialists prevents a wrong hop from becoming a wandering conversation that bounces around the tree accumulating context and cost. A leaf that can only answer or finish is far easier to reason about than one that can send control anywhere. A useful middle option, when you want a sub-agent's *result* rather than to hand it the conversation, is to invoke it as a tool instead of transferring to it: control returns to the caller with a value, so the parent stays in charge of the flow. Choosing between "hand over the conversation" and "call and come back" is one of the real structural decisions in a tree. ## Rule four: the model is a per-node decision `model` is set per `LlmAgent`. A router that emits a single transfer decision, a formatter that reshapes JSON and a checker that answers yes-or-no do not need the same model as the agent doing the substantive reasoning. In a tree of a dozen agents, most nodes are cheap nodes, and matching model to node is usually a larger cost lever than any prompt optimisation — while also cutting latency on the hops that sit on the critical path. ## Rule five: shape for evaluation and for incidents Two operational constraints should shape the tree as much as the logic: **Evaluation.** A subtree you can run standalone can be evaluated standalone. Keep specialists free of assumptions about who invoked them — take inputs from state under documented keys, write results under documented keys — and each becomes independently testable. A specialist that only works when reached through a particular router is untestable except end-to-end, which means it is effectively untested. **Incident triage.** When a run goes wrong, the first question is always "which agent decided this?". A deterministic skeleton makes that trivial for most of the path and narrows the probabilistic part to a few named decision points. A tree that is LLM-transfer all the way down turns every incident into a full-trace reconstruction. **Blast radius.** Because state is a flat shared namespace, one agent writing a key another agent reads is a coupling that no type checker will catch. Larger trees need key naming to be a convention with an owner — namespaced per subtree, documented — or you will get cross-subtree interference that presents as a mysterious wrong answer rather than an error. ## Two structural facts to know An agent instance belongs to a single parent, so "reuse this specialist under two coordinators" means constructing two instances (or invoking it as a tool from one of them), not sharing one object. And `global_instruction` only takes effect on the root, which makes it the right home for tree-wide policy and the wrong home for anything subtree-specific. ## The answer in one breath Deterministic skeleton at the top; narrow, well-differentiated LLM routing near the leaves; breadth before depth; transfers fenced so a mistake cannot wander; model chosen per node; subtrees kept independently runnable so they can be evaluated and debugged in isolation.

  • Why not one coordinator with twenty sub-agents?
    Routing is a model choice over sibling names and descriptions, so accuracy falls as the charters start overlapping, and the errors concentrate on the ambiguous requests you care most about. You also carry all twenty descriptions in the router's context on every turn. Group into domains and route in two narrow steps, or replace the routing entirely with deterministic composition where the flow is already known.
  • When do you set disallow_transfer_to_parent and disallow_transfer_to_peers?
    On leaf specialists that should answer and stop. Without them, an agent that was reached by mistake can hand control onward, and a single bad routing decision becomes a conversation wandering the tree, accumulating context and cost. Fencing turns that into a bounded wrong answer you can see in one trace — much easier to detect and to fix.
  • How does per-agent model selection change the economics of a tree?
    Most nodes in a real tree are cheap nodes — routers, formatters, checkers — that emit a decision rather than substantive reasoning. Since `model` is set per `LlmAgent`, matching model to node typically saves more than prompt tuning does, and it also removes latency from hops that sit on the critical path before any useful work starts.
  • Can the same specialist agent sit under two different coordinators?
    Not as one shared instance — an agent instance belongs to a single parent in the tree. Construct a separate instance per parent from a shared factory function so the prompt and tools stay in one place, or have one parent invoke it as a tool rather than adopting it as a sub-agent, which also keeps control with the caller.

saying these in an interview costs you the question

  • Making the root an LlmAgent that is told to run stages in order
  • Adding sub-agents indefinitely and blaming the model for misrouting
  • Treating tree depth as free because the framework handles transfer
  • Using one expensive model for every node including routers
  • Sharing one agent instance across two parents in the tree

context