<?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: OpsVeritas</title>
    <description>The latest articles on DEV Community by OpsVeritas (opsveritas).</description>
    <link>https://dev.to/opsveritas</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%2Forganization%2Fprofile_image%2F13404%2F56e2340b-6cae-4cc9-9224-ecb013f9d8b9.png</url>
      <title>DEV Community: OpsVeritas</title>
      <link>https://dev.to/opsveritas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/opsveritas"/>
    <language>en</language>
    <item>
      <title>The Real Cost of Not Knowing</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Mon, 07 Sep 2026 14:44:13 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-real-cost-of-not-knowing-10c0</link>
      <guid>https://dev.to/opsveritas/the-real-cost-of-not-knowing-10c0</guid>
      <description>&lt;h2&gt;
  
  
  The Real Cost of Not Knowing
&lt;/h2&gt;

&lt;p&gt;Most automation teams think about monitoring backwards. They see the $99/month price tag and do a quick mental math: "That's expensive. We've been running workflows fine for two years without it."&lt;/p&gt;

&lt;p&gt;Then a workflow fails silently for 6 hours. Not erroring, just doing nothing. Candidates don't get scored. Payment records don't sync. Leads don't get tagged. Everything looks green in the logs.&lt;/p&gt;

&lt;p&gt;The cost of that 6-hour window is almost never $99.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "Silent" Failures Are Expensive
&lt;/h2&gt;

&lt;p&gt;A silent failure is a workflow that returns HTTP 200 and exits cleanly, but processed zero items. Your monitoring dashboard doesn't see an error. Your error tracking doesn't ping. Your team finds out when a customer says "I applied three days ago and haven't heard back."&lt;/p&gt;

&lt;p&gt;Here's the math that makes this expensive:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revenue workflows&lt;/strong&gt; (payment reconciliation, lead capture, subscription processing):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If your workflow touches 50 transactions/hour at an average value of $20 each: 6 hours x 50 x $20 = $6,000 in unprocessed value.&lt;/li&gt;
&lt;li&gt;Detection delay if you're checking manually once a day: lose another 18 hours.&lt;/li&gt;
&lt;li&gt;Cost of recovery (manual backfill, customer support, retry fee): $500-$2,000.&lt;/li&gt;
&lt;li&gt;Total: $6,500-$8,000 for one undetected 6-hour gap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Compliance workflows&lt;/strong&gt; (audit logs, data sync, regulatory reporting):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Silent failure = missing logs or records.&lt;/li&gt;
&lt;li&gt;Audit discovery cost: compliance review + documentation recovery: $1,000-$5,000.&lt;/li&gt;
&lt;li&gt;Regulatory fine risk if the gap affects reporting deadlines: $5,000-$50,000+.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Candidate/hiring workflows&lt;/strong&gt; (resume screening, interview scheduling, panel coordination):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hiring round stalls because candidates aren't being moved through the pipeline.&lt;/li&gt;
&lt;li&gt;Each day of stall costs hiring velocity: 1-2 strong candidates who lose interest.&lt;/li&gt;
&lt;li&gt;Cost of replacing a failed hire due to slow pipeline: $20,000-$100,000.&lt;/li&gt;
&lt;li&gt;Cost of filling a role one week late: $30,000-$50,000 in productivity loss.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The pattern:&lt;/strong&gt; if your workflow touches anything with business value (revenue, compliance, hiring, customer data), a 6-hour detection window usually costs more than a year of monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Break-Even Framework
&lt;/h2&gt;

&lt;p&gt;Here's a framework you can run in a spreadsheet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cost of one silent-failure incident:
= (detection_delay_hours / 24) x daily_workflow_value
+ recovery_cost
+ business_impact_cost

Daily workflow value =
(transactions_per_day) x (average_value_per_transaction)
OR (revenue_at_risk_per_day)
OR (compliance_penalty_risk_per_day)

Annual monitoring cost = $99/mo x 12 = $1,188

Break-even point =
Annual monitoring cost / Cost of one incident
(If the cost is high, break-even is often &amp;lt; 1 incident per year)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example: a Make scenario that syncs 500 customers/day to your CRM&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transactions per day: 500
Value per transaction: customer relationship data
(if sync fails, support team has to manually fix entries = $50/incident)
Detection delay if manual: 24 hours
Recovery overhead: 8 hours x $150/hr labor = $1,200

Cost of one 24-hour undetected sync failure:
= (24 / 24) x (500 x $50) + $1,200
= $25,000 + $1,200
= $26,200

Annual monitoring cost: $1,188

Break-even: $1,188 / $26,200 = 0.045 incidents/year
(Meaning: one incident every 22 years)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've run this workflow for 2 years without a silent failure, congratulations, you've been lucky. Monitoring is insurance. The question is whether you can afford a $26,000 loss to save $1,188 in premiums.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Monitoring" Actually Means Here
&lt;/h2&gt;

&lt;p&gt;When we say monitoring catches silent failures, the mechanism is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your workflow completes without error.&lt;/li&gt;
&lt;li&gt;Monitoring logs: &lt;code&gt;status: success&lt;/code&gt;, &lt;code&gt;items_processed: 0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Alert fires immediately: "Workflow succeeded but produced zero output."&lt;/li&gt;
&lt;li&gt;You know in 10 minutes instead of 24 hours.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For n8n, Make, Zapier, and GitHub Actions, &lt;a href="https://app.opsveritas.com" rel="noopener noreferrer"&gt;OpsVeritas&lt;/a&gt; connects via a read-only API key or a monitoring node. No changes to your workflows, no rip-and-replace. You get per-run visibility: status, items processed, run time, and execution logs. Silent failures, stale workflows, cost spikes, and performance degradation all surface before your customers notice.&lt;/p&gt;

&lt;p&gt;The monthly cost is the same regardless of platform: $99 (Starter) covers 100 workflows. If you're running 10+ workflows that touch revenue, data, or compliance, your break-even is usually less than one incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Question
&lt;/h2&gt;

&lt;p&gt;Ask yourself: "What's the business value of the workflows I'm monitoring? How long can one of them stay silent before it costs me more than I'm spending on monitoring?"&lt;/p&gt;

&lt;p&gt;If that number is less than 30 days, monitoring isn't a cost center. It's insurance. And like all insurance, you don't buy it because you expect a payout. You buy it because the cost of being wrong is higher than the cost of peace of mind.&lt;/p&gt;

&lt;p&gt;The best time to add monitoring is before you need it. The second-best time is right after you find out why you needed it the first time.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>devops</category>
      <category>automation</category>
    </item>
    <item>
      <title>Building a DIY Health Check for Your Zapier Webhooks (And Where It Falls Apart)</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Thu, 03 Sep 2026 06:18:03 +0000</pubDate>
      <link>https://dev.to/opsveritas/building-a-diy-health-check-for-your-zapier-webhooks-and-where-it-falls-apart-4dba</link>
      <guid>https://dev.to/opsveritas/building-a-diy-health-check-for-your-zapier-webhooks-and-where-it-falls-apart-4dba</guid>
      <description>&lt;p&gt;If you run anything business-critical through Zapier webhooks, you've probably had the moment: a zap that looked fine in the dashboard, that had been quietly not firing for two days. Here's a simple health check you can build yourself in about twenty minutes, and the point at which it stops being enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic pattern: a dead man's switch
&lt;/h2&gt;

