跳到正文
Google Developers Blog·· 20 小时前精选AI 评分73

Google 开源 AQuA 环境质量智能体,自动诊断生产环境 Agent 故障

The Outer Loop, Insights First: An Ambient Quality Agent That Diagnoses Your Production Agent

AI 导读

Google 发布并开源 AQuA(Ambient Quality Agent),一个在 Google Cloud 项目内旁路运行的质量智能体,按计划从 Cloud Trace、Cloud Logging 或 BigQuery 抽取生产轨迹,经抽样、评审、聚类、验证、追踪五阶段流水线输出经核验的失败洞察。

推荐理由

原文给出五阶段流水线、真实修复前后数字和每轮成本,读者可评估这套生产外环方案能否迁移到自己的 Agent 栈。

正文 · AI 翻译

2026年10月8日

你的智能体返回了 HTTP 200,保持在延迟预算之内,也没有任何工具调用抛出错误。然而,它在从未向选座子智能体询问 3A 是否空闲的情况下,就把座位 3A 记录为已确认;或者向一位资料显示为素食者的旅客推荐了一家佛罗伦萨牛排馆。

前 80% 是相对容易的部分

我们合作的每一个在生产环境中运行智能体的团队,都在试图回答同样的三个问题:我的智能体表现如何?它的失败模式有哪些,即那些反复出现的失败方式?以及我如何爬升:改变一些东西,知道它有帮助,并防止它退回原状?

让智能体达到前 80%——即通过你预先设想到的测试用例——如今可能相对直接和快速。一次评估、一个编码智能体,再加上运行、评分、修复、比较这样紧凑的内循环,通常几天内就能让智能体在已知场景中实现任务成功。然后你发布了,质量曲线就趋于平缓或下降。

Figure-1-Quality-Curve-Pre-Launch-vs-Production

图 1。智能体质量在发布前快速攀升,之后在生产中波动。

让剩下 20% 更难的是,发布之后基准会移动。随着用户发现智能体实际能做什么,使用情况会发生变化,真实流量不再像你最初的评估集。与此同时,底层系统也在变化:当你升级模型、更新你的 harness,或更改某个工具或技能时,一切仍然运行,健康检查依然全绿(图 2),但对话质量和任务成功可能会以标准部署流水线从不警告的方式发生变化。

Figure-2-Silent-Failure-Infra-Green-vs-Trace

图 2。每一项基础设施健康检查都保持绿色。失败是静默的,发生在对话内部。

而当一次会话真的出错时,弄清楚为什么意味着要区分几个从外部看几乎一模一样的层面。例如:

  • 模型可能幻觉出了一个参数,或丢掉了三轮之前的一个约束。
  • 编排 harness可能路由到了错误的子智能体,或在轮次之间丢失了状态。
  • 工具契约可能拒绝了某个输入,因为它的有效值从未在 schema 中记录。
  • 指令或技能可能只是缺少了一条没人想到要写下来的规则。

这些失败模式可能属于不同的负责人,也有不同的修复方法。原始轨迹记录的是什么接在什么之后发生,而不是什么导致了什么。要区分这些层面,需要将失败的轨迹与产生它们的精确代码版本放在一起阅读。在线评估仪表盘告诉你评分发生了变化,而编码智能体可以在你知道该看哪里之后检查一条 trace,但在生产规模下,没人能手工阅读每一段对话。

Figure-3-Inner-and-Outer-Loop-Quality-Flywheel

图 3。AQuA 运行生产外循环,并将发现的结果反馈到你的内循环中。

在我们六月的文章中,我们在 travel-concierge 上端到端地走通了发布前的内循环。这篇文章介绍外循环,它已开源发布为可组合的构建模块,你可以在自己的项目中运行、适配到你的技术栈,并在我们探索团队如何在生产中实现持续智能体质量的过程中帮助我们塑造它。

AQuA 是什么:一个 24/7 质量智能体,在你的笔记本电脑合上时观察、聚类并诊断生产失败

AQuA (Ambient Quality Agent) 在你的 Google Cloud 项目中的智能体旁无人值守运行,按计划、每次部署后或按需(即使你的笔记本电脑处于关闭状态)扫描来自 Cloud Trace、Cloud Logging 或 BigQuery 的生产轨迹。原始会话记录、源代码快照和 BigQuery 表都留在你的项目边界内,AQuA 从不位于请求路径中,也不会回写到你的智能体。

