DEV Community

AnikethSai
AnikethSai

Posted on AI-assisted

The Best Sales Rep Left. Her Experience Didn't Have To.

A sales team shouldn't lose ten years of experience because one person changed jobs. I built a sales agent around one shared Hindsight memory bank to test that idea.

The senior rep had left three months earlier.

Nobody had deleted the CRM records. The calls were still there. The emails were still there. The closed deals were still there.

But the useful part of her experience was effectively gone.

She knew which objections were harmless, which ones usually killed a deal, which competitor mentions mattered, and which follow-ups had actually worked.

The new reps had access to the records.

They didn't have access to the memory.

That was the problem I wanted to solve.

Hindsight, Vectorize's open-source agent memory system, became the memory layer.

The CRM already remembers. It just doesn't remember like a team.

A CRM can tell you that a deal was lost.

It usually doesn't give a new rep the experience of someone who has seen that situation twenty times.

So instead of asking the agent:

"What should I do with this deal?"

I wanted it to ask:

"What has happened to deals like this one before?"

The agent reads existing calls, emails, and CRM notes and turns closed deals into structured memories.

The pipeline is:

retain → extract → recall → reflect → score → explain → draft

Hindsight handles the core memory operations: retain, recall, and reflect.

The rest of the system turns those memories into something useful during an active deal.

One memory bank for the entire team

This was the first decision that mattered.

I could have created a memory bank for every rep.

I didn't.

Every closed deal goes into:

BANK_ID = "sales-team-shared"
Enter fullscreen mode Exit fullscreen mode

The point is simple.

When Rep A loses a deal, Rep B shouldn't have to learn the same lesson from scratch.

When Rep C joins six months later, the bank shouldn't start empty.

That's the difference between personal memory and organizational memory.

I store structured deal facts rather than dumping entire transcripts into memory:

{
    "content": render_deal(deal),
    "context": f"{deal.outcome} deal, {deal.objection_stage} stage",
    "tags": [
        f"objection:{deal.objection}",
        f"stage:{deal.objection_stage}",
        f"outcome:{deal.outcome}"
    ]
}
Enter fullscreen mode Exit fullscreen mode

Hindsight can then recall experiences based on the shape of the deal instead of simply matching phrases from an old transcript.

The new rep gets an unfair advantage

Imagine a new rep is handling an Evaluation-stage deal.

The prospect says:

"Finance has frozen new vendor spend."

The rep has never heard that objection in a real deal before.

The agent has.

It recalls ten historical deals with the same objection at the same stage.

Six were lost.

Four survived.

The agent doesn't tell the rep:

"This deal will probably fail."

Instead, it gives her something actionable:

"6 of 10 past budget-freeze deals at Evaluation were lost. Here are the approaches used in the four that survived."

That's the behavior I wanted.

Not prediction for the sake of prediction.

Experience transfer.

But there was a problem with letting the model remember everything

An early version trusted the model to summarize the historical pattern.

That worked beautifully until it didn't.

The model could say "most of these deals were lost" when the actual data was different.

So I made one rule non-negotiable:

The model writes the words. Code does the math.

For example:

lost = sum(
    d.outcome == "lost"
    for d in scoped_deals
)

total = len(scoped_deals)
Enter fullscreen mode Exit fullscreen mode

The model can explain the result.

It cannot decide what the result is.

Every generated explanation has to contain the exact counts. If validation fails, the system retries and eventually falls back to a deterministic template.

Hindsight's reflection output can still be used for contextual reasoning, but the computed statistics remain authoritative.

The memory gets better without retraining

This is the part I found most interesting.

Suppose the bank initially contains:

6 lost / 10 total

The next month, another similar deal closes as a loss.

Now the same situation becomes:

7 lost / 11 total

No prompt change.

No fine-tuning.

No model retraining.

The memory changed.

Therefore the agent's behavior changed.

That's what I wanted an agent memory system to feel like.

A shared memory also creates a new failure mode

If everyone contributes to the same memory, bad memories can affect everyone.

So I don't treat every recalled item as statistical ground truth.

Hindsight's recall is useful for finding relevant experiences, but retrieval is not the same thing as reconstructing a complete dataset.

If I ask the system for "6 of 10," I need all ten relevant records, not the ten most similar records that happened to fit inside a context window.

So statistics are reconstructed separately and checked against known totals.

recalled = fetch_all_deals(
    client,
    bank_id=BANK_ID
)

if tally(recalled) != expected:
    return "COUNT MISMATCH"
Enter fullscreen mode Exit fullscreen mode

If Hindsight isn't reachable, the system falls back to a local store and explicitly says so.

It never pretends the memory backend answered when it didn't.

Five things this changed my mind about

1. Organizational memory is different from search. Finding an old CRM note isn't the same as transferring the experience behind it.

2. Shared memory changes onboarding. A new rep can inherit patterns accumulated before they joined the company.

3. Memory needs boundaries. Tags and structured facts make historical comparisons much more precise.

4. Retrieval isn't automatically evidence. What an agent recalls and what the full dataset contains are two different things.

5. The model shouldn't own the numbers. If a number influences a business decision, I want to know exactly which records produced it.

The senior rep is still gone.

Her experience doesn't have to be.

Every closed deal now becomes another piece of institutional memory available to whoever handles the next one.

Hindsight remembers it.

The next rep gets to use it.

Code: [repo link] · Demo: [demo link]# The Best Sales Rep Left. Her Experience Didn't Have To.

A sales team shouldn't lose ten years of experience because one person changed jobs. I built a sales agent around one shared Hindsight memory bank to test that idea.

The senior rep had left three months earlier.

