google-adk
Skill275 starsChanged 36 days agoApache-2.0View on GitHub
Best practices for building AI agents with Google's Agent Development Kit (ADK) in Python, covering agent design, tools, sessions, memory, artifacts, evaluation, and deployment. Use when building LLM agents or multi-agent systems with ADK, defining ADK tools, wiring up sessions/state/memory, working with ADK artifacts, writing agent evals, or deploying ADK agents to Vertex AI Agent Engine or Cloud Run.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- sheikh-mohammad/agent-factory-claude-skillstheir own version, first seen Aug 4, 2026
- kumaran-is/claude-code-onboardingtheir own version, first seen May 25, 2026
- milistu/agent-skillstheir own version, first seen Mar 2, 2026
- prakhar1989/adk-skilltheir own version, first seen Jan 16, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- kumaran-is/claude-code-onboarding★ 35same name
- milistu/agent-skills★ 8same name
- sheikh-mohammad/agent-factory-claude-skills★ 6same name
- prakhar1989/adk-skill★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository264 other files it gives its agents.
- accessibility-a11ySkill
- alpine-jsSkill
- analytics-data-analysisSkill
- android-developmentSkill
- angular-developmentSkill
- angularSkill
- anime-jsSkill
- anthropic-claude-developmentSkill
- api-developmentSkill
- apollo-graphqlSkill
- aspnet-coreSkill
- astroSkill
- auth0-authenticationSkill
- autogen-developmentSkill
- automl-hyperparameter-optimizationSkill
- aws-developmentSkill
- azureSkill
- backend-developmentSkill
- bash-scriptingSkill
- beautifulsoup-parsingSkill
- bitbucket-workflowSkill
- blazorSkill
- blender-python-addonSkill
- blockchainSkill
- bootstrapSkill
- business-central-developmentSkill
- cheerio-parsingSkill
- chrome-extension-developmentSkill
- ci-cd-best-practicesSkill
- clean-architectureSkill
- clean-codeSkill
- clerk-authenticationSkill
- cloudflare-developmentSkill
- computer-vision-opencvSkill
- convexSkill
- cppSkill
- c-sharpSkill
- cssSkill
- cypressSkill
- data-analysis-jupyterSkill
- data-analystSkill
- data-jupyter-pythonSkill
- deep-learning-pythonSkill
- deep-learning-pytorchSkill
- deep-learningSkill
- deno-typescriptSkill
- design-systemsSkill
- devopsSkill
- django-pythonSkill
- django-rest-api-developmentSkill
- dockerSkill
- dotnetSkill
- drizzle-ormSkill
- drupal-developmentSkill
- elasticsearch-best-practicesSkill
- electron-developmentSkill
- elixirSkill
- embedded-stm32Skill
- esbuild-bundlerSkill
- ethereumSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. 0 are common, 5 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Keep each agent focused on a single clear goal, persona, and tool set — avoid one agent that tries to do everything.
- Very specific: line 28
Use LlmAgent for flexible, reasoning-driven behavior and workflow agents (SequentialAgent, ParallelAgent, LoopAgent) for deterministic …
- Very specific: line 29
Write instructions that define task boundaries, tool-use rules ("always call lookup_order before answering order questions"), and …
- Very specific: line 31
Keep the model name configurable (environment variable or config file) so it can be swapped across gemini-2.0-flash, gemini-2.5-pro, or …
- Very specific: line 32
Use output_schema (a Pydantic model) when the agent's final response must be structured data consumed by other code.
- Distinctive: line 38
Keep secrets, credentials, and privileged API keys out of agent instructions and prompts.
- Very specific: line 41
Prefer FunctionTool for custom Python logic, AgentTool to let one agent call another agent as a tool, and built-in tools (google_search, …
- Very specific: line 112
Use session.state for current-conversation data — user preferences discovered mid-conversation, counters, intermediate results.
- Very specific: line 113
Use a MemoryService for cross-session recall and retrieval (facts that should persist after the session ends and be searchable in future …
- Distinctive: line 114
Keep state values small and serializable (strings, numbers, small dicts/lists) — never store large files or binary payloads directly in …
- Distinctive: line 120
Use artifacts for generated files, uploaded files, reports, images, audio, and any other binary data — not session state.
- Very specific: line 127
Add .evalset.json test cases covering tool-call trajectories (which tools were called, in what order, with what arguments) and final …
- Very specific: line 128
Run adk eval <agent_module> <eval_set_file> in CI to catch prompt regressions before merging instruction changes.
- Very specific: line 129
Use ADK's trace and event logs (adk web's trace view, or Runner events) to debug agent decisions — inspect which tool was called, what …
- Very specific: line 130
Keep local development, staging, and production configuration separate (different SessionService/ArtifactService backends, different API …
- Distinctive: line 131
Add observability for latency, tool failures, token use, and handoff failures — wrap tool functions with timing/logging decorators and …
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Google Agent Development Kit (ADK)
This skill covers building production-grade AI agents with Google's Agent Development Kit (ADK) for Python, including agent composition, tool design, session/state/memory management, artifacts, evaluation, and deployment.
Workflow for Building an ADK Agent
- Define the agent — Create an
LlmAgent(orAgent) with a clearname,model,instruction, anddescription. Keep the instruction focused on one job. - Author tools — Write plain Python functions with type hints and docstrings, or wrap existing APIs with
FunctionTool. Validate all inputs before side effects. - Compose multi-agent systems — For complex workflows, split responsibility across sub-agents and use
SequentialAgent,ParallelAgent, orLoopAgentfor deterministic orchestration, or delegate viasub_agentsfor LLM-driven routing. - Wire up session and state — Choose a
SessionService(in-memory for dev,DatabaseSessionServiceor Vertex AI-managed for production) and usesession.statefor conversation-scoped data. - Add memory (optional) — Configure a
MemoryServicefor cross-session recall when the agent needs to remember facts between separate conversations. - Handle artifacts (optional) — Configure an
ArtifactServicewhen the agent generates or receives files, images, or other binary outputs. - Run locally — Use
adk web,adk run, or theRunnerAPI to exercise the agent against aSession. - Evaluate — Write
.evalset.jsontest cases and runadk evalto check tool-call trajectories and response quality against regressions. - Deploy — Package the agent for Vertex AI Agent Engine, Cloud Run, or GKE, and separate dev/staging/prod configuration.
Agent Design
- Keep each agent focused on a single clear goal, persona, and tool set — avoid one agent that tries to do everything.
- Use
LlmAgentfor flexible, reasoning-driven behavior and workflow agents (SequentialAgent,ParallelAgent,LoopAgent) for deterministic orchestration that doesn't need an LLM to decide the next step. - Write instructions that define task boundaries, tool-use rules ("always call
lookup_orderbefore answering order questions"), and escalation behavior ("if you cannot resolve the issue, transfer tohuman_handoff_agent"). - Split multi-agent systems by responsibility (e.g., a "triage" agent, a "billing" agent, a "technical support" agent) rather than by implementation convenience.
- Keep the model name configurable (environment variable or config file) so it can be swapped across
gemini-2.0-flash,gemini-2.5-pro, or other supported models without code changes. - Use
output_schema(a Pydantic model) when the agent's final response must be structured data consumed by other code.
Tools
- Give tools narrow, typed inputs and outputs — a single function should do one thing, with a docstring the LLM uses to decide when to call it.
- Validate tool arguments before performing any side effect (writes, external calls, payments).
- Keep secrets, credentials, and privileged API keys out of agent instructions and prompts; inject them at the tool implementation layer instead.
- Handle tool errors explicitly and return actionable failure messages (e.g.,
{"status": "error", "message": "order_id not found"}) rather than raising unhandled exceptions that break the agent loop. - Be aware of ADK tool limitations — some built-in tools (e.g.,
google_search,code_execution) cannot be combined with other tools on the same agent; delegate to a dedicated sub-agent instead. - Prefer
FunctionToolfor custom Python logic,AgentToolto let one agent call another agent as a tool, and built-in tools (google_search,BuiltInCodeExecutor) only when their constraints fit the use case.
Example: Defining an Agent with Tools
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from google.adk.runners import InMemoryRunner
from google.genai import types
def get_order_status(order_id: str) -> dict:
"""Look up the current status of a customer order.
Args:
order_id: The unique identifier of the order, e.g. "ord-12345".
Returns:
A dict with 'status' ('found' or 'error') and either 'state'
and 'updated_at', or an error 'message'.
"""
if not order_id or not order_id.startswith("ord-"):
return {"status": "error", "message": "invalid order_id format"}
# In production this would call a real order service.
orders = {"ord-12345": {"state": "shipped", "updated_at": "2026-08-30T10:00:00Z"}}
order = orders.get(order_id)
if order is None:
return {"status": "error", "message": f"no order found for {order_id}"}
return {"status": "found", **order}
root_agent = Agent(
name="order_support_agent",
model="gemini-2.0-flash",
description="Answers customer questions about order status.",
instruction=(
"You help customers check their order status. "
"Always call get_order_status before answering an order question. "
"If the tool returns an error, apologize and ask the customer to "
"double-check their order ID. Never invent an order status."
),
tools=[FunctionTool(func=get_order_status)],
)
async def main() -> None:
runner = InMemoryRunner(agent=root_agent, app_name="order_support")
session = await runner.session_service.create_session(
app_name="order_support", user_id="user-1"
)
message = types.Content(
role="user", parts=[types.Part(text="What's the status of ord-12345?")]
)
async for event in runner.run_async(
user_id="user-1", 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)
if __name__ == "__main__":
import asyncio
asyncio.run(main())Sessions, State, and Memory
- Use
session.statefor current-conversation data — user preferences discovered mid-conversation, counters, intermediate results. - Use a
MemoryServicefor cross-session recall and retrieval (facts that should persist after the session ends and be searchable in future sessions). - Keep state values small and serializable (strings, numbers, small dicts/lists) — never store large files or binary payloads directly in session state.
- Make state keys stable and documented; use prefixes (
user:,app:,temp:) to scope state lifetime consistently across the app. - For production, use
DatabaseSessionServiceor the managed Vertex AI session service instead ofInMemorySessionService, which loses all state on process restart.
Artifacts
- Use artifacts for generated files, uploaded files, reports, images, audio, and any other binary data — not session state.
- Configure an
ArtifactService(e.g.,InMemoryArtifactServicefor dev,GcsArtifactServicefor production) on theRunnerbefore relying on artifact operations likesave_artifactorload_artifact. - Version artifact filenames intentionally (ADK auto-increments versions per filename) and avoid overwriting semantically different outputs under the same name.
- Store only references or short summaries in session state when the full content belongs in an artifact — e.g., keep
report_v2.pdfas the artifact and"generated report v2"as the state note.
Evaluation and Deployment
- Add
.evalset.jsontest cases covering tool-call trajectories (which tools were called, in what order, with what arguments) and final response quality. - Run
adk eval <agent_module> <eval_set_file>in CI to catch prompt regressions before merging instruction changes. - Use ADK's trace and event logs (
adk web's trace view, orRunnerevents) to debug agent decisions — inspect which tool was called, what arguments were passed, and what the model saw. - Keep local development, staging, and production configuration separate (different
SessionService/ArtifactServicebackends, different API keys, different model tiers). - Add observability for latency, tool failures, token use, and handoff failures — wrap tool functions with timing/logging decorators and export metrics to your existing monitoring stack.
- Deploy to Vertex AI Agent Engine for a managed, autoscaled runtime, or containerize with
adk deploy cloud_run/ a custom Dockerfile for Cloud Run or GKE when more control over the environment is needed.
Common Mistakes
- Making one agent responsible for every workflow instead of decomposing into focused sub-agents.
- Letting tools accept arbitrary shell, SQL, or HTTP input without validation, which turns a tool call into an injection vector.
- Relying on prompt text for access control — instructions like "never reveal other users' data" are guidance, not enforcement; check permissions in tool code.
- Hiding important side effects (payments, deletions, external notifications) behind generic tool names like
processorhandle— name tools for what they actually do. - Forgetting to set
output_keyoroutput_schemawhen downstream code depends on a structured final response, leading to fragile string parsing. - Skipping evals on instruction changes — a rephrased prompt can silently change which tools the model chooses to call.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

