<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Elia Secchi</title>
    <description>The latest articles on DEV Community by Elia Secchi (@eliasecchi).</description>
    <link>https://dev.to/eliasecchi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4228703%2F01ffca4d-4322-4a02-9046-d6ed74ee3f29.png</url>
      <title>DEV Community: Elia Secchi</title>
      <link>https://dev.to/eliasecchi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eliasecchi"/>
    <language>en</language>
    <item>
      <title>Find the production agent failures that every health check misses</title>
      <dc:creator>Elia Secchi</dc:creator>
      <pubDate>Thu, 05 Nov 2026 15:46:25 +0000</pubDate>
      <link>https://dev.to/googlecloud/find-the-production-agent-failures-that-every-health-check-misses-39j8</link>
      <guid>https://dev.to/googlecloud/find-the-production-agent-failures-that-every-health-check-misses-39j8</guid>
      <description>&lt;p&gt;Your agent returns HTTP 200 and stays inside its latency budget, and no tool call raises an error. Yet it records seat 3A as confirmed without ever asking the seat-selection sub-agent whether 3A is free. Nothing in your dashboards turns red, because the only evidence of the mistake sits inside the conversation.&lt;/p&gt;

&lt;p&gt;AQuA (Ambient Quality Agent) is an open-source quality agent. It surfaces that kind of failure across many sessions and, when you ask, traces a failure to the line of code behind it. We built AQuA, and Dima Melnyk and I wrote the full &lt;a href="https://developers.googleblog.com/the-outer-loop-insights-first-an-ambient-quality-agent-that-diagnoses-your-production-agent/" rel="noopener noreferrer"&gt;Developers Blog post&lt;/a&gt; about it. This companion walks through the same sweep and shows how to run the dashboard on your laptop with no cloud project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is hard
&lt;/h2&gt;

&lt;p&gt;Getting an agent to the first 80%, where it handles the cases you anticipated, takes days with an eval dataset and a run, grade, fix and compare loop. Then you launch and the curve flattens. Usage shifts, and a model, harness or tool change can alter task success while health checks stay green.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvx7gilarnyjws5liubh8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvx7gilarnyjws5liubh8.webp" alt="A quality curve that climbs before launch, flattens with silent failures after it, and climbs again once AQuA runs." width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 1. Quality stalls after launch on failures that report 200 OK.&lt;/p&gt;

&lt;p&gt;Diagnosing a failure is harder still, because several layers look identical from the outside. The model may have dropped a constraint, the harness may have misrouted to a sub-agent, a tool contract may have rejected an undocumented value, or the instructions may lack a rule. A raw trajectory shows what happened but says little about why, and nobody can read failing trajectories next to the code that produced them by hand at production volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AQuA is
&lt;/h2&gt;

&lt;p&gt;AQuA is an &lt;a href="https://adk.dev" rel="noopener noreferrer"&gt;Agent Development Kit (ADK)&lt;/a&gt; agent that runs unattended beside your agent in your Google Cloud project, outside the request path. It sweeps production sessions from &lt;a href="https://docs.cloud.google.com/trace/docs" rel="noopener noreferrer"&gt;Cloud Trace&lt;/a&gt;, &lt;a href="https://docs.cloud.google.com/logging/docs" rel="noopener noreferrer"&gt;Cloud Logging&lt;/a&gt; or &lt;a href="https://docs.cloud.google.com/bigquery/docs" rel="noopener noreferrer"&gt;BigQuery&lt;/a&gt; on a schedule, after each deployment, or on demand. Each sweep has five stages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9pe3jk0asa6bp4me5r5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9pe3jk0asa6bp4me5r5.webp" alt="Five boxes, Sample (random sessions), Review (one finding per failure), Cluster (same cause, grouped), Verify (opt-in, false alarms dropped) and Track (NEW or RECURRING), lead in turn to a larger box labelled Root cause at file:line." width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 2. Each stage narrows the findings, and when you ask, AQuA adds a root cause at file:line.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sample:&lt;/strong&gt; AQuA pulls a random sample of up to 1,000 recent sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review:&lt;/strong&gt; a review agent reads a shortened copy of each session, can query the full session with a &lt;code&gt;jq&lt;/code&gt; tool, and writes an &lt;code&gt;actual / expected&lt;/code&gt; finding for every failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cluster:&lt;/strong&gt; AQuA groups findings that share a failure mechanism into candidate issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify (opt-in):&lt;/strong&gt; with &lt;code&gt;agents-cli aqua attach --verification&lt;/code&gt;, a separate model checks each candidate against up to three transcripts, and &lt;code&gt;--enforce-verification&lt;/code&gt; withholds rejected candidates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track:&lt;/strong&gt; AQuA matches the survivors against open insights as &lt;code&gt;NEW&lt;/code&gt;, &lt;code&gt;RECURRING&lt;/code&gt;, or &lt;code&gt;RESOLVED&lt;/code&gt; after 14 days unseen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Root-cause analysis runs only on request, from the dashboard &lt;strong&gt;Chat&lt;/strong&gt; or &lt;code&gt;agents-cli aqua run&lt;/code&gt;. AQuA reads the failing trajectories against the source snapshot captured at deploy time and cites lines as &lt;code&gt;&amp;lt;path&amp;gt;:&amp;lt;start&amp;gt;-&amp;lt;end&amp;gt;&lt;/code&gt;. It proposes an edit and never applies it or opens a pull request. When the fault lies outside your code, it pins the failure to a step in the trajectory without citing a line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Walkthrough: a sweep on travel-concierge
&lt;/h2&gt;

