<?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: SHRISHANT KASHID</title>
    <description>The latest articles on DEV Community by SHRISHANT KASHID (@shrishant_kashid_4bfc909f).</description>
    <link>https://dev.to/shrishant_kashid_4bfc909f</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%2F3938605%2F4e9acb08-7619-46c8-b773-c45ef7a3e248.png</url>
      <title>DEV Community: SHRISHANT KASHID</title>
      <link>https://dev.to/shrishant_kashid_4bfc909f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shrishant_kashid_4bfc909f"/>
    <language>en</language>
    <item>
      <title>How I Built a Sales Agent That Scores Deal Health from Memory — No CRM Update Required</title>
      <dc:creator>SHRISHANT KASHID</dc:creator>
      <pubDate>Mon, 18 May 2026 17:53:16 +0000</pubDate>
      <link>https://dev.to/shrishant_kashid_4bfc909f/how-i-built-a-sales-agent-that-scores-deal-health-from-memory-no-crm-update-required-2b81</link>
      <guid>https://dev.to/shrishant_kashid_4bfc909f/how-i-built-a-sales-agent-that-scores-deal-health-from-memory-no-crm-update-required-2b81</guid>
      <description>&lt;p&gt;Sales reps talk to the same people for months. The context — budget concerns raised in week two, the competitor mentioned offhand in week five, the onboarding objection that nearly killed the deal — lives in CRM fields nobody reads, or only in the rep's head. Every call starts with re-establishing what both sides already know.&lt;br&gt;
