The problem: agents forget, businesses lose leads
Home-service businesses (HVAC, plumbing, electrical, roofing) lose 25-40% of inbound leads to missed calls and slow responses. Every existing "solution" — shared inboxes, spreadsheets, CRM notes — is stateless. When a lead calls back a week later, nobody remembers the context. When the owner checks on a customer, the history is gone.
Agents need memory the way businesses do: durable, queryable, and global.
What it does
CallbackOps is a lead-recovery agent with CockroachDB as its persistent memory:
- Ingest every inbound lead (missed-call log, web form, voicemail transcript) into CRDB
- Classify urgency/intent with Gemini (emergency / booking / quote / spam) — the classification, confidence, and reasoning are STORED, not recomputed
- Recall: when a lead contacts again — any channel, any time later — the agent retrieves the full interaction history + embedding similarity to past leads in milliseconds
- Route: emergencies escalate, bookings propose slots, and every action is journaled with an audit trail in CRDB
- Report: daily owner report generated from the durable event log
The memory is the product: leads, conversations, embeddings (pgvector-compatible), and an append-only event log — all in one CRDB database that survives restarts, scales globally, and gives the business a single source of truth.
How we built it
- CockroachDB schema:
leads(with 384-dim vector column),events(append-only audit log),agent_state— designed for serializable, region-survivable consistency - Semantic recall: new leads are matched against historical leads by cosine similarity ("Sarah's neighbor" retrieves "Sarah Mitchell's job from March") — verified working
- Gemini 3.5 Flash for classification via the official google-genai SDK with a REST fallback chain; all outputs persisted to CRDB with confidence scores
- Two CRDB tools used: the database as agentic memory (vector + relational) and event-sourced state that any agent process can resume from — stateless compute, durable memory
- Python, zero external services beyond CRDB + Gemini
Challenges we ran into
- ORM layers don't expose CRDB's vector capabilities well — we dropped to raw SQL with parameterized queries for the vector paths
- Making the recall demo honest: we seed real lead histories and query live, no mock outputs
- Keeping the agent process stateless — all context lives in CRDB, so any restart resumes exactly where it left off
Accomplishments
- Semantic recall verified end-to-end: similarity queries return the right historical leads
- 12/12 benchmark leads classified at 0.95+ confidence with every decision journaled
- One database serves OLTP (lead writes), vector search (recall), and event sourcing (audit) simultaneously
What we learned
- "Agentic memory" is less about storing everything and more about retrieval shape: what the agent needs in context at decision time
- CRDB's serializable transactions remove a whole class of "who called first" race conditions that plague lead-routing systems
What's next
- Multi-region deployment: San Diego today, any region tomorrow, with no application changes
- Dormant-lead resurrection: nightly CRDB jobs surface 6-24 month-old leads for re-engagement
- Spanish-language support for San Diego's bilingual market
Built With
- cockroachdb
- google-cloud-run
- google-gemini-3.5-flash
- opensearch
- python
- strands-sdk
Log in or sign up for Devpost to join the conversation.