<?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: Prithvi Tomar</title>
    <description>The latest articles on DEV Community by Prithvi Tomar (@prithvi_tomar_f4437bfefd4).</description>
    <link>https://dev.to/prithvi_tomar_f4437bfefd4</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3874170%2Fb9da6aa6-312c-429d-9a1d-b5c3c19f1ba6.png</url>
      <title>DEV Community: Prithvi Tomar</title>
      <link>https://dev.to/prithvi_tomar_f4437bfefd4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prithvi_tomar_f4437bfefd4"/>
    <language>en</language>
    <item>
      <title># Same churn signal, two different right answers</title>
      <dc:creator>Prithvi Tomar</dc:creator>
      <pubDate>Sun, 12 Apr 2026 13:33:17 +0000</pubDate>
      <link>https://dev.to/prithvi_tomar_f4437bfefd4/-same-churn-signal-two-different-right-answers-32hg</link>
      <guid>https://dev.to/prithvi_tomar_f4437bfefd4/-same-churn-signal-two-different-right-answers-32hg</guid>
      <description>&lt;p&gt;Your CRM knows when a customer goes quiet. It has no idea why that customer bought in the first place.&lt;br&gt;
That gap is the entire reason I spent a weekend building this thing. Live demo here if you want to click around before reading further.&lt;br&gt;
Meet Alice and Bhavik&lt;br&gt;
Alice took 109 days and 167 events to make her first purchase. She bounced on product pages, walked away, came back, walked away again, and only bought after finding a cheaper alternative on a discount. Bhavik took 14 minutes and 16 events. He found what he wanted and bought the high-spec version at full price.&lt;br&gt;
Both are now quiet. Both trigger the same "at risk" flag in any standard retention system, which sends them the same templated "we miss you, here's 10% off" email.&lt;br&gt;
But Alice and Bhavik are not the same problem. The right play for Alice is a loyalty rate — she is price-sensitive and she will trade time for money. The right play for Bhavik is a webinar on the advanced features he never explored — he bought decisively at full price, which means he responds to capability, not discounts. Send them the wrong one and you either leave money on the table or you train a price-sensitive customer to wait for your next discount email.&lt;br&gt;
Same signal. Different right answers. The difference lives in events from months ago. This is not a retrieval problem — you can't solve it with a vector database and a clever prompt. You need Hindsight, which gives you memory that has structure over time.&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.amazonaws.com%2Fuploads%2Farticles%2Fctdmdajmbql4jbay9ijz.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.amazonaws.com%2Fuploads%2Farticles%2Fctdmdajmbql4jbay9ijz.png" alt=" " width="800" height="424"&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.amazonaws.com%2Fuploads%2Farticles%2Fbqndth7nfkfjb5svxse1.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.amazonaws.com%2Fuploads%2Farticles%2Fbqndth7nfkfjb5svxse1.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How it's wired&lt;br&gt;
Two agents. Plain Python classes. No agent framework — they communicate exclusively through shared memory, which turned out to be a much cleaner pattern than I expected.&lt;br&gt;
The ConversionAgent watches pre-conversion events and writes them to a per-customer Hindsight bank. The RetentionAgent, when a churn signal fires, calls reflect() twice: once against the customer's bank to figure out who they are, and once against a shared playbook bank to pick the right play.&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.amazonaws.com%2Fuploads%2Farticles%2Fxfsic83zk6zuxk0xub38.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.amazonaws.com%2Fuploads%2Farticles%2Fxfsic83zk6zuxk0xub38.png" alt=" " width="800" height="188"&gt;&lt;/a&gt;&lt;br&gt;
The architectural decision I want to keep talking about a year from now is two memory banks, not one. The per-customer bank tracks one person's lifecycle. The playbook bank holds research findings from Bain, Forrester, and Reichheld, plus pre-curated mental models grounding each retention strategy in real evidence. They have incompatible dispositions — one is empathetic, the other is highly skeptical — and they belong in separate banks.&lt;br&gt;
Here's the playbook bank in production: 38 memories, 940 knowledge-graph edges, 21 world facts consolidated into 17 observations, 4 mental models, 3 directives. All from the research seed data:&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.amazonaws.com%2Fuploads%2Farticles%2Futneoer2bne4s2pppdc3.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.amazonaws.com%2Fuploads%2Farticles%2Futneoer2bne4s2pppdc3.png" alt=" " width="800" height="427"&gt;&lt;/a&gt;&lt;br&gt;
And here's the knowledge graph Hindsight built automatically. No retrieval code lives in my repo:&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.amazonaws.com%2Fuploads%2Farticles%2F28ht05dqzduzz3af7wxp.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.amazonaws.com%2Fuploads%2Farticles%2F28ht05dqzduzz3af7wxp.png" alt=" " width="678" height="722"&gt;&lt;/a&gt;&lt;br&gt;
I wrapped the SDK in a thin, opinionated wrapper:&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;class&lt;/span&gt; &lt;span class="nc"&gt;HindsightWrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Thin, opinionated wrapper over hindsight-client 0.5.0.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;raw&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Hindsight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Escape hatch to the underlying SDK client. Avoid unless needed.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The single sentence in the per-customer bank's reflect mission that changed everything: "When asked about retention or churn, I always reference the conversion-phase memories that established this customer's decision profile." Without it, the agent grounds reasoning in whatever's most recent — which for a churn signal is always the silence. With it, the agent reaches back months automatically. I tweaked that string more carefully than I tweaked any actual Python code.&lt;br&gt;
The moment it fires&lt;br&gt;
Trigger churn on Alice. The reasoning trace streams in line by line:&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.amazonaws.com%2Fuploads%2Farticles%2Fwil1a8dyapdgun3nc45a.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.amazonaws.com%2Fuploads%2Farticles%2Fwil1a8dyapdgun3nc45a.png" alt=" " width="800" height="699"&gt;&lt;/a&gt;&lt;br&gt;
Mental model check (green) hits "price-sensitive retention plays." Observation search (blue) pulls "Alice exhibits price-sensitive hesitation across multiple sessions." Recall (gold) pulls the actual Month 1 memories — the repeated pricing-page visits, the abandoned carts, the eventual discount-driven conversion. Recommendation: loyalty-rate play. The based_on evidence cites 54 conversion-phase memories by ID.&lt;br&gt;
Same signal on Bhavik. Completely different path. The mental model it hits is feature-driven, not price-sensitive. The observation is about decisive, urgency-responsive behavior. The raw facts cite 14 minutes of confident product-page views. Recommendation: feature webinar. 14 conversion-phase memories cited.&lt;br&gt;
Two customers. Identical present-tense signal. Two different right answers. Both grounded in evidence the LLM could not have guessed at because the evidence predated the query by months:&lt;br&gt;
I sat there for a minute just looking at it. This is the moment I had been chasing — agent memory doing work that no amount of prompt engineering on a stateless LLM could replicate.&lt;br&gt;
What surprised me&lt;br&gt;
The most educational bug I hit was an entity labels gotcha in hindsight-client 0.5.0. The Python SDK types entity_labels as list[str], so I did the obvious thing — passed flat strings. The update_bank_config call returned 200 OK. The next retain() call failed with this:&lt;br&gt;
1 validation error for LabelGroup&lt;br&gt;
  Input should be a valid dictionary or instance of LabelGroup&lt;br&gt;
