Awesome-omni-skill adk-skill

Build single-agent and multi-agent systems using Google's Agent Development Kit (ADK) in Python, Java, Go, or TypeScript. Use when user says 'build an agent with ADK', 'create a Gemini agent', 'multi-agent pipeline', 'agent orchestration with Google', or mentions ADK, google-adk, google agent development kit, sequential/parallel/loop agents, agent tools, callbacks, state management, agent testing, or agent deployment with Gemini. Do NOT use for LangChain, CrewAI, AutoGen, or non-ADK agent frameworks.

install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/adk-skill" ~/.claude/skills/diegosouzapw-awesome-omni-skill-adk-skill && rm -rf "$T"
manifest: skills/development/adk-skill/SKILL.md
source content

Google Agent Development Kit (ADK) Guide

Overview

ADK is Google's open-source framework for building AI agents powered by Gemini models. It supports single-agent and multi-agent architectures with built-in tool integration, state management, callbacks, guardrails, and deployment options.

Critical Rules

  1. Every agent package MUST have
    __init__.py
    that imports the agent module:
    from . import agent
  2. Entry point MUST be
    root_agent
    -- a module-level variable in
    agent.py
    (Python). Not
    agent
    , not
    my_agent
    .
  3. Set
    GOOGLE_API_KEY
    in
    .env
    or configure Vertex AI credentials before running.
  4. Always set
    max_iterations
    on
    LoopAgent
    to prevent unbounded execution.
  5. One agent = one responsibility. Split agents with 5+ tools into specialists.
  6. Use
    output_key
    +
    output_schema
    for reliable data flow between agents -- not free text.

Documentation & Resources

For up-to-date API references and detailed guides beyond this skill, always consult:

Supported Languages

LanguagePackageInstall
Python
google-adk
pip install google-adk
Java
com.google.adk:google-adk
Maven/Gradle
Go
google.golang.org/adk
go get
TypeScript
@google/adk
npm install @google/adk

This guide shows Python examples. For Java, Go, and TypeScript patterns, see references/multi-language.md.

Quick Reference

TaskApproach
Single agent
Agent
or
LlmAgent
with tools and instructions
Sequential pipeline
SequentialAgent
with ordered sub_agents
Parallel execution
ParallelAgent
with independent sub_agents
Iterative refinement
LoopAgent
with max_iterations or checker agent
Agent-as-toolWrap agent with
AgentTool
for on-demand delegation
Remote agent (A2A)
RemoteA2aAgent
+
to_a2a()
for cross-service agents
Custom toolsPython functions with type hints + docstrings
Structured outputPydantic model via
output_schema
+
output_key
State management
callback_context.state
and
tool_context.state
MCP integration
MCPToolset
with connection params
Testing
pytest
with
InMemoryRunner
EvaluationEvalSet with
.test.json
,
adk eval
CLI, pytest

Project Structure

Every ADK project follows this layout:

my_agent/
├── my_agent/
│   ├── __init__.py          # Must import agent module
│   ├── agent.py             # Defines root_agent (entry point)
│   ├── prompts.py           # Instruction strings (optional)
│   ├── tools.py             # Custom tool functions (optional)
│   ├── sub_agents/          # Sub-agent packages (optional)
│   └── shared_libraries/    # Callbacks, utilities (optional)
├── tests/
│   └── test_agent.py
├── pyproject.toml
└── .env                     # GOOGLE_API_KEY or GOOGLE_CLOUD_PROJECT

Critical: init.py

# my_agent/__init__.py
from . import agent

Critical: root_agent

The

root_agent
variable at module level is the framework entry point:

# my_agent/agent.py
from google.adk.agents import Agent

root_agent = Agent(
    name="my_agent",
    model="gemini-2.5-flash",
    description="Brief description for agent discovery",
    instruction="Detailed system prompt...",
    tools=[...],
)

pyproject.toml

Minimal config:

requires-python = ">=3.10"
,
dependencies = ["google-adk"]
, build-backend
setuptools
. For full example and environment config, see references/advanced-patterns.md.


Agent Types

1. LlmAgent (Single Agent)

The fundamental building block. Wraps a single LLM call with tools and instructions.

from google.adk.agents import LlmAgent

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    description="General assistant",
    instruction="""You are a helpful assistant.
    Use the search tool when you need current information.""",
    tools=[search_tool],
    output_schema=ResponseModel,   # Optional structured output
    output_key="response",         # State key for output
    generate_content_config=types.GenerateContentConfig(
        temperature=0.7,
    ),
)

2. SequentialAgent

Runs sub-agents in order. Output of each flows to the next via shared state.

from google.adk.agents import SequentialAgent

pipeline = SequentialAgent(
    name="research_pipeline",
    description="Research then summarize",
    sub_agents=[
        researcher_agent,    # Step 1: writes to state["research"]
        summarizer_agent,    # Step 2: reads state["research"]
    ],
)

