<?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: NIKITHA THAMMAIAH</title>
    <description>The latest articles on DEV Community by NIKITHA THAMMAIAH (@nikitha_thammaiah_0668e91).</description>
    <link>https://dev.to/nikitha_thammaiah_0668e91</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%2F4231678%2Fbff8bb14-f942-4b2a-a53b-a63645abe5b4.jpg</url>
      <title>DEV Community: NIKITHA THAMMAIAH</title>
      <link>https://dev.to/nikitha_thammaiah_0668e91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nikitha_thammaiah_0668e91"/>
    <language>en</language>
    <item>
      <title>My On-Call Agent Remembered the Rollback That Never Works</title>
      <dc:creator>NIKITHA THAMMAIAH</dc:creator>
      <pubDate>Sat, 07 Nov 2026 07:49:32 +0000</pubDate>
      <link>https://dev.to/nikitha_thammaiah_0668e91/my-on-call-agent-remembered-the-rollback-that-never-works-458c</link>
      <guid>https://dev.to/nikitha_thammaiah_0668e91/my-on-call-agent-remembered-the-rollback-that-never-works-458c</guid>
      <description>&lt;p&gt;The alert said &lt;code&gt;checkout-api p99 4.8s, HikariCP 50/50, v3.18.2 deployed 12 minutes ago&lt;/code&gt;. I gave it to the same LLM twice. The first answer, step four: &lt;em&gt;"roll back the deployment."&lt;/em&gt; The second answer put rollback at the top of its &lt;strong&gt;Avoid&lt;/strong&gt; list: &lt;em&gt;"Rollback attempts in INC-2291 and INC-2347 did not improve the incident and were aborted."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same model, same prompt shape, same alert. The only difference was that the second call had memory.&lt;/p&gt;

&lt;p&gt;That gap is the whole reason I built Déjà Vu, an on-call agent that keeps our incident history in &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight agent memory&lt;/a&gt; and gets better every time someone closes an incident. This post is about what it took to make that answer show up reliably, because the first version didn't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4tz7175ce9w25uqhodys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4tz7175ce9w25uqhodys.png" alt="Same alert, same model: without memory it suggests a rollback; with Hindsight memory it says rollback failed twice" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem is not missing knowledge
&lt;/h2&gt;

&lt;p&gt;Every on-call team I've worked with has the answer to tonight's outage written down somewhere. It's in a postmortem from two months ago, in a Slack thread, or in the head of the engineer who's on leave. The failure mode isn't that nobody knows. It's that at 2 AM nobody remembers, and the reflexes take over: roll back the last deploy, scale up, restart pods.&lt;/p&gt;

&lt;p&gt;Those reflexes are usually fine. For one specific class of incident they're poison. Our checkout service had the same pool-exhaustion incident twice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INC-2291&lt;/strong&gt;: a payment SDK bump raised the HTTP read timeout from 3s to 30s. When the bank API slowed down, request threads held database connections while they waited, and the Hikari pool ran dry. The on-call rolled back checkout (14 minutes, no change), then scaled from 24 to 40 pods, which made connection pressure worse. Time to mitigate: 52 minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INC-2347&lt;/strong&gt;: same symptoms, new trigger (three retries on a 3s timeout). The responder &lt;em&gt;started a rollback again&lt;/em&gt; before checking gateway latency, and aborted after 10 minutes once a senior engineer remembered INC-2291.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A stateless LLM can't help here. It will give textbook advice, and the textbook says roll back the recent deploy. What I needed was an agent that knows &lt;em&gt;our&lt;/em&gt; incidents, including the parts nobody writes in the summary: what we tried that didn't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it hangs together
&lt;/h2&gt;

&lt;p&gt;The system is small on purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser UI ──► FastAPI
                ├── agent.py   prompt building, output checks
                ├── llm.py     Groq (gpt-oss-120b), JSON mode
                └── memory.py  Hindsight: retain · recall · reflect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hindsight does the memory work. There are three operations, and each maps to a moment in the incident lifecycle:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Moment&lt;/th&gt;
