跳到正文
北京时间
原文
Google Developers Blog·· 20 小时前精选AI 评分66

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% 之所以更难,是因为上线后地基会移动。随着用户发现智能体实际能做什么,使用方式会发生变化,线上流量也不再像你最初的评估集。与此同时,底层系统也在变化:当你升级模型、更新你的运行框架,或更改某个工具或技能时,一切仍然能运行,健康检查也保持绿色(图 2),但对话质量和任务成功率可能会以标准部署流水线永远不会警告你的方式发生变化。

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

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

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

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

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

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

图 3. AQuA 负责生产环境的外循环,并将发现的问题反馈到你的内循环中。

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

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

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

Figure-4-AQuA-Sidecar-Architecture

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

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

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

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

  1. 采样。从你的遥测数据(Cloud Trace / Cloud Logging 或 BigQuery)中随机抽取最多 1,000 个近期会话的样本(设有上限以保持运行成本可预测)。
  2. 审查。在 agent 的指令、工具以及可选的 goal.md 的参照下,依据一份包含九项常见故障(流程、工具选择与参数、依据、任务完成等)的检查清单对每个会话进行评分。当某个会话失败时,它会写入一条结构化的 actual / expected 发现。
  3. 聚类。将具有相同失败机制的会话发现归入候选问题簇。
  4. 验证。由另一个模型依据最多三份完整会话记录检查每个候选簇,并丢弃证据不支持的簇。
  5. 跟踪。将存活的簇与 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 向 place_agent 询问美食旅行建议时,若请求中未传入“vegan”,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 条 trace)、验证摘要,以及 15 条关联的会话 trace 及其触发该洞察的确切发现:

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

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

从洞察卡片点击 Investigate 会针对 Revision 1 的 33 个文件源代码快照启动根因诊断代理(Gemini 3.8 Flash)。将该 15 条失败 trace 与仓库树交叉比对后,代理将 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 条 trace 的内部基准上,验证器拒绝了 24 个候选聚类中的 4 个),而聚类的 trace 数量只为你提供粗略的优先级排序,而非验证每一个成员会话。
  • 洞察在于其引用,而非自报的置信度分数。该 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)按 Gemini 平台标准定价 总计花费 3.76 美元(约每会话 0.12 美元)。根因诊断(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)上接入环境质量扫描,而无需为每个智能体部署边车。
  • 声明式与托管式智能体。 当被观察的智能体本身是声明式或托管式的,而不是任意应用代码时,“源代码”就坍缩为系统指令、工具模式和技能。这将根因搜索空间缩小到一组有界的结构化产物,让平台能够自动接入追踪捕获和修订快照,并将已验证的通过和失败轨迹转化为有依据的学习信号——而实时生产流量没有真实标签——供优化器或智能体自身的内存与自学习循环使用。

试用它,并帮助塑造它的发展方向

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

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

已复制

要将 AQuA 接入你在 Google Cloud 中的自有代理,并使用开箱即用的 ADK 脚手架(所有遥测数据、源快照和 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

已复制

要从你的编码代理(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,是为了与在生产环境中运行代理的团队协作,共同塑造它的发展方向。当你在自己的技术栈上试用它时,我们很想听听你的想法:

  1. 并行的质量代理是否契合你的架构?这个工作流中哪些部分你希望在自己的仓库中保持可定制,哪些部分最终希望由平台为你运行(例如跨一组代理进行接入)?
  2. 环境式质量代理将如何融入你的工程工作流?你团队中谁先对洞察进行分诊,在哪个界面(CLI/编码代理、IDE 或 Cloud Console),接下来会发生什么?
  3. 在代理质量工程中的这些难题里,我们应该先解决哪一个:从 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 仓库 · 从你的编码代理驱动代理质量飞轮 · 代理评估文档

上一页

下一页

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