ADK 新增 live evaluation 功能,用 LLM 模拟用户生成真实音频,自动评分语音回复与工具调用,支持 CI/CD 集成。
让一个 live agent 上线生产,靠的不只是一个漂亮的 demo。它必须在一通语音对话中一轮接一轮地做出正确的动作,时机和恢复与内容同样重要。昨天听起来完美无缺的行为,可能因为一次 prompt 调整或模型迭代而悄然改变。工具停止触发、上下文在轮次之间丢失、插话被忽略。要有把握地发布,需要的是可重复的证据——证明这个 agent 在真实用户的实际对话中能够持续表现稳定。
正因为如此,我们才将原生 live evaluation 引入 ADK。现在,你可以用模拟用户驱动一个实时的、基于语音的 agent——以音频方式说出轮次、对语音回复打分——全部在你已经为文本 agent 运行的同一套 eval loop 中完成。本文将一个 live agent 从"demo 里能跑"带到"在 ADK 中可量化、可信赖"。
要看到实际效果,我们将构建一个完整的 live evaluation loop:创建 agent、编写 eval case、运行 eval、检查记录结果。
示例使用基于 graph 的 workflow:三个单一职责的 live agent 串联在一起,每个阶段运行在 gemini-live-2.5-flash-native-audio 上。
from google.adk.agents.llm_agent import Agent
from google.adk.tools.tool_context import ToolContext
from google.adk.workflow import START, Workflow
from pydantic import BaseModel, Field
LIVE_MODEL = "gemini-live-2.5-flash-native-audio"
def validate_date_of_birth(dob: str, tool_context: ToolContext) -> dict:
"""Validate a confirmed date of birth against records (mocked)."""
match = dob == "1985-07-12"
tool_context.state["dob_verified"] = match
return {"match": match}
greeter_agent = Agent(
model=LIVE_MODEL,
name="greeter_agent",
mode="task",
instruction="You are Sam, a friendly care-team assistant. Greet the caller "
"and confirm you're speaking with John Doe before sharing anything else. "
"Ask one question per turn, then complete your task with the confirmed name.",
)
dob_verifier_agent = Agent(
model=LIVE_MODEL,
name="dob_verifier_agent",
mode="task",
tools=[validate_date_of_birth],
instruction="Ask for the caller's date of birth, read it back to confirm, "
"then call validate_date_of_birth in YYYY-MM-DD format. Complete your task "
"with 'verified' or 'unverified'.",
)
goals_agent = Agent(
model=LIVE_MODEL,
name="goals_agent",
mode="task",
instruction="Identity is verified. Proactively share the upcoming "
"appointment on Tuesday, June 16th at 3 PM with Dr. Example, answer any "
'questions, then wrap up warmly and end with "Goodbye."',
)
root_agent = Workflow(
name="live_workflow",
edges=[
(START, greeter_agent),
(greeter_agent, dob_verifier_agent),
(dob_verifier_agent, goals_agent),
],
)
每个阶段都是一个普通的 live agent,workflow 只是将它们串联起来并将输出从前一个阶段传递到下一个阶段。这个流程走过三个步骤,中间有一次工具调用,因此生成了一条丰富的多轮轨迹,值得评分。当控制在 agent 之间转移时,用户感知不到任何交接。音频流在整个交互过程中保持开放,ADK 携带累积的会话状态和对话历史向前推进,因此每个 agent 都在上下文中接续,而不是冷启动。
eval set 是一个包含测试用例的 JSON 文件。测试用例与运行方式解耦,因此你可以混合两种不同的风格:对话场景和固定对话。
第一种是对话场景:你描述一个目标和一个 persona,模拟用户即兴发挥说出轮次。
{
"eval_id": "example_scenario_case",
"conversation_scenario": {
"starting_prompt": "Hello?",
"conversation_plan": "You are John Doe. Confirm your name when greeted. When asked for your date of birth, give July 12th, 1985, and confirm it when read back. Listen to the appointment details, ask what you should bring to the visit, then say you have no other questions and let the call wrap up.",
"user_persona": "NOVICE"
},
"session_input": {
"app_name": "live_workflow",
"user_id": "test_user_id",
"state": {}
}
}
user_persona 塑造模拟用户的沟通方式。ADK 内置了几个 persona,NOVICE 告诉模拟器只分享高层目标、等待 agent 询问具体细节,从而测试 agent 引导对话的能力。Persona 是由 prompt 驱动而非硬编码的,因此你可以用自定义 persona 扩展集合。一旦 conversation_plan 满足,模拟器自行结束场景,所以你编写目标脚本,让它决定通话何时结束。作为防止对话失控的保障,max_allowed_invocations 限制了总轮次数,为每个动态 case 提供可预测的上限。
你也可以编写一个固定对话,逐字逐句地脚本化用户的轮次。静态 case 作为 live run 的输入,与模拟用户一样有效。
{
"eval_id": "example_fixed_case",
"conversation": [
{
"user_content": {
"role": "user",
"parts": [{ "text": "Hi, yes, this is John Doe." }]
}
},
{
"user_content": {
"role": "user",
"parts": [{ "text": "My date of birth is July 12th, 1985." }]
}
}
]
}
在 test_config.json 中,添加 live_model_config 并让 ADK 指向 llm_audio 用户模拟器。上述 case 中的每个用户轮次都用你选择的 Gemini TTS 语音合成语音,流式传输给 live agent。
{
"criteria": {
"rubric_based_multi_turn_trajectory_quality_v1": {
"threshold": 0.7,
"judge_model_options": { "judge_model": "gemini-3.7-flash" },
"rubrics": [
{
"rubric_id": "verifies_identity_first",
"rubric_content": {
"text_property": "Across the call, the agent confirms the caller's name and validates their date of birth before disclosing any appointment details."
}
}
// ... further end-to-end rubrics
]
}
},
"live_model_config": {
"timeout_seconds": 300
},
"user_simulator_config": {
"type": "llm_audio",
"model": "gemini-3.7-flash",
"max_allowed_invocations": 10,
"audio_model": "gemini-3.1-flash-tts-preview",
"audio_model_configuration": {
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {
"prebuilt_voice_config": { "voice_name": "Kore" }
},
"language_code": "en-US"
}
}
}
}
有几个值得注意的点:
live_model_config 启用 live 模式。省略此配置则以标准文本模式运行完全相同的测试用例。
model vs. audio_model:model 驱动模拟用户的轮次决策逻辑,而 audio_model 将这些轮次合成为语音。调整 voice_name 和 language_code 可以用不同的语音和口音测试 agent 性能。
criteria 配置指标和通过/失败阈值。基于 rubric 的 LLM judge(如 trajectory quality)端到端地评估对话——非常适合 multi-agent graph。你也可以附加单轮指标来评分个别回复或工具执行。
一段语音回复可以用数百种不同的措辞表达正确意思。自然语言 rubric 以人类评审员的方式判断意图,只需定义一次,就能自动应用到 suite 中的每一条对话。
准备好 agent、eval set 和配置后,从 CLI 运行 evaluation:
uv run adk eval \
contributing/samples/live/live_workflow \
contributing/samples/live/live_workflow/live_workflow.evalset.json \
--config_file_path contributing/samples/live/live_workflow/test_config.json
注意:确保已安装 eval extras(uv pip install -e ".[eval]")并且为 Live API 和 Gemini TTS 配置了 API 凭证。
同一套 pipeline 可以通过 AgentEvaluator 以编程方式调用,让你轻松将 live voice evaluation 集成到 CI/CD pipeline 中,在发布前捕获回归问题。
为了交互式调试,ADK Web 现在原生支持 live evaluations。运行设置对话框包含 Standard | Live 模式切换。选择 Live 后,会显示输入模态选项(Audio 或 Text)以及模拟用户的语音和语言设置。
运行完成后,ADK 将 live 音频流重建为干净的 transcript。每个轮次在独立的消息气泡中呈现,包含 transcript 文本和内联可播放的音频片段,让你能够评估 agent 听起来如何,而不仅仅是说了什么。
准备好测试你的 live agent了吗?克隆 live_workflow sample,运行 adk eval,然后在 ADK Web 中查看结果。
查看 ADK 文档,获取关于用户模拟、合成音频 profile 和自定义评估指标的深入指南。你的 voice agent 不必靠感觉发布——现在可以量化发布。