Figure-4-AQuA-Sidecar-Architecture

图 4. AQuA 在你的 Google Cloud 项目中的智能体旁运行,在请求路径之外读取轨迹和部署时的源代码快照。

每次运行都会读取近期会话的样本,并将其送入一个五阶段流水线:

Figure-5-Five-Stage-Sweep-and-Verification-Pipeline

图 5. 五阶段扫描流水线将原始生产会话转化为经过验证的洞察,根因诊断按需针对已部署的源代码快照运行。

  1. 采样 (Sample)。 从你的遥测数据(Cloud Trace / Cloud Logging 或 BigQuery)中随机抽取最多 1,000 个近期会话的样本(设置上限以保持运行成本可预测)。
  2. 审查 (Review)。 在智能体的指令、工具以及可选的 goal.md 的参照下,根据一份包含九类常见故障(流程、工具选择与参数、依据性、任务完成度等)的清单对每个会话进行评分。当会话失败时,它会写入一条结构化的 actual / expected 发现。
  3. 聚类 (Cluster)。 将具有相同故障机制的会话发现归组为候选问题簇。
  4. 验证 (Verify)。 由另一个模型根据最多三份完整记录检查每个候选簇,并丢弃证据不支持的簇。
  5. 跟踪 (Track)。 将存活的簇与 BigQuery 中的开放洞察(跨运行跟踪的已验证问题)进行匹配,标记为 NEW、RECURRING,或在 14 天未见后自动标记为 RESOLVED。

把它想象成一位做首轮筛查的初级质量工程师:阅读对话、过滤噪声,并为轮值人员准备好带有证据会话的案件档案。

为了让第 2 阶段贴合你的领域,你编写一段通俗英语的开发者目标(goal.md),它会附加到每个审查提示中;确定性的 Python 自定义指标(eval_config.yaml)与评判器一同运行,以追踪通过率趋势。默认情况下,AQuA 使用单遍 session_review 评判器,它每个会话一次模型调用即可根据该清单评估对话(保持计划扫描的经济性,并产生驱动聚类的 actual / expected 差异)。你也可以选择启用 Gemini 平台托管的轨迹 AutoRaters(task_success、tool_use_quality、trajectory_quality),它们运行专用的逐指标评估器(例如,如果你希望根据标准化的开箱即用评分标准为会话打分,或将指标与离线评估对齐)。

当某个洞察值得调查时,你可以从仪表盘的 Chat 或 agents-cli aqua run 触发根因分析。AQuA 会读取失败的轨迹以及部署时捕获的不可变源代码快照:当缺陷在你的仓库中时,它引用 <path>:<start>-<end> 并提出锚定到快照行的编辑建议;当故障在你的代码之外(上游依赖、交接或检索到的载荷)时,它将失败归因于轨迹中的那一步,而不提出代码差异。它从不会自行应用编辑或发起拉取请求。

它位于你已有的循环之间:离线评估根据已知测试用例对候选版本打分,在线评估监控生产环境中的通过率趋势,而编码代理或专用优化器则编辑提示词和代码。AQuA 将原始生产流量转化为经过诊断、锚定代码的洞察,以及归档的失败记录,为你的内层循环提供素材。

在 travel-concierge 上运行多智能体扫描

让我们在 travel-concierge(google/adk-recipes)上走一遍运行流程,它将旅行者路由到各个子智能体(inspiration_agent、place_agent、poi_agent, planning_agent、flight_search_agent、flight_seat_selection_agent、booking_agent 和 pre_trip / in_trip / post_trip),并通过 memorize(key, value)(travel_concierge/tools/memory.py)将进行中的行程存储在会话状态中。

1. 部署、捕获源快照,并设定开发者目标

将 AQuA 附加到 travel-concierge 项目需要三条 agents-cli 命令:

agents-cli extension add "${AQUA_CHECKOUT}"

agents-cli infra single-project --project="${GOOGLE_CLOUD_PROJECT}" --apply

agents-cli deploy --project="${GOOGLE_CLOUD_PROJECT}" --region us-east1