&lt;p&gt;The core idea is old and reliable. Instead of asking "did my zap run correctly," ask "has my zap checked in recently."&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write a heartbeat.&lt;/strong&gt; At the end of your critical zap, add a final step that writes a timestamp somewhere durable: a row in a Google Sheet, a key in Airtable, a record in your own database. It doesn't matter what the zap actually did upstream; this step just proves the zap reached its last action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poll the heartbeat.&lt;/strong&gt; A second, independent zap (or a simple cron job, or an n8n schedule trigger, whatever you already have running) checks that timestamp every 15 or 30 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alert on staleness, not on error.&lt;/strong&gt; If the timestamp hasn't moved in longer than your zap's expected interval, say double the normal gap, fire a Slack message or an email. You're not catching an error. You're catching silence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This catches the most obvious failure mode: a zap that stops triggering entirely, because a connected account's token expired, a filter got misconfigured, or the upstream service changed its webhook payload shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it breaks down
&lt;/h2&gt;

&lt;p&gt;The dead man's switch only tells you the zap is still executing. It says nothing about whether each individual run did anything useful. That's the gap that actually causes the most damage, because it's invisible even to this fix.&lt;/p&gt;

&lt;p&gt;Concretely: your webhook-triggered zap runs at 9am, 10am, 11am, every hour, checking in on schedule. But three of those runs processed zero records because the incoming payload's field names changed slightly and your filter step silently excluded everything. The heartbeat updates right on schedule. The zap is "healthy." It's also doing nothing.&lt;/p&gt;

&lt;p&gt;Catching that requires a different kind of check: not "did the zap run," but "did the zap's output match what it normally produces." That means tracking volume per run, not just liveness, and comparing it against a baseline instead of a fixed rule, since a genuinely quiet Sunday and a broken filter look identical from a single data point.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the DIY version stops scaling
&lt;/h2&gt;

&lt;p&gt;The heartbeat-and-poll pattern works fine for one or two critical zaps. It gets unwieldy fast once you're running a dozen workflows across Zapier, Make, and n8n, each needing its own heartbeat step, its own polling job, its own alerting logic, and its own baseline for what "normal volume" even looks like.&lt;/p&gt;

&lt;p&gt;At that point, a tool like &lt;a href="https://app.opsveritas.com" rel="noopener noreferrer"&gt;OpsVeritas&lt;/a&gt; can help. It sits outside your workflows and watches for silent failures at scale: zero-output runs, silent stalls, volume drops against a rolling baseline, so your team isn't rebuilding health checks in every zap by hand.&lt;/p&gt;

</description>
      <category>zapier</category>
      <category>automation</category>
      <category>webhooks</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Why "HTTP 200" Doesn't Mean Your Automation Worked</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Thu, 03 Sep 2026 06:17:48 +0000</pubDate>
      <link>https://dev.to/opsveritas/why-http-200-doesnt-mean-your-automation-worked-41lp</link>
      <guid>https://dev.to/opsveritas/why-http-200-doesnt-mean-your-automation-worked-41lp</guid>
      <description>&lt;p&gt;Every automation platform, n8n, Make, Zapier, and the custom pipelines teams build on top of them, tells you when a run "succeeded." The problem is what that word actually means under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two different definitions of success
&lt;/h2&gt;

&lt;p&gt;In application code, success usually means a specific outcome happened: a row got inserted, a record got returned, a message got delivered. If it didn't happen, you get an exception, a non-200 status, something loud.&lt;/p&gt;

&lt;p&gt;In workflow automation, "success" almost always means something narrower: the run finished executing every node without one of them throwing an unhandled error. That's it. Nothing about what the nodes actually produced.&lt;/p&gt;

&lt;p&gt;These two definitions look similar from a distance. They diverge exactly where it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the gap opens
&lt;/h2&gt;

&lt;p&gt;Take a typical n8n workflow: a trigger, a filter node, an HTTP request node, a database write. If the filter node's condition is slightly wrong, say it excludes every record instead of the ones you meant to exclude, the workflow doesn't error. It just filters everything out, so the HTTP request and database write nodes never fire, or fire with zero items. The execution log shows green across every node. Nothing crashed. Nothing timed out.&lt;/p&gt;

&lt;p&gt;Same shape of problem in Make: a scenario polls an API, transforms the response, and syncs it to a destination. If the source query is malformed in a way the API accepts (wrong filter value, wrong date range), you get a 200 response with an empty result set. The scenario "succeeds" at processing zero records.&lt;/p&gt;

&lt;p&gt;Zapier is the same pattern with a friendlier UI. A trigger that's scoped too narrowly fires never, or fires without the fields downstream steps expect. The zap's history shows a clean run. It just ran on nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this isn't a platform bug
&lt;/h2&gt;

&lt;p&gt;It's tempting to file this under "these tools should be smarter." They can't be, not without knowing your intent. A workflow engine has no way to know that your lead-sync scenario is supposed to move roughly 40 to 80 records a day. It only knows whether each node's own operation completed. Whether the operation was meaningful is business context the platform was never given.&lt;/p&gt;

&lt;p&gt;That's the actual architectural gap: execution-level success and outcome-level success are checked at different layers, and most teams only instrument the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What validating at the boundary actually looks like
&lt;/h2&gt;

&lt;p&gt;The fix isn't more error handling inside the workflow. It's a check that sits outside the workflow and compares what actually happened against what should have happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Item count, not just status code. A sync that normally moves 50-plus records and today moved zero is a signal, even though every node returned 200.&lt;/li&gt;
&lt;li&gt;Baseline comparison, not a fixed threshold. "Zero is always bad" is too blunt for workflows with legitimately idle days. Compare against a rolling baseline instead.&lt;/li&gt;
&lt;li&gt;Alerting on the absence of activity, not just the presence of errors. Most monitoring is built to catch exceptions. It has to be deliberately built to catch silence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this requires touching the workflow's own logic. It's a layer that watches outputs, independent of whether the workflow thinks it succeeded.&lt;/p&gt;

&lt;p&gt;That's the pattern behind &lt;a href="https://app.opsveritas.com" rel="noopener noreferrer"&gt;OpsVeritas&lt;/a&gt;: watching for the runs that finish green and produce nothing, the failures automation platforms aren't designed to see. If you're running n8n, Make, or Zapier at any real volume, it's worth a look.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>devops</category>
      <category>n8n</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>The Silent Wrong Answer</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Sun, 23 Aug 2026 14:53:05 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-silent-wrong-answer-47n3</link>
      <guid>https://dev.to/opsveritas/the-silent-wrong-answer-47n3</guid>
      <description>&lt;p&gt;Your agent returned a well-formed response. The output looks right. Then your customer replies: "That's not what I asked for."&lt;/p&gt;

&lt;p&gt;This is the failure class that hits hardest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Silent Wrong Answer
&lt;/h2&gt;

&lt;p&gt;There's a hierarchy of agent failures, and most of the attention goes to the loud ones: crashes, timeouts, exceptions in the logs. Your monitoring catches those instantly. But there's a quieter failure — the one that slips through because everything &lt;em&gt;looks&lt;/em&gt; fine — and it can damage your reputation faster than any outage.&lt;/p&gt;

&lt;p&gt;Your agent completes successfully. HTTP 200. No errors. The output parses. It's well-formed JSON or clean text. Your logs show a successful execution. By every standard measure, the agent did its job.&lt;/p&gt;

&lt;p&gt;Except it didn't.&lt;/p&gt;

&lt;p&gt;The output is plausible. It has the right structure. It contains relevant information. But when your customer reads it, they realize it doesn't actually answer what they asked. Maybe it's an off-by-one error in a calculation. Maybe it misunderstood a constraint and applied the wrong business rule. Maybe it hallucinated a confident-sounding answer to a question it didn't actually know how to solve.&lt;/p&gt;

&lt;p&gt;Your customer doesn't see "the monitoring missed this." They see: "Your automation is broken" — and they're not wrong. The damage is immediate: lost trust, delayed work, questions about whether they should even be using your automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Failure Class Is Invisible
&lt;/h2&gt;

