The hardest part of building an AI assistant for a long-running sales process wasn't getting a language model to answer questions.
That part is almost suspiciously easy.
The harder problem was making the answer change when something important in the deal changed.
That distinction is what led me to build Foresight around Hindsight. I didn't want deal history to sit around as a giant pile of documents that the model occasionally got to rummage through. I wanted it to behave more like actual state.
Because a sales deal isn't just a conversation.
It's a moving target with commitments, constraints, people, deadlines, budgets, and approximately seventeen things that someone promised three weeks ago and has now forgotten.
Enterprise sales is basically accumulated context.
A deal can run for weeks or months. Different people enter at different stages. A technical evaluator cares about architecture. Security has its own requirements. Finance has a budget. Procurement has contract constraints. And somehow the salesperson is expected to remember what was promised to all of them.
A conventional LLM interface starts with the latest message:
"Can you give us 40% off and get us into production in two weeks?"
Technically, that's a perfectly understandable request.
Practically, it tells me almost nothing about whether that request makes sense for this particular deal.
In the ACME example I built, the model needs to know that the current quote is $72,000, the customer's budget is $50,000, a competitor is around $48,000, the normal deployment time is four to six weeks, and the security team is still waiting for a SOC 2 report.
And then there's the tiny detail that tends to ruin everything:
The customer never actually agreed to a two-week deployment.
So the useful question isn't:
"How should I answer this message?"
It's:
"What does this message mean given everything that has already happened?"
That became the central design problem for Foresight.
I split the system into two kinds of knowledge.
The first is relatively stable company knowledge: standard deployment timelines, discount authority, security requirements, and other rules that apply to the seller.
The second is deal memory: what actually happened with this particular customer.
Foresight stores that second category in a separate Hindsight memory bank for the deal. The architecture in the repository makes that boundary pretty clear.
The important part is that I'm not asking the LLM to somehow remember an entire three-month conversation and then hope it develops a photographic memory overnight.
Instead, the application can retain what happened and later recall the parts that matter to the current request.
This is where Hindsight's GitHub repository and its agent memory documentation fit naturally into the architecture.
That changed how I thought about the problem.
Memory stopped being a UI feature.
It became an input to the reasoning pipeline.
And honestly, that felt much more useful.
At first glance, the obvious approach is pretty simple:
Retrieve some memories, shove them into the prompt, and ask the LLM what it thinks.
Technically, that works.
But it leaves out the interesting question:
What happens when the new request contradicts something I already know?
For Foresight, the retrieved memories aren't just background information. They're evidence. The system checks that evidence against the new request and against company constraints.
That's where the Collision Check comes in.
For example, if the customer asks for a two-week deployment, Foresight can recall that the engineering team previously established a four-to-six-week deployment window.
If the customer asks for a large discount, it can recall the customer's budget, the current quote, the competitor's price, and the salesperson's discount authority.
If security is still waiting for a document that was promised earlier, that's another collision.
The model is still doing the language reasoning.
The difference is that it's reasoning over a deliberately assembled representation of the deal rather than staring at one isolated prompt like it just woke up five minutes ago.
This is the part of Foresight I found most useful.
Initially, the ACME deal has an unresolved security blocker. The memory records that the SOC 2 report was promised to the security lead and that no fulfilment has been recorded.
Then the customer's new request arrives:
The Collision Check finds several pieces of context.
First, security has said that production data cannot be used until the SOC 2 review is complete.
Second, the technical team has established a normal deployment window of four to six weeks.
Third, the commercial request has to be considered alongside a $50,000 budget, a $48,000 competitor price, a $72,000 current quote, and the salesperson's discount authority.
So the resulting recommendation isn't simply "accept" or "reject."
Instead, the application can point to the evidence and tell the salesperson what needs to happen first.
That's a much more useful answer.
The system isn't just saying:
"Here's a paragraph that sounds reasonable."
It's saying:
"Here's what I remember, here's what conflicts, and here's why that matters."
That distinction ended up being one of the most important design decisions I made.
This is also where the commitment ledger became useful.
Instead of storing promises as random pieces of text buried somewhere in conversation history, Foresight exposes them as actual state.
It sounds like a small UI decision, but it makes the reasoning much easier to follow.
A salesperson can look at the deal and immediately understand why the system is raising a warning.
And more importantly, the system has something concrete to update.
Which brings me to the part I cared about most.
Suppose the salesperson actually sends the SOC 2 report.
If memory is only being used as a read-only retrieval feature, not much has fundamentally changed. The UI might show a new status, but unless that change reaches the reasoning layer, the system is still operating on yesterday's understanding of the deal.
Foresight instead treats the update as a memory operation.
The salesperson marks the SOC 2 report as sent.
Hindsight gets updated.
The Collision Check runs again.
The recommendation is recalculated.
Now the security collision disappears.
The system can move from:
"Don't discuss deployment dates until the security requirement is satisfied."
toward:
"The security blocker has changed. Now we can actually discuss the commercial request and deployment timeline."
That was the point where Hindsight stopped feeling like some external memory service I had bolted onto the application.
It started feeling like part of the application's state model.
The memory isn't there just to make the assistant sound more conversational.
The memory changes what the system concludes.
And that's a much more interesting use of memory than teaching an AI assistant to remember someone's name.
I also wanted to keep a distinction between remembering the past and anticipating what might happen next.
That's where the Predictive Foresight section comes in.
It uses the current deal stage, unresolved stakeholder requirements, and previous inquiries to anticipate likely customer questions.
For example, if the CFO has a hard budget deadline and procurement is becoming involved, the next questions probably aren't going to be about the technical architecture. They might be about payment terms, renewal increases, or contract timing.
Foresight can surface those likely questions before they arrive and suggest counter-questions for the salesperson.
So the broader flow becomes pretty simple:
Remember what happened.
Understand what's happening now.
Anticipate what might happen next.
Hindsight supplies the first part.
The rest of the application turns that memory into current and forward-looking reasoning.
For a deeper explanation of the underlying concept, I found Vectorize's explanation of agent memory useful because it frames memory as something an agent can retain and retrieve over time rather than simply stuffing increasingly absurd amounts of text into every prompt. Adding memory because an application is "AI" isn't really a design.
It's a checkbox.
I found it much more useful to start with a specific failure mode:
The assistant gives an answer that is locally reasonable but globally wrong for the deal.
Once that failure is clear, the memory requirements become much easier to define.
I need previous commitments.
I need stakeholder requirements.
I need commercial context.
I need decisions and changes over time.
I don't need every sentence ever exchanged to be treated as equally important.
That last part matters more than it sounds. More context isn't automatically better context. Sometimes it's just more text wearing a fake moustache and pretending to be useful.
The useful output of memory retrieval isn't a giant block of text that gets dumped into a prompt.
For Foresight, recalled information needs to participate in an actual check. The system should be able to identify which remembered fact conflicts with the current request and explain why that conflict matters.
That's why the Collision Check exists as a separate concept rather than just being another prompt.
The model gets context.
The application gives that context a job.
A memory system becomes much more useful when it can represent change.
"Security is waiting for the SOC 2 report" and "Security received the SOC 2 report" aren't two unrelated facts.
They're two states of the same deal.
The application needs to be able to move from one state to the other and make downstream reasoning reflect that change.
That was a big shift in how I thought about memory.
I wasn't trying to build an archive.
I was trying to build something closer to a changing state model.
This separation prevented a subtle class of mistakes.
"Deployment normally takes four to six weeks" is a company constraint.
"ACME has not completed its security review" is a deal fact.
They're both relevant, but they're relevant for different reasons.
Mixing them into one giant knowledge base makes it harder to understand where a recommendation came from.
Keeping them separate lets the reasoning layer combine stable policy with customer-specific history without turning the whole thing into one enormous context soup.
Showing that an assistant remembers someone's name isn't particularly impressive.
Showing that updating one remembered fact removes a blocker and changes the recommended action is much stronger.
It gives memory an observable consequence.
And I think that's the real test.
If I remove or update a memory and nothing meaningful changes downstream, then why is that memory there? The architecture is deliberately small:
Deal memory.
Recall.
Collision detection.
Evidence.
Action-oriented response.
I would resist the temptation to turn it into a collection of agents just because that is fashionable right now.
Not every software problem needs twelve agents having a meeting with each other.
The interesting engineering problem here is maintaining a useful representation of deal state and making changes to that state propagate into reasoning reliably.
The broader lesson I took from building Foresight is that long-running AI applications need something closer to state management than chat history.
Foresight started from a pretty simple observation:
A sales conversation cannot be understood from its latest message alone.
Using Hindsight gave me a way to make that history persistent, queryable, and updateable. The application then turns those memories into collision checks, commitments, recommendations, and predictions.
So the assistant doesn't just remember what happened.
It can use what happened to understand what's happening now, and prepare for what might happen next.
Which, admittedly, is a much more useful definition of "AI memory" than remembering that someone's favorite color is blue.