<?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: Neha Reddy</title>
    <description>The latest articles on DEV Community by Neha Reddy (@nehareddy01).</description>
    <link>https://dev.to/nehareddy01</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%2F4147618%2F647b3c08-2b42-48f0-9445-980290fe4f24.png</url>
      <title>DEV Community: Neha Reddy</title>
      <link>https://dev.to/nehareddy01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nehareddy01"/>
    <language>en</language>
    <item>
      <title>I Keyed Hindsight Memory by Vendor, Not by Employee</title>
      <dc:creator>Neha Reddy</dc:creator>
      <pubDate>Mon, 28 Sep 2026 18:34:09 +0000</pubDate>
      <link>https://dev.to/nehareddy01/i-keyed-hindsight-memory-by-vendor-not-by-employee-5228</link>
      <guid>https://dev.to/nehareddy01/i-keyed-hindsight-memory-by-vendor-not-by-employee-5228</guid>
      <description>&lt;p&gt;Six months after our IT team squeezed a 20% discount out of Microsoft, someone in Finance sat down with the same account manager and opened with a lowball offer. The negotiation stalled for a week. Nobody in Finance knew that IT had already learned that exact tactic doesn't work.&lt;/p&gt;

&lt;p&gt;The knowledge existed. It just lived in one person's head, and that person was in a different department.&lt;/p&gt;

&lt;p&gt;That's the problem I built &lt;strong&gt;Leverage&lt;/strong&gt; to fix, and it changed how I think about agent memory. Almost every memory setup I see is &lt;em&gt;personal&lt;/em&gt;: an assistant remembers user A's history with user A. That model breaks the moment the valuable knowledge belongs to a &lt;em&gt;relationship&lt;/em&gt; rather than a person. So I flipped the key. Memory in Leverage is stored &lt;strong&gt;per vendor&lt;/strong&gt;, not per employee, on top of &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt;, an open-source agent memory system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the system does
&lt;/h2&gt;

&lt;p&gt;Leverage has two jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Log a negotiation.&lt;/strong&gt; Any employee records how a deal went: discount, payment terms, what the vendor bent on, what it refused, which tactic worked or failed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get a brief.&lt;/strong&gt; Before a meeting, anyone (including a new hire who has never spoken to that vendor) opens the vendor page and gets a synthesized brief built from &lt;em&gt;everyone else's&lt;/em&gt; deals.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The stack is a Next.js 15 frontend and a FastAPI backend. Hindsight does the memory work through its three primitives: &lt;code&gt;retain&lt;/code&gt; (write), &lt;code&gt;recall&lt;/code&gt; (search), and &lt;code&gt;reflect&lt;/code&gt; (synthesize). There's one write path and one read path, and both go through the same shared bank per vendor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Procurement ─┐
IT           ─┤
Sales-Ops    ─┼─►  Hindsight bank "vendor-microsoft"  ─► reflect() ─► Brief
Finance      ─┤
New hire     ─┘  (reads the same bank)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkd2xvnsf4rd6b3kqljy3.jpeg" 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%2Fkd2xvnsf4rd6b3kqljy3.jpeg" alt="Leverage system architecture" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Where Hindsight sits: one shared bank per vendor between the FastAPI backend and a small SQLite index.&lt;/em&gt;&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%2Fg66hdx2tah6w19umr2b5.jpeg" 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%2Fg66hdx2tah6w19umr2b5.jpeg" alt="Sign in/Sign up page" width="800" height="377"&gt;&lt;/a&gt;&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%2F87ofa2jtch04ttp49pcg.jpeg" 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%2F87ofa2jtch04ttp49pcg.jpeg" alt="Vendor list with confidence badges" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Each vendor card shows its Hindsight bank id and a confidence badge based on how many deals are recorded.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The through-line: one line of code that decides everything
&lt;/h2&gt;

&lt;p&gt;The whole design rests on a function that is almost embarrassingly small:&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;vendor_bank_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vendor&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;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;clean_vendor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vendor&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vendor&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&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;vendor-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean_vendor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Microsoft", " microsoft " and "MICROSOFT" all resolve to &lt;code&gt;vendor-microsoft&lt;/code&gt;. Every employee writes into that bank and reads from that bank. There is no user id anywhere in the memory key. The person who logged the deal is stored as &lt;em&gt;content&lt;/em&gt; inside the memory, not as the address of it.&lt;/p&gt;