&lt;th&gt;Hindsight call&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Postmortem published&lt;/td&gt;
&lt;td&gt;&lt;code&gt;retain&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Incident stored with its real timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alert fires&lt;/td&gt;
&lt;td&gt;&lt;code&gt;recall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Similar incidents and failed attempts retrieved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident closed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;retain&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What fixed it, what wasted time, whether the agent helped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"What keeps going wrong?"&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reflect&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reasoned answer across the whole history&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I picked Hindsight over a homegrown vector store for one reason: I didn't want to build fact extraction, entity linking and temporal search myself. When you &lt;code&gt;retain&lt;/code&gt; a postmortem, Hindsight splits it into typed facts (world facts, experiences) and then consolidates them in the background into &lt;em&gt;observations&lt;/em&gt;, which are beliefs backed by evidence. Its &lt;code&gt;recall&lt;/code&gt; runs semantic, keyword, graph and temporal search in parallel and reranks the results. The &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight docs&lt;/a&gt; explain the internals. What mattered to me is that a query about "checkout latency" can reach a fact about "Hikari pool exhaustion" even though the two share no keywords.&lt;/p&gt;

&lt;p&gt;The bank gets a mission when it's created, which shapes how &lt;code&gt;reflect&lt;/code&gt; reasons:&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;MISSION&lt;/span&gt; &lt;span class="o"&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;I am the on-call memory for an e-commerce platform&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s SRE team. I track incidents, their symptoms, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;root causes, the fixes that worked and the actions that wasted time. I prefer fixes verified in past &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidents over generic advice, and I notice when the same failure pattern comes back with a new trigger.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;self&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;span class="nf"&gt;create_bank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;bank_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;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;On-call incident memory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mission&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MISSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;disposition&lt;/span&gt;&lt;span class="o"&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;skepticism&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;literalism&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;empathy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skepticism is at 4 deliberately. An incident agent that believes everything it reads is worse than none.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first version found the incident and missed the lesson
&lt;/h2&gt;

&lt;p&gt;My first triage did one broad recall: &lt;em&gt;"Incidents on checkout-api or with similar symptoms… what was the root cause, what fixed it, and what did not help?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It matched INC-2291 and INC-2347 right away, with high confidence and the correct root cause. It also returned &lt;strong&gt;56 memories in 5.3 seconds&lt;/strong&gt;, most of them about cart-svc DNS caching, pricing caches and TLS certificates. The facts I cared about most, &lt;em&gt;"rolled back checkout-api, no improvement"&lt;/em&gt;, weren't in the results at all. So the agent recommended the right fix and still didn't warn against the rollback. Worse, it invented CLI commands (&lt;code&gt;ffctl set pg_circuit_breaker=true&lt;/code&gt;) that exist nowhere in our tooling.&lt;/p&gt;

&lt;p&gt;I made three changes, and each one taught me something about working with memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Failed attempts are their own memories
&lt;/h3&gt;

&lt;p&gt;In the postmortem text, the failed rollback was one clause inside a long paragraph. Extraction is good, but that clause was competing with symptoms, root cause and fix for attention. So the seed step now retains failed attempts as separate documents:&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;if&lt;/span&gt; &lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed_attempts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed_attempts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retain&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;During incident &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, these actions did NOT help or made it worse: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;failed_attempts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; Next time on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;service&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, do not try this first.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed mitigation attempt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&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;kind&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;failed_attempt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a re-seed (Hindsight only charges for changed content, so re-sending the unchanged postmortems cost nothing), consolidation produced observations like &lt;em&gt;"Do not attempt a rollback of checkout-api v3.16.1 as a first step during future incidents."&lt;/em&gt; That isn't a sentence I wrote. Hindsight derived it from the evidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F719n7ua2mq974s6c38d5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F719n7ua2mq974s6c38d5.png" alt="Memory trace: world facts and consolidated observations, including &amp;quot;Do not attempt a rollback of checkout-api as a first step&amp;quot;" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Two narrow recalls beat one broad one
&lt;/h3&gt;

&lt;p&gt;One query was trying to answer two different questions. I split it:&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;build_queries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; incident with symptoms like: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; Root cause and fix that worked.&lt;/span&gt;&lt;span class="sh"&gt;"&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;Actions that did NOT help or made it worse during incidents on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two recalls run in parallel with the baseline LLM call, at different budgets (&lt;code&gt;mid&lt;/code&gt; for symptoms, &lt;code&gt;low&lt;/code&gt; for failures). Recall dropped from 12 seconds to about 6, and the result set shrank from 56 memories to 23 relevant ones. Both rollback failures now show up in every checkout triage.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Memory about other services is a liability
&lt;/h3&gt;

&lt;p&gt;Then I triaged an alert the agent had never seen: &lt;code&gt;recommendation-svc OOMKilled 14 times after a new embedding model rollout&lt;/code&gt;. With memory on, it produced three confident Avoid items, citing checkout-api, inventory-svc and platform-k8s incidents. The recall had faithfully returned the nearest memories, and the LLM had faithfully used them. Nothing in that chain was technically wrong, and the output was still nonsense.&lt;/p&gt;