除了 AQuA 的运行器、BigQuery 数据集和 Cloud Run 仪表盘(位于 Identity-Aware Proxy 之后),agents-cli deploy 还会将 travel-concierge 源代码树的不可变快照写入 Cloud Storage,并以部署修订版(Revision 1)作为键。

在仪表盘的 Configuration 页面上,我们保存一个 开发者目标(goal.md),以引导评审关注高层次的产品不变量并抑制风格噪音(同时仍要求每项发现都引用一个具体的轮次,其中智能体或子智能体违反了其指令或工具状态):

Goal: Help travelers move from trip inspiration to a concrete itinerary and confirmed bookings across our sub-agents, with every confirmed flight, hotel, seat, and recommendation grounded in tool results and the traveler's profile.
Failure modes to make sure we cover:
- Mid-conversation changes (a weak spot in pre-launch testing): if a user updates destination, dates, or flight/hotel choices after an initial plan, make sure subsequent sub-agent tool calls and state updates reflect the change.
- Dropped context when handing off or delegating across inspiration_agent, planning_agent, and booking_agent (such as traveler profile preferences or prior selections).
Ignore: tone, greetings, small talk, or sessions where the user browses options and leaves without booking.

纯文本

已复制

如果你还希望在 eval_config.yaml 中使用确定性的 Python 评分标准来追踪通过率随时间的变化,可以将其与扫描一起通过 agents-cli aqua metrics publish 发布。

2. 扫描并验证聚类

在一次 32 个会话的多智能体扫描中(对四个脚本化旅行者旅程进行 32 次重放,在 travel_concierge 及其子智能体上产生 1,583 个 OpenTelemetry span),5 个会话干净通过,27 个会话产生 42 项结构化发现,每项发现都按 span 限定到特定子智能体的隔离指令和工具声明。以下是 planning_agent 上的一项发现:

实际:当用户在同一轮中选择去程航班 UA204 并请求座位 3A 和 3B 时,planning_agent 直接将这些座位号保存到会话状态,而没有调用 flight_seat_selection_agent 来检查 3A 和 3B 是否可用。

预期:planning_agent 应先调用 flight_seat_selection_agent 验证座位可用性和价格,然后再将去程或返程座位号保存到会话状态。

聚类将这 42 项发现归为 9 个候选聚类。验证器(Gemini 3.7 Flash)根据最多三份完整记录以及每个子智能体的定义检查每个聚类,并拒绝 3 个误报聚类:其中两个聚类中,旅行者已明确要求乘坐第一班返程航班或直接跳转到预订;第三个聚类中,聚类将来自两个不同子智能体(flight_search_agent 和 inspiration_agent)的不相关提示词-工具不匹配合并在一起。剩下 6 个已验证问题,其中首要问题是:

  • 当用户主动指定座位时绕开座位可用性检查(15 个会话,planning_agent):当旅行者在选择航班的同时指定座位(或在行程中途切换目的地后立即指定),planning_agent 会直接将座位写入会话状态(返回 HTTP 200 且工具错误为零),而不调用 flight_seat_selection_agent 来检查该座位是否存在或是否开放。
  • 跨子代理边界丢弃饮食约束(7 个会话,inspiration_agent → place_agent):inspiration agent 的提示中包含旅行者画像(food_preference: vegan),但 place_agent 被封装为一个隔离的工具,其提示从未收到该画像。当 inspiration_agent 在未于请求中传入“vegan”的情况下向 place_agent 询问美食旅行创意时,place_agent 推荐了 Carbonara 和 Bistecca alla Fiorentina(牛排)。
  • poi_agent 中提示与工具集矛盾(5 个会话,poi_agent):兴趣点子代理的提示要求来自 Google Maps Grounding Lite 的经过验证的图片、地图和地点 ID 字段,但该代理被声明为空工具列表( tools=[] ),因此它伪造了占位符 https://example.com/... URL。

Figure-6-Verified-Insights-Dashboard-List

图 6. 来自旅行礼宾扫描的经过验证的洞察,按受影响的会话数排序。

3. 对照已部署代码进行诊断

在仪表板中打开排名第一的洞察,会显示该集群的完整细分:匹配的会话数(15 条痕迹)、验证摘要,以及 15 条关联的会话痕迹及触发该洞察的确切发现:

