<?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: Deepika Chintamreddy</title>
    <description>The latest articles on DEV Community by Deepika Chintamreddy (@deepika_chintamreddy_b528).</description>
    <link>https://dev.to/deepika_chintamreddy_b528</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%2F4235670%2F91e7991a-8cca-43e9-b6f6-43ed62f77c3e.png</url>
      <title>DEV Community: Deepika Chintamreddy</title>
      <link>https://dev.to/deepika_chintamreddy_b528</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deepika_chintamreddy_b528"/>
    <language>en</language>
    <item>
      <title>My Hindsight Debugging Agent Learned to Say "I Don't Know"</title>
      <dc:creator>Deepika Chintamreddy</dc:creator>
      <pubDate>Mon, 09 Nov 2026 18:15:40 +0000</pubDate>
      <link>https://dev.to/deepika_chintamreddy_b528/my-hindsight-debugging-agent-learned-to-say-i-dont-know-4cjh</link>
      <guid>https://dev.to/deepika_chintamreddy_b528/my-hindsight-debugging-agent-learned-to-say-i-dont-know-4cjh</guid>
      <description>&lt;p&gt;Demo video: &lt;a href="https://youtu.be/4BKfKYZqbJA" rel="noopener noreferrer"&gt;https://youtu.be/4BKfKYZqbJA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first version of my debugging agent told me, with full confidence, that my team had hit this exact error twice before. Ticket #1124 in March. Ticket #1389 in October. Neither ticket exists. The model made both up, and it did it because I had told it to.&lt;/p&gt;

&lt;p&gt;This is the story of how I built DevMind, a debugging assistant with team memory, and how fixing that one bug taught me more about agent memory than the rest of the project did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What DevMind does
&lt;/h2&gt;

&lt;p&gt;A developer pastes an error message and a stack trace. DevMind searches the team's past debugging history, finds fixes that look related, and asks an LLM to write a diagnosis that uses them. If a teammate already fixed something similar, the answer says who, when, and what they changed. If nobody did, it says that too.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;FastAPI backend&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt; for the memory layer, running on Hindsight Cloud&lt;/li&gt;
&lt;li&gt;Groq with &lt;code&gt;openai/gpt-oss-120b&lt;/code&gt; for the reasoning&lt;/li&gt;
&lt;li&gt;A plain HTML and JavaScript page, no framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full code is here: &lt;a href="https://github.com/Deepikachintamreddy/devmind-hindsight" rel="noopener noreferrer"&gt;DevMind on GitHub&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer pastes error
        |
        v
FastAPI  /api/analyze
        |
        |-- Hindsight recall()   -&amp;gt; closest past bug fixes
        |-- Hindsight reflect()  -&amp;gt; short synthesis across them
        |
        v
LLM (Groq) -&amp;gt; diagnosis with "From team memory" and "Suggested" sections
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why I used Hindsight instead of a plain vector store
&lt;/h2&gt;

&lt;p&gt;A debugging history is not a pile of documents. It is a set of events: who fixed what, in which file, on which day, and why. I wanted the memory layer to keep that structure instead of handing me back raw text chunks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt; does this with three calls, and the whole integration fits in a few lines. The &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt; idea is simple: the agent writes what happened, and later it reads back only what is relevant.&lt;/p&gt;

&lt;p&gt;Retaining a fix looks like this (simplified from &lt;code&gt;backend/services/memory.py&lt;/code&gt;):&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;await&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;aretain&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;MEMORY_BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                      &lt;span class="c1"&gt;# developer, error, root cause, fix
&lt;/span&gt;    &lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;make_document_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_path&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;reported_on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;# when the bug was actually fixed
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recalling and reflecting on a new error:&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;arecall&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;MEMORY_BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&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;reflection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;areflect&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;MEMORY_BANK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I seeded the bank with ten sample bugs written by me, each with a developer name, a file path, a root cause, a fix, and a date spread over about eight weeks. Hindsight turned those ten records into roughly forty stored memories. It pulled out the people, the dates, the files, and separate facts for the cause and the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug: an agent that lied when memory was off
&lt;/h2&gt;

&lt;p&gt;I wanted a clear before and after, so I added a switch. Every analysis runs twice: once with memory off, once with memory on. The page shows both answers side by side.&lt;/p&gt;

&lt;p&gt;My system prompt said, roughly, that the assistant has a persistent memory of every bug the team ever fixed. I used the same prompt for both runs and only removed the retrieved memories for the "off" run.&lt;/p&gt;

&lt;p&gt;The model did what I asked. It acted like it had a history, found nothing in front of it, and filled the gap. For the JWT error it wrote that there were "two exact matches in the team's history" and cited two ticket numbers with months. Both were invented.&lt;/p&gt;

