DEV Community

srivallisurve
srivallisurve

Posted on

How I Used Hindsight to Catch Sales Contradictions

Stop Summarizing Calls: How I Used Hindsight to Catch Sales Contradictions

If you look at most AI sales tools today, they all do the exact same thing: they take a massive transcript of a sales call, feed it into a large language model (LLM), and output a bulleted summary.

Summarization is easy. It is also practically useless for closing complex B2B deals.

When I started building DealMind AI, I realized that compressing past conversations into high-level summaries destroys the most critical data a sales rep needs: chronology. A sales cycle is a narrative. If a prospect says "budget is fully approved" in Week 1, but says "we need to reduce scope due to budget" in Week 3, an LLM summarizing the whole month will often just blend those into "budget was discussed."

To build an agent that actually helps reps prepare for calls, I had to stop summarizing and start detecting structural contradictions. Here is how I used Hindsight to feed chronological memory to an LLM, forcing it to act like an elite sales analyst rather than a glorified stenographer.

The Flaw of the Single Context Window

Initially, my approach to agent memory was naive. I assumed I could just query a database for all past notes, cram them into the prompt, and ask the LLM for advice.

The problem is that LLMs suffer from "lost in the middle" syndrome. When you feed them a wall of unstructured text, they lose the temporal relationship between statements. The AI doesn't understand that Statement B invalidates Statement A because Statement B happened three weeks later.

Enforcing Chronology in the Prompt

To fix this, I completely changed how our FastAPI backend communicated with our Groq-powered analysis service (llama-3.1-70b-versatile).

First, we use Hindsight to surgically retrieve only the historical memories relevant to the specific deal. But instead of just concatenating them, we strictly format them as a chronological array before they ever touch the LLM prompt.


# Extract and order the memories chronologically
if not memories:
    memories_text = "No historical memories available. Provide generic preparation."
else:
    memories_text = "\n\n".join(f"[Memory {i+1}]: {mem}" for i, mem in enumerate(memories))

# Inject them clearly into the user message
user_message = f"USER QUERY: {query}\n\nSALES CALL MEMORIES (Chronological):\n{memories_text}\n\nProvide the required JSON analysis."
Enter fullscreen mode Exit fullscreen mode

Prompting for Contradictions, Not Summaries

Formatting the data chronologically wasn't enough; I had to explicitly forbid the LLM from summarizing.

In our SYSTEM_PROMPT, I added rigorous instructions directing the model to evaluate the timeline for structural shifts. I explicitly taught the agent the difference between a "change" and a "contradiction."


SYSTEM_PROMPT = """You are an elite sales intelligence analyst for DealMind AI.
...
CRITICAL INSTRUCTIONS:
1. Reason CHRONOLOGICALLY based only on the supplied memories. Do not hallucinate facts.
2. Distinguish between mere updates/changes vs. genuine contradictions.
   - Example of a change: "Budget was open, now it is tight." (Record in changes_detected)
   - Example of a contradiction: "Stakeholder A said they use AWS. Stakeholder B said they are 100% Azure." (Record in contradictions)
...
"""
Enter fullscreen mode Exit fullscreen mode

By forcing the LLM to output its findings into strict JSON arrays for changes_detected and contradictions, the model's behavior completely transformed.

Instead of saying, "The prospect is concerned about budget," the agent started outputting highly tactical alerts: "Contradiction detected: In Memory 1, the prospect explicitly stated budget was not a blocker. In Memory 3, they requested a scope reduction due to budget constraints."

The agent stopped acting like a note-taker and started acting like a strategic partner.

Lessons Learned

Building a chronological contradiction engine taught me a lot about how to handle historical data in LLM pipelines:

1. Summarization destroys data

Never summarize historical interactions before running your final analysis. Summarization inherently smooths over the sharp edges and contradictions that usually contain the most valuable insights. Store and retrieve raw, chronological memories.

2. Time is a crucial feature

LLMs do not intuitively understand time. If you do not explicitly label your injected context with chronological markers (e.g., [Memory 1], [Memory 2]), the model will treat a three-month-old statement with the same weight as something said yesterday.

3. Force the model to show its work

By creating explicit JSON keys for changes_detected and contradictions, we forced the LLM to traverse the chronological timeline and justify its risk assessment. If you just ask for a "recommendation," the LLM will skip the hard reasoning steps.

If you are tired of building AI wrappers that just summarize text, you need to rethink how you handle historical context. Start building agents that can reason across time, and check out the Hindsight docs to see how to implement persistent, chronological memory in your own projects.

Shout-out to: Code.in.

Top comments (0)