Silent corruption followed by a misleading error. The SDK type hint is wrong — entity labels need a rich dict shape with key, description, type, and values. The fix lives in my HindsightWrapper so neither agent has to think about it. If you're using hindsight-client 0.5.0 and your retains fail with LabelGroup errors, check your entity label shape.&lt;br&gt;
Honest lessons&lt;br&gt;
Thin retain content is the biggest mistake I made. My first retains were raw page-view data. Hindsight's observations came back generic and useless. What worked was writing an explicit interpretive summary at retain time — "Alice viewed the band product page for the second time, suggesting hesitation" — giving Hindsight a high-signal fact to consolidate. Don't dump events. Write the fact you want the agent to learn.&lt;br&gt;
Composed data is honest, not a weakness. Alice and Bhavik's events come from real Retailrocket visitor behavior. Product names come from Amazon Reviews 2023. The retention research is grounded in published findings from Bain, Forrester, and Reichheld at HBR. Every individual fact is sourced from a public dataset. The composition into coherent personas is mine. This is how data science with public datasets works every day.&lt;br&gt;
The thing I wish I'd known at hour zero&lt;br&gt;
The memory architecture is the product. The agents and the frontend are glue. I went into this wanting a better vector store. I came out convinced that what I actually wanted the whole time was agent memory with structure over time — and that's a completely different category of tool. Vector databases give you similarity search. Hindsight gives you a persistent, opinionated view of a relationship that gets sharper with evidence and that you can interrogate in natural language.&lt;br&gt;
If you're building agents that need to reason about anything more than the last thing that happened, stop gluing vector stores together and go read the Hindsight docs. I wish someone had told me that a month ago.&lt;br&gt;
Try the live demo here(&lt;a href="https://cross-live-intiligent.vercel.app/" rel="noopener noreferrer"&gt;https://cross-live-intiligent.vercel.app/&lt;/a&gt;) with the following github repo (&lt;a href="https://github.com/prithvi471/cross-live-intiligent" rel="noopener noreferrer"&gt;https://github.com/prithvi471/cross-live-intiligent&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Composed real data from Retailrocket, Amazon Reviews 2023, and Customer Support on Twitter, grounded in published retention research from Bain &amp;amp; Company, Forrester, and Frederick Reichheld at Harvard Business Review.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