Nobody had deleted the CRM records. The calls were still there. The emails were still there. The closed deals were still there.

But the useful part of her experience was effectively gone.

She knew which objections were harmless, which ones usually killed a deal, which competitor mentions mattered, and which follow-ups had actually worked.

The new reps had access to the records.

They didn't have access to the memory.

That was the problem I wanted to solve.

Hindsight, Vectorize's open-source agent memory system, became the memory layer.

The CRM already remembers. It just doesn't remember like a team.

A CRM can tell you that a deal was lost.

It usually doesn't give a new rep the experience of someone who has seen that situation twenty times.

So instead of asking the agent:

"What should I do with this deal?"

I wanted it to ask:

"What has happened to deals like this one before?"

The agent reads existing calls, emails, and CRM notes and turns closed deals into structured memories.

The pipeline is:

retain → extract → recall → reflect → score → explain → draft

Hindsight handles the core memory operations: retain, recall, and reflect.

The rest of the system turns those memories into something useful during an active deal.

One memory bank for the entire team

This was the first decision that mattered.

I could have created a memory bank for every rep.

I didn't.

Every closed deal goes into:

BANK_ID = "sales-team-shared"
Enter fullscreen mode Exit fullscreen mode

The point is simple.

When Rep A loses a deal, Rep B shouldn't have to learn the same lesson from scratch.

When Rep C joins six months later, the bank shouldn't start empty.

That's the difference between personal memory and organizational memory.

I store structured deal facts rather than dumping entire transcripts into memory:

{
    "content": render_deal(deal),
    "context": f"{deal.outcome} deal, {deal.objection_stage} stage",
    "tags": [
        f"objection:{deal.objection}",
        f"stage:{deal.objection_stage}",
        f"outcome:{deal.outcome}"
    ]
}
Enter fullscreen mode Exit fullscreen mode

Hindsight can then recall experiences based on the shape of the deal instead of simply matching phrases from an old transcript.

The new rep gets an unfair advantage

Imagine a new rep is handling an Evaluation-stage deal.

The prospect says:

"Finance has frozen new vendor spend."

The rep has never heard that objection in a real deal before.

The agent has.

It recalls ten historical deals with the same objection at the same stage.

Six were lost.

Four survived.

The agent doesn't tell the rep:

"This deal will probably fail."

Instead, it gives her something actionable:

"6 of 10 past budget-freeze deals at Evaluation were lost. Here are the approaches used in the four that survived."

That's the behavior I wanted.

Not prediction for the sake of prediction.

Experience transfer.

But there was a problem with letting the model remember everything

An early version trusted the model to summarize the historical pattern.

That worked beautifully until it didn't.

The model could say "most of these deals were lost" when the actual data was different.

So I made one rule non-negotiable:

The model writes the words. Code does the math.

For example:

lost = sum(
    d.outcome == "lost"
    for d in scoped_deals
)

total = len(scoped_deals)
Enter fullscreen mode Exit fullscreen mode

The model can explain the result.

It cannot decide what the result is.

Every generated explanation has to contain the exact counts. If validation fails, the system retries and eventually falls back to a deterministic template.

Hindsight's reflection output can still be used for contextual reasoning, but the computed statistics remain authoritative.

The memory gets better without retraining

This is the part I found most interesting.

Suppose the bank initially contains:

6 lost / 10 total

The next month, another similar deal closes as a loss.

Now the same situation becomes:

7 lost / 11 total

No prompt change.

No fine-tuning.

No model retraining.

The memory changed.

Therefore the agent's behavior changed.

That's what I wanted an agent memory system to feel like.

A shared memory also creates a new failure mode

If everyone contributes to the same memory, bad memories can affect everyone.

So I don't treat every recalled item as statistical ground truth.

Hindsight's recall is useful for finding relevant experiences, but retrieval is not the same thing as reconstructing a complete dataset.

If I ask the system for "6 of 10," I need all ten relevant records, not the ten most similar records that happened to fit inside a context window.

So statistics are reconstructed separately and checked against known totals.

recalled = fetch_all_deals(
    client,
    bank_id=BANK_ID
)

if tally(recalled) != expected:
    return "COUNT MISMATCH"
Enter fullscreen mode Exit fullscreen mode

If Hindsight isn't reachable, the system falls back to a local store and explicitly says so.

It never pretends the memory backend answered when it didn't.

Five things this changed my mind about

1. Organizational memory is different from search. Finding an old CRM note isn't the same as transferring the experience behind it.

2. Shared memory changes onboarding. A new rep can inherit patterns accumulated before they joined the company.

3. Memory needs boundaries. Tags and structured facts make historical comparisons much more precise.

4. Retrieval isn't automatically evidence. What an agent recalls and what the full dataset contains are two different things.

5. The model shouldn't own the numbers. If a number influences a business decision, I want to know exactly which records produced it.

The senior rep is still gone.

Her experience doesn't have to be.

Every closed deal now becomes another piece of institutional memory available to whoever handles the next one.

Hindsight remembers it.

The next rep gets to use it.

Code:https://github.com/ANIKETHSAI9813/lost_agent.git

Top comments (1)

Collapse
 
presango profile image
Priya Nair (Presango) •

The shared bank instead of per-rep banks is the decision I would have gotten wrong, and your reasoning for it is convincing. One thing from running a small sales motion: the experience that walks out the door is mostly about timing, not content. She knew when in a call a pricing objection was harmless versus fatal. Tagging by objection_stage gets at that, but I would be curious whether you store where in the conversation the memory came from, minute 5 or minute 40, because the same words mean different things at each. Also, how do you keep a shared bank from hardening one rep’s bad habit into team memory if she closed a lot despite it?