关于 adk-eval-guide
adk-eval-guide 是面向 ADK Agent 开发者的评估指南,涵盖指标选择、评估集配置与迭代排错。它提供从测试失败诊断到修正并重跑的实践流程。
主要功能
- 01评估指标选择与配置
- 02评估集结构说明
- 03迭代式修复评估失败
- 04多轮对话与用户模拟
- 05多模态评估参考
- 06常见问题排查
适用场景
- 01为 CI/CD 设置回归评估
- 02诊断工具调用轨迹不匹配
- 03测试多轮对话表现
- 04处理图像或音频输入评估
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ adk-docs --skill adk-eval-guide安装后在 Claude Code 中输入/adk-eval-guide确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/builtin-tools-eval.mdcriteria-guide.mdmultimodal-eval.mduser-simulation.md详细介绍
ADK 评估指南
使用脚手架生成的项目? 如果你使用了
/adk-scaffold,就已经有make eval、tests/eval/evalsets/和tests/eval/eval_config.json。从make eval开始,然后逐步迭代。未使用脚手架生成? 直接使用
adk eval— 请参阅下文的运行评估。
参考文件
| 文件 | 内容 |
|---|---|
references/criteria-guide.md | 完整的指标参考 — 全部 8 项标准、匹配类型、自定义指标、评审模型配置 |
references/user-simulation.md | 动态对话测试 — ConversationScenario、用户模拟器配置、兼容的指标 |
references/builtin-tools-eval.md | google_search 和模型内部工具 — 调用轨迹行为、指标兼容性 |
references/multimodal-eval.md | 多模态输入 — evalset 架构、内置指标限制、自定义评估器模式 |
评估修复循环
评估是一个迭代过程。当分数低于阈值时,诊断原因、修复问题并重新运行 — 不要只报告失败。
如何迭代
- 从小规模开始:从 1-2 个评估用例开始,而不是运行完整套件
- 运行评估:
make eval(如果没有 Makefile,则使用adk eval) - 查看分数 — 找出失败的项目及其原因
- 修复代码 — 调整提示词、工具逻辑、指令或 evalset
- 重新运行评估 — 验证修复是否有效
- 重复步骤 3-5,直到用例通过
- 只有这时才添加更多评估用例并扩大覆盖范围
预计迭代 5-10 次以上。 这是正常的 — 每次迭代都会让 Agent 变得更好。
分数未达标时应修复什么
| 失败项 | 修改方法 |
|---|---|
tool_trajectory_avg_score 低 | 修复 Agent 指令(工具调用顺序),更新 evalset 中的 tool_uses,或切换到 IN_ORDER/ANY_ORDER 匹配类型 |
response_match_score 低 | 调整 Agent 指令的措辞,或放宽预期回复 |
final_response_match_v2 低 | 优化 Agent 指令,或调整预期回复 — 该指标评估的是语义,而非字面匹配 |
rubric_based 分数低 | 优化 Agent 指令,以解决未通过的特定评分细则 |
hallucinations_v1 低 | 收紧 Agent 指令,确保回复以工具输出为依据 |
| Agent 调用了错误的工具 | 修复工具描述、Agent 指令或 tool_config |
| Agent 调用了多余的工具 | 使用 IN_ORDER/ANY_ORDER 匹配类型,添加严格的停止指令,或切换到 rubric_based_tool_use_quality_v1 |
选择合适的评估标准
| 目标 | 推荐指标 |
|---|---|
| 回归测试 / CI/CD(快速、确定性) | tool_trajectory_avg_score + response_match_score |
| 语义回复正确性(允许措辞灵活) | final_response_match_v2 |
| 不提供参考答案时评估回复质量 | rubric_based_final_response_quality_v1 |
| 验证工具使用推理 | rubric_based_tool_use_quality_v1 |
| 检测幻觉内容 | hallucinations_v1 |
| 安全合规性 | safety_v1 |
| 动态多轮对话 | 用户模拟 + hallucinations_v1 / safety_v1(请参阅 references/user-simulation.md) |
| 多模态输入(图像、音频、文件) | tool_trajectory_avg_score + 用于回复质量评估的自定义指标(请参阅 references/multimodal-eval.md) |
如需了解包含配置示例、匹配类型和自定义指标的完整指标参考,请参阅 references/criteria-guide.md。
运行评估
# 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 选项: --config_file_path、--print_detailed_results、--eval_storage_uri、--log_level
评估集管理:
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>
配置架构(eval_config.json)
camelCase 和 snake_case 字段名均可使用(Pydantic 别名)。以下示例使用 snake_case,与官方 ADK 文档一致。
完整示例
{
"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." }
}
]
}
}
}
也可以使用简单的阈值简写:"response_match_score": 0.8
有关自定义指标、judge_model_options 的详细信息以及 user_simulator_config,请参阅 references/criteria-guide.md。
EvalSet 架构(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": {} }
}
]
}
关键字段:
intermediate_data.tool_uses— 预期的工具调用轨迹(按时间顺序排列)intermediate_data.intermediate_responses— 预期的子 Agent 响应(适用于多 Agent 系统)session_input.state— 初始会话状态(覆盖 Python 级别的初始化)conversation_scenario— 用户模拟的conversation替代方案(参见references/user-simulation.md)
常见问题
主动性轨迹差距
大模型经常会执行用户未要求的额外操作(例如,在 save_preferences 后调用 google_search)。这会导致 EXACT 匹配下的 tool_trajectory_avg_score 评估失败。解决方案:
- 使用
IN_ORDER或ANY_ORDER匹配类型 — 容许在预期的工具调用之间出现额外调用 - 在预期轨迹中包含 Agent 可能调用的所有工具
- 使用
rubric_based_tool_use_quality_v1,而不是轨迹匹配 - 添加严格的停止指令:“调用 save_preferences 后停止。不要搜索。”
多轮对话需要为所有轮次指定 tool_uses
tool_trajectory_avg_score 会评估每次调用。如果未指定中间轮次的预期工具调用,即使 Agent 调用了正确的工具,评估也会失败。
{
"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 参数必须与 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")
before_agent_callback 模式(状态初始化)
始终使用回调初始化指令模板中使用的会话状态变量。这可以防止首轮对话时发生 KeyError 崩溃:
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}...",
)
评估状态覆盖(类型不匹配风险)
请谨慎设置评估集中的 session_input.state。它会覆盖 Python 级别的初始化:
// WRONG — initializes feedback_history as a string, breaks .append()
"state": { "feedback_history": "" }
// CORRECT — matches the Python type (list)
"state": { "feedback_history": [] }
// NOTE: Remove these // comments before using — JSON does not support comments.
模型的思考模式可能会跳过工具
启用了“思考”功能的模型可能会跳过工具调用。使用 tool_config 并设置 mode="ANY" 来强制使用工具,或切换为非思考模型,以确保工具调用行为可预测。
常见的评估失败原因
| 现象 | 原因 | 解决方法 |
|---|---|---|
中间轮次缺少 tool_uses | 轨迹要求每次调用都匹配 | 为所有轮次添加预期的工具调用 |
| Agent 提及工具输出中没有的数据 | 幻觉 | 收紧 Agent 指令;添加 hallucinations_v1 指标 |
| “Session not found” 错误 | 应用名称不匹配 | 确保 App 的 name 与目录名称一致 |
| 分数在不同运行之间波动 | 模型具有非确定性 | 设置 temperature=0 或使用基于评分标准的评估 |
tool_trajectory_avg_score 始终为 0 | Agent 使用了 google_search(模型内部工具) | 移除轨迹指标;参见 references/builtin-tools-eval.md |
| 轨迹评估失败,但工具调用正确 | 调用了额外工具 | 切换为 IN_ORDER/ANY_ORDER 匹配类型 |
| LLM 评审器忽略评估中的图像/音频 | get_text_from_content() 会跳过非文本部分 | 使用支持视觉能力的评审器编写自定义指标(参见 references/multimodal-eval.md) |
深入了解:ADK 文档
如需查看官方评估文档,请获取以下页面:
- 评估概述:
https://adk.dev/evaluate/index.md - 标准参考:
https://adk.dev/evaluate/criteria/index.md - 用户模拟:
https://adk.dev/evaluate/user-sim/index.md
调试示例
用户说:“tool_trajectory_avg_score 是 0,哪里出了问题?”
- 检查 Agent 是否使用了
google_search— 如果是,请参见references/builtin-tools-eval.md - 检查是否使用了
EXACT匹配,以及 Agent 是否调用了额外工具 — 尝试使用IN_ORDER - 比较评估集中的预期
tool_uses与 Agent 的实际行为 - 修复不匹配之处(更新评估集或 Agent 指令)