I wanted to fix that with a simple constraint: one lookup before the call, one note after. No structured fields, no mandatory forms, no CRM discipline required.&lt;br&gt;
The result is SalesMemory — a web app that gives reps a persistent agent memory layer across every prospect interaction. Before a call, the rep gets a structured brief: objections raised, budget signals, competitor mentions, deal health score. After the call, they write 2–3 sentences. That's it. The agent does the rest.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The Core Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React + Vite + Tailwind CSS (Vercel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Python + FastAPI (Render)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory layer:&lt;/strong&gt; Hindsight via the hindsight-client Python SDK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM:&lt;/strong&gt; Groq API — llama-3.3-70b-versatile
5.&lt;strong&gt;Database:&lt;/strong&gt; None&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point is intentional. Hindsight is the only persistence layer in the system. Every interaction is stored as a memory with metadata, recalled via semantic query, and fed directly to the LLM. There's no PostgreSQL, no schema, no ORM. The tradeoff — you can't write &lt;code&gt;SELECT SUM(deals) WHERE stage = 'closing'&lt;/code&gt;is one we made consciously, because the gain is something SQL can never give you: semantic retrieval.&lt;br&gt;
Querying Hindsight for "Priya's budget concerns" returns everything contextually relevant to that topic, even if the rep logged it as "she mentioned the rollout budget might be an issue until Q3." Keyword search doesn't do that. SQL doesn't do that.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;How Memory Is Stored and Recalled&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After a call, the rep types the prospect name, writes a few sentences about what happened, and picks an outcome tag (First contact / Objection logged / Positive signal / Deal progressed). The backend formats that into a structured memory entry and stores it permanently via Hindsight:&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;retain_interaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospect_name&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="n"&gt;summary&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="n"&gt;outcome&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="n"&gt;timestamp&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="n"&gt;content&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;
Prospect: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prospect_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Date: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Outcome: &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="s"&gt;
Summary: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summary&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="n"&gt;client&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;pipeline_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PIPELINE_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;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;prospect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prospect_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outcome&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&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="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;call_log&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 metadata is what makes this trustworthy. Without it, you're doing full semantic search across everything and hoping the right memories surface. With&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;{"prospect": name, "type": "call_log"}&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, the timeline view for any individual prospect filters reliably — you get their history, not someone else's.&lt;br&gt;
Before the next call, the system recalls up to ten recent interactions for that prospect:&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;recall_prospect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospect_name&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;results&lt;/span&gt; &lt;span class="o"&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;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;pipeline_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PIPELINE_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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prospect interactions with &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prospect_name&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;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&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;results&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That recalled context — the full interaction history, in plain language — goes directly into the LLM prompt for the pre-call brief. No transformation step, no structured parsing of past data. The model reads what the rep wrote and extracts signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Deal Health Score: Compute It Fresh Every Time&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most products that surface a "health score" store it somewhere. We don't. The score doesn't exist until a brief is requested, at which point the LLM reads all recalled memory for that prospect and reasons about momentum, risk, and confidence.&lt;br&gt;
This architecture has one property that surprised me: the score automatically improves as memory accumulates. There are no recalculation jobs, no schema migrations when the scoring logic changes. Update the prompt, and the next brief for every prospect reflects the updated reasoning.&lt;br&gt;
The system prompt gives the LLM explicit scoring guidance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BRIEF_SYSTEM_PROMPT = """
You are a sales intelligence assistant. You read raw memory from past prospect
interactions and return a structured JSON pre-call brief for a sales rep.

Deal health scoring guide:
- 0-20: Cold. No engagement, no signals, or long silence.
- 21-40: Warming up. Early interest but objections unresolved.
- 41-60: Engaged. Active conversations, some positive signals.
- 61-80: Hot. Strong signals, near decision stage.
- 81-100: Closing. Verbal commitment or trial agreed.

Return ONLY valid JSON. No explanation. No markdown. No code fences.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scoring logic penalizes unresolved objections, budget uncertainty, long gaps since last contact, and competitor mentions without resolution. It rewards pilot agreements, confirmed budgets, multiple positive signals, and clear next steps.&lt;br&gt;
The output is a structured object with six fields: &lt;code&gt;score&lt;/code&gt;, &lt;code&gt;label&lt;/code&gt;, &lt;code&gt;momentum&lt;/code&gt;, &lt;code&gt;risk&lt;/code&gt;, &lt;code&gt;recommended_action&lt;/code&gt;, and &lt;code&gt;confidence&lt;/code&gt;. That last field — confidence — is calibrated to how much memory actually exists for the prospect. A rep walking into their first call gets &lt;code&gt;confidence: low&lt;/code&gt; and a frank note that there's no history to draw on. After four or five interactions, &lt;code&gt;confidence: medium&lt;/code&gt; or &lt;code&gt;high&lt;/code&gt; means the score is actually grounded in something.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What the Memory Compounding Looks Like in Practice&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's Priya Sharma, VP Sales at Rentokil, after four logged interactions:&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Interaction 1:&lt;/em&gt;&lt;/strong&gt; Budget freeze flagged.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Interaction 2:&lt;/em&gt;&lt;/strong&gt; Onboarding timeline concern raised.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Interaction 3:&lt;/em&gt;&lt;/strong&gt; ROI calculator landed well. Pilot requested.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Interaction 4:&lt;/em&gt;&lt;/strong&gt; Pilot agreed. Data migration concern surfaced.&lt;/p&gt;

&lt;p&gt;Pre-call brief after interaction 4:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Score: 70/100
Label: Engaged
Momentum: ↑ Improving
Risk: "Data migration concerns may stall the deal"
Recommended action: "Provide a detailed data migration plan and timeline to alleviate Priya's concerns"
Confidence: Medium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The brief for Priya after interaction 1 was generic — "budget freeze mentioned, no clear next step, proceed cautiously." The brief after interaction 4 is specific, scored, and tells the rep exactly what to do on this call. That delta is the entire product value made visible.&lt;/p&gt;

&lt;p&gt;Compare that to James Okafor, Head of Revenue at Paysend. Three interactions: API reliability concern, then a technical deep dive that went well, then a security report sent — after which he went silent for seven days. His brief: &lt;code&gt;Score: ~61, Engaged but stalling. Risk: competitor discount pressure. Status: Needs attention now.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The agent flagged James as "needs attention now" in the weekly digest. Without memory, he's just a name in a pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Weekly Digest: One Prompt, All Prospects&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The most interesting architectural decision in the system is the digest endpoint. Instead of making one LLM call per prospect and merging the results, it recalls memory for every known prospect in a single pass, builds one large prompt with all contexts, and asks the model to categorize and prioritize all of them simultaneously:&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;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_digest&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;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;all_prospects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_all_prospects&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;prospect_contexts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;all_prospects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;recalled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recall_prospect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;recalled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;prospect_contexts&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;context&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;recalled&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_digest_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prospect_contexts&lt;/span&gt;&lt;span class="p"&gt;)&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;groq_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&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;llama-3.3-70b-versatile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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;role&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;system&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DIGEST_SYSTEM_PROMPT&lt;/span&gt;&lt;span class="p"&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;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1200&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&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;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output buckets every prospect into one of three categories:&lt;/p&gt;

&lt;p&gt;🔴 Needs attention now — no response in 5+ days, stalled deal, at-risk signal&lt;br&gt;
🟡 Follow up this week — active deal, clear next step needed&lt;br&gt;
🟢 On track — waiting on prospect, no rep action needed&lt;/p&gt;

&lt;p&gt;Each item includes a specific reason and a one-sentence action. The LLM reasons better when it can see all five prospects simultaneously — it can compare James Okafor going silent for seven days against Marcus Webb where budget is confirmed but the rep hasn't followed up on the lunch-and-learn request. Five separate calls can't produce that relative prioritization.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I Learned&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Semantic recall is not keyword search.&lt;/strong&gt; "She pushed back on timing" and "onboarding timeline is a concern" both surface for the same Hindsight query. This matters in practice because reps don't log notes in consistent language, and you can't force them to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The prompt is the product.&lt;/strong&gt; The deal health score quality is entirely determined by the system prompt. "Rate the deal from 0 to 100" produces meaningless scores. Explicit deduction logic — "unresolved objections drop the score; pilot agreements raise it" — produces scores that match what an experienced rep would say about the deal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Metadata is what makes retrieval trustworthy.&lt;/strong&gt; Storing every interaction with &lt;code&gt;{"prospect": name, "outcome": outcome, "timestamp": timestamp}&lt;/code&gt; means the timeline view filters accurately by prospect. Without it, semantic search is a guess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One LLM call beats five.&lt;/strong&gt; The digest endpoint cuts latency, cuts API cost, and produces more coherent prioritization because the model can compare prospects it can see simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No CRM update required" is the actual value prop.&lt;/strong&gt; Every sales tool has told reps to keep the CRM updated. None of them do. A system that works with informal, unstructured notes — because Hindsight stores and recalls semantic meaning, not structured fields — removes the compliance burden entirely.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
&lt;a href="https://github.com/vectorize-io/hindsight" rel="noopener noreferrer"&gt;Hindsight&lt;/a&gt; is built on a simple premise: agents that can't remember aren't really agents. Between sessions, they lose everything. With &lt;a href="https://vectorize.io/what-is-agent-memory" rel="noopener noreferrer"&gt;persistent memory across sessions&lt;/a&gt;, an agent can genuinely compound intelligence over time — each interaction making every future interaction more useful.&lt;br&gt;
For sales, that property maps directly to something reps care about: walking into every call knowing exactly what happened before, what to address, and what's at risk. One lookup before, one note after. The agent handles everything in between.&lt;br&gt;
If you want to build something similar, the &lt;a href="https://hindsight.vectorize.io/" rel="noopener noreferrer"&gt;Hindsight documentation&lt;/a&gt; covers the retain/recall/reflect architecture in depth&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%2F8ucip1wtmulw70jpjvcb.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%2F8ucip1wtmulw70jpjvcb.PNG" alt="Pre-call Brief" width="655" height="451"&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%2F7rj9ocvcmtx320cduhev.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%2F7rj9ocvcmtx320cduhev.PNG" alt="Memory timeline" width="460" height="522"&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%2Fnhxkor7y2d3ftny51qur.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%2Fnhxkor7y2d3ftny51qur.PNG" alt="Hindsight Memory - World Facts" width="800" height="491"&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%2Fiq5ghw3vj6ikm0svyd0p.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%2Fiq5ghw3vj6ikm0svyd0p.PNG" alt="Hindsight Memory - Expreience" width="800" height="455"&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%2Fi6e90cx5ancany3tdekl.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%2Fi6e90cx5ancany3tdekl.PNG" alt="Hindsight Memory - Observations" width="800" height="474"&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%2Fl085nzo19izncv3gxyuj.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%2Fl085nzo19izncv3gxyuj.PNG" alt="Hindsight Memory - Entities" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