&lt;p&gt;We pointed an earlier AQuA release, with verification on, at &lt;code&gt;travel-concierge&lt;/code&gt; from &lt;code&gt;google/adk-recipes&lt;/code&gt;, an agent that routes a traveler across sub-agents. We ran 32 replays of four scripted journeys, which produced 1,583 OpenTelemetry spans. Five of the 32 sessions passed, and 27 produced 42 findings, such as this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;actual:   When the user selected outbound flight UA204 and requested seats 3A and 3B in the same
          turn, planning_agent saved those seat numbers directly to session state without calling
          flight_seat_selection_agent to check whether 3A and 3B were available.
expected: planning_agent should call flight_seat_selection_agent to verify seat availability and
          pricing before saving outbound or return seat numbers to session state.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clustering grouped the 42 findings into 9 candidates. The verifier rejected 3, including one that merged unrelated mismatches from two sub-agents. The 6 verified issues included skipped seat checks (15 sessions), a vegan profile lost between &lt;code&gt;inspiration_agent&lt;/code&gt; and &lt;code&gt;place_agent&lt;/code&gt; (7 sessions), and a &lt;code&gt;poi_agent&lt;/code&gt; declared with &lt;code&gt;tools=[]&lt;/code&gt; despite needing verified map data (5 sessions).&lt;/p&gt;

&lt;p&gt;In that release, choosing &lt;strong&gt;Investigate&lt;/strong&gt; on the top insight sent the diagnosis agent through the 33-file snapshot of the deployed revision (in v0.3.0 you ask &lt;strong&gt;Chat&lt;/strong&gt; for a root cause). It traced the seat bug to line 93 of &lt;code&gt;travel_concierge/sub_agents/planning/prompt.py&lt;/code&gt;, where the instructions call the seat sub-agent only when presenting a seat map. It traced the vegan bug to line 23 of &lt;code&gt;travel_concierge/sub_agents/inspiration/prompt.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxcyveg90f8ia4fdcdrb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxcyveg90f8ia4fdcdrb.webp" alt="On the left, a box reading 200 OK and seat 3A confirmed; an arrow leads to a box on the right reading planning/prompt.py:93 and 15 sessions never checked the seat, with 5/32 to 13/32 full passes below it." width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 3. The failure as your dashboard sees it and as AQuA sees it; the full-pass gain came from this fix and the vegan one.&lt;/p&gt;

&lt;p&gt;After the two one-line prompt fixes shipped as a second revision, we replayed the same 32 sessions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measure&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Seat check bypass&lt;/td&gt;
&lt;td&gt;15 sessions&lt;/td&gt;
&lt;td&gt;2 sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vegan profile dropped&lt;/td&gt;
&lt;td&gt;7 sessions&lt;/td&gt;
&lt;td&gt;0 sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;poi_agent&lt;/code&gt; empty tool list&lt;/td&gt;
&lt;td&gt;5 sessions&lt;/td&gt;
&lt;td&gt;untouched, still tracked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full-session passes&lt;/td&gt;
&lt;td&gt;5/32&lt;/td&gt;
&lt;td&gt;13/32&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cost and limits
&lt;/h2&gt;