3. ParallelAgent

Runs sub-agents concurrently. Use for independent tasks.

from google.adk.agents import ParallelAgent

parallel = ParallelAgent(
    name="multi_channel",
    description="Send to all channels simultaneously",
    sub_agents=[
        email_agent,
        slack_agent,
        calendar_agent,
    ],
)

4. LoopAgent

Repeats sub-agents until termination. Two termination patterns:

Pattern A: Fixed iterations

from google.adk.agents import LoopAgent

loop = LoopAgent(
    name="refinement_loop",
    description="Iteratively refine output",
    sub_agents=[writer_agent, critic_agent],
    max_iterations=3,
)

Pattern B: Checker agent with escalate

# The checker agent uses tool_context.actions.escalate = True to stop
def check_quality(score: float, tool_context: ToolContext) -> str:
    """Check if quality meets threshold."""
    if score >= 0.9:
        tool_context.actions.escalate = True
        return "Quality threshold met, stopping loop."
    return "Quality below threshold, continuing refinement."

checker = Agent(
    name="checker",
    model="gemini-2.5-flash",
    instruction="Evaluate the output quality and call check_quality.",
    tools=[check_quality],
)

loop = LoopAgent(
    name="quality_loop",
    sub_agents=[generator_agent, checker],
)

5. Composing Agent Types

Nest agent types freely for complex workflows. Example:

SequentialAgent
containing a
ParallelAgent
containing
LlmAgent
s. See references/advanced-patterns.md for hierarchical workflow examples.


Tools

Function Tools

Any Python function with type hints and a docstring becomes a tool:

def get_weather(city: str, units: str = "celsius") -> dict:
    """Get current weather for a city.

    Args:
        city: The city name to look up weather for.
        units: Temperature units - 'celsius' or 'fahrenheit'.

    Returns:
        dict with temperature, conditions, and humidity.
    """
    # Implementation
    return {"temperature": 22, "conditions": "sunny", "humidity": 45}

agent = Agent(
    name="weather_agent",
    model="gemini-2.5-flash",
    instruction="Help users check the weather.",
    tools=[get_weather],
)

Requirements:

  • Type hints on all parameters
  • Docstring with description and Args section
  • Return type annotation

Tools with State Access

Use

ToolContext
to read/write session state:

from google.adk.tools import ToolContext

def add_to_cart(item: str, quantity: int, tool_context: ToolContext) -> dict:
    """Add an item to the shopping cart."""
    cart = tool_context.state.get("cart", [])
    cart.append({"item": item, "quantity": quantity})
    tool_context.state["cart"] = cart
    return {"status": "added", "cart_size": len(cart)}

AgentTool (Agent-as-Tool)

Wrap an agent to use it as a tool for another agent:

from google.adk.tools.agent_tool import AgentTool

specialist = Agent(
    name="code_reviewer",
    model="gemini-2.5-pro",
    instruction="Review code for bugs and best practices.",
)

coordinator = Agent(
    name="coordinator",
    model="gemini-2.5-flash",
    instruction="Coordinate tasks. Use code_reviewer for code reviews.",
    tools=[AgentTool(agent=specialist)],
)

Built-in Tools

from google.adk.tools import google_search

agent = Agent(
    name="researcher",
    tools=[google_search],
)

MCP Tools

from google.adk.tools.mcp_tool import MCPToolset, StdioConnectionParams
from mcp import StdioServerParameters

agent = Agent(
    name="db_agent",
    tools=[
        MCPToolset(
            connection_params=StdioConnectionParams(
                server_params=StdioServerParameters(
                    command="npx",
                    args=["-y", "some-mcp-server"],
                ),
            ),
        ),
    ],
)

For advanced tool patterns (FunctionTool, ToolboxToolset, long-running tools), see references/tools-reference.md.


Callbacks

Callbacks intercept the agent lifecycle. Return

None
to proceed, return a value to short-circuit.

CallbackSignatureUse Case
before_agent_callback
(CallbackContext)
Initialize state
before_tool_callback
(BaseTool, dict, CallbackContext) -> dict|None
Validate inputs, auto-approve
after_tool_callback
(BaseTool, dict, ToolContext, dict) -> dict|None
Post-process results
before_model_callback
(CallbackContext, LlmRequest)
Rate limit, safety filter
def before_tool(tool, args, tool_context) -> dict | None:
    """Return dict to skip tool execution with that response."""
    if tool.name == "approve_discount" and args.get("value", 0) > 50:
        return {"status": "rejected", "reason": "Discount too large"}
    return None  # Proceed normally

agent = Agent(
    name="guarded_agent",
    model="gemini-2.5-flash",
    instruction="...",
    before_tool_callback=before_tool,
)

For rate limiting, input validation, and safety callbacks, see references/advanced-patterns.md.


State Management

