npx skills add https://github.com/google/adk-docs
eliasecchig/adk-skills · Archived
adk-eval-guide
MUST READ before running any ADK evaluation. ADK evaluation methodology — eval metrics, evalset schema, LLM-as-judge, tool trajectory scoring, and common failure causes. Use when evaluating agent quality, running adk eval, or debugging eval results. Do NOT use for API code patterns (use adk-cheatsheet), deployment (use adk-deploy-guide), or project scaffolding (use adk-scaffold).
Installation
npx skills add eliasecchig/adk-skills --skill adk-eval-guide
Stronger alternatives
This repository is archived — consider an actively maintained alternative.
ALWAYS ACTIVE — read at the start of any ADK agent development session. ADK development lifecyc…
12 installsMUST READ before creating or enhancing any ADK agent project. Use when the user wants to build …
9 installsMUST READ before deploying any ADK agent. ADK deployment guide — Agent Engine, Cloud Run, GKE, …
9 installsMUST READ before writing or modifying ADK agent code. ADK API quick reference for Python — agen…
9 installsSimilar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Guidance for distinctive, intentional visual design when building new UI or reshaping an existi…
866.4K installsBrowser automation CLI for AI agents. Use when the user needs to interact with websites, includ…
810.4K installsReview UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "chec…
617.3K installsBuild, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and …
576.5K installsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe …
568.9K installsAlso in this package
Other skills from eliasecchig/adk-skills.
npx skills add eliasecchig/adk-skills
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
Repository health
main
Skill metadata
Parsed from SKILL.md frontmatter.
More metadata
- author
- version
- 0.3.0
- managed-by
- adk-skills-setup
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md11,796 B -
docs
SUMMARY.md406 B
History
- First recorded snapshot · 9 installs
SKILL.md
ADK Evaluation Guide
Scaffolded project? If you used
/adk-scaffold, you already havemake eval,tests/eval/evalsets/, andtests/eval/eval_config.json. Start withmake evaland iterate from there.
Non-scaffolded? Useadk evaldirectly — see [Running Evaluations](#running-evaluations) below.
Reference Files
| File | Contents |
|---|---|
references/criteria-guide.md |
Complete metrics reference — all 8 criteria, match types, custom metrics, judge model config |
references/user-simulation.md |
Dynamic conversation testing — ConversationScenario, user simulator config, compatible metrics |
references/builtin-tools-eval.md |
google_search and model-internal tools — trajectory behavior, metric compatibility |
references/multimodal-eval.md |
Multimodal inputs — evalset schema, built-in metric limitations, custom evaluator pattern |
The Eval-Fix Loop
Evaluation is iterative. When a score is below threshold, diagnose the cause, fix it, rerun — don't just report the failure.
How to iterate
- Start small: Begin with 1-2 eval cases, not the full suite
- Run eval:
make eval(oradk evalif no Makefile) - Read the scores — identify what failed and why
- Fix the code — adjust prompts, tool logic, instructions, or the evalset
- Rerun eval — verify the fix worked
- Repeat steps 3-5 until the case passes
- Only then add more eval cases and expand coverage
Expect 5-10+ iterations. This is normal — each iteration makes the agent better.
What to fix when scores fail
| Failure | What to change |
|---|---|
tooltrajectoryavg_score low |
Fix agent instructions (tool ordering), update evalset tooluses, or switch to INORDER/ANY_ORDER match type |
responsematchscore low |
Adjust agent instruction wording, or relax the expected response |
finalresponsematch_v2 low |
Refine agent instructions, or adjust expected response — this is semantic, not lexical |
rubric_based score low |
Refine agent instructions to address the specific rubric that failed |
hallucinations_v1 low |
Tighten agent instructions to stay grounded in tool output |
| Agent calls wrong tools | Fix tool descriptions, agent instructions, or tool_config |
| Agent calls extra tools | Use INORDER/ANYORDER match type, add strict stop instructions, or switch to rubricbasedtoolusequality_v1 |
Choosing the Right Criteria
| Goal | Recommended Metric |
|---|---|
| Regression testing / CI/CD (fast, deterministic) | tooltrajectoryavgscore + responsematch_score |
| Semantic response correctness (flexible phrasing OK) | finalresponsematch_v2 |
| Response quality without reference answer | rubricbasedfinalresponsequality_v1 |
| Validate tool usage reasoning | rubricbasedtoolusequality_v1 |
| Detect hallucinated claims | hallucinations_v1 |
| Safety compliance | safety_v1 |
| Dynamic multi-turn conversations | User simulation + hallucinationsv1 / safetyv1 (see references/user-simulation.md) |
| Multimodal input (image, audio, file) | tooltrajectoryavg_score + custom metric for response quality (see references/multimodal-eval.md) |
For the complete metrics reference with config examples, match types, and custom metrics, see references/criteria-guide.md.
Running Evaluations
# Scaffolded projects:
make eval EVALSET=tests/eval/evalsets/my_evalset.json
# Or directly via ADK CLI:
adk eval ./app <path_to_evalset.json> --config_file_path=<path_to_config.json> --print_detailed_results
# Run specific eval cases from a set:
adk eval ./app my_evalset.json:eval_1,eval_2
# With GCS storage:
adk eval ./app my_evalset.json --eval_storage_uri gs://my-bucket/evals
CLI options: --configfilepath, --printdetailedresults, --evalstorageuri, --log_level
Eval set management:
adk eval_set create <agent_path> <eval_set_id>
adk eval_set add_eval_case <agent_path> <eval_set_id> --scenarios_file <path> --session_input_file <path>
Configuration Schema (test_config.json)
Both camelCase and snakecase field names are accepted (Pydantic aliases). The examples below use snakecase, matching the official ADK docs.
Full example
{
"criteria": {
"tool_trajectory_avg_score": {
"threshold": 1.0,
"match_type": "IN_ORDER"
},
"final_response_match_v2": {
"threshold": 0.8,
"judge_model_options": {
"judge_model": "gemini-2.5-flash",
"num_samples": 5
}
},
"rubric_based_final_response_quality_v1": {
"threshold": 0.8,
"rubrics": [
{
"rubric_id": "professionalism",
"rubric_content": { "text_property": "The response must be professional and helpful." }
},
{
"rubric_id": "safety",
"rubric_content": { "text_property": "The agent must NEVER book without asking for confirmation." }
}
]
}
}
}
Simple threshold shorthand is also valid: "responsematchscore": 0.8
For custom metrics, judgemodeloptions details, and usersimulatorconfig, see references/criteria-guide.md.
EvalSet Schema (evalset.json)
{
"eval_set_id": "my_eval_set",
"name": "My Eval Set",
"description": "Tests core capabilities",
"eval_cases": [
{
"eval_id": "search_test",
"conversation": [
{
"invocation_id": "inv_1",
"user_content": { "parts": [{ "text": "Find a flight to NYC" }] },
"final_response": {
"role": "model",
"parts": [{ "text": "I found a flight for $500. Want to book?" }]
},
"intermediate_data": {
"tool_uses": [
{ "name": "search_flights", "args": { "destination": "NYC" } }
],
"intermediate_responses": [
["sub_agent_name", [{ "text": "Found 3 flights to NYC." }]]
]
}
}
],
"session_input": { "app_name": "my_app", "user_id": "user_1", "state": {} }
}
]
}
Key fields:
intermediatedata.tooluses— expected tool call trajectory (chronological order)intermediatedata.intermediateresponses— expected sub-agent responses (for multi-agent systems)session_input.state— initial session state (overrides Python-level initialization)conversation_scenario— alternative toconversationfor user simulation (seereferences/user-simulation.md)
Common Gotchas
The Proactivity Trajectory Gap
LLMs often perform extra actions not asked for (e.g., googlesearch after savepreferences). This causes tooltrajectoryavg_score failures with EXACT match. Solutions:
- Use
INORDERorANYORDERmatch type — tolerates extra tool calls between expected ones - Include ALL tools the agent might call in your expected trajectory
- Use
rubricbasedtoolusequality_v1instead of trajectory matching - Add strict stop instructions: "Stop after calling save_preferences. Do NOT search."
Multi-turn conversations require tool_uses for ALL turns
The tooltrajectoryavg_score evaluates each invocation. If you don't specify expected tool calls for intermediate turns, the evaluation will fail even if the agent called the right tools.
{
"conversation": [
{
"invocation_id": "inv_1",
"user_content": { "parts": [{"text": "Find me a flight from NYC to London"}] },
"intermediate_data": {
"tool_uses": [
{ "name": "search_flights", "args": {"origin": "NYC", "destination": "LON"} }
]
}
},
{
"invocation_id": "inv_2",
"user_content": { "parts": [{"text": "Book the first option"}] },
"final_response": { "role": "model", "parts": [{"text": "Booking confirmed!"}] },
"intermediate_data": {
"tool_uses": [
{ "name": "book_flight", "args": {"flight_id": "1"} }
]
}
}
]
}
App name must match directory name
The App object's name parameter MUST match the directory containing your agent:
# CORRECT - matches the "app" directory
app = App(root_agent=root_agent, name="app")
# WRONG - causes "Session not found" errors
app = App(root_agent=root_agent, name="flight_booking_assistant")
The beforeagentcallback Pattern (State Initialization)
Always use a callback to initialize session state variables used in your instruction template. This prevents KeyError crashes on the first turn:
async def initialize_state(callback_context: CallbackContext) -> None:
state = callback_context.state
if "user_preferences" not in state:
state["user_preferences"] = {}
root_agent = Agent(
name="my_agent",
before_agent_callback=initialize_state,
instruction="Based on preferences: {user_preferences}...",
)
Eval-State Overrides (Type Mismatch Danger)
Be careful with session_input.state in your evalset. It overrides Python-level initialization:
// WRONG - initializes feedback_history as a string, breaks .append()
"state": { "feedback_history": "" }
// CORRECT - matches the Python type (list)
"state": { "feedback_history": [] }
Model thinking mode may bypass tools
Models with "thinking" enabled may skip tool calls. Use tool_config with mode="ANY" to force tool usage, or switch to a non-thinking model for predictable tool calling.
Common Eval Failure Causes
| Symptom | Cause | Fix |
|---|---|---|
Missing tool_uses in intermediate turns |
Trajectory expects match per invocation | Add expected tool calls to all turns |
| Agent mentions data not in tool output | Hallucination | Tighten agent instructions; add hallucinations_v1 metric |
| "Session not found" error | App name mismatch | Ensure App name matches directory name |
| Score fluctuates between runs | Non-deterministic model | Set temperature=0 or use rubric-based eval |
tooltrajectoryavg_score always 0 |
Agent uses google_search (model-internal) |
Remove trajectory metric; see references/builtin-tools-eval.md |
| Trajectory fails but tools are correct | Extra tools called | Switch to INORDER/ANYORDER match type |
| LLM judge ignores image/audio in eval | gettextfrom_content() skips non-text parts |
Use custom metric with vision-capable judge (see references/multimodal-eval.md) |
Deep Dive: ADK Docs
For the official evaluation documentation, fetch these pages using WebFetch:
- Evaluation overview:
https://google.github.io/adk-docs/evaluate/index.md - Criteria reference:
https://google.github.io/adk-docs/evaluate/criteria/index.md - User simulation:
https://google.github.io/adk-docs/evaluate/user-sim/index.md
Debugging Example
User says: "tooltrajectoryavg_score is 0, what's wrong?"
- Check if agent uses
google_search— if so, seereferences/builtin-tools-eval.md - Check if using
EXACTmatch and agent calls extra tools — tryIN_ORDER - Compare expected
tool_usesin evalset with actual agent behavior - Fix mismatch (update evalset or agent instructions)