DEV Community

THOUSEEF F
THOUSEEF F

Posted on

Building a Deal Intelligence Agent with Persistent Multi-Deal Memory

Building a Deal Intelligence Agent with Persistent Multi-Deal Memory

In complex B2B sales cycles, context is everything. Sales representatives frequently step into critical pricing or discovery calls having forgotten key notes from weeks prior, or repeating strategies that failed in similar circumstances elsewhere in the organization. While traditional Customer Relationship Management (CRM) databases act as passive records of transaction state, they lack the active intelligence to parse, remember, and connect the dots across multiple sales pipelines.

To solve this problem, we built the Deal Intelligence Agent: a memory-powered sales companion that parses call transcripts, extracts structured facts, retains them into a persistent memory graph, and generates actionable, context-aware pre-call briefings.

By leveraging Hindsight (Vectorize) as a specialized, persistent agent memory layer and Groq for high-speed LLM inference, the agent learns which objection-handling tactics work and briefs representatives before their next call.

The Architecture: Why Traditional RAG Falls Short
In a standard Retrieval-Augmented Generation (RAG) system, raw documents or transcript chunks are embedded and queried via simple semantic search. For sales cycles, this approach fails. A raw transcript contains noise, casual greetings, and unstructured tangents. If a representative queries, "What was the CFO's pricing objection?", a vector search on raw text might return paragraphs of negotiation transcript, forcing the LLM to guess the state of the objection.

The Deal Intelligence Agent resolves this by separating ingestion, structured memory extraction, and relational retrieval:

Call transcript (paste or API)


┌─────────────────────────────────┐
│ Structured Fact Extraction │ Groq parses transcript into structured
│ (gpt-oss-120b / qwen3-32b) │ events (objections, concerns, etc.)
└────────────────┬────────────────┘


┌─────────────────────────────────┐
│ Hindsight Memory Retain │ Retains structured facts to Hindsight Cloud

│ (Vectorize Memory Bank) │ using custom document layouts
└────────────────┬────────────────┘


┌─────────────────────────────────┐
│ Hindsight Memory Recall │ Executes dual-path query:
│ (Dual-Path Semantic Search) │ 1. Own-deal history timeline
│ │ 2. Cross-deal resolved patterns
└────────────────┬────────────────┘


┌─────────────────────────────────┐
│ Briefing Generator (Groq) │ Fuses own-deal history + successful
│ │ tactics into a suggested playbook
└────────────────┬────────────────┘


┌─────────────────────────────────┐
│ Rep-Facing UI (React) │ Highlights the persistent memory payoff
└─────────────────────────────────┘

1*.Ingestion & Parsing: **Call transcripts are processed by Groq. Instead of storing the text, the LLM maps conversations to a rigid schema containing the deal_id, call_number, fact_type, category, detail, response_used, outcome, and stakeholder.
2.
Persistent Retention: **The structured fact is converted to a specialized memory document and written directly to Hindsight using unique document IDs.
3.
Dual-Path Recall:* Before a call, the orchestrator queries Hindsight twice: once for the active deal's timeline, and once for resolved objections of the same category across all other deals in the workspace.
4.**Briefing Synthesis: **Groq merges the specific deal history with the cross-deal resolution strategies to output a structured preparation card.

Memory Schema: What Gets Retained
For an agent to learn over time, memories must be structured. The schema we designed maps to five key sales interactions: objection, competitor_mention, stakeholder_concern, commitment_made, and pricing_discussion.
{
"deal_id": "latticeworks-2026-expansion",
"call_number": 2,
"fact_type": "objection",
"category": "annual_billing",
"detail": "Customer pushed back on annual prepay and asked for quarterly terms.",
"response_used": "Rep offered quarterly billing with a small premium and a success checkpoint after 90 days.",
"outcome": "unresolved",
"stakeholder": "CFO",
"timestamp": "2026-07-17"
}
By storing the outcome ("unresolved", "resolved", or "monitoring") and the response_used, the system can identify not just what happened, but whether the rep's tactic worked.

Implementing Persistent Memory with Hindsight
The integration uses Hindsight as the primary vector memory layer. When a new call is ingested, the backend generates a serialized document string and retains it:

app/memory.py

async def retain_fact(self, fact: DealFact) -> None:
if self._client:
await self._client.aretain(
bank_id=self.settings.hindsight_bank_id,
content=fact.to_memory_document(),
context=f"deal_id={fact.deal_id};call_number={fact.call_number};fact_type={fact.fact_type}",
document_id=f"{fact.deal_id}-call-{fact.call_number}-{fact.fact_type}",
)
The magic happens during the pre-call briefing. Instead of just pulling files related to the company name, the orchestrator runs a cross-deal query to find patterns:

app/memory.py

async def recall_cross_deal_patterns(
self, deal_id: str, category: str, fact_type: str
) -> list[RecallMemory]:
# Query Hindsight for resolved objections in the same category from other deals
query = (
f"Resolved {fact_type} memories from other deals with category {category}. "
f"Exclude deal {deal_id} and prioritize tactics that worked."
)
memories = await self._recall(query)

# Filter to ensure we don't leak current deal info and only return resolved wins
return [
    m for m in memories
    if deal_id not in m.text and "resolved" in m.text.lower()
]
Enter fullscreen mode Exit fullscreen mode

This query is what enables the system's "learning" behavior. If a new company raises a blocker about IT bandwidth, Hindsight recalls that the sales team successfully bypassed this blocker in a previous contract by proposing a scoped pilot clinic rather than a broad launch.

Designing for Resilience and Bad Venue Environments
Network timeouts, API outages, or poorly formatted LLM outputs frequently break agentic applications. To ensure production-grade reliability, we built a three-stage fallback chain:

LLM Validation and Retry: The primary parser extracts facts using openai/gpt-oss-120b and validates them against Pydantic models. If the JSON is malformed, the system retries once with the fallback model qwen/qwen3-32b and a stricter formatting prompt.
Deterministic Regex Fallback: If the fallback LLM fails or times out, the backend invokes a regex-based keyword parser. It scans for terms like "annual", "quarterly", or "migration" and constructs a structured DealFact with default fields, preventing ingestion failure.
**Local Vector Fallback: **If the primary Hindsight Cloud endpoint goes offline or times out, the application falls back to a local memory store. This ensures the representative receives a cached timeline and basic briefings even during total network separation.

***Visualizing the Memory Payoff:* Frontend Design**

To build trust, the React user interface has a side-by-side Before/After Toggle showing what the briefing looks like "Without Memory" versus "With Memory".

Without Memory: Shows the generic advice a rep would get if they relied on standard CRM fields (e.g., "The deal is in Stage 3, follow up on pricing").
With Memory: Renders the specific timeline, lists active stakeholder risks, and shows the Hindsight-recalled tactic with direct references to the historical deals where it worked.
A loading delay is intentionally introduced when selecting a deal, displaying a "Recalling memory..." state. This micro-interaction demonstrates the real-time retrieval from the vector database, giving users clear feedback that the system is querying historical records.

Conclusion
By treating memory as a structured, queryable data store rather than a plain text repository, we can build agents that actively learn from historical wins. The Deal Intelligence Agent shows that combining Hindsight's flexible retain/recall system with fast LLMs can transform sales enablement from passive record-keeping into a dynamic playbook.

Top comments (0)