&lt;p&gt;The fix is one function:&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;same_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;kept&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memories&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&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;kept&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kept&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI now prints "&lt;em&gt;30 about other services ignored&lt;/em&gt;" in the memory trace header, so it's clear the agent saw them and chose not to use them. I also reject any incident ID in the LLM's output that never appeared in the recalled memories.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like now
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Checkout alert, before closing the loop.&lt;/strong&gt; Without memory: "roll back the deployment," "consider scaling pods." With Hindsight: matches INC-2291 and INC-2347; &lt;em&gt;Do first&lt;/em&gt;: check gateway latency, enable &lt;code&gt;pg_circuit_breaker&lt;/code&gt;, set &lt;code&gt;pg_client_retries=0&lt;/code&gt;; &lt;em&gt;Avoid&lt;/em&gt;: rollback (failed twice), scaling to 40 pods (made it worse).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After I closed the incident.&lt;/strong&gt; I recorded the resolution in the UI: circuit breaker plus zero retries, rollback skipped, 9 minutes. The API retains it:&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;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolution_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incident resolution reported by on-call engineer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;incident_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&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;service&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kind&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;resolution&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;helpful&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suggestion_helpful&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the next triage of the same alert, my resolution came back as the first recalled memory and the top match. Confidence went from medium to high. &lt;em&gt;Do first&lt;/em&gt; reordered so the proven fix, the circuit breaker, became step one instead of "check the read timeout." Nobody edited a runbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The never-seen alert.&lt;/strong&gt; For recommendation-svc, the agent with memory returned &lt;em&gt;low confidence, seen before: none, avoid: none&lt;/em&gt;. The agent without memory returned &lt;strong&gt;high&lt;/strong&gt; confidence and cited &lt;em&gt;"past incidents where manual pod deletion delayed resolution"&lt;/em&gt;, incidents it cannot possibly know about. That contrast surprised me more than anything else. A stateless model doesn't just lack history; it invents it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asking the memory directly.&lt;/strong&gt; &lt;code&gt;reflect("Which first actions have repeatedly wasted time during checkout incidents?")&lt;/code&gt; came back with both rollbacks, how long each one cost (14 and 10 minutes), the scaling mistake, the shared root cause and the fixes that worked. Every claim traced back to a retained fact. This is what a new on-call engineer should read before their first sale-night shift.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6hqltr5r2pd3u1kdm2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6hqltr5r2pd3u1kdm2q.png" alt="reflect() answering which first actions keep wasting time on checkout incidents, citing INC-2291 and INC-2347" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons I'd reuse
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Retain the negative space.&lt;/strong&gt; The most valuable memory in incident response is &lt;em&gt;what didn't work&lt;/em&gt;, and postmortem prose buries it. Give failed attempts their own retain call and their own document ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One recall per question.&lt;/strong&gt; A broad query lets loosely related memories crowd out the one fact you need. Two narrow queries in parallel were faster and more precise than one big one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope memory before you trust it.&lt;/strong&gt; Recall returns the nearest memories, not the relevant ones. Filter by the entity you're actually reasoning about, and show what you dropped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the baseline visible.&lt;/strong&gt; Running the same alert with and without memory, side by side, is the best debugging tool I had. It's also how I noticed the stateless model inventing incidents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close the loop in the product, not in a wiki.&lt;/strong&gt; The learning comes from one &lt;code&gt;retain&lt;/code&gt; call at resolution time, with a "did the agent help?" bit. If that step takes more than 30 seconds, nobody will do it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One honest pain point: the synchronous Hindsight Python client binds its HTTP session to the event loop of the first thread that uses it. When I parallelized the recalls, the next &lt;code&gt;retain&lt;/code&gt; call failed with a 500. The fix was to give each client its own dedicated thread and route every call to it through that thread. It's a small detail, but it cost me an hour.&lt;/p&gt;

&lt;p&gt;The same-service filter is also a trade-off I haven't fully resolved. Some lessons do transfer: "don't scale consumers during a rebalance storm" applies to any Kafka service. A smarter version would filter by failure pattern instead of service name, which is something Hindsight's observations and &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt; model make possible. For now, precision wins.&lt;/p&gt;

&lt;p&gt;The bigger takeaway is that a memory layer doesn't replace on-call judgment. It replaces the senior engineer who happened to remember INC-2291, and makes that memory available to whoever is holding the pager tonight.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>sre</category>
    </item>
  </channel>
</rss>