Figure-7-Insight-Detail-and-Linked-Session-Traces

图 7. 仪表板中的洞察详情视图,显示失败摘要和 15 条关联的会话痕迹。

从洞察卡片点击 Investigate 会针对 Revision 1 的 33 个文件源码快照启动根因诊断代理(Gemini 3.8 Flash)。代理将 15 条失败痕迹与仓库目录树交叉比对,将 bug 追溯到 travel_concierge/sub_agents/planning/prompt.py 的第 93 行:航班搜索指令只告诉 planning_agent,在展示座位图供用户选择时才调用 flight_seat_selection_agent,遗漏了用户直接提供座位号的情况。它在聊天中提出一个锚定到具体行的修复方案(并同样将 vegan 画像传递 bug 追溯到 travel_concierge/sub_agents/inspiration/prompt.py 的第 23 行):

Figure-8-Investigator-Chat-Root-Cause-Diagnosis

图 8. 仪表板聊天中的根因诊断,将建议的指令修复锚定到已部署的源码快照。

4. 从编码代理闭环并在 Revision 2 上验证

同一洞察载荷,包括其锚定的 edits[] 和 occurrences[].rubrics[].trace,可通过 agents-cli aqua get-insight 获取。编码代理(使用 agents-cli-aqua 和 google-agents-cli-eval 技能)可以无头触发诊断、在分支上应用编辑、将失败会话的用户输入提取到本地重放文件,并在开启拉取请求前验证修复:

# 1. Pull new insights affecting >= 10 sessions without a root cause


agents-cli aqua list-insights --status NEW --root-cause false \
  | jq -r '.insights | sort_by(-.trace_count) | .[] | select(.trace_count >= 10) | "\(.insight_id)  \(.label)"'


# 2. Trigger root-cause analysis headlessly and fetch the anchored edit + evidence traces


agents-cli aqua run 'Diagnose insight 220d9209e27d4e16a73b4ad4741caa81. What is the root cause, and how would you fix it?'
agents-cli aqua get-insight 220d9209e27d4e16a73b4ad4741caa81 > insight.json


# 3. Extract the user turns from the attached trace in insight.json for local replay (or add to your eval set)


jq '{state: {}, queries: [.occurrences[0].rubrics[0].trace[] | select(.role == "user") | .content]}' \
  insight.json > ./b4b38471-inputs.json
adk run --replay ./b4b38471-inputs.json travel_concierge

纯文本

已复制

在应用两处单行提示修复(planning/prompt.py:93 和 inspiration/prompt.py:23)并部署 Revision 2 后,在相同的开发者目标下对其重放相同的 32 个会话,结果显示:

  • 座位选择绕过下降 87%,从 15 个会话降至 2 个边缘情况会话。
  • Vegan 画像遗漏从 7 个会话降至 0。
  • 完整会话通过数增加一倍以上,从 5/32 增至 13/32。
  • 未触及的 5 个会话 poi_agent 缺陷( tools=[] )仍保留在队列中跟踪。

足以让你放心采取行动的发现

诊断你的代理的代理有时会出错。这是使用模型作为评判者的固有特性。在设计 AQuA 时,核心工程要求是确保未经验证的假设绝不会看起来与经过验证的发现一样:

  • 在与完整转录记录核验之前,聚类只是声称。 每个聚类抽查最多三条完整转录记录,可在其进入你的队列之前验证这一失败模式确实存在(在一项包含 87 条轨迹的内部基准上,验证器驳回了 24 个候选聚类中的 4 个),而聚类中的轨迹数量则为你提供粗略的优先级排序,而非逐一核验每个成员会话。
  • 洞察力体现为其引用,而非自报的置信度分数。 schema 中不存在 confidence 字段:每一次出现都链接到其在 Cloud Trace 中的会话 ID,每一个根因都引用 <path>:<start>-<end> 范围,服务器会依据该修订版本的快照进行校验。任何指向不存在文件或行的引用都会被驳回。
  • 跳过或失败的工作会显示在运行记录上。 被驳回的聚类、超过 50 个聚类验证上限的聚类、评分标准错误,以及空或未捕获的 trace 窗口,都会明确记录在该次运行中,而不会被计为干净的会话。
  • 设计即为如此的行为可被永久忽略。 一旦你在某条发现上点击 Dismiss,未来的扫描不会将其作为 NEW 重新打开。

