xiaohongshu
xiaohongshu
building-with-google-adk
Use when building AI agents with Google's Agent Development Kit (ADK). Triggers include creating ADK agents, Gemini-powered agents, multi-agent workflows, MCP integration with ADK, agent evaluation, workflow agents (Sequential/Parallel/Loop), Vertex AI deployment, or comparing OpenAI SDK with ADK...
Full skill instructions
Build production-grade AI agents using Google's Agent Development Kit.
# Install ADK
pip install google-adk
# Or with uv (recommended)
uv add google-adk
# Create new agent project
adk create my_agent
# Run locally
adk run my_agent
# Web UI for debugging
adk web
# .env
GOOGLE_API_KEY=your_gemini_api_key
# .env
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_PROJECT=your_project_id
GOOGLE_CLOUD_LOCATION=us-central1
# Authenticate with gcloud
gcloud auth application-default login
gcloud services enable aiplatform.googleapis.com
┌─────────────────────────────────────────────────────────────────┐
│ ADK Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ LlmAgent │ │WorkflowAgent │ │ BaseAgent │ │
│ │ (AI-driven) │ │(Deterministic)│ │ (Custom) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └──────────┬────────┴───────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Runner │ │
│ │ Orchestrates agent execution, handles events, state │ │
│ └────────────────────────┬────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┴────────────────────────────────┐ │
│ │ SessionService │ │
│ │ InMemory (dev) | Firestore | VertexAI (production) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Tools │ │
│ │ FunctionTool | google_search | McpToolset | AgentTool │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
from google.adk.agents import Agent
from google.adk.tools import google_search
root_agent = Agent(
name="assistant",
model="gemini-2.5-flash",
instruction="You are a helpful assistant. Answer user questions.",
description="Main assistant for general queries.",
tools=[google_search]
)
from google.adk.agents import LlmAgent, SequentialAgent
researcher = LlmAgent(
name="researcher",
model="gemini-2.5-flash",
instruction="Research the topic thoroughly.",
tools=[google_search]
)
writer = LlmAgent(
name="writer",
model="gemini-2.5-flash",
instruction="Write an article based on the research."
)
pipeline = SequentialAgent(
name="content_pipeline",
description="Research, then write.",
sub_agents=[researcher, writer]
)
from google.adk.agents import LlmAgent, ParallelAgent
fact_checker = LlmAgent(name="fact_checker", ...)
sentiment_analyzer = LlmAgent(name="sentiment", ...)
parallel_analysis = ParallelAgent(
name="analysis",
description="Run fact-checking and sentiment analysis in parallel.",
sub_agents=[fact_checker, sentiment_analyzer]
)
from google.adk.agents import LlmAgent, LoopAgent
from google.adk.tools import exit_loop
solver = LlmAgent(
name="solver",
model="gemini-2.5-flash",
instruction="Solve the problem. Call exit_loop when complete.",
tools=[exit_loop]
)
iterative_solver = LoopAgent(
name="iterative_solver",
description="Iterate until solution found.",
sub_agents=[solver],
max_iterations=5
)
from google.adk.tools import FunctionTool
def get_weather(city: str) -> dict:
"""Get weather for a city.
Args:
city: The city name to get weather for.
Returns:
Weather data including temperature and conditions.
"""
# Implementation
return {"city": city, "temp": "22°C", "condition": "Sunny"}
agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
instruction="Provide weather information.",
tools=[get_weather] # ADK auto-wraps as FunctionTool
)
from google.adk.tools import google_search
from google.adk.code_executors import BuiltInCodeExecutor
agent = Agent(
name="research_agent",
model="gemini-2.0-flash",
tools=[google_search],
code_executor=BuiltInCodeExecutor() # Enables code execution
)
from google.adk.tools.agent_tool import AgentTool
search_agent = Agent(
name="search_agent",
model="gemini-2.0-flash",
tools=[google_search],
instruction="You specialize in Google searches."
)
code_agent = Agent(
name="code_agent",
model="gemini-2.0-flash",
code_executor=BuiltInCodeExecutor(),
instruction="You specialize in code execution."
)
# Coordinator uses other agents as tools
root_agent = Agent(
name="coordinator",
model="gemini-2.0-flash",
instruction="Delegate search tasks to search_agent, code to code_agent.",
tools=[AgentTool(agent=search_agent), AgentTool(agent=code_agent)]
)
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
root_agent = LlmAgent(
model='gemini-2.0-flash',
name='filesystem_agent',
instruction='Help users manage their files.',
tools=[
McpToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command='npx',
args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
)
)
)
]
)
adk run my_agent # Terminal chat
adk web # Web UI with debugging
from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
agent = Agent(
name="assistant",
model="gemini-2.5-flash",
instruction="You are helpful."
)
runner = Runner(
app_name="my_app",
agent=agent,
session_service=InMemorySessionService()
)
async def run():
session = await runner.session_service.create_session(
app_name="my_app",
user_id="user123"
)
message = types.Content(
role='user',
parts=[types.Part(text="Hello!")]
)
async for event in runner.run_async(
user_id=session.user_id,
session_id=session.id,
new_message=message
):
if event.content and event.content.parts:
for part in event.content.parts:
if part.text:
print(part.text)
from google.adk.runners import InMemoryRunner
runner = InMemoryRunner(agent=agent)
await runner.run_debug("Hello!") # Quick test
# Access state in tool functions
from google.adk.tools.tool_context import ToolContext
def get_preference(tool_context: ToolContext) -> str:
"""Get user preference from session state."""
return tool_context.state.get("preference", "default")
def set_preference(preference: str, tool_context: ToolContext) -> dict:
"""Set user preference in session state."""
tool_context.state["preference"] = preference
return {"status": "saved"}
# Firestore for persistence
from google.adk.sessions import FirestoreSessionService
session_service = FirestoreSessionService(
project="your-project",
database="(default)"
)
# Vertex AI for managed deployment
from google.adk.sessions import VertexAiSessionService
session_service = VertexAiSessionService(
project="your-project",
location="us-central1"
)
from google.adk.agents.callback_context import CallbackContext
from google.adk.models.llm_request import LlmRequest
from google.adk.models.llm_response import LlmResponse
from google.genai import types
from typing import Optional
def block_keyword_guardrail(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
"""Block requests containing BLOCK keyword."""
last_message = ""
if llm_request.contents:
for content in reversed(llm_request.contents):
if content.role == 'user' and content.parts:
last_message = content.parts[0].text or ""
break
if "BLOCK" in last_message.upper():
return LlmResponse(
content=types.Content(
role="model",
parts=[types.Part(text="Request blocked by guardrail.")]
)
)
return None # Allow request to proceed
agent = Agent(
name="guarded_agent",
model="gemini-2.5-flash",
instruction="You are helpful.",
before_model_callback=block_keyword_guardrail
)
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.tool_context import ToolContext
from typing import Optional, Dict, Any
def block_sensitive_city(
tool: BaseTool,
args: Dict[str, Any],
tool_context: ToolContext
) -> Optional[Dict]:
"""Block weather requests for Paris."""
if tool.name == "get_weather":
city = args.get("city", "").lower()
if city == "paris":
return {
"status": "error",
"message": "Weather for Paris is restricted."
}
return None # Allow tool execution
agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
tools=[get_weather],
before_tool_callback=block_sensitive_city
)
{
"eval_set_id": "weather_agent_tests",
"eval_cases": [
{
"eval_id": "basic_weather_request",
"conversation": [
{
"user_content": {
"parts": [{"text": "What's the weather in London?"}],
"role": "user"
},
"final_response": {
"parts": [{"text": "The weather in London is..."}],
"role": "model"
},
"intermediate_data": {
"tool_uses": [
{"name": "get_weather", "args": {"city": "London"}}
]
}
}
],
"session_input": {
"app_name": "weather_agent",
"user_id": "test_user"
}
}
]
}
# CLI
adk eval ./agent.py ./tests/eval_set.test.json --print_detailed_results
# Pytest integration
pytest tests/integration/
from google.adk.evaluation.agent_evaluator import AgentEvaluator
@pytest.mark.asyncio
async def test_weather_agent():
await AgentEvaluator.evaluate(
agent_module="weather_agent",
eval_dataset_file_path_or_dir="tests/weather_tests.test.json"
)
uv run adk deploy agent_engine \
--project=your-project-id \
--region=us-central1 \
--staging_bucket="gs://your-bucket" \
--display_name="My Agent" \
./my_agent
uv run adk deploy cloud_run \
--project=your-project-id \
--region=us-central1 \
--service_name=my-agent-service \
./my_agent
from vertexai.preview import reasoning_engines
from vertexai import agent_engines
import vertexai
vertexai.init(
project="your-project",
location="us-central1",
staging_bucket="gs://your-bucket"
)
adk_app = reasoning_engines.AdkApp(
agent=root_agent,
enable_tracing=True
)
remote_app = agent_engines.create(
agent_engine=adk_app,
extra_packages=["./my_agent"],
requirements=["google-cloud-aiplatform[adk,agent_engines]"]
)
| Scenario | Pattern | Why |
|---|---|---|
| Simple Q&A | Single Agent | Minimal overhead |
| Research → Write → Edit | SequentialAgent | Clear pipeline |
| Parallel analysis | ParallelAgent | Faster execution |
| Iterative refinement | LoopAgent | Convergence-based |
| Specialized routing | Agent with sub_agents | LLM-driven delegation |
| Explicit tool routing | Multiple AgentTool | Coordinator pattern |
| MCP server connection | McpToolset | Standard protocol |
| Production persistence | VertexAiSessionService | Managed, scalable |
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from typing import List, Optional
# In-memory task storage
tasks: List[dict] = []
def add_task(title: str, description: Optional[str] = None) -> dict:
"""Add a new task."""
task = {
"id": len(tasks) + 1,
"title": title,
"description": description,
"completed": False
}
tasks.append(task)
return {"status": "created", "task": task}
def list_tasks() -> dict:
"""List all tasks."""
return {"tasks": tasks}
def complete_task(task_id: int) -> dict:
"""Mark a task as completed."""
for task in tasks:
if task["id"] == task_id:
task["completed"] = True
return {"status": "completed", "task": task}
return {"status": "error", "message": f"Task {task_id} not found"}
def delete_task(task_id: int) -> dict:
"""Delete a task."""
global tasks
tasks = [t for t in tasks if t["id"] != task_id]
return {"status": "deleted", "task_id": task_id}
root_agent = Agent(
name="task_manager",
model="gemini-2.5-flash",
instruction="""You are a TaskManager assistant.
Help users manage their tasks:
- Add new tasks with add_task
- List all tasks with list_tasks
- Complete tasks with complete_task
- Delete tasks with delete_task
Always confirm actions and show current task list after changes.""",
tools=[add_task, list_tasks, complete_task, delete_task]
)
| Issue | Symptom | Fix |
|---|---|---|
| Auth not working | 403 errors | Check GOOGLE_API_KEY or Vertex AI setup |
| Tools not called | Agent ignores tools | Improve instruction clarity |
| State not persisting | Data lost between runs | Use FirestoreSessionService |
| MCP server not connecting | Tool discovery fails | Verify absolute paths, check npx |
| Slow first request | 5+ second delay | Pre-warm session service |
| Sub-agents not used | Delegation fails | Add clear description to sub-agents |
Run: python3 scripts/verify.py
Expected: ✓ building-with-google-adk valid
.env has valid GOOGLE_API_KEY or Vertex AI configname, model, instruction)xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience