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:

  1. Ingest every inbound lead (missed-call log, web form, voicemail transcript) into CRDB
  2. Classify urgency/intent with Gemini (emergency / booking / quote / spam) — the classification, confidence, and reasoning are STORED, not recomputed
  3. 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
  4. Route: emergencies escalate, bookings propose slots, and every action is journaled with an audit trail in CRDB
  5. 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
Share this project:

Updates

Submission history