智能体质量工程中的难题,以及这一方向将走向何处

这一参考实现中的若干边界,是我们在生产环境中看到的实际问题之间有意做出的权衡:

  1. 在大规模场景下选择要读取哪些会话。 深度评估多轮轨迹的成本远高于检查一个 HTTP 状态码,因此这一 MVP 每次运行随机抽样最多 1,000 个会话(ORDER BY RAND())。加入低成本的结构性预筛(重试、延迟尖峰、高轮次、用户点踩)是顺理成章的下一步,不过仅根据异常进行过滤往往会导致拉出一百份同样的超时。更难的问题在于,捕捉一个破坏了关键工作流 1% 的静默回归——此时所有结构性信号看起来都正常——而又不必对全部 50,000 个每日会话运行深度评判器。
  2. 通用检查清单与领域目标及 SME 校准的对比。 goal.md 与自定义指标可将评审引向领域规则,但让模型评判器与领域专家达成一致仍是一项真正的工程工作。
  3. 有界验证与可预测的运行成本。 每次运行最多验证 50 个聚类、每个最多 3 条转录记录,可在轨迹深度扩展时保持运行成本可预测。在一次 96 会话的单智能体扫描中(每会话约 5 至 6 个 span),评审、聚类与验证总计花费 0.70 美元(约每会话 0.007 美元;Gemini 3.1 Pro 与 Gemini 3.7 Flash 合计 220,841 输入 / 48,736 输出 token)。在上面那次 32 会话的旅行礼宾扫描中(travel_concierge 及其子智能体共 1,583 个 span,每会话约 50 个 span),评审与聚类(Gemini 3.1 Pro,1,635,197 输入 / 128,740 输出 token)加上 9 次聚类验证(Gemini 3.7 Flash,1,131,937 输入 / 36,976 输出 token)总计花费 3.76 美元(约每会话 0.12 美元),按标准 Gemini 平台定价计算。根因诊断(Gemini 3.8 Flash)仅在需要时运行,每个被调查的洞察花费 0.33 至 2.47 美元,具体取决于它拉取多少条完整轨迹。
  4. 长时程轨迹与上下文压缩。 传递完整转录记录对十轮对话有效,但在运行数百轮、产生数兆字节工具输出的编码或研究智能体上就会失效。这些场景需要语义轨迹压缩,将 500 轮的 trace 折叠为子任务里程碑,并隔离出它在哪里偏离轨道。
  5. 从归档记录到可复现的测试用例。adk run --replay 将录制的用户轮次重新发送到本地代码,这在工具具有幂等性或被模拟时可行,但静态重放无法重建外部环境状态(如果数据库某行发生了变化、某个 API 超时,或第 3 轮依赖于智能体在第 2 轮所说的话,重新发送静态轮次就会产生偏差)。

