Guides the creation of Google ADK (Agent Development Kit) agents. Use when the user asks to create, configure, or understand ADK agents, workflows, or tools.
CRITICAL: You must ONLY use the following models. NO gemini-1.5 or gemini-2.0 (unless flash), and NO text-bison:
gemini-3-flash-preview (Prioritize this).global region. You MUST set os.environ["GOOGLE_CLOUD_LOCATION"] = "global" before initializing ADK.google.genai.types for all message and content schemas in current ADK (v1.23+).os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "true" for ADK to correctly route to Vertex AI.import vertexai
from vertexai.agent_engines import AdkApp
from google.adk.agents import LlmAgent
gemini-2.5-flash, gemini-2.5-flash-liteWhen an agent needs to produce structured data (JSON), ALWAYS use output_schema with a Pydantic model. This enforces strict JSON output from the model.
Important: Use output_key to automatically store the parsed JSON in the session state.
from pydantic import BaseModel, Field
from google.adk.agents import LlmAgent
# 1. Define Pydantic Schema
class CapitalOutput(BaseModel):
capital: str = Field(description="The capital of the country.")
population: int = Field(description="Population of the capital.")
# 2. Register Agent
structured_capital_agent = LlmAgent(
name="capital_agent",
model="gemini-3-flash-preview",
instruction="You are a Capital Information Agent. Given a country, respond ONLY with JSON.",
output_schema=CapitalOutput, # Enforces JSON output format
output_key="found_capital" # Stores dict result in ctx.session.state['found_capital']
)
import { z } from 'zod';
import { Schema, Type } from '@google/genai';
import { LlmAgent } from '@google/adk';
// 1. Define Schema using @google/genai types
const CapitalOutputSchema: Schema = {
type: Type.OBJECT,
properties: {
capital: { type: Type.STRING, description: 'The capital city.' },
},
required: ['capital'],
};
// 2. Register Agent
const agent = new LlmAgent({
name: 'capital_agent',
model: 'gemini-3-flash-preview',
instruction: 'Respond with JSON.',
outputSchema: CapitalOutputSchema,
outputKey: 'found_capital',
});
// Define Schema
Schema capitalOutput = Schema.builder()
.type("OBJECT")
.properties(Map.of("capital", Schema.builder().type("STRING").build()))
.build();
LlmAgent agent = LlmAgent.builder()
.model("gemini-3-flash-preview")
.outputSchema(capitalOutput)
.outputKey("found_capital")
.build();
CRITICAL: If you cannot find the answer in this skill or your existing knowledge, you MUST use the brave_web_search tool (available via brave-search MCP) to find the latest documentation, error fixes, or examples. Do not hallucinate API methods.
[ ] Define Agent Type: Determine if you need a single LlmAgent or a workflow (SequentialAgent, ParallelAgent, LoopAgent).
[ ] Define Tools: Identify necessary tools (Google Search, Custom Python Functions, MCP).
[ ] Create Agent File: Scaffold the agent class/definition in Python (or requested language).
[ ] Setup Runner: Create the main entrypoint with Runner and InMemorySessionService (or other).
[ ] Validation: Ensure type hints in tools are correct for auto-schema generation.
Read the Docs First: This skill includes a distilled documentation set in resources/distilled/. Always check these high-density files first for specific implementation details.
resources/distilled/ (Relative to this skill)resources/adk_docs.md.grep_search or view_file to locate patterns.Core Components:
LlmAgent: Basic unit. Needs name, instruction, and optional tools.SequentialAgent: Chain of agents. Output of Agent A -> Context for Agent B.ParallelAgent: Run multiple agents at once. Good for research.LoopAgent: Iterative tasks. Needs a completion condition.Tooling:
@tool decorator for custom Python functions.State Management:
ctx.session.state to pass data between agents in a workflow.Session Attribute Error: NEVER use ctx.session.history. In ADK v1.23+, use ctx.session.events.gemini-3 models ONLY work in global. If you get a 404, verify os.environ["GOOGLE_CLOUD_LOCATION"] = "global".runner.run_async(...) instead of runner.run(...) inside async endpoints to prevent blocking.event.text and event.content.parts. Structured output often comes via the content path.output_schema, the resulting JSON might arrive as multiple text chunks or a single block. Always collect the full_text from the stream before trying to json.loads().