State is a shared dictionary across agents, tools, and callbacks. Scopes:

state["key"]
(session),
app:key
(app-wide),
user:key
(user-wide).

Passing data between agents: Use

output_key
to write to state, read in next agent's instruction:

researcher = Agent(name="researcher", output_key="findings", output_schema=ResearchOutput, ...)
writer = Agent(name="writer", instruction="Write report based on state['findings'].", ...)
pipeline = SequentialAgent(name="pipeline", sub_agents=[researcher, writer])

Structured Output

Use Pydantic models for typed, validated agent output:

from pydantic import BaseModel

class AnalysisResult(BaseModel):
    summary: str
    key_findings: list[str]
    confidence: float
    recommendations: list[str]

agent = Agent(
    name="analyzer",
    model="gemini-2.5-flash",
    instruction="Analyze the provided data and return structured results.",
    output_schema=AnalysisResult,
    output_key="analysis",  # Stored in state["analysis"]
)

Running and Testing

Local Development

# Install
pip install google-adk

# Set API key
export GOOGLE_API_KEY="your-key"

# Run interactively
adk run my_agent

# Run with web UI
adk web my_agent

Testing with InMemoryRunner

import pytest
from google.adk.runners import InMemoryRunner
from google.genai import types

@pytest.mark.asyncio
async def test_agent():
    runner = InMemoryRunner(agent=root_agent, app_name="test")
    session = await runner.session_service.create_session(
        user_id="test_user", app_name="test",
    )
    content = types.Content(
        role="user", parts=[types.Part.from_text(text="Hello")],
    )
    events = []
    async for event in runner.run_async(
        user_id="test_user", session_id=session.id, new_message=content,
    ):
        events.append(event)
    assert "expected" in events[-1].content.parts[0].text.lower()

Evaluation

ADK provides built-in evaluation for tool correctness, response quality, and safety. Define eval cases in

.test.json
files and run with
adk eval
,
pytest
, or the web UI. See references/evaluation.md for eval data formats, all 8 metrics, and patterns.


Model Selection

Use

gemini-2.5-flash
for most agents (fast, cost-effective). Use
gemini-2.5-pro
for complex reasoning. Configure via
generate_content_config=types.GenerateContentConfig(temperature=0.2)
.


Design Patterns

PatternWhen to UseADK Implementation
Sequential pipelineMulti-step tasks with dependencies
SequentialAgent
with ordered sub-agents
Fan-out / Fan-inIndependent tasks then synthesis
ParallelAgent
→ merger
Agent
Reflection loopQuality matters more than speed
LoopAgent
with producer + critic agents
Dynamic routingDiverse inputs need different handlingParent
Agent
with
sub_agents
(Auto-Flow)
Layered fallbackTool failures need graceful recovery
SequentialAgent
: primary → fallback → response
Guardrailed agentSafety/compliance requirements
before_model_callback
+
before_tool_callback
Resource tieringCost optimization under constraintsDifferent
model
per agent (Pro vs Flash)

Key design rules:

  • Split agents with 5+ tools into focused specialists. One agent = one responsibility.
  • Pass data between agents via
    output_key
    +
    output_schema
    (Pydantic) -- never rely on free text.
  • Set
    max_iterations
    on every
    LoopAgent
    . No exceptions.
  • Separate generation from evaluation -- use a different agent to critique (avoids self-review bias).
  • Write precise sub-agent
    description
    fields -- they drive Auto-Flow routing decisions.
  • Embed reasoning steps in instructions: "1. Analyze 2. Plan 3. Execute 4. Verify".
  • Include a fallback route for unclear inputs -- ambiguous requests must not be silently misrouted.

For hierarchical workflows, agent transfer, and deployment patterns, see references/advanced-patterns.md. For comprehensive design patterns (chaining, reflection, planning, memory, error handling, HITL, guardrails, RAG, resource optimization, reasoning, evaluation, prompting), see references/design-patterns.md. For A2A (Agent-to-Agent) protocol patterns -- exposing agents as A2A servers, consuming remote agents with

RemoteA2aAgent
, agent cards, and cross-service communication -- see references/a2a-protocol.md. For common errors, debugging, and performance tips, see references/troubleshooting.md.


Decision Guide

When to use which agent type:

Single task, one LLM call? → Agent / LlmAgent
Steps must run in order? → SequentialAgent
Steps are independent? → ParallelAgent
Need iteration/refinement? → LoopAgent
Need on-demand delegation? → AgentTool
Remote agent, different service? → RemoteA2aAgent (A2A)
Complex multi-stage? → Compose agent types

When to use which tool type:

Simple function? → Python function with type hints
Need state access? → Add ToolContext parameter
Delegate to another agent? → AgentTool
Remote agent over network? → RemoteA2aAgent (A2A protocol)
External MCP server? → MCPToolset
Database access? → ToolboxToolset
Web search? → google_search (built-in)