agents-cli 评估数据集 Schema 详解:EvaluationDataset 字段规范、单轮/多智能体示例与 rubric_groups 实战
【免费下载链接】agents-cliThe CLI and skills that turn any coding assistant into an expert at creating, evaluating, and deploying AI agents on Google Cloud.项目地址: https://gitcode.com/GitHub_Trending/ag/agents-cli
本文以 agents-cli 技能包中的 dataset_schema.md 为主体,系统讲解 Agent Platform 评估 SDK 的标准数据集格式(EvaluationDataset):核心类型树、单轮/多轮/多智能体 JSON 示例、按指标类型划分的必填字段、逐用例评分标准rubric_groups及服务端约束。读完本文,你可以直接手写或审查tests/eval/datasets/下的评估数据集,并理解agents-cli eval generate/eval grade流水线如何消费这些字段,从而避免最常见的 400 报错。
一、先建立全景:数据集在 eval 三阶段流水线中的位置
写数据集之前,需要先知道它在整条评估流水线里的位置。从源码 src/google/agents/cli/eval/_paths.py 的模块注释可以确认,agents-cli 把评估产物划分为三个阶段,且四类文件共用同一个 SDK 类型EvaluationDataset作为容器,但不同阶段填充的字段不同,彼此不可互换:
| 阶段 | 内容 | 默认位置 | 消费者 | 生产者 |
|---|---|---|---|---|
| Stage 1 | 待推理的 eval case:顶层prompt(单条用户消息),或agent_data(以用户消息结尾的续接对话) | tests/eval/datasets/*.json | eval generate | scaffold / 手工编写 |
| Stage 2 | 已填充的 traces(agent_data中已包含 agent 回复与工具调用) | artifacts/traces/traces_<ts>.json | eval grade | eval generate、eval dataset synthesize |
| Stage 3 | 打分结果 | artifacts/grade_results/ | eval analyze | eval grade |
这个分层直接决定了本文 schema 的两种使用姿态:你手写的是 Stage 1 的"推理输入"(prompt或以用户消息收尾的agent_data),而带完整responses与工具调用的"打分输入"(traces)由eval generate自动生成,通常不需要手写。eval generate的入口对这一约束有显式校验,见 src/google/agents/cli/eval/cmd_generate.py:
eval_cases = data.get("eval_cases") if not eval_cases: raise click.ClickException( "Dataset must contain a non-empty 'eval_cases' list.\n" " Each eval_case must have either a 'prompt' field or " "'agent_data' whose turns end with a user message." ) for i, case in enumerate(eval_cases): has_prompt = bool(case.get("prompt")) has_agent_data = bool(case.get("agent_data")) if not has_prompt and not has_agent_data: raise click.ClickException( f"eval_cases[{i}] is missing both 'prompt' and 'agent_data'.\n" ... )即:eval_cases必须非空,且每个 case 必须提供prompt或agent_data二者之一——这与 schema 文档末尾"Common Mistakes"表中"不要在一个 case 里混用prompt和agent_data"的规则完全对应。
二、核心类型树(Core Types)
原文档给出的类型树如下(以该技能版本所针对的 SDK 为准,权威定义见 Agent Platform 评估 SDK 公开源码中的types/evals.py与types/common.py):
EvaluationDataset └── eval_cases: list[EvalCase] # 评估用例列表 EvalCase ├── prompt: Content # 单轮:用户查询 ├── responses: list[ResponseCandidate] # 单轮:模型回复(列表形式以支持多候选评估) ├── reference: ResponseCandidate # 标准答案,`final_response_match` 所需 ├── context: str | Content # 源文本,`grounding` 所需 ├── agent_data: AgentData # 多轮:完整对话轨迹 ├── rubric_groups: dict[str, RubricGroup] # 逐用例评分标准,由托管 rubric 指标打分 └── (允许额外字段) # 供自定义指标使用的自定义字段 ResponseCandidate └── response: Content # 实际的 Content(role + parts) AgentData ├── agents: dict[str, AgentConfig] # 智能体定义 └── turns: list[ConversationTurn] # 按时间顺序排列的对话轮次 ConversationTurn ├── turn_index: int # 从 0 开始的轮次编号 └── events: list[AgentEvent] # 该轮内的事件 AgentEvent ├── author: str # "user"、agent_id 或 "tool" └── content: Content # 带 role 和 parts 的 Content
responses与reference的包装层(原文档重点标注):两者都把Content包在一层ResponseCandidate对象里。所以单轮用例要写成"responses": [{"response": {"role": "model", "parts": [...]}}]和"reference": {"response": {"role": "model", "parts": [...]}}——而不是裸的Content。与之相对,prompt和agent_data.turns[].events[].content是裸Content(没有包装层)。
这一"半数字段包一层、半数字段裸写"的不对称设计是整个 schema 里最容易写错的地方,仓库中 scaffold 出的示例数据集恰好演示了reference的正确写法,见 basic-dataset.json:
{ "eval_case_id": "capital_lookup", "prompt": { "role": "user", "parts": [{"text": "What is the capital of France?"}] }, "reference": { "response": { "role": "model", "parts": [{"text": "The capital of France is Paris."}] } } }注意prompt是裸 Content,而reference外层多了一个response键。
三、单轮数据集(Single-Turn)
适用于简单的 prompt-response 评估场景(问答、摘要等)。完整示例:
{ "eval_cases": [ { "eval_case_id": "capital_of_france", "prompt": { "role": "user", "parts": [{"text": "What is the capital of France?"}] }, "responses": [ { "response": { "role": "model", "parts": [{"text": "The capital of France is Paris."}] } } ], "reference": { "response": { "role": "model", "parts": [{"text": "Paris"}] } } }, { "eval_case_id": "summarize_article", "prompt": { "role": "user", "parts": [{"text": "Summarize this article: ..."}] }, "responses": [ { "response": { "role": "model", "parts": [{"text": "The article discusses..."}] } } ] } ] }注意第二个用例只写了prompt+responses、没有reference——这说明responses与reference的组合取决于你选用的指标类型:
按指标类型划分的必填字段
| 指标类别 | 必填字段 |
|---|---|
| 预定义指标(单轮) | prompt、responses |
| 计算型指标(computation-based) | responses、reference |
| 翻译类指标 | prompt(源语言)、responses、reference |
| 自定义 LLM/代码指标 | 你的模板/函数中引用的字段 |
从源码看,"计算型指标"对应的正是 SDK 按名称特判的exact_match、bleu、rouge*一族——src/google/agents/cli/eval/eval_utils.py 中的_is_sdk_computed_metric函数明确列出了这批指标名,它们走 SDK 自身的 transformer 分支而非预定义指标分支,因此必须携带reference才能算出分数。
四、多轮 / 多智能体数据集(Multi-Turn / Multi-Agent)
用于评估多轮 agent 对话,包括多个协作智能体与工具调用系统。规则要点:
agents映射声明所有参与智能体;turns是按时间顺序排列的对话,每个event的author必须是"user"、agents映射中的某个 agent ID、或"tool"。
完整示例(路由 + 专家 agent + 工具调用的多智能体场景):
{ "eval_cases": [ { "eval_case_id": "flight_booking_via_specialist", "agent_data": { "agents": { "router": { "agent_id": "router", "agent_type": "RouterAgent", "instruction": "Route requests to the appropriate specialist." }, "flight_bot": { "agent_id": "flight_bot", "agent_type": "SpecialistAgent", "instruction": "Search and book flights.", "tools": [{ "function_declarations": [{ "name": "search_flights", "description": "Search flights by destination", "parameters": { "type": "OBJECT", "properties": { "destination": {"type": "STRING"} } } }] }] } }, "turns": [ { "turn_index": 0, "events": [ { "author": "user", "content": { "parts": [{"text": "Book a flight to NYC"}] } }, { "author": "router", "content": { "parts": [{"text": "Routing to flight_bot."}] } } ] }, { "turn_index": 1, "events": [ { "author": "flight_bot", "content": { "parts": [{ "function_call": { "name": "search_flights", "args": {"destination": "NYC"} } }] } }, { "author": "flight_bot", "content": { "parts": [{ "function_response": { "name": "search_flights", "response": {"flights": [{"id": "AA123", "price": 320}]} } }] } }, { "author": "flight_bot", "content": { "parts": [{"text": "Found AA123 to NYC for $320."}] } } ] } ] } } ] }三个实战细节:
turn_index必须从 0 开始连续编号(见后文 Common Mistakes)。- 工具调用必须成对出现
function_call/function_response两个 part,且工具回复要包在function_responsepart 里,不能直接写裸文本。 - 单 agent 多轮用例只需省略多余的 agent 定义、在
agents里保留一个条目即可;events的author取值约束不变("user"/ agent ID /"tool")。
另外,_paths.py的注释还提到一种 Stage 1 用法:以用户消息结尾的"续接对话"——agent_data的最后一个 turn 以用户消息结束,eval generate会把 agent 的下一条回复追加进去再评估(源码中称为 "N+1" 模式)。
五、逐用例评分标准:rubric_groups
EvalCase.rubric_groups用于挂接用例级的评分标准:每个 rubric 由托管 rubric 指标(managed rubric metric)打出一个 pass/fail 判定,得分为通过比例。关键使用姿势是:写在 Stage 1 推理输入数据集上,eval generate会把它原样带到 trace 上(eval generate只搬运你写的reference、context、rubric_groups,从不自行生成)。
示例:
{ "eval_cases": [ { "eval_case_id": "booking_confirmation", "prompt": {"role": "user", "parts": [{"text": "Book my flight to Paris."}]}, "rubric_groups": { "booking_rubrics": { "rubrics": [ {"rubric_id": "confirmation_check", "content": {"property": {"description": "The model must confirm the booking and provide a reference number."}}} ] } } } ] }评分侧的配置与结果:
- 在
metrics_to_run里列出一个托管 rubric 指标; - 若一个用例有多个 group,用
metric_spec_parameters.rubric_group_key指定选用哪一个; - 结果里每个指标带
rubric_verdicts(含evaluated_rubric.rubric_id、verdict、reasoning),得分为通过比例。
服务端约束(400 报错速查)
| 场景 | 服务端报错 |
|---|---|
rubric_group_key在 case 上不存在 | 400:rubric_group_key '<name>' not found in instance.rubric_groups |
| case 有多个 group 但 metric spec 未给 key | 400:Multiple rubric groups provided in instance but no rubric_group_key specified in metric spec |
| 单轮指标跑多轮 trace | 400:Single-turn metric '<name>_v1' received agent_eval_data with N turns |
两条重要的边界规则:
- rubric 托管指标是单轮的:
multi_turn_task_success虽然接受rubric_group_key,但它评的是自己生成的 rubric(hash ID),不读你的rubric_groups。要给多轮用例定标准,应改用本地custom_function_file判定函数(见 metrics-guide.md),它能在instance参数里直接拿到rubric_groups。 - 指标对数据集里所有 case 生效,所以单轮与多轮 case 要拆成各自独立的"数据集 + 配置"两件套,不要混在一个数据集里。
从源码可以印证这条路由逻辑:eval_utils.py 在解析自定义指标时,如果条目里出现rubric_group_name会直接拒绝并提示:要评 case 的rubric_groups,必须用托管 rubric 指标(如final_response_quality)配合metric_spec_parameters.rubric_group_key选择 group;若坚持用自定义prompt_template判定,则应删掉rubric_group_name字段。
六、常见错误速查表(Common Mistakes)
原文档的核心速查表,写数据集时应逐条对照:
| 错误 | 修正 |
|---|---|
使用role="assistant" | 使用role="model"(Vertex 约定) |
缺少turn_index | 始终设置从 0 开始的连续编号 |
工具回复没有包function_response | 包在function_responsepart 里 |
多轮场景误用prompt字段 | 改用带完整轨迹的agent_data |
一个 case 里混用prompt和agent_data | 每个EvalCase二选一 |
其中最后一条有 CLI 级强制校验(见第一节cmd_generate.py的报错信息),前四条则会在服务端或指标计算阶段以 400 / 无分数等形式暴露。
七、与 agents-cli 命令、配置文件的衔接
数据集只是 Stage 1,把它跑起来还需要指标配置文件。scaffold 生成的 eval_config.yaml 展示了数据集字段如何被自定义指标消费:
metrics_to_run: - custom_response_quality custom_metrics: # 默认:本地 LLM-as-judge(见 response_quality.py)。 - name: custom_response_quality custom_function_file: response_quality.py - name: agent_turn_count custom_function: | def evaluate(instance): turns = (instance.get("agent_data") or {}).get("turns", []) return {'score': len(turns)}对应的 response_quality.py 中evaluate(instance)读取的instance字段(prompt、response、reference、agent_data)正是本文 schema 里 case 级字段的运行时投影——reference存在时会自动追加"与标准答案不一致要扣分"的评分指令。而agent_turn_count直接依赖agent_data.turns的结构,验证了多轮 schema 的字段名在本地代码指标中同样生效。
典型运行链路(命令细节见 google-agents-cli-eval 技能主文件):
# 一键式:跑 agent + 打分,产物写入 artifacts/grade_results/results_<ts>.{json,html} agents-cli eval run # 分体式:手写/修改本 schema 的数据集后 agents-cli eval generate --dataset tests/eval/datasets/custom.json # Stage 1 -> Stage 2 agents-cli eval grade # Stage 2 -> Stage 3 agents-cli eval compare baseline.json candidate.json # 对比两轮结果补充两个实现层面的事实,帮助排错:
- 打分配置与数据集的解耦:
eval grade通过 cmd_grade.py 将 traces 目录下的多个 JSON 文件各自EvaluationDataset.model_validate_json后合并全部eval_cases再统一打分,所以 trace 文件可以分散存放。 - 区域默认值:eval_utils.py 中
DEFAULT_EVAL_REGION = "global"——eval run/eval grade/eval submit默认走global端点,不继承项目 manifest 的部署区域,不支持的区域会被服务端拒绝。
参考文件索引
| 文件 | 作用 |
|---|---|
| dataset_schema.md(本文主体) | 标准 EvaluationDataset schema、单轮/多轮/多智能体 JSON、常见错误 |
| skills 分发包同名副本 | 与上面内容逐字相同的技能分发包副本(仓库中两份完全一致) |
| metrics-guide.md | 指标全集、metric_spec_parameters参数、自定义指标字段参考 |
| google-agents-cli-eval SKILL.md | 评估工作流、命令说明、数据集两种形态(推理输入/打分输入) |
| _paths.py | 三阶段产物路径与文件命名约定(Stage 1/2/3 的单一事实来源) |
| cmd_generate.py | eval generate对eval_cases、prompt/agent_data的入口校验 |
| eval_utils.py | 指标解析、rubric_group_name拒绝逻辑、计算型指标特判 |
| basic-dataset.json | scaffold 生成的最小单轮数据集(含reference包装层示例) |
| eval_config.yaml / response_quality.py | 自定义指标如何消费 case 级字段 |
适用前提与限制:本文 schema 描述的是该技能版本所针对的 Agent Platform 评估 SDK 类型树;权威字段定义以 SDK 公开源码(agentplatform包内types/evals.py、types/common.py)为准。命令默认值(默认数据集路径tests/eval/datasets/basic-dataset.json、产物目录artifacts/traces/与artifacts/grade_results/、评估区域默认global)均以当前仓库src/google/agents/cli/eval/下的实现为准;eval generate的内置本地服务器与eval dataset synthesize等能力仅在 ADK 项目上可用。
【免费下载链接】agents-cliThe CLI and skills that turn any coding assistant into an expert at creating, evaluating, and deploying AI agents on Google Cloud.项目地址: https://gitcode.com/GitHub_Trending/ag/agents-cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考