&lt;p&gt;Standard observability catches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Empty output&lt;/strong&gt; (silent failures proper) — when an agent returns success but produces zero useful tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format errors&lt;/strong&gt; — when the JSON doesn't parse or the response structure is wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution failures&lt;/strong&gt; — timeouts, API errors, exceptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those catch a response that is &lt;em&gt;structurally correct but semantically wrong&lt;/em&gt;. The agent produced output. It's well-formed. It ran to completion. Everything your logs and dashboards show you says "success."&lt;/p&gt;

&lt;p&gt;This is the gap most builders discover by accident — when a customer tells you about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost
&lt;/h2&gt;

&lt;p&gt;If you're building automations or AI agents for clients, for a product, or for yourself at scale, this failure class compounds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Discovery delay.&lt;/strong&gt; You don't find out until someone downstream uses the output and realizes it's wrong. Could be hours, could be days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attribution chaos.&lt;/strong&gt; Your customer doesn't report "the agent output was wrong" — they report "your automation didn't work," and now you're debugging blind. Was it the agent? The integration? The underlying data? You have to work backward from the complaint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reputation hit.&lt;/strong&gt; For agencies and builders, each wrong output erodes trust in your entire automation. If the agent gets the details wrong once, why should they trust it next time?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compounding failures.&lt;/strong&gt; If the wrong output feeds into a downstream process (another workflow, a database update, a customer communication), the damage multiplies before you even notice.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Catching It Before Your Customer Does
&lt;/h2&gt;

&lt;p&gt;You can't prevent wrong outputs entirely — that's a problem in AI that outlives any monitoring tool. But you can &lt;em&gt;detect&lt;/em&gt; them automatically, before they reach a customer.&lt;/p&gt;

