DEV Community

Nainika Rechintala
Nainika Rechintala

Posted on

sales ai agent with hindsight

 I Built a Sales Agent That Learns With Hindsight

A sales agent can summarize a meeting perfectly and still be useless in the next one. The hard part is not generating another good answer; it is carrying the right lessons forward.

I built DealMind around that problem: a sales intelligence agent that remembers what happened across customer meetings, recalls the relevant history before the next conversation, and learns again from the outcome.

The interesting part was not adding another chat interface. It was deciding what should live in ordinary application state and what should become long-term agent memory.

The system I wanted

DealMind is built around a simple workflow.

A salesperson selects a deal and asks for a briefing before the next customer meeting. The system combines the structured deal record with memories accumulated from earlier meetings and asks the language model to turn that context into a concise plan.

The stack is deliberately straightforward:

React and Vite for the web interface

FastAPI for the backend API

SQLite for structured deal, contact, and meeting data

Groq for extraction, analysis, and brief generation

Hindsight for long-term agent memory

That separation matters.

SQLite knows that NovaTech Solutions has an $85,000 deal in negotiation. It can tell me who the contacts are and when meetings happened.

Hindsight answers a different question: what have I learned about this relationship that should influence the next interaction?

I used Hindsight agent memory because I did not want to turn the application database into a giant bag of conversation text. The database stores facts. Hindsight stores experience that the agent can recall when it becomes relevant.

The core loop: retain, recall, learn

The most useful mental model for the system is a loop:

Meeting notes
|
v
Analyze with LLM
|
v
Retain useful experience in Hindsight
|
v
... time ...
|
v
Next meeting request
|
v
Recall relevant memories
|
v
Generate personalized brief
|
v
Meeting outcome
|
v
Analyze + retain again

This is much closer to how I wanted an agent to behave than simply appending the previous conversation to the next prompt.

The application extracts things that can matter later: requirements, objections, competitors, stakeholders, unresolved concerns, commitments, what worked, and what failed.

The important distinction is that I do not need every sentence from every meeting to appear in the next prompt. I need the pieces that can change the next decision.

Why Hindsight belongs outside the relational database

One of the first design decisions I made was to keep structured business data and agent memory separate.

For example, the initial data model contains objects such as Company, Deal, Contact, and Meeting.

A deal can be represented with ordinary fields:

deal = Deal(
company_id=nova_tech.id,
deal_value=85000.0,
stage="Negotiation",
expected_close_date="2025-04-15",
status="Active"
)

That is exactly the kind of information a relational database should own.

Meeting history is structured in the same way:

Meeting(
deal_id=deal.id,
date="2025-03-01",
title="ROI Demonstration & Negotiation Session",
notes="Met with Michael Rao (CFO) and Sarah Chen. "
"An ROI demonstration worked well. "
"A discount-based approach did not resolve the customer's concern.",
summary="An ROI demonstration worked well with CFO Michael Rao. "
"A discount-based approach did not resolve the customer's concern.",
outcome="ROI approach validated. Contract pending executive briefing.",
next_action="Prepare executive AI meeting brief for final sign-off."
)

The interesting information here is not just the date or title.

There are lessons embedded in the meeting: ROI resonated, discounting did not, and the deal still needs executive alignment.

Those lessons are exactly what I want the memory layer to make available later.

The Hindsight GitHub repository and Hindsight documentation were useful references for treating memory as a first-class component rather than as another database table.

The behavior change is the product

The easiest way to understand DealMind is to compare the agent before and after it has accumulated experience.

Imagine the salesperson asks:

Prepare me for tomorrow's NovaTech meeting.

A stateless agent can produce reasonable advice from the current deal:

Focus on the customer's pricing concerns and demonstrate product value.

That sounds fine, but it does not prove the agent learned anything.

With accumulated memory, the briefing can become much more specific:

Pricing has already been raised as an objection.

A discount-based approach did not resolve the concern.

An ROI demonstration worked well with the CFO.

Security and compliance remain important.

A competitor offering lower initial setup pricing was previously discussed.

API integration is a key technical requirement.

The next conversation should avoid repeating approaches that already failed.

That is the behavior I was trying to build.

The model did not suddenly become more intelligent. The system gave it access to relevant experience.

Designing memory around decisions, not transcripts

This was probably the most important implementation choice.

It is tempting to send an entire meeting transcript into a memory system and call that “memory.” I think that misses the point.

For DealMind, I want memory to answer questions such as:

What objections keep appearing?

Which stakeholders care about which issues?

Which competitor has been mentioned?

What approach worked?

What approach failed?

What is still unresolved?

What commitment was made?

What should change in the next conversation?

That gives the recall step a practical purpose.

The briefing service can then combine three sources of context:

Current deal state
+
Relevant Hindsight memories
+
Current meeting objective
|
v
Personalized meeting brief

This also keeps the prompt from becoming a historical dump.

The goal is not maximum context. The goal is useful context.

Closing the learning loop

The other important piece is what happens after the meeting.

A briefing is only useful if the system can learn whether its assumptions were correct.

After a meeting, DealMind analyzes the outcome and retains the useful changes in the relationship.

For example, suppose the next meeting reveals that the security team accepted the proposed data-retention model but the CFO still wants stronger ROI evidence.

That should not disappear when the meeting ends.

It should become part of what the agent knows before the following meeting.

This creates a feedback loop:

Past meetings
↓
Memory
↓
Next-meeting recommendation
↓
New outcome
↓
Updated memory
↓
Better-informed recommendation

The timeline in the interface makes this progression visible instead of hiding memory behind the API.

That matters for debugging, too. When an agent produces an unexpected recommendation, I want to inspect the memories that influenced it rather than treating the output as magic.

What I learned building it

  1. Memory should change behavior

Adding a memory layer is not enough.

A useful test is simple: remove memory and ask the same question. Then restore memory and ask again.

If the answer is basically identical, the memory integration is probably ornamental.

For DealMind, the test is whether previous pricing objections, competitor mentions, successful approaches, and unresolved security concerns actually change the next-meeting brief.

  1. Keep facts and experience separate

A database is excellent at answering:

What is the deal value?

Memory is better suited to:

What happened the last time we discussed price?

Keeping those responsibilities separate made the architecture easier to reason about.

  1. Store outcomes, not just conversations

A meeting transcript contains a lot of information that will never matter again.

The durable signal is usually smaller: a new objection, a changed requirement, a failed tactic, a successful explanation, a new stakeholder, or a commitment.

That is what I want the agent to retain.

  1. Make memory inspectable

Agent memory can otherwise become difficult to debug.

A visible memory timeline and memory explorer give me a way to answer:

Why did the agent say that?

That is especially important when the application is making recommendations rather than simply answering questions.

  1. Test the learning loop, not just the UI

The most important end-to-end test is not whether the dashboard loads.

It is:

meeting → analyze → retain
↓
recall later
↓
generate brief
↓
record outcome
↓
retain again

If that loop works, the rest of the application has something meaningful to present.

Where I would take it next

The current architecture gives me a useful foundation for making the memory layer more sophisticated.

I would add stronger handling for conflicting memories, stale information, and confidence around older observations. I would also make memory provenance more explicit so a salesperson can see which previous interactions influenced a recommendation.

But I would resist turning DealMind into a general-purpose sales chatbot.

The useful unit is still the decision before the next meeting.

That is why I chose Hindsight as a dedicated memory layer. The value is not that the agent can remember everything. The value is that it can carry forward the right lessons, retrieve them at the right moment, and use them to change what it does next.

For me, that is the difference between an agent that has a conversation and an agent that accumulates experience.

Top comments (0)