&lt;p&gt;In the earlier release, the 32-session sweep cost $3.76 at standard Gemini platform pricing, about $0.12 per session at about 50 spans each. A 96-session sweep of a single agent (5 to 6 spans per session) cost $0.70, and on-demand root-cause analysis cost $0.33 to $2.47 per insight. v0.3.0 reviews each session with an agent that can query the whole session, so its costs differ. An agent that diagnoses your agent will sometimes be wrong, so these limits and safeguards matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sampling is random.&lt;/strong&gt; A sweep reads up to 1,000 sessions, so a regression that breaks 1% of a critical workflow can slip through. You can store an SQL selector with &lt;code&gt;agents-cli aqua attach --selector-file&lt;/code&gt; to choose which conversations it reads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification is opt-in and bounded.&lt;/strong&gt; It covers up to 50 clusters per run and three transcripts each. AQuA does not check every member session, so a cluster's trace count is only a rough priority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights carry citations.&lt;/strong&gt; The insight schema has no confidence field. The server validates every cited &lt;code&gt;&amp;lt;path&amp;gt;:&amp;lt;start&amp;gt;-&amp;lt;end&amp;gt;&lt;/code&gt; range against the snapshot and rejects a reference to a nonexistent file or line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These numbers come from scripted journeys, not your traffic. Two one-line prompt edits moved full passes from 5/32 to 13/32, and no health check pointed at either line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The demo needs Python 3.11 to 3.13, &lt;code&gt;uv&lt;/code&gt; and &lt;code&gt;npm&lt;/code&gt;. It shows a generated month of data with no Google Cloud project, credentials or model calls. &lt;code&gt;make install&lt;/code&gt; creates the virtual environment, and &lt;code&gt;make demo&lt;/code&gt; builds the front end and then starts the dashboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/google/adk-recipes.git
&lt;span class="nb"&gt;cd &lt;/span&gt;adk-recipes/core/python/ambient-quality-agent
make &lt;span class="nb"&gt;install
&lt;/span&gt;make demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rdutp1v1c7dtq4k3hi3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2rdutp1v1c7dtq4k3hi3.webp" alt="A terminal showing selected startup lines of make demo: 16 generated insights, the guided-tour link and the dashboard serving on port 8080." width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 4. Selected lines of what &lt;code&gt;make demo&lt;/code&gt; printed at startup, read from its log with &lt;code&gt;sed&lt;/code&gt;: the generated data, the tour link and the dashboard on port 8080.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;http://localhost:8080/?tour&lt;/code&gt; for a guided tour. The demo observes &lt;code&gt;travel_desk_agent&lt;/code&gt;, a synthetic travel-and-expense agent so its insights differ from the walkthrough. None has a root cause unless you start the demo with &lt;code&gt;MOCK_ROOT_CAUSE=0.5 make demo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zdw5615d1yzcokpp0a2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zdw5615d1yzcokpp0a2.webp" alt="The top of the AQuA insights page, listing three recurring failures of the demo agent with their occurrence and trajectory counts." width="652" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 5. The insights page on demo data: 16 insights affecting 3,742 trajectories, ranked by impact.&lt;/p&gt;

&lt;p&gt;To attach AQuA to your own &lt;a href="https://google.github.io/agents-cli/" rel="noopener noreferrer"&gt;Agents CLI&lt;/a&gt; project, add the extension, which pins v0.3.0 here. Agents CLI extensions are experimental, and AQuA needs &lt;code&gt;agents-cli&lt;/code&gt; 1.10 or later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;agents-cli extension add google/adk-recipes#core/python/ambient-quality-agent &lt;span class="nt"&gt;--ref&lt;/span&gt; ambient-quality-agent/v0.3.0
agents-cli &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deployment needs a Google Cloud project in an organization, because the dashboard sits behind &lt;a href="https://docs.cloud.google.com/iap/docs" rel="noopener noreferrer"&gt;Identity-Aware Proxy&lt;/a&gt; (IAP). Without an organization, set &lt;code&gt;TF_VAR_ui_iap_enabled=false&lt;/code&gt; and open it with &lt;code&gt;agents-cli aqua ui-proxy&lt;/code&gt;. The &lt;a href="https://github.com/google/adk-recipes/tree/main/core/python/ambient-quality-agent" rel="noopener noreferrer"&gt;AQuA README&lt;/a&gt; covers deployment and the &lt;code&gt;agents-cli aqua&lt;/code&gt; commands. The &lt;a href="https://developers.googleblog.com/the-outer-loop-insights-first-an-ambient-quality-agent-that-diagnoses-your-production-agent/" rel="noopener noreferrer"&gt;Developers Blog post&lt;/a&gt; has the full design discussion and the team credits.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>debugging</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