&lt;p&gt;The fix was two prompts, not one. When memory is off, the model gets a prompt that says it has no access to any team history, must not mention past tickets, dates or teammates, and must write "No team memory available" under the memory section. The prompt used with memory on got stricter too. Facts about the team's past may only come from the retrieved text, and the fix section has to separate the two sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;From team memory: ...
Suggested (generated, not from memory): ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That label alone made the output much easier to trust. When I read an answer now, I can see which steps a teammate actually performed and which ones the model is proposing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does now
&lt;/h2&gt;

&lt;p&gt;For the JWT null-pointer error in &lt;code&gt;src/middleware/auth.js&lt;/code&gt;, the two cards behave like this.&lt;/p&gt;

&lt;p&gt;Without memory, the answer is generic and correct: check the token, guard the decoded payload, return a 401. It says "No team memory available" and names nobody.&lt;/p&gt;

&lt;p&gt;With memory, it says that Priya Sharma fixed the same error in the same file on 2026-09-14, that the cause was silent token expiry plus a Redis session that still held the old token, and that the fix was an explicit expiry check, clearing the Redis cache, and an auto-logout on the frontend for 401 responses. All of that came from stored memory. The code sample underneath is labelled as generated.&lt;/p&gt;

&lt;p&gt;The payment race condition works the same way. The memory answer points to Ananya Krishnan's fix from 2026-09-25, &lt;code&gt;SELECT FOR UPDATE&lt;/code&gt; row locking plus an &lt;code&gt;asyncio.gather&lt;/code&gt; test, and the generic answer only says "add a lock".&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%2Fr37sws0ty0oa0x7t50f3.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%2Fr37sws0ty0oa0x7t50f3.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The case I like best is an error nobody on the team has seen, an SMTP authentication failure. Hindsight still returns its five closest memories, which are unrelated. The model reads them, decides they do not apply, writes "No relevant team memory found", and labels everything else as generated advice.&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%2Fl4slxrum315tvcib2a17.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%2Fl4slxrum315tvcib2a17.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two more things that went wrong
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Duplicates.&lt;/strong&gt; My first seed script ran every time I ran my test script. After a few runs the bank held 65 memories instead of about 35, and the recalled snippets started repeating each other. The fix was a stable &lt;code&gt;document_id&lt;/code&gt; built from the error type and file path, so storing the same bug again updates it instead of adding a copy, plus a reset endpoint to clear the bank. I also stopped the test script from seeding by default. Each store call also costs credits, so duplicates were a money problem as well as a quality problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recall has no "nothing relevant" signal.&lt;/strong&gt; I tried to filter out unrelated snippets using the score on each recalled item. In the runs I checked, the &lt;code&gt;final&lt;/code&gt; score simply dropped by a fixed step per rank, 1.0, 0.975, 0.95 and so on. It is a position, not a relevance measure. A threshold that happened to cut the unrelated CORS snippet for the JWT error would have kept four unrelated ones for a new error. I removed the filter and moved the judgement into the prompt: the retrieved memories are only the closest matches and may be unrelated, and the model should use one only if it describes the same or a similar error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test the agent with memory off.&lt;/strong&gt; If your prompt claims a history, the model will invent one the moment retrieval comes back empty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate remembered facts from generated advice in the output.&lt;/strong&gt; A simple label makes answers easier to check and easier to trust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give writes a stable identity.&lt;/strong&gt; Without a document ID, every re-run of an import script quietly makes your memory worse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not treat recall rank as relevance.&lt;/strong&gt; A search always returns something. Decide what "no match" means and test it with an input you know has no match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store real dates.&lt;/strong&gt; Passing the real fix date as the timestamp made the answers read like a team history instead of a list of facts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;p&gt;The ten bugs are synthetic, written by me. The bank belongs to one fictional team, and I have not tested DevMind against a real team's history. Recall quality on thousands of messy tickets is an open question I cannot answer from ten records. The code samples in the answers come from the model, and I have treated them as suggestions to review, not as fixes to paste.&lt;/p&gt;

&lt;p&gt;I wrote the code with a coding agent in my editor. I also used Band desktop to run a three-agent team: a lead, an implementer and a reviewer. The reviewer checked my repository cleanup commit item by item against the task, and the implementer wrote a short README section for the live test script, which the reviewer checked against what the script really does. The implementer kept failing with a context overflow error until I changed its model, so the cleanup edits themselves were made in my editor, not by that agent.&lt;/p&gt;

&lt;p&gt;If you want to try it, the repo is at &lt;a href="https://github.com/Deepikachintamreddy/devmind-hindsight" rel="noopener noreferrer"&gt;github.com/Deepikachintamreddy/devmind-hindsight&lt;/a&gt;, and the &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight documentation&lt;/a&gt; covers the memory calls in more detail.&lt;/p&gt;

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