Skip to content

3.1 Single-Agent Design, Prompting & ADK Parameters

1. Key Concept Definitions: Inside an ADK LlmAgent

Section titled “1. Key Concept Definitions: Inside an ADK LlmAgent”

Before wiring multiple agents together, review the six core configuration primitives of ADK’s fundamental building block—the LlmAgent (also aliased as Agent):

1. description vs. instruction
description is external routing metadata read by parent/coordinator agents to decide task delegation. instruction is read by this agent’s own LLM to govern its reasoning, persona, and tool use.
2. Dynamic {state_key} Templates
Placing {var_name} inside instruction automatically interpolates session.state[‘var_name’] at runtime. Adding a trailing question mark ({var_name?}) safely ignores missing keys.
3. output_schema vs. output_key
output_schema takes a Pydantic BaseModel to force strict JSON output (disabling tool calls on that agent turn). output_key automatically writes the final output into session.state[output_key].
4. include_contents=‘none’
Strips prior conversation history from the model call so a stateless worker or formatting sub-agent processes only its instruction (including any injected {state_key} variables).
5. Built-In & ReAct Planners
Attaching BuiltInPlanner (with Gemini ThinkingConfig) or PlanReActPlanner instructs the agent to generate an explicit multi-step reasoning plan before calling tools or answering.
6. Model Tiering & Transfer Bounds
Pair Gemini Flash (for low-latency routers/extractors) with Gemini Pro (for complex reasoning), and prevent premature handoffs using disallow_transfer_to_parent / peers.

2. Interactive Architecture Decision Engine: Inside an ADK LlmAgent

Section titled “2. Interactive Architecture Decision Engine: Inside an ADK LlmAgent”

Switch between the 3 LlmAgent Design Scenarios below and click the 4 stages to inspect how parameters flow through Rosku Bank’s Loan Intake Agent:

Stage 1 / 4
1. Identity & Routename + description2. Brain & Promptinstruction + {state}3. Output Contractoutput_schema4. State Handoffoutput_key -> state
PARAMETERS: NAME & DESCRIPTION
1. How Parent Agents Discover & Route to This Agent
Input / Configuration Rule
Set a unique agent ‘name’ and a crisp, capability-focused ‘description’ stating when to delegate to this agent.
Output Behavior & Architecture Rule
Changing ‘instruction’ will NOT fix parent routing mistakes! Parent orchestrators only inspect ‘description’ when choosing a sub-agent.

3. Visual Parameter Reference Table: ADK LlmAgent Inputs & Outputs

Section titled “3. Visual Parameter Reference Table: ADK LlmAgent Inputs & Outputs”

Review this complete Input/Output Parameter Matrix for LlmAgent:

LlmAgent Parameter Expected Input Type Runtime Output / Effect Core Architecture Rule
name str (Unique identifier, e.g., "loan_intake_agent") Identifies the agent in logs, traces, and transfer calls (transfer_to_agent). Must be unique across the agent hierarchy; avoid spaces or special characters.
description str (Capability summary) Read by parent/coordinator LLMs to decide task delegation. Never put internal formatting rules here; put routing capabilities here!
instruction str (Supports {state_var} templates) or Callable Guides this agent’s own LLM behavior, persona, and tool usage. Automatically injects values from session.state when {key} syntax is used.
model str (e.g., "gemini-2.5-flash" or "gemini-2.5-pro") Selects the underlying reasoning engine for this specific agent. Use Flash for low-latency routers/extractors; use Pro for deep reasoning sub-agents.
tools list of Functions, BaseTool, or MCPToolset Exposes callable actions to the LLM during its reasoning loop. LLM uses function docstrings and type hints to decide when and how to call each tool.
output_schema Pydantic BaseModel class Forces the final response to conform strictly to a JSON schema. Important Constraint: Enabling output_schema disables tool calling and agent transfers for that agent!
output_key str (e.g., "dti_result") Saves the agent’s final text/JSON output into session.state["dti_result"]. Primary mechanism for passing outputs to the next agent in a pipeline!
include_contents 'default' or 'none' Controls whether prior conversation history is sent to the LLM. Set to 'none' for stateless worker agents that only need {state_key} inputs to save tokens!
generate_content_config GenerateContentConfig object Sets temperature, top_p, max_output_tokens, and safety settings. Use temperature=0.0 for deterministic routing and structured data extraction.
disallow_transfer_to_parent / peers bool (True or False) Restricts whether the sub-agent can autonomously transfer control back up or sideways. Set to True when a specialist sub-agent must complete its assigned step without bouncing early.
planner BuiltInPlanner or PlanReActPlanner Enables explicit step-by-step reasoning/thinking plans prior to tool execution. Use BuiltInPlanner(thinking_config=...) for Gemini thinking models or PlanReActPlanner for structured Plan-Act-Observe loops.

4. Real-World Deep Dive: LlmAgent Parameter Brain-Twisters

Section titled “4. Real-World Deep Dive: LlmAgent Parameter Brain-Twisters”
Architect Question How It Works Under the Hood in Production
“Why does an LlmAgent configured with BOTH tools=[credit_check] AND output_schema=LoanJSON fail to call its tool, and how do we solve it?” Two-Step Sequential Split: In ADK, setting output_schema constrains the model’s decoding output strictly to that JSON schema, preventing intermediate function-calling turns on that agent. Solve this with a 2-step SequentialAgent: Agent 1 calls credit_check and saves to output_key="raw_credit"; Agent 2 (with no tools and include_contents='none') reads {raw_credit} and applies output_schema=LoanJSON!
“If we set include_contents='none' on Agent 2 so prior chat history is excluded, how does Agent 2 still receive the data from Agent 1?” State Interpolation Still Runs on instruction! Even when include_contents='none' strips the conversation history list, ADK still resolves {raw_credit} placeholders inside Agent 2’s instruction from session.state['raw_credit']—giving Agent 2 the exact structured input it needs at a fraction of the token cost!
“How do we inject dynamic context into instruction if we do NOT want ADK’s automatic {brace} interpolation to parse literal curly braces (like JSON examples) in our prompt?” Pass a Callable InstructionProvider Function: Instead of passing a static str to instruction, pass a Python function def build_instruction(ctx: ReadonlyContext) -> str:. When instruction is a callable function, ADK uses your function’s return string verbatim and skips automatic {brace} parsing!