&lt;p&gt;The mechanism is straightforward: write a rubric — a short sentence or checklist describing what a &lt;em&gt;correct&lt;/em&gt; output should look like for your agent. Then grade every execution's output against that rubric, using an AI judge that applies your criteria.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"The total must equal the sum of line items" (finance automation)&lt;/li&gt;
&lt;li&gt;"All three fields must be present: name, email, phone" (data extraction)&lt;/li&gt;
&lt;li&gt;"The response must cite at least one source from the provided documents" (research agent)&lt;/li&gt;
&lt;li&gt;"The date must be in YYYY-MM-DD format and must not be in the future" (scheduling automation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time your agent runs, the output is graded against your rubric. If it fails, you get an alert: "Wrong Output" — &lt;em&gt;before&lt;/em&gt; that output goes downstream, &lt;em&gt;before&lt;/em&gt; your customer sees it.&lt;/p&gt;

&lt;p&gt;The rubric is your criteria, not an external fact-check. This matters: you're not asking the system to verify whether the answer is universally true; you're checking whether it meets &lt;em&gt;your&lt;/em&gt; specific requirements. That's a much tighter problem.&lt;/p&gt;

&lt;p&gt;And because the judge is imperfect (it can miss things, it can misapply your rubric), the tool is alert-only: it flags the execution for review, it doesn't silently block the agent. You can test your rubric against your agent's recent real executions before enabling it, so a badly written rubric gets caught by &lt;em&gt;you&lt;/em&gt;, not by a false-positive flood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters For Builders
&lt;/h2&gt;

&lt;p&gt;If you're shipping an automation or an AI agent into production — whether it's a client's workflow, a product feature, or your own internal system — the wrong output isn't just a technical problem. It's a trust problem.&lt;/p&gt;

&lt;p&gt;Your customer doesn't care that the agent's logs looked good. They care that the output was wrong. Every undetected wrong output is a moment you didn't catch your own mistake before it reached them.&lt;/p&gt;

&lt;p&gt;Catching them automatically, before they're visible to anyone downstream, is insurance. It's the observability layer that sits above the code and above the framework — the layer that answers the question most builders forget to ask: &lt;em&gt;not "did the agent run," but "did the agent produce the right thing?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The difference, when your customer is about to find out, is everything.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>observability</category>
      <category>devops</category>
    </item>
    <item>
      <title>Cost Governance for AI Agents: From Detection to Enforcement</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Tue, 18 Aug 2026 19:23:56 +0000</pubDate>
      <link>https://dev.to/opsveritas/cost-governance-for-ai-agents-from-detection-to-enforcement-42mp</link>
      <guid>https://dev.to/opsveritas/cost-governance-for-ai-agents-from-detection-to-enforcement-42mp</guid>
      <description>&lt;p&gt;Your AI agent is burning money. It hasn't crashed, it's running fine, and the only way you find out is when the bill shows up.&lt;/p&gt;

&lt;p&gt;Here's the pattern: an agent gets confused and calls the same tool over and over. Or a model upgrade quietly triples the cost per token. Or one bad execution fires a hundred times in parallel. From the SDK's point of view, every one of those is a success. Status 200, output returned, nothing to flag.&lt;/p&gt;

&lt;p&gt;We think about cost governance as three layers, and they build on each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detection
&lt;/h2&gt;

&lt;p&gt;You need per-execution visibility, not a monthly total. Token count, cost in dollars, latency, per run. That's how you find out which agent burned $500 yesterday instead of which month burned $10k.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagnosis
&lt;/h2&gt;

&lt;p&gt;An agent that costs $5 one day and $500 the next isn't random. Either the cost per call spiked (something's asking for way more tokens than usual) or the call count spiked (it's looping). Knowing which one happened tells you what to actually fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcement
&lt;/h2&gt;

&lt;p&gt;This is the part most teams skip. Once you know an agent's normal cost profile, you can pause it automatically if it breaks that pattern hard enough, or if it crosses a budget you set. That check runs before the next API call goes out, so it stops the spend rather than just reporting it after the fact. It fails open too, so a network hiccup on the check itself never breaks your agent's normal operation. And restarting it once you've found the root cause takes seconds.&lt;/p&gt;

&lt;p&gt;Detection and diagnosis should always be on. Enforcement is opt-in, because the policy is yours to set. One team wants a hard stop. Another wants an alert and a human in the loop.&lt;/p&gt;

&lt;p&gt;None of this works without seeing every execution, though. Sampled metrics will miss the loop that cost you a thousand dollars in five minutes.&lt;/p&gt;

&lt;p&gt;If you're running agents in production, the cost story shouldn't be a surprise invoice weeks later. It should be a dial you can turn today.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>We Built Monitoring Into Our Own AI Agents. Here's What We Learned.</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Mon, 17 Aug 2026 17:30:42 +0000</pubDate>
      <link>https://dev.to/opsveritas/we-built-monitoring-into-our-own-ai-agents-heres-what-we-learned-enm</link>
      <guid>https://dev.to/opsveritas/we-built-monitoring-into-our-own-ai-agents-heres-what-we-learned-enm</guid>
      <description>&lt;p&gt;We run marketing workflows on an AI agent. When we tried to monitor it with existing tools, we found ourselves flying blind in ways we didn't expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We Didn't Know We Had
&lt;/h2&gt;

&lt;p&gt;Three months ago, our marketing agent was supposed to draft social posts every morning. One Tuesday, it hadn't. We checked the logs. No errors. The LLM call succeeded. HTTP 200. The response came back. And yet: no draft. Just a blank.&lt;/p&gt;

&lt;p&gt;This is the failure mode that most observability tooling doesn't catch. The agent executed. The infrastructure said "success." But the agent produced nothing — zero output tokens, an empty response, a request that returned 200 OK but accomplished zero.&lt;/p&gt;

&lt;p&gt;We had to manually check the execution history to find it. By then, someone else had noticed the absence.&lt;/p&gt;

&lt;p&gt;That's when we realized: we couldn't see what was actually happening in our own agents in real time. We needed to build visibility from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from First Principles
&lt;/h2&gt;

&lt;p&gt;We asked: what do we actually need to know about an AI agent execution?&lt;/p&gt;

&lt;p&gt;Not just "did it error?" — because errors aren't the only way an agent fails. We needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did it run at all? (HTTP status, latency)&lt;/li&gt;
&lt;li&gt;Did it consume what we expected? (tokens, cost)&lt;/li&gt;
&lt;li&gt;Did it produce anything? (output length, not just "success" status)&lt;/li&gt;
&lt;li&gt;Did it do the right thing? (the harder one — we'll come back to this)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most APM tools watch infrastructure: request latency, error rates, dependencies. None of those answer "was the output empty?" They watch the wrapper, not what happened inside.&lt;/p&gt;

&lt;p&gt;So we wrote an SDK wrapper for our agents. Simple design:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Intercept the LLM client calls (OpenAI, Anthropic, etc.)&lt;/li&gt;
&lt;li&gt;Capture the telemetry: tokens in/out, cost, latency, and — crucially — the output itself&lt;/li&gt;
&lt;li&gt;Send it somewhere we could query and alert on it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The SDK runs inside our own environment, not between us and the LLM provider. Your API keys stay in your process. We only ever see the telemetry.&lt;/p&gt;

&lt;p&gt;That design choice matters: it means we can capture what the model actually returned, but we can't see your proprietary prompt or system instructions. Read-only observability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Built (And Why)
&lt;/h2&gt;

&lt;p&gt;The first version just captured raw metrics. We logged tokens consumed (input/output), cost calculated from per-model pricing, latency, status (success/failure/timeout), model name (so we could auto-calculate cost from a built-in rate table), and a summary of the output.&lt;/p&gt;

&lt;p&gt;We pushed it to a dashboard and set up basic alerts: if cost spiked, flag it. If latency crossed a threshold, flag it.&lt;/p&gt;

&lt;p&gt;This caught infrastructure problems. It didn't catch silent failures.&lt;/p&gt;

&lt;p&gt;So we added silent-failure detection: if status is "success" but output_tokens equals 0, that's an alert. The agent ran. It returned 200. It produced nothing.&lt;/p&gt;

&lt;p&gt;We caught three more of them within a week using this rule alone.&lt;/p&gt;

&lt;p&gt;Then came the harder question: what if the output looks fine but is actually wrong?&lt;/p&gt;

&lt;p&gt;An agent returns a well-formed response. Tokens flow normally. Cost is where we'd expect. But the output is garbage — a recommendation that doesn't match the input, a calculation that's off, a response that's just not what was asked for.&lt;/p&gt;

&lt;p&gt;No metric catches that. No baseline can. You need a human (or another model) to grade it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Correctness Problem
&lt;/h2&gt;

&lt;p&gt;We built a "correctness check" feature: you write a rubric in plain English describing what a correct output should look like ("The response must include a specific name and a recommendation. The recommendation must be actionable."). Then we run every execution's output past an AI grader against that rubric.&lt;/p&gt;

&lt;p&gt;The grader isn't perfect. That's the whole point of making it reviewable. On every alert, we let you give a thumbs-up or thumbs-down: "did the judge get this right?" Over time, that feedback becomes a record of accuracy.&lt;/p&gt;

&lt;p&gt;And if the judge is systematically wrong about something, you can flag a disagreement and add it as an example the judge learns from. The correction is always manual — we don't auto-add examples from feedback — so a bad rubric can't teach itself to fail.&lt;/p&gt;

&lt;p&gt;This catches the "200 OK but completely wrong" case. It doesn't solve the problem of an imperfect judge. It just makes the imperfection visible and reviewable, rather than hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;The infrastructure lies to you. HTTP 200 is not a guarantee of work done. Latency is not a guarantee of usefulness. Error rates don't tell you about silent failures. You need eyes on the actual output.&lt;/p&gt;

&lt;p&gt;Secrets stay secrets. You can have observability without sharing your API keys or your prompt logic. An SDK that runs in your own environment sees everything your code sees, but only sends us aggregates and summaries. That's the design that lets us help you without breaking your security model.&lt;/p&gt;

&lt;p&gt;The easiest failures to miss are the ones that don't error. An agent that times out, an API that 500s — those are obvious. An agent that returns 200 with no response? That's what sits in your queue unnoticed until a customer tells you.&lt;/p&gt;

&lt;p&gt;Correctness is a human problem with AI help. You can't write a metric that "correctness" is. You can write a rubric and ask another model to grade it, and you can let humans correct the grader. The system becomes useful when the correction loop is tight and transparent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gaps We Hit
&lt;/h2&gt;

&lt;p&gt;When we were building this, we looked at what existed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application performance monitoring tools watch latency, errors, and infrastructure — not AI-specific problems like silent failures or cost anomalies.&lt;/li&gt;
&lt;li&gt;LLM observability tools (the newer ones) watch tokens and cost, which is closer — but most don't distinguish between "agent returned success with no output" and "agent returned success with output." The metrics look the same.&lt;/li&gt;
&lt;li&gt;Logging frameworks let you log whatever you want, but they don't automatically flag patterns. You're reading through logs manually or writing custom rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We needed something that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Auto-detected which model you were using (so cost was automatic, no config)&lt;/li&gt;
&lt;li&gt;Flagged silent failures specifically (not just errors)&lt;/li&gt;
&lt;li&gt;Didn't require you to share your API keys with us&lt;/li&gt;
&lt;li&gt;Let you define what "correct" means and alert when it's violated&lt;/li&gt;
&lt;li&gt;Gave you real-time visibility without slowing down your agent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's what we built. And we're eating our own dogfood: this very marketing system runs on an AI agent that we monitor with our own product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;We're learning as we use it. The silent-failure detection is solid — it catches what the infrastructure can't see. The cost anomaly detection helps catch runaway loops. The correctness check is useful but imperfect by design: we don't claim to know what "correct" means for your use case, only to help you define and enforce it.&lt;/p&gt;

&lt;p&gt;The thing we're still figuring out: how to make the correctness feedback loop even tighter. Right now, if the judge disagrees with you, you can promote that disagreement into a training example. But how many examples does the judge actually need to improve? When does a rubric become accurate enough to trust? How do you know when you've taught it enough?&lt;/p&gt;

&lt;p&gt;Those are open questions. We're answering them live, with real agents, real failures, and real feedback from the builders using the system.&lt;/p&gt;

&lt;p&gt;If you're building AI agents and you're wondering whether your monitoring is good enough, ask yourself: could you spot a silent failure in your own agent right now? Not an error — just an execution that returned success but produced nothing?&lt;/p&gt;

&lt;p&gt;If the answer is "not without checking the logs manually," you've found the gap we're trying to close.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>The Hidden Math: Why "Cheapest Model" Doesn't Mean Cheapest Execution</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Wed, 12 Aug 2026 10:20:37 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-hidden-math-why-cheapest-model-doesnt-mean-cheapest-execution-562b</link>
      <guid>https://dev.to/opsveritas/the-hidden-math-why-cheapest-model-doesnt-mean-cheapest-execution-562b</guid>
      <description>&lt;h1&gt;
  
  
  The Hidden Math: Why "Cheapest Model" Doesn't Mean Cheapest Execution
&lt;/h1&gt;

&lt;p&gt;You're building an AI agent. Smart cost strategy: route to GPT-4o when you need reasoning, Haiku for simple classification, Groq when it's available and fast. In your head, the math is simple: pick the cheapest model per task.&lt;/p&gt;

&lt;p&gt;In practice, you ship code and never really know if it worked.&lt;/p&gt;

&lt;p&gt;Here's the gap: &lt;strong&gt;cheapest model ≠ cheapest execution.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A single agent run might span multiple model calls. One task uses Anthropic's Sonnet ($3 / 1M input, $15 / 1M output). Another uses OpenAI's GPT-4o mini ($0.15 / 1M input, $0.60 / 1M output). A third falls back to Groq Llama 3.1 when latency spikes. By the time the execution finishes, you have no idea which model was actually called, how many tokens each burned, or whether that "cheap" fallback actually saved money — or whether a long output summary from one call inflated the token count beyond what you budgeted.&lt;/p&gt;

&lt;p&gt;The assumption breaks immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the math matters (and why it's invisible)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Token costs compound differently by model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take a real scenario: your agent needs to summarize a customer support transcript (2,000 input tokens). You budgeted for Haiku: 2,000 tokens × $0.80 / 1M = $0.0016 input cost. Cheap.&lt;/p&gt;

&lt;p&gt;But Haiku hits a rate limit. Code routes to Sonnet as fallback. Same 2,000 input tokens, now $0.006 — nearly 4× more. Multiply that across 100 daily runs, and you've overrun your mental budget without knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output lengths are invisible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worse: you don't even know the output token count. An agent that "completes" a task could've produced 500 output tokens (brief response) or 5,000 (verbose reasoning). With Sonnet outputting at $15 / 1M, that's the difference between $0.0075 and $0.075 per run. Neither is huge. But if your agent runs 1,000 times a month and half your executions unexpectedly verbose?&lt;/p&gt;

&lt;p&gt;You're now $37 over budget without seeing why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-model routing compounds the blind spot.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you route across three providers with six fallback models, you lose the ability to reason about cost at a glance. Did GPT-4o actually run, or did it fail and drop to Sonnet? How many times did Groq get chosen? Which model produced the longest outputs? You shipped it all, but you're flying blind on the arithmetic that actually happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unsexy solution: measure and account
&lt;/h2&gt;

&lt;p&gt;Here's what works (and it's not flashy):&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Log every model call with input + output token counts.
&lt;/h3&gt;

&lt;p&gt;Before you route, log which model was selected. After the call returns, log the actual token counts from the response metadata. Not a guess — the real numbers.&lt;/p&gt;

&lt;p&gt;Why: your mental model of "mostly cheap, sometimes fallback" gets replaced with actual data. You can group by model, see fallback rates, and measure whether your routing actually favors the cheap path.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compute cost inline using per-model rates.
&lt;/h3&gt;

&lt;p&gt;Every model has a published price per 1M tokens (input and output separate). Compute cost at execution time using actual tokens.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: 2,000 tokens&lt;/li&gt;
&lt;li&gt;Output: 1,500 tokens&lt;/li&gt;
&lt;li&gt;Model: Anthropic Sonnet ($3 / 1M input, $15 / 1M output)&lt;/li&gt;
&lt;li&gt;Cost: (2,000 / 1M × $3) + (1,500 / 1M × $15) = $0.006 + $0.0225 = &lt;strong&gt;$0.0285 per run&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sixty runs a day? That's $1.71 / day, $51 / month. You now know the actual stake.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Bucket by model + routing path.
&lt;/h3&gt;

&lt;p&gt;At the end of each day (or run batch), group executions by which model actually ran and whether it was your first choice or a fallback. Count, sum costs, measure fallback frequency.&lt;/p&gt;

&lt;p&gt;If Groq was supposed to be your primary but it failed 20% of the time, you now have evidence to either increase fallback tolerance, switch providers, or accept that Sonnet is your real cost center.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Alert on outliers.
&lt;/h3&gt;

&lt;p&gt;A single execution shouldn't surprise you. If one run's cost is 3σ above the 30-day average for that agent, you want to know why: did it produce an unexpectedly long output? Did it hit a fallback you didn't expect? Was there a retry loop?&lt;/p&gt;

&lt;p&gt;The math stops being invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys you
&lt;/h2&gt;

&lt;p&gt;You move from "I think this is cheap" to "I know what this costs, per execution, per model, per routing path."&lt;/p&gt;

&lt;p&gt;That's the difference between budgeting in hope and budgeting in fact.&lt;/p&gt;

&lt;p&gt;The math isn't exciting. But it's urgent, because runaway cost is usually a routing or retry problem hiding in production, and it stays hidden until the bill lands.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>llm</category>
      <category>observability</category>
    </item>
    <item>
      <title>The Silent Failure Detection Framework: Catching Agents That "Succeed" and Do Nothing</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:01:59 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-silent-failure-detection-framework-catching-agents-that-succeed-and-do-nothing-ak4</link>
      <guid>https://dev.to/opsveritas/the-silent-failure-detection-framework-catching-agents-that-succeed-and-do-nothing-ak4</guid>
      <description>&lt;p&gt;Your LLM agent returned a response. No error, no exception. But did it actually do what you asked?&lt;/p&gt;

&lt;p&gt;That's the silent failure problem. The system behaves normally — HTTP 200, status success — but the output is empty or nonsensical. Nothing alerts you. The customer complains first. To catch these, you need to know what makes a silent failure detectable in the first place. Here's the framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you're actually hunting
&lt;/h2&gt;

&lt;p&gt;A silent failure is execution that reports success but produces zero (or useless) output. The agent didn't crash — it just did nothing. The most common pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent calls the model.&lt;/li&gt;
&lt;li&gt;Model responds with ~0 output tokens, or a blank response.&lt;/li&gt;
&lt;li&gt;No error is raised.&lt;/li&gt;
&lt;li&gt;The calling code proceeds, unaware.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two other variants show up often: an agent looping indefinitely without progress (tool calls that never advance state), and output that's structurally valid but semantically empty — "I don't know" when it should have searched.&lt;/p&gt;

&lt;p&gt;Standard error monitoring misses all three, because there is no error. You're checking the wrong signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three detection levers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Token counting — the baseline signal
&lt;/h3&gt;

&lt;p&gt;Every LLM call produces input tokens (your prompt) and output tokens (the model's response). Measurable, deterministic, available in the response metadata from every provider.&lt;/p&gt;

&lt;p&gt;The insight: a healthy agent call has a predictable token range, per agent. A ticket-summarizer might consume ~100-200 input tokens and produce ~50-150 output tokens, run after run. If an execution comes back with 100 input tokens and 0 output tokens, that's a signal worth flagging — not proof of failure on its own, but worth alerting on.&lt;/p&gt;

&lt;p&gt;How to implement it: log input/output tokens for every execution, compute the median and standard deviation of output tokens over the past 30 days, flag anything below the 10th percentile or exactly zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;baseline_median_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;past_30_days_output_tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;baseline_std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;stdev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;past_30_days_output_tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;is_anomaly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today_output_tokens&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;baseline_median&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;baseline_std&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;OR &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today_output_tokens&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Cost anomaly — a derived signal
&lt;/h3&gt;

&lt;p&gt;Cost = input_tokens × input_rate + output_tokens × output_rate. When token consumption drops, cost drops with it. Cost is often easier to track than raw tokens because it's vendor-independent — you can aggregate across models.&lt;/p&gt;

&lt;p&gt;If your agent normally costs $0.02-$0.05 per run and today it's $0.0001, something's very wrong. Same approach: baseline median/std over 30 days, alert below the 5th percentile. Cost lags token anomalies slightly since it's derived, but it's the easier number to reason about in business terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Output examination — the confirmatory signal
&lt;/h3&gt;

&lt;p&gt;If tokens suggest an anomaly, the next question is what the model actually said. Store a short excerpt of the output (not the whole response, that's usually too large), and you can scan for empty strings, repetitive/looping output, or run a secondary AI judge against a correctness rubric.&lt;/p&gt;

&lt;p&gt;Capture the first 500 characters, flag anything empty or suspiciously short against your baseline. Rubric-based judging is optional but valuable for high-stakes agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it together
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Every execution logs input_tokens, output_tokens, cost_usd, output_summary, executed_at.&lt;/li&gt;
&lt;li&gt;On a schedule (nightly, or hourly at volume), compute per-agent baselines and flag anything below threshold.&lt;/li&gt;
&lt;li&gt;On a flag: alert the engineer with the output summary attached so triage is immediate, and optionally auto-pause the agent if the cost anomaly is severe.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why this works, and where it doesn't
&lt;/h2&gt;

&lt;p&gt;Strengths: no false positives from error logs, since you're measuring execution quality directly rather than exceptions. Early signal — tokens are real-time, so you catch problems in minutes. Framework-agnostic — LangChain, CrewAI, raw SDK, every model call produces tokens. Low friction — logging tokens is a few lines of code.&lt;/p&gt;

&lt;p&gt;Limitations: you need baseline history (a brand-new agent with five executions has no reliable range yet), the technique is context-dependent (agents with legitimately wide output variance need a wider baseline), and detection isn't prevention — flagging a failure doesn't stop the next expensive call, that needs an actual pause or rate limit on top.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical next step
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log tokens — add input_tokens, output_tokens, cost_usd to every execution record.&lt;/li&gt;
&lt;li&gt;Compute a baseline once you have a week or two of history.&lt;/li&gt;
&lt;li&gt;Set an alert on the 10th percentile of output tokens, or output_tokens == 0.&lt;/li&gt;
&lt;li&gt;Triage once. When it fires, you'll either see a genuine empty response (actionable) or a legitimate edge case you exclude next round.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You won't catch every silent failure this way. You'll catch the common ones — the ones that hurt most because they're invisible until someone notices.&lt;/p&gt;

&lt;p&gt;If you'd rather not build and maintain this plumbing yourself, that's the layer we built into the AI Agents Control Tower — token tracking, baselining, and anomaly alerting, so you define thresholds instead of infrastructure. Either way the principle holds: measure the tokens, establish the baseline, alert on the gap. Silent failures are only silent until you start listening.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>observability</category>
      <category>devops</category>
    </item>
    <item>
      <title>Token budget guardrails: enforcement, not just visibility</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Sat, 08 Aug 2026 11:39:57 +0000</pubDate>
      <link>https://dev.to/opsveritas/token-budget-guardrails-enforcement-not-just-visibility-3k89</link>
      <guid>https://dev.to/opsveritas/token-budget-guardrails-enforcement-not-just-visibility-3k89</guid>
      <description>&lt;p&gt;You've been monitoring your agent's token spend for weeks. Then one run goes wild — 50x the usual token count — and by the time you notice, half your budget is gone.&lt;/p&gt;

&lt;p&gt;Visibility is the first step. Enforcement is the second, and it's the one that actually stops the bleed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: seeing the spike after the damage
&lt;/h2&gt;

&lt;p&gt;Most monitoring setups give you a dashboard. Your agent runs, consumes tokens, and at month end you see the bill. Even with a live dashboard, the response chain is slow: monitor, alert, human, decision, pause. That gap costs real money.&lt;/p&gt;

&lt;p&gt;What you actually need is a guardrail that stops the agent from running the moment it crosses a ceiling you defined in advance. Not "alert the team" — "reject the call before it happens."&lt;/p&gt;

&lt;p&gt;This matters because of how token explosions actually happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry loops — an agent keeps calling the same tool because it misreads the response. Each retry burns tokens. A single run can loop 10-50 times before anyone notices.&lt;/li&gt;
&lt;li&gt;Context bloat — the agent accumulates conversation history or debug logs in its context window. By run 100, input tokens are 3x baseline.&lt;/li&gt;
&lt;li&gt;Hallucinated retries — the model thinks a tool call failed when it actually succeeded, so it tries again. Logs look clean. Cost doesn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every case, the agent still succeeds — HTTP 200. The token spend doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set per-agent token budgets
&lt;/h2&gt;

&lt;p&gt;Start with a baseline. Run your agent 20-50 times under normal conditions and record the token count per execution. This is your reference point — not average monthly spend, but typical spend per single run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example: a document-retrieval agent
- Run 1: 3,200 input + 450 output = 3,650 total
- Run 2: 3,100 input + 480 output = 3,580 total
- Run 3: 3,400 input + 520 output = 3,920 total
Average per run: ~3,700 tokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From that baseline, set two thresholds:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-run ceiling.&lt;/strong&gt; Set it at 2-3x typical spend. Anomalies exist — a genuinely complex query might need more — but 3x is usually where something's actually wrong. If baseline is 3,700 tokens, ceiling lands around 10,000-11,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monthly budget ceiling.&lt;/strong&gt; Divide your monthly LLM budget by expected run count, then apply a safety margin. Budget $100/month, expect 100 runs — that's $1/run. At roughly $0.002 per 1K tokens for cheaper models, that's about 500 tokens/run. Set the monthly ceiling around $80 (a 20% margin) and enforce it across all agents.&lt;/p&gt;

&lt;p&gt;The math is simple. The enforcement is what actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation: the kill-switch pattern
&lt;/h2&gt;

&lt;p&gt;Once you've defined ceilings, the agent needs to check them before each call, not after.&lt;/p&gt;

&lt;p&gt;If you're using the AI Agents Control Tower, this is built in. The kill switch is an opt-in feature that pauses your agents the moment your org crosses its monthly budget:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable the kill switch in org settings and define your monthly token/cost limit.&lt;/li&gt;
&lt;li&gt;Wrap your LLM client with the SDK's enforcement layer (&lt;code&gt;wrap_langchain&lt;/code&gt; for LangChain models) — adds a lightweight status check (~3ms, cached) before each inference call.&lt;/li&gt;
&lt;li&gt;If the limit's crossed, the SDK raises &lt;code&gt;OpsVeritasKilledError&lt;/code&gt; instead of calling the model. The agent stops. No token burn, no surprise bill.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The kill switch fails open — if the status check itself fails (a network blip), the call proceeds normally. You're protected against silent failures, not against your own infrastructure breaking.&lt;/p&gt;

&lt;p&gt;In code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;opsveritas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wrap_langchain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your-secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Wrap the model for telemetry (which agent ran, how many tokens)
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Add enforcement: blocks the call if budget is exceeded
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;wrap_langchain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# model.invoke() now raises OpsVeritasKilledError
# if the org's monthly limit is breached
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For non-LangChain setups, use the Universal Webhook to POST your agent's token telemetry to the control tower after each run. Include &lt;code&gt;cost_usd&lt;/code&gt; in the payload and the system tracks spend in real time across all agents. The kill switch still fires at the org level, but you own the decision of whether to actually call the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Per-agent ceilings: a second layer
&lt;/h2&gt;

&lt;p&gt;The org-wide kill switch is insurance. For finer control, add per-agent ceilings inside your agent's own execution loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;baseline_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3700&lt;/span&gt;  &lt;span class="c1"&gt;# your per-run baseline
&lt;/span&gt;    &lt;span class="n"&gt;ceiling_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;11000&lt;/span&gt;  &lt;span class="c1"&gt;# 3x baseline
&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;total_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input_tokens&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_tokens&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;total_tokens&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ceiling_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent exceeded token ceiling: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total_tokens&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ceiling_tokens&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# retry with a simpler query, alert the user, or flag for review
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;budget_exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This layer catches anomalies per execution, not per month. If one run gets expensive, you know immediately, and you can retry, degrade gracefully, or fail loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring what matters
&lt;/h2&gt;

&lt;p&gt;Once guardrails are in place, track three metrics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tokens per run (p50, p95) — tells you if the baseline is drifting. A climbing trend means the agent is degrading.&lt;/li&gt;
&lt;li&gt;Cost per run — token count alone doesn't account for model differences; a gpt-4o run costs differently than gpt-4o-mini.&lt;/li&gt;
&lt;li&gt;% of runs hitting the ceiling — if more than 1-2% of runs exceed the threshold, either the ceiling's wrong or the agent has a real problem.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most monitoring tools show total spend. What you need is per-execution visibility — the individual run that went wild, not just the aggregate bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real lesson
&lt;/h2&gt;

&lt;p&gt;Visibility without enforcement is a dashboard you check after something breaks. Enforcement without visibility is a kill switch that fires mysteriously. You need both.&lt;/p&gt;

&lt;p&gt;Set baselines from real data. Define ceilings at 2-3x normal. Enforce before the call, not after. Track per-run metrics, not just aggregate spend. When an anomaly hits, you'll catch it in milliseconds, not at month end.&lt;/p&gt;

&lt;p&gt;Cost governance is reliability. Silent token loops are a failure mode just as real as crashes — they just hide longer.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>devops</category>
      <category>observability</category>
    </item>
    <item>
      <title>The eval illusion: why passing tests doesn't mean safe in production</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Fri, 07 Aug 2026 06:04:18 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-eval-illusion-why-passing-tests-doesnt-mean-safe-in-production-11h1</link>
      <guid>https://dev.to/opsveritas/the-eval-illusion-why-passing-tests-doesnt-mean-safe-in-production-11h1</guid>
      <description>&lt;p&gt;You built an AI agent. The reasoning holds up — your eval suite checks that it picks the right tool for each task, chains them logically, recovers from a bad step. Scores are high. You ship it.&lt;/p&gt;

&lt;p&gt;Three days later, a customer says the agent returned a successful response and did nothing. No errors in the logs. Your monitoring flags something odd though: output tokens dropped to zero while input tokens looked totally normal. A silent failure your evals never had a chance to catch.&lt;/p&gt;

&lt;p&gt;That's not a hole in your eval strategy. It's a different category of problem entirely.&lt;/p&gt;

&lt;p&gt;Evals test reasoning in a controlled environment. Does it pick the right tool? Does it combine tools correctly? Does it recover when something looks wrong? Yes, mostly — because it's running with fresh context, clean input, and nothing else competing for its attention.&lt;/p&gt;

&lt;p&gt;The reliability stack tests what happens once that same agent is loose in the real world. Did it actually execute what it decided to do? Did the output match what the model claimed? Did it quietly loop when a tool failed? These aren't reasoning questions. They're runtime questions, and evals were never built to answer them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What evals miss
&lt;/h2&gt;

&lt;p&gt;Evals run under close to ideal conditions — fresh context, known inputs, tools that behave the way you mocked them, one clean execution path.&lt;/p&gt;

&lt;p&gt;Production runs under none of that. APIs time out at random. Rate limits show up mid-run. Real users send things your training data never saw. Context balloons across hundreds of runs. And sometimes the agent just quietly retries a failing tool call, over and over, with nothing logged as an error.&lt;/p&gt;

&lt;p&gt;Here's a concrete version of that: your eval tests an agent that fetches user data from an API and summarizes it. It passes clean. In production, that API is slow one day. The timeout fires, the model reads that as a failed call, and decides to retry. Then retries again. Thirty attempts and 120,000 tokens later, it gives up and returns nothing — but logs "success" the whole way through, because technically nothing errored.&lt;/p&gt;

&lt;p&gt;Your evals never saw a slow API. They never saw a third retry. They definitely never logged what the agent does when it finally gives up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reliability stack actually watches
&lt;/h2&gt;

&lt;p&gt;A few signals fill that gap, and none of them come from an eval suite:&lt;/p&gt;

&lt;p&gt;Silent failures show up as a mismatch between input and output tokens — normal input, near-zero output means the agent processed the request and produced nothing.&lt;/p&gt;

&lt;p&gt;Latency anomalies show up when success stays green but timing spikes. That's almost always a loop or a retry burning time in the background.&lt;/p&gt;

&lt;p&gt;Token drift shows up when the same task starts costing more tokens over time on the same agent — usually prompt bloat or state quietly accumulating.&lt;/p&gt;

&lt;p&gt;Cost spikes are the most obvious canary. A 10x jump in cost per run is rarely a coincidence.&lt;/p&gt;

&lt;p&gt;And execution paths — which tools actually got called, in what order, did they all succeed — tell you whether the agent's recovery logic works under real failure, not just the happy path you tested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;The gap between shipped and safe isn't a code quality problem. It's an observability problem.&lt;/p&gt;

&lt;p&gt;A well-reasoned agent with a clean eval score can still loop forever on a timeout, return silent success while doing nothing, or spike cost 100x from one bad retry cascade. None of those are logic errors — they only show up once the agent meets a messy, real execution environment.&lt;/p&gt;

&lt;p&gt;Your evals proved it can reason. Something else has to prove it can run safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;You don't need to rebuild the agent or the eval suite. You need visibility into execution itself: wrap the LLM client so every run logs tokens, latency, cost, and output length. Run it long enough to know your baselines. Alert when something drifts from them. Log which tools actually got called and what happened when one failed.&lt;/p&gt;

&lt;p&gt;Evals and the reliability stack aren't competing with each other. One proves the agent can think. The other proves that thinking survives contact with production.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>observability</category>
      <category>devops</category>
    </item>
    <item>
      <title>The Silent Loop: Why Latency and Token Count Together Catch What Status Codes Miss</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Thu, 06 Aug 2026 06:33:17 +0000</pubDate>
      <link>https://dev.to/opsveritas/the-silent-loop-why-latency-and-token-count-together-catch-what-status-codes-miss-dai</link>
      <guid>https://dev.to/opsveritas/the-silent-loop-why-latency-and-token-count-together-catch-what-status-codes-miss-dai</guid>
      <description>&lt;p&gt;You deploy an AI agent that calls a flaky API. The API fails 10% of the time. Your agent is wired to retry on failure, good practice, right?&lt;/p&gt;

&lt;p&gt;Then something goes wrong. The API stays broken for an hour. Your agent keeps retrying. Each retry consumes tokens. The loop never errors out, it just cycles. Success status, because the agent finished (it gave up after N retries). But the cost? Climbing in a straight line while no work got done.&lt;/p&gt;

&lt;p&gt;This is the infinite retry loop, not a crash, not a timeout, just silent token bleed. Your logs look healthy. Your error rate is zero. Your bill is bleeding.&lt;/p&gt;

&lt;p&gt;The reason most monitoring misses this: error rates and request counts don't catch it. The agent isn't erroring, it's succeeding at retrying. What does catch it is a pattern you can measure right now: latency and token count moving together, in a way that doesn't match your normal execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Math of the Pattern
&lt;/h2&gt;

&lt;p&gt;When a healthy agent runs, there's a relationship between how long it takes and how many tokens it uses. Call this the latency-to-token ratio.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A normal run: 2 seconds, 500 tokens. Ratio: 250 tokens/sec.&lt;/li&gt;
&lt;li&gt;Another normal run: 3 seconds, 800 tokens. Ratio: ~267 tokens/sec.&lt;/li&gt;
&lt;li&gt;Your baseline range: say, 200-300 tokens/sec.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the loop starts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First 30 seconds: 15,000 tokens. Ratio: 500 tokens/sec. Way above baseline.&lt;/li&gt;
&lt;li&gt;Next 30 seconds: another 15,000 tokens. Still climbing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The signal is clear: latency is spiking, and token consumption is accelerating disproportionately. The agent is doing a lot of token work in a short time, characteristic of retry loops where the model is being re-invoked repeatedly against the same or similar inputs.&lt;/p&gt;

&lt;p&gt;By contrast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A normal, slow run (agent thinking hard): latency high, tokens high, but the ratio stays in your normal band. The model had a complex problem; it thought longer and used more tokens. Proportional.&lt;/li&gt;
&lt;li&gt;A loop: latency high, tokens extremely high (disproportionate spike), ratio breaks baseline. The model is being called over and over in the same second window, burning tokens on retry cycles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building the Heuristic
&lt;/h2&gt;

&lt;p&gt;Here's the threshold pattern builders should use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Establish your baseline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run 20 normal agent executions. For each, compute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;output_tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Record the 50th and 95th percentile ratios. Call these p50_ratio and p95_ratio.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;p50: 250 tokens/sec&lt;/li&gt;
&lt;li&gt;p95: 400 tokens/sec (accounting for "thinking hard" runs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Set alert thresholds&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caution zone: ratio &amp;gt; p95_ratio * 1.5 (e.g., &amp;gt; 600 tokens/sec)&lt;/li&gt;
&lt;li&gt;Alert zone: ratio &amp;gt; p95_ratio * 2.5 (e.g., &amp;gt; 1000 tokens/sec)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Combine with duration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If latency is also above your normal range (e.g., &amp;gt; 2 standard deviations from mean), weight the alert higher. A 45-second run with 20,000 tokens (444 tokens/sec) might be fine. A 45-second run with 50,000 tokens (1111 tokens/sec) is almost certainly looping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Watch the trend, not the single run&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A single run can be an outlier. Watch for the pattern across 3+ consecutive runs in a 5-minute window:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If 2 or more runs breach the alert threshold, fire the alert.&lt;/li&gt;
&lt;li&gt;If the ratio stays elevated, the loop is ongoing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Catches Loops Before Cost Explodes
&lt;/h2&gt;

&lt;p&gt;Consider the numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal agent: 500 tokens/run, $0.00075 per run (at typical pricing).&lt;/li&gt;
&lt;li&gt;Loop for 1 hour: 150 retries, ~5000 tokens per cycle, = 750,000 tokens, ~$1.13 per hour.&lt;/li&gt;
&lt;li&gt;Loop for 4 hours undetected: $4.50. Small. Still bad.&lt;/li&gt;
&lt;li&gt;Loop for a full day: $27. Big enough to be noticed in a weekly bill review. Too late.&lt;/li&gt;
&lt;li&gt;Loop caught at 30 minutes via latency+token spike: ~$0.56. Caught, stopped, learning drawn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latency-token ratio detects the loop in the first 2-3 runs, not after hours or days. You catch it while the cost is still negligible.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Instrument This (No Vendor Lock-in)
&lt;/h2&gt;

&lt;p&gt;You don't need a specialized tool to start. Just log three numbers per execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"agent_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my_agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"duration_ms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;45000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then compute the ratio in your log aggregator (Datadog, New Relic, CloudWatch, or a simple script):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;output_tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# or your alert threshold
&lt;/span&gt;&lt;span class="nf"&gt;send_alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;High token-per-second ratio: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're wrapping an LLM SDK (OpenAI, Anthropic, etc.), you already have access to output_tokens and request duration. Logging that pair takes three lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Deeper Pattern
&lt;/h2&gt;

&lt;p&gt;This heuristic works because infinite loops have a structural signature: they burn tokens fast relative to the time they're supposed to be thinking. A model pondering a hard question runs long and uses tokens proportionally. A retry loop cycles the model through shallow re-attempts, burning tokens in bursts.&lt;/p&gt;

&lt;p&gt;By watching both dimensions together, you're detecting the imbalance that characterizes the loop without needing to parse logs, understand retry logic, or set up complex alerting rules.&lt;/p&gt;

&lt;p&gt;It's not perfect, a pathological case might fool it. But it catches the 99% case: the silent loop that's invisible when you're watching latency alone, and eats budget fast when you're not watching at all.&lt;/p&gt;

&lt;p&gt;Start logging latency + output tokens today. Compute the ratio. Set the thresholds. You'll catch the next loop before your bill does.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're already running agents in production, pull 20 recent runs and compute your p50 and p95 right now. That baseline is your first line of defense against cost creep.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>monitoring</category>
      <category>devops</category>
    </item>
    <item>
      <title>You Shipped the Agent. Now Build the Monitoring Layer.</title>
      <dc:creator>Babar Hayat</dc:creator>
      <pubDate>Wed, 05 Aug 2026 07:54:18 +0000</pubDate>
      <link>https://dev.to/opsveritas/you-shipped-the-agent-now-build-the-monitoring-layer-9jn</link>
      <guid>https://dev.to/opsveritas/you-shipped-the-agent-now-build-the-monitoring-layer-9jn</guid>
      <description>&lt;p&gt;You've shipped your first AI agent to production. The dashboard shows it running. But you have no real idea what it costs per request, or whether it's quietly failing in ways your error logs would never catch.&lt;/p&gt;

&lt;p&gt;This is the gap most builders find out about the hard way: deployment isn't observability. An agent can return HTTP 200, log success, and produce zero useful output — all without a single error anywhere in the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why standard monitoring misses AI agents
&lt;/h2&gt;

&lt;p&gt;Typical app observability — latency, error rates, uptime — was built for request/response workflows. It catches crashes, timeouts, explicit errors. AI agents fail differently. They fail silently.&lt;/p&gt;

&lt;p&gt;Three ways this shows up in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP 200, logs show success, zero output tokens generated. The agent ran, the API call succeeded, the response came back empty. No error. Just nothing.&lt;/li&gt;
&lt;li&gt;A hundred requests, ninety blank outputs. Your logs say 90% success. Your users see broken functionality.&lt;/li&gt;
&lt;li&gt;Cost per request 10x what it was last week — the agent's looping, retrying tool calls, burning tokens, and the logs still say "success."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are crashes. Nothing you're currently watching will flag them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you actually need to see
&lt;/h2&gt;

&lt;p&gt;Four signals, once the agent's live:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tokens per execution&lt;/strong&gt; (input + output). Your canary — zero output tokens on a "successful" run means something's broken.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost per request&lt;/strong&gt;, computed from tokens × model pricing. Aggregates hide loops; per-execution cost reveals them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Did it actually produce output&lt;/strong&gt; — separate from whether the HTTP call succeeded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency and retry patterns&lt;/strong&gt; — a 2-second call suddenly taking 30 usually means it's looping on a tool call.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Three ways to wire it in
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SDK instrumentation
&lt;/h3&gt;

&lt;p&gt;The easiest path if you're on OpenAI, Anthropic, or an OpenAI-compatible provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;opsveritas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;opsveritas&lt;/span&gt;
&lt;span class="n"&gt;opsveritas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;your OpsVeritas SDK key&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# from your OpsVeritas org, not OpenAI/Anthropic
&lt;/span&gt;&lt;span class="n"&gt;opsveritas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines, and every call gets tracked — tokens, cost, output status, latency, model — without your API keys ever leaving your process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Webhook
&lt;/h3&gt;

&lt;p&gt;For frameworks without SDK support, or when you want full control over what gets sent. The &lt;code&gt;x-agents-key&lt;/code&gt; here is a key OpsVeritas issues to your org specifically — it's separate from your OpenAI/Anthropic credentials, which never touch OpsVeritas in this flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://ai-agents-control-tower.onrender.com/webhooks/agent-execution &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-agents-key: &amp;lt;your OpsVeritas webhook key&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "agent_name": "customer-support-bot",
    "status": "success",
    "input_tokens": 245,
    "output_tokens": 0,
    "cost_usd": 0.0042,
    "duration_ms": 1240,
    "executed_at": "2026-08-04T14:22:15Z"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Just log it locally
&lt;/h3&gt;

&lt;p&gt;If you're not ready for a platform yet — capture tokens, cost, and whether there was output on every run, print it as structured JSON, and grep for &lt;code&gt;output_tokens: 0&lt;/code&gt; in your own logs. Fifteen minutes, no external dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set the thresholds
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cost per request under 2x your baseline — above that, something's looping.&lt;/li&gt;
&lt;li&gt;Output tokens should never be zero on a run marked successful.&lt;/li&gt;
&lt;li&gt;Latency spikes usually mean retries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams skip this because it feels like overhead — right up until an agent burns a day's budget in an hour, or fails silently for your highest-value customer. Start with one agent, capture tokens and cost, watch for zeros. That's most of the observability you actually need, and it's a few minutes of work.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>monitoring</category>
      <category>devops</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
