skip to content

In Google ADK, what is the difference between an agent's instruction and description?

level: juniorimportance: must knowfreq 64%

answer

  1. one faces inward, one faces outward
  2. who reads the field, and when
  3. routing metadata vs system prompt
  4. siblings compete on description text
  5. root-only field covers the whole tree

basics

~20 s

instruction is the agent's own prompt — it tells that agent how to behave. description is a one-line summary other agents read when deciding whether to hand work over, so it drives delegation rather than behaviour.

solid answer

~40 s

On an ADK `LlmAgent`, `instruction` and `description` face in opposite directions. `instruction` faces inward: it is folded into that agent's system prompt and shapes what it says, which tools it reaches for, and what format it produces. `description` faces outward: it is what a *parent or sibling* agent sees when the LLM is choosing whether to transfer control, so it is effectively routing metadata. That is why a leaf agent with no siblings can get away with a thin description, while an agent that sits inside a `sub_agents` list must have a sharp, distinctive one — vague or overlapping descriptions are the usual root cause of "the coordinator keeps picking the wrong specialist". There is also `global_instruction`, which only takes effect on the root agent and applies across the whole agent tree.

code

python · 23 lines
python
from google.adk.agents import LlmAgent

refunds = LlmAgent(
    name="refund_specialist",
    model="gemini-2.0-flash",
    description="Handles refunds and returns; does not change shipping addresses.",
    instruction="Confirm the order id, check eligibility, then state the refund amount and timeline.",
)

shipping = LlmAgent(
    name="shipping_specialist",
    model="gemini-2.0-flash",
    description="Handles delivery status and address changes; does not issue refunds.",
    instruction="Look up the shipment, report its status, and offer an address change if allowed.",
)

coordinator = LlmAgent(
    name="support_coordinator",
    model="gemini-2.0-flash",
    global_instruction="Always answer in the customer's language and never invent order details.",
    instruction="Route the customer to the right specialist. Do not answer domain questions yourself.",
    sub_agents=[refunds, shipping],
)

go deeper

for a junior

Know that instruction is the agent's own prompt and description is what other agents read when deciding to hand over. Saying that one sentence clearly is most of the answer at this level.

for a middle

Explain the consequence: descriptions are routing metadata that siblings compete on, so misrouting is a description bug while bad output is an instruction bug. Mention instruction templating with {key} placeholders.

for a senior

Show that you debug with the split — read the trace to see which agent received the turn, then fix the corresponding field — and that you write sibling descriptions as a mutually exclusive set rather than one at a time.

for a principal

Own it as a convention: cross-cutting policy lives in the root's global_instruction, routing vocabulary is standardised across teams, and description quality is treated as an interface contract because it determines routing accuracy as the tree grows.

## Two fields, two audiences An ADK `LlmAgent` is constructed with, among other things, `name`, `model`, `instruction`, `description`, `tools` and `sub_agents`. Beginners often treat `instruction` and `description` as a long and short version of the same thing. They are not: they are read by different parties at different times. **`instruction` is read by this agent's own model.** ADK assembles the agent's request and folds `instruction` in as system guidance. Everything about how the agent behaves lives here: its persona, the steps it should follow, the tools it should prefer, the output format, the refusals. If the agent misbehaves, `instruction` is what you edit. **`description` is read by *other* agents' models.** When an `LlmAgent` has `sub_agents`, ADK exposes a transfer capability to the model, and the choice of target is made from the candidate agents' `name` and `description`. So `description` is a routing label — a short, discriminative statement of what this agent is *for*, written for a reader who has only that line to go on. ## Why the split exists Keeping them separate is what makes multi-agent trees composable. An agent's internal prompt can be long, opinionated and full of formatting rules without bloating every routing decision made above it. And the routing label can be tuned independently: you can rewrite a description to fix a misrouting problem without touching the agent's behaviour at all. It also means the two fail differently, which is the practical part of the answer: - A bad `instruction` produces an agent that does the wrong thing once it is invoked. - A bad `description` produces an agent that is invoked at the wrong time, or never invoked, while its own behaviour is perfect. Diagnosing agent misbehaviour starts with deciding which of those two you are looking at. If the trace shows the wrong agent received the turn, the bug is in descriptions. If the right agent received it and then produced nonsense, the bug is in its instruction. ## Writing a good description Because descriptions compete with each other, they should be written as a set, not one at a time. Useful properties: - **Discriminative** — it should say what this agent handles that its siblings do not. Two siblings described as "answers customer questions" and "helps customers with queries" give the router nothing to choose on. - **Scoped** — naming the domain and the boundary ("handles refunds and returns; does not change shipping addresses") lets the router rule the agent out as well as in. - **Short** — every sibling's description sits in the routing context on every turn, so long descriptions are a recurring token cost across the whole tree. `name` matters for the same reason: it is the identifier the model produces when it transfers, and it appears alongside the description, so a name like `refund_specialist` is doing routing work that `agent_2` is not. ## Instruction templating `instruction` is not a static string. ADK substitutes session-state values into it using `{key}` placeholders, so an agent can be written once and re-used across steps that differ only in the data they operate on. A placeholder written as `{key?}` is treated as optional, so a missing value does not blow up the run. This is the mechanism that lets a downstream agent in a `SequentialAgent` read what an upstream agent produced. ## global_instruction There is a third field, `global_instruction`, that applies across an entire agent tree rather than to one agent. Only the root agent's `global_instruction` takes effect; setting it on a nested agent does nothing. Use it for cross-cutting rules every agent must respect — brand voice, a language requirement, a blanket prohibition — and keep per-agent behaviour in each agent's own `instruction`. Repeating the same three safety rules inside eight agents' instructions is a maintenance trap; that content belongs in `global_instruction` on the root. ## The one-line summary to give an interviewer "`instruction` is how this agent behaves; `description` is how other agents decide to call it; `global_instruction` on the root is what every agent in the tree obeys." If you can then name the failure mode each one causes when written badly, you have answered the question at the level it is actually being asked.

  • What does global_instruction do that instruction does not?
    `global_instruction` applies to every agent in the tree, but only the root agent's value takes effect — setting it on a nested agent has no effect. It is the right home for cross-cutting rules such as tone, language or blanket prohibitions, so you do not copy the same paragraph into eight agents' `instruction` fields and then have them drift apart.
  • A coordinator keeps routing billing questions to the support agent. Which field do you edit first?
    The descriptions, not the instructions. Misrouting means the transfer decision was wrong before the target agent ever ran, and that decision is made from sibling `name` and `description`. Rewrite both siblings' descriptions together so each states what it owns and what it does not, then re-test; only if the correct agent now receives the turn and still answers badly do you touch its `instruction`.
  • Does an agent with no siblings still need a description?
    It matters much less. `description` is consumed when some other agent's model is choosing a transfer target, so a single root agent or a leaf inside a `SequentialAgent` — where ordering is fixed by code — is not being selected on its description. It is still worth writing as documentation, and it becomes load-bearing the moment that agent is added to a `sub_agents` list.
  • Can instruction contain values produced earlier in the run?
    Yes — ADK substitutes session-state values into `instruction` via `{key}` placeholders, with `{key?}` marking one as optional so a missing value does not fail the run. That is how a downstream agent in a `SequentialAgent` consumes what an upstream agent wrote, without you having to build the prompt string yourself.

saying these in an interview costs you the question

  • Calling description a shorter version of instruction
  • Putting behaviour rules in description and hoping the agent follows them
  • Leaving sibling descriptions vague, then blaming the model for misrouting
  • Setting global_instruction on a nested agent and expecting it to apply
  • Thinking instruction is read by the parent agent when routing

context