&lt;p&gt;That's the entire inversion. Per-user memory answers "what did I tell you?" Per-entity memory answers "what does the organization know about this vendor?" For anything collaborative, the second question is the one that saves money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing memories Hindsight can actually use
&lt;/h2&gt;

&lt;p&gt;Hindsight extracts facts, entities and time from what you retain, so the quality of what goes in matters. The form gives me structured fields, but I don't retain JSON. I turn each deal into plain, explicit sentences.&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%2Ff2d9rbnqwrfxzrxa5lzn.jpeg" 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%2Ff2d9rbnqwrfxzrxa5lzn.jpeg" alt="Log negotiation form" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Any employee logs a deal here, and it's retained into the vendor's shared bank.&lt;/em&gt;&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%2Fkk4t20rp9vcdgqh0qxq7.jpeg" 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%2Fkk4t20rp9vcdgqh0qxq7.jpeg" alt="Terms and tactics fields" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Flexible terms, firm terms and the tactic used become facts Hindsight can reason over.&lt;/em&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="n"&gt;lines&lt;/span&gt; &lt;span class="o"&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;Negotiation Record: On &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, employee &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;logged_by&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; from the &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;department&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; department conducted a negotiation with vendor &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;discount_pct&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;Discount achieved: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;discount_pct&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% discount was agreed with &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vendor&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;firm_terms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;Contract firmness: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vendor&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; was firm, rigid, and refused to budge on: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean_firm&lt;/span&gt;&lt;span class="p"&gt;)&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tactic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This negotiation tactic WORKED successfully...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tactic_worked&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This negotiation tactic FAILED...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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;Tactic used: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tactic&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;outcome&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;Then the retain call passes the deal date as the memory's timestamp, so the history is time-aware rather than "whenever it was uploaded":&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;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="n"&gt;context&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="s"&gt;Vendor negotiation conducted by &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;logged_by&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) with &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vendor&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="n"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;iso_timestamp&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;Spelling out "WORKED" and "FAILED" and naming the department in the sentence felt heavy-handed. It turned out to be the right call, because the department and outcome become facts the memory layer can reason over later, which is what makes the attribution in the UI possible.&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%2Fs8kayuhmoudas30pztr3.jpeg" 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%2Fs8kayuhmoudas30pztr3.jpeg" alt="Negotiation added confirmation" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;After a deal is logged, the deal count and confidence update immediately.&lt;/em&gt;&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%2Fphgwzqeljy388iyfkq3t.jpeg" 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%2Fphgwzqeljy388iyfkq3t.jpeg" alt="Terminal output from recall" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recall returns the retained deals with their dates and the people involved.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflect is the product
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;recall&lt;/code&gt; is useful for "show me the sources." But the feature people actually use is &lt;code&gt;reflect&lt;/code&gt;: I hand Hindsight a prompt and it reasons across the whole vendor bank. The prompt is mostly guardrails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Base every field strictly on the retained negotiation memories for this vendor.

ANTI-HALLUCINATION RULES:
- Never guess, extrapolate, or invent numbers or contract terms not explicitly present in memory.
- If there is no recorded evidence for a field, use null or an empty list.
- Distinguish observed historical behavior from guarantees
  (e.g. use "Historically observed up to..." rather than promising future terms).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is a JSON brief: max discount achieved, payment terms, what the vendor is flexible on, what it's firm on, tactics that worked, tactics that failed. Because LLMs sometimes wrap JSON in prose, the parser tries a strict &lt;code&gt;json.loads&lt;/code&gt;, falls back to extracting the first &lt;code&gt;{...}&lt;/code&gt; block, and falls back again to an empty, valid brief. Numbers get range-checked (a discount outside 0-100 becomes &lt;code&gt;null&lt;/code&gt;), and confidence is coerced to one of three allowed values.&lt;/p&gt;

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

&lt;p&gt;With nine deals logged by five colleagues across four departments, the Microsoft brief reads like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Brief&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;💰 Pricing&lt;/td&gt;
&lt;td&gt;Historically up to 20% discount&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📅 Terms&lt;/td&gt;
&lt;td&gt;60-day payment terms accepted as the standard; 30 and 50 days also recorded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📄 Flexible on&lt;/td&gt;
&lt;td&gt;Discount, contract duration, payment terms, volume discounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 Firm on&lt;/td&gt;
&lt;td&gt;Liability clause, SLA penalties&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅ Worked&lt;/td&gt;
&lt;td&gt;Asking for a discount before discussing contract length&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌ Failed&lt;/td&gt;
&lt;td&gt;Opening with an aggressive lowball offer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📊 Confidence&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2F0onniehwmpzq179wfwc0.jpeg" 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%2F0onniehwmpzq179wfwc0.jpeg" alt="Organizational Memory panel" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Organizational Memory panel shows how many deals and colleagues the brief is built from.&lt;/em&gt;&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%2Foyqtk78j1ex4vfi38t4y.jpeg" 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%2Foyqtk78j1ex4vfi38t4y.jpeg" alt="Negotiation playbook" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The brief Hindsight synthesizes: discount, terms, firm clauses, and tactics that worked or failed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The frontend shows a "Contributed by" panel next to it, listing the colleagues and departments behind those conclusions. That panel exists because a brief nobody can verify is just a confident-sounding paragraph. Showing that Procurement, IT, Sales-Ops and Finance all contributed is what makes someone trust it enough to act on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A design decision I got wrong first
&lt;/h2&gt;

&lt;p&gt;My first instinct was to let the model decide the confidence level; the reflect prompt even asks for one. But confidence is a statement about &lt;em&gt;how much evidence exists&lt;/em&gt;, and that's something I can count exactly, so the API doesn't trust the model's answer:&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;confidence_label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&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="o"&gt;-&amp;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;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;High&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Medium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The brief endpoint overwrites whatever &lt;code&gt;reflect&lt;/code&gt; returned with &lt;code&gt;store.confidence_label(count)&lt;/code&gt;. The model still explains its reasoning, but the badge is deterministic.&lt;/p&gt;

&lt;p&gt;I'll also admit something a little embarrassing: my reflect prompt and this function briefly disagreed about the thresholds, because the same rule lived in two places. A vendor with a handful of deals could get "Medium" from one and "Low" from the other. The fix was to treat the counted value as the single source of truth and stop describing thresholds inside the prompt. Rules that exist twice will diverge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Hindsight ends and SQLite begins
&lt;/h2&gt;

&lt;p&gt;There is a small SQLite table in the backend, and I was strict about what it's allowed to hold: vendor name, who logged a deal, their department, and when. That's it. It powers the vendor list and the contributor tags without invoking an LLM just to render a page.&lt;/p&gt;

&lt;p&gt;All the actual negotiation content lives only in Hindsight. If I deleted the SQLite file, I'd lose the fast vendor list and nothing else. Hindsight is the memory, not a cache in front of a real database, and keeping that line clean made the whole system easier to reason about.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Key memory by the thing people need to know about.&lt;/strong&gt; If the knowledge belongs to a vendor, a customer, or a codebase, don't key it by user. One shared bank per entity is what turns a personal assistant into institutional memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write memories as explicit sentences.&lt;/strong&gt; Structured fields are great for forms, but what you retain should read like a clear statement of fact. Say who, when, and what happened.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't ask a model for things you can count.&lt;/strong&gt; Let the LLM synthesize, and let code own the numbers and the labels users rely on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give &lt;code&gt;reflect&lt;/code&gt; permission to say "I don't know."&lt;/strong&gt; Telling it to return &lt;code&gt;null&lt;/code&gt; for unsupported fields did more for trust than any tuning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show your sources in the UI.&lt;/strong&gt; Attribution tags cost a SQLite table and a component, and they did more for credibility than the prose quality of the brief.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One limitation worth naming: &lt;code&gt;reflect&lt;/code&gt; calls run an LLM every time, so I keep them off list views and only run them when someone opens a vendor page. If you're building something similar, that split between cheap structural queries and expensive synthesis is worth planning early.&lt;/p&gt;

&lt;p&gt;If you want to try the same pattern, start with the &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight docs&lt;/a&gt;, read the &lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight GitHub repo&lt;/a&gt;, and skim Vectorize's overview of &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;agent memory&lt;/a&gt;. You can also spin up a bank in the &lt;a href="https://ui.hindsight.vectorize.io" rel="noopener noreferrer"&gt;Hindsight Cloud console&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>python</category>
    </item>
  </channel>
</rss>