在平台层面真正可泛化的东西。在 Google 自家的一手智能体中,底层原语(追踪与反馈摄取、核心评估器、数据集管理)可以干净地共享,而外层循环工作流往往是根据产品各自的工具、领域不变量、数据管道和编排框架定制的。随着基础模型和智能体在阅读轨迹和浏览代码方面越来越强,单个评分和根因推理会自动变得更强,这就是为什么我们将 AQuA 的提示词视为模块化配方,并将其洞察视为对原始轨迹和源快照的索引,这样更强的模型或编程智能体总能将完整的示例记录直接拉入上下文。更强的模型和智能体本身无法提供的,是周边平台。以下是我们正在思考的一些下一步方向:

  • 多信号摄取与静默失败差异比对。将追踪扫描与在线评估分数、延迟/成本峰值、SME 校准评分,以及通过 Feedback 服务获得的最终用户反应结合起来,就可以把用户明确抱怨的会话与一般流量进行对比,然后在用户从未点击差评、却悄悄放弃工作流的会话中发现同样的缺陷。
  • 从诊断洞察到沙箱化的反事实测试用例。在另一个领域,CodeMender 扫描代码中的漏洞,并提出它已通过静态和动态分析、差分测试、模糊测试和 SMT 求解器验证过的补丁。它“先扫描再验证”的形态直接对应 AQuA 的“先扫描再验证”。但修复路径不同:一旦外部状态已经推进,实时对话就没有确定性预言机(没有崩溃输入或失败测试),而且修复可能位于工具契约、编排交接或上游依赖中,而不是一个你可以孤立地爬坡优化的提示词。将一个经过验证的失败聚类转化为带有模拟工具状态和模拟用户的封闭沙箱测试用例,以便编程智能体或优化器可以跨越代码、工具和提示词进行爬坡,这是超越记录重放的自然下一步。
  • 跨智能体舰队的零脚手架接入。今天的参考实现是在其仓库中与单个 ADK 智能体 1:1 搭建的;对于在生产中运行数十个智能体的团队,我们正在探索如何直接从现有项目遥测中,在智能体舰队(1:N)范围内接入环境质量扫描,而无需为每个智能体部署 sidecar。
  • 声明式与托管智能体。当被观察的智能体本身是声明式或托管的,而不是任意应用代码时,“源代码”就坍缩为系统指令、工具模式和技能。这会将根因搜索空间缩小到一组有限的结构化工件,让平台自动接入追踪捕获和修订快照,并将经过验证的通过和失败轨迹转化为有根据的学习信号——而实时生产流量没有真值标签——供优化器或智能体自身的内存与自学习循环使用。

试用它,帮助塑造它的未来方向

要在一个合成的月度运行与洞察数据集上本地探索该仪表板,无需云项目、无需凭据、也无需模型调用:

git clone https://github.com/google/adk-recipes.git
cd adk-recipes/core/python/ambient-quality-agent
make demo         # serves the dashboard locally on synthetic data

Shell

已复制

要借助开箱即用的 ADK 脚手架将 AQuA 接入你在 Google Cloud 中的自有 agent(所有遥测、源快照和 BigQuery 表都保留在你项目内、你的服务账号下,置于 IAP 之后):

agents-cli extension add "${AQUA_CHECKOUT}"
agents-cli infra single-project --project="${GOOGLE_CLOUD_PROJECT}" --apply
agents-cli deploy --project="${GOOGLE_CLOUD_PROJECT}"

Shell

已复制

要从你的编码 agent(Antigravity、Gemini CLI、Claude Code 或 Cursor)驱动这两个循环,请安装 agents-cli-aqua 技能(skills/agents-cli-aqua/SKILL.md)以及内循环评估技能(npx skills add https://github.com/google/agents-cli --skill google-agents-cli-eval)。

我们公开分享 AQuA,以与在生产环境中运行 agent 的团队协作,共同塑造它的未来方向。当你在自己的技术栈上试用它时,我们很乐意听听你的想法:

  1. 并行的质量 agent 是否契合你的架构?这套工作流的哪些部分你希望在自己的仓库中保持可自定义,而哪些部分最终希望由平台替你运行(例如跨一组 agent 进行接入)?
  2. 环境式质量 agent 将如何融入你的工程工作流?你团队中谁首先对洞察进行分诊,在哪个界面(CLI/编码 agent、IDE 或 Cloud Console),以及接下来会发生什么?
  3. 在 agent 质量工程的这些难题中,我们应该先解决哪一个:从 50,000 个会话中挑选出值得阅读的 40 个、将静默失败与用户反馈进行对比、把失败聚类转化为可复现的沙盒测试用例、压缩长时程轨迹,还是别的什么?

致谢(按字母顺序): AQuA 由 Ákos Frohner、 Aleksandra Grzegorczyk、 Alessandro Grassi、 Andrzej Kiewicz、 Angelica Bilanenko、 Dima Melnyk、 Elia Secchi、 Iwo Naglik、 Lucas Matuszkowiak、 Ludwik Trammer、 Maciej Pawłowski、 Max Gasztych、 Pavel Sirotkin、 Saksham Singhal、 Xi Liu、 Yaroslav Polyakov 以及更广泛的 Gemini 平台团队共同构建。

了解更多: Ambient Quality Agent 仓库 · 从你的编码 agent 驱动 Agent Quality Flywheel · Agent Evaluation 文档

上一页

下一页

来源:Google Developers Blog · developers.googleblog.com