惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

www.infosecurity-magazine.com
www.infosecurity-magazine.com
D
DataBreaches.Net
T
Tailwind CSS Blog
M
MIT News - Artificial intelligence
Stack Overflow Blog
Stack Overflow Blog
F
Full Disclosure
V2EX - 技术
V2EX - 技术
N
News and Events Feed by Topic
Help Net Security
Help Net Security
L
LangChain Blog
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Google Online Security Blog
Google Online Security Blog
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
B
Blog RSS Feed
N
Netflix TechBlog - Medium
N
News | PayPal Newsroom
TaoSecurity Blog
TaoSecurity Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Vulnerabilities – Threatpost
B
Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园_首页
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AI
AI
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyberwarzone
Cyberwarzone
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
G
GRAHAM CLULEY
Vercel News
Vercel News
罗磊的独立博客
MyScale Blog
MyScale Blog
Last Week in AI
Last Week in AI
博客园 - 司徒正美
C
CERT Recently Published Vulnerability Notes
GbyAI
GbyAI
Scott Helme
Scott Helme
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
A
About on SuperTechFans
P
Privacy International News Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
5 prospects, 20 past interactions, one agent that knew all of it before the call started.
Suhail Tambo · 2026-05-19 · via DEV Community

**

I Threw Away the Database and Let Hindsight Remember Everything

**

The first thing most developers do when they start a new project is spin up a database. Postgres, SQLite, whatever — you create a schema, define your tables, and build your data model before you write a single line of business logic. I've done it a hundred times.

For SalesMemory, we didn't. Not because we were being clever. Because once we understood what we were actually building, a relational database was the wrong tool for the job.

Here's what we built: a persistent, agent memory layer for sales reps. Before a call, the rep types a prospect name and gets a structured brief — objections raised, budget signals, competitor mentions, deal health score — synthesised from every past interaction. After the call, they log 2–3 sentences. The agent stores it permanently. Every future brief gets smarter because of it.

The technology making this possible is Hindsight, an agent memory system built by Vectorize that handles retain, recall, and reflect across sessions. Without it, the agent forgets everything the moment a session ends. With it, the agent compounds intelligence over time.

But the more interesting story isn't "we used a memory layer." It's what happens when you commit to that memory layer as your only persistence layer — and what you give up and gain when you do.

**

The Problem We Were Actually Solving

**

Sales reps talk to the same prospects across weeks and months. The context from those conversations — objections raised, budget signals, competitor comparisons, personal details — lives in CRM notes nobody reads, or only in the rep's head.

Every call without memory is a wasted opportunity. The rep re-introduces themselves. They miss that the prospect already said budget is frozen until Q3. They forget that onboarding speed was the deal-breaker last time.

Our product fixes that with one lookup before the call and one note after.

The thing is: this problem doesn't fit neatly into a relational schema. Prospect data isn't structured. A rep logs "she seemed unsure about the onboarding" — not {objection_type: "onboarding", sentiment: "negative", confidence: 0.7}. You can't schema-design your way to capturing what a sales conversation actually contains.

**

The Architecture: One Persistence Layer

**

Most developers would immediately reach for Postgres. We deliberately didn't.

Hindsight is the only persistence layer in SalesMemory. There is no database. Every call log goes into Hindsight via client.retain(). Every pre-call brief is generated by feeding recalled Hindsight memory into the LLM. The entire interaction history lives in semantic memory, not rows.

Here's what storing an interaction looks like:

python
def retain_interaction(prospect_name: str, summary: str, outcome: str, timestamp: str):
    content = f"""
Prospect: {prospect_name}
Date: {timestamp}
Outcome: {outcome}
Summary: {summary}
"""
    client.retain(
        pipeline_id=PIPELINE_ID,
        content=content,
        metadata={
            "prospect": prospect_name,
            "outcome": outcome,
            "timestamp": timestamp,
            "type": "call_log"
        }
    )

Enter fullscreen mode Exit fullscreen mode

And recalling it before a call:

python
def recall_prospect(prospect_name: str) -> str:
    results = client.recall(
        pipeline_id=PIPELINE_ID,
        query=f"prospect interactions with {prospect_name}",
        top_k=10
    )
    return results

Enter fullscreen mode Exit fullscreen mode

That's the entire data layer. No ORM. No migrations. No schema versioning. No connection pooling. No ALTER TABLE when the product changes.

The tradeoff is real: you can't do SELECT COUNT(*) FROM deals WHERE stage = 'closing'. You can't run SQL aggregations across your prospect base. If you need that kind of reporting, you need a database.

What you gain is something SQL can never give you: semantic retrieval. When we query Hindsight with "prospect interactions with Priya Sharma", it returns contextually relevant memories — not just exact-match rows. A rep who logged "she pushed back on timing" and another who wrote "onboarding timeline is a concern" both surface for the same query. Hindsight understands meaning, not keywords.

**

The Deal Health Score: Computed, Not Stored

**

Here's the design decision I find most interesting.

Every pre-call brief includes a Deal Health Score from 0–100. It's one of the features users notice immediately — they want to know if a deal is improving or stalling before they pick up the phone.

We don't store this score anywhere.

There is no deals table with a health_score column. No score recalculation job. No stale data problem. The score is computed fresh on every brief request by feeding all recalled memory into the LLM with a specific scoring rubric:

python
BRIEF_SYSTEM_PROMPT = """
You are a sales intelligence assistant. You read raw memory from past prospect
interactions and return a structured JSON pre-call brief for a sales rep.

Deal health scoring guide:
- 0-20: Cold. No engagement, no signals, or long silence.
- 21-40: Warming up. Early interest but objections unresolved.
- 41-60: Engaged. Active conversations, some positive signals.
- 61-80: Hot. Strong signals, near decision stage.
- 81-100: Closing. Verbal commitment or trial agreed.

Return ONLY valid JSON. No explanation. No markdown. No code fences.

Enter fullscreen mode Exit fullscreen mode

The LLM returns a structured object: score, label (Cold / Warming up / Engaged / Hot / At risk), momentum (improving / stalling / declining), risk (single biggest risk in plain English), recommended_action, and confidence (based on how much memory exists).

Critically: the score automatically improves as more memory accumulates. After one interaction, confidence is low and the score reflects limited data. After four interactions, the LLM has seen objections, resolutions, competitor mentions, and deal progression — and the score reflects that. No developer had to build a recalculation system. It just works because the memory compounds.

Here's a real example. Priya Sharma, VP Sales at Rentokil, after four logged interactions:

Score: 70/100
Label: Engaged
Momentum: ↑ Improving
Risk: "Data migration concerns may stall the deal"
Recommended action: "Provide a detailed data migration plan and timeline"
Confidence: Medium

Enter fullscreen mode Exit fullscreen mode

Compare that to what the brief looks like for a prospect with zero interactions: "No prior context found. Approach as a first contact." Same system, same code — the intelligence difference is entirely a function of accumulated memory.

The Weekly Digest: One Prompt, Five Prospects

The digest endpoint does something non-obvious.

Instead of making five separate recall calls and then trying to merge and compare the results, we pull memory for all prospects in a single pass, build one large prompt containing all contexts, and ask the LLM to categorise and prioritise everything simultaneously:

python
async def generate_digest() -> dict:
    all_prospects = get_all_prospects()
    prospect_contexts = []

    for name in all_prospects:
        recalled = recall_prospect(name)
        if recalled:
            prospect_contexts.append({"name": name, "context": recalled})

    prompt = build_digest_prompt(prospect_contexts)
    response = groq_client.chat.completions.create(
        model="llama-3.3-70b-versatile",
        messages=[
            {"role": "system", "content": DIGEST_SYSTEM_PROMPT},
            {"role": "user", "content": prompt}
        ],
        temperature=0.3,
        max_tokens=1200
    )
    return json.loads(response.choices[0].message.content.strip())

Enter fullscreen mode Exit fullscreen mode

The LLM returns a prioritised action plan sorted into three buckets: 🔴 Needs attention now, 🟡 Follow up this week, 🟢 On track.

action plan

Why one call instead of five? The LLM reasons better when it can compare prospects it can see simultaneously. James Okafor hasn't responded in seven days after we sent him a security report — that surfaces as "needs attention now" because the LLM can see both that there's been recent positive momentum and that the silence is abnormal relative to his prior cadence. Five separate calls wouldn't give it that context.

It also cuts latency by roughly 4x and eliminates a merge step that would require its own logic to get right.

What This Taught Us

Semantic memory is not keyword search. The difference matters when reps log notes informally. "She pushed back on timing" and "onboarding timeline is a concern" both surface for the same recall query because Hindsight retrieves by meaning, not string match. This makes the system usable in the way humans actually communicate.

The prompt is the product. The quality of the deal health score is entirely determined by the scoring rubric in the system prompt. Vague instructions ("rate this deal") produce vague, inconsistent scores. Specific rubrics with deduction/addition logic produce scores that match human intuition. We spent more time on the scoring prompt than on any other single piece of code.

Metadata is what makes retrieval trustworthy. Storing {"prospect": name, "outcome": outcome, "timestamp": timestamp} alongside the content means the memory timeline filters by prospect reliably. Without metadata, you're doing full semantic search on everything and hoping the right things surface. The structure you add at storage time is what you get back at retrieval time.

One LLM call beats five. We initially prototyped the digest as five separate calls with a merge step. The output was coherent per-prospect but missed cross-prospect comparisons the LLM could make when it saw everything at once. Collapsing to one call improved output quality, cut latency, and simplified the code.

The "no CRM update required" framing is what makes it sell. Every salesperson has been told to keep the CRM updated. Nobody does. Our system works with informal, unstructured notes because Hindsight stores and recalls semantic meaning, not structured fields. "She seemed unsure about the onboarding" is valid input. The bar for logging is low enough that reps actually use it.

**

What We'd Do Differently

**

The no-database choice works for the workflows we built. It would break immediately if we needed aggregate reporting — total deal value by stage, close rate by rep, pipeline velocity. For a production system serving a real sales team, you'd probably want Hindsight as the semantic memory layer alongside a lightweight analytics store for structured metrics. They're not mutually exclusive.

The scoring prompt also needs human calibration at scale. Our rubric produces sensible scores for the five prospects we tested it against. Whether it holds across fifty different industries, deal sizes, and sales styles is an open question.

The thing that surprised me most building this: the memory layer isn't a feature. It's the entire product. Without persistent memory across sessions, every brief is generic and every digest is meaningless. With it, the agent genuinely gets smarter over time in the way a good sales manager does — by remembering what happened and reasoning about what it means.


That's the gap SalesMemory fills. Not smarter AI. Just AI that remembers.

Check out the Hindsight documentation if you want to build something similar — the Python SDK is straightforward and the retain/recall pattern maps cleanly to most agent use cases.