Build a Voice Support Agent (memory + routing + RAG)

Build a complete voice support agent on one database — caller memory, real-time skill routing, RAG-grounded spoken answers, an urgency model, and a semantic cache, all in SQL. The brain for any STT/TTS stack (Vapi, LiveKit, Twilio, Pipecat).

All recipes· voice-agents· 24 minutesadvancedsql
Instance: localhost:8080

Opens your running SynapCores (Build a Voice Support Agent (memory + routing + RAG) will be staged for a preview — nothing runs until you click Run). No instance yet? Install free in ~30s.

Share

Objective

A production voice support agent has to do everything at once, fast: recognize the caller and recall their history, route the spoken request to a skill in real time, answer from your knowledge base in short grounded sentences, score urgency to know when to escalate, and cache common answers to keep latency low. That's the whole voice cluster working together. Here you'll assemble it into one agent on one database — no vector store, no cache service, no model server, no graph DB. Your STT/TTS and telephony live outside; the support brain is the database. See Use it from your agent for wiring it into any voice stack.

Step 1: Create the caller memory (returning-caller recognition)

Per-caller history, embedded for recall on call-answer.

CREATE TABLE IF NOT EXISTS recipe_vsupport_memory (
  memory_id INTEGER PRIMARY KEY,
  caller_id TEXT,
  content   TEXT,
  embedding VECTOR(384)
);
INSERT INTO recipe_vsupport_memory (memory_id, caller_id, content) VALUES
 (1,'caller-5','Called last week about the app crashing on export; promised a fix.'),
 (2,'caller-5','Prefers to be called Sam; values quick, direct answers.'),
 (3,'caller-5','On the Pro plan, works from home, treats outages as urgent.');
UPDATE recipe_vsupport_memory SET embedding = EMBED(content);

Step 2: Create the skill router (real-time routing)

Skills the voice agent routes spoken requests to, embedded for meaning-based routing.

CREATE TABLE IF NOT EXISTS recipe_vsupport_skills (
  skill_id    INTEGER PRIMARY KEY,
  skill_name  TEXT,
  description TEXT,
  embedding   VECTOR(384)
);
INSERT INTO recipe_vsupport_skills (skill_id, skill_name, description) VALUES
 (1,'tech_support','The product is broken, crashing, erroring, or not working.'),
 (2,'billing_help','Questions about charges, invoices, declined cards, or refunds.'),
 (3,'account_access','Cannot log in, locked out, or needs a password reset.'),
 (4,'speak_to_human','Caller is upset or explicitly asks for a live agent.');
UPDATE recipe_vsupport_skills SET embedding = EMBED(description);

Step 3: Create the knowledge base (RAG for spoken answers)

Help content the agent grounds short spoken answers in.

CREATE TABLE IF NOT EXISTS recipe_vsupport_kb (
  chunk_id  INTEGER PRIMARY KEY,
  content   TEXT,
  embedding VECTOR(384)
);
INSERT INTO recipe_vsupport_kb (chunk_id, content) VALUES
 (1,'If the app crashes on export, update to the latest version and retry; the v4.2 patch fixes the export crash.'),
 (2,'To reset a password, use Forgot Password on the sign-in screen to get an email link.'),
 (3,'Refunds are issued within 14 days of purchase to the original payment method.'),
 (4,'Service status and incidents are posted at status.example.com.');
UPDATE recipe_vsupport_kb SET embedding = EMBED(content);

Step 4: Train an urgency model (when to escalate)

Learn which call signals mean "escalate to a human now."

CREATE TABLE IF NOT EXISTS recipe_vsupport_history (
  hist_id     INTEGER PRIMARY KEY,
  is_outage   INTEGER,                                -- 1 if service-down
  is_paying   INTEGER,
  frustration INTEGER,                                -- 0..1 scaled to int 0..10
  prior_calls INTEGER,
  escalate    INTEGER                                 -- label: 1 = hand to human
);
INSERT INTO recipe_vsupport_history
 (hist_id, is_outage, is_paying, frustration, prior_calls, escalate) VALUES
 (1,1,1,9,3,1),(2,0,0,2,0,0),(3,1,1,8,4,1),(4,0,1,3,1,0),
 (5,1,1,7,2,1),(6,0,0,1,0,0),(7,1,1,9,5,1),(8,0,1,4,1,0),
 (9,1,1,8,2,1),(10,0,0,2,0,0),(11,1,1,7,3,1),(12,0,1,3,1,0),
 (13,1,1,9,4,1),(14,0,0,1,0,0),(15,1,1,8,2,1),(16,0,1,4,1,0),
 (17,1,1,7,3,1),(18,0,0,2,0,0),(19,1,1,9,5,1),(20,0,1,3,1,0);
CREATE EXPERIMENT vsupport_escalate_exp AS
SELECT is_outage, is_paying, frustration, prior_calls, escalate AS target
FROM recipe_vsupport_history
WITH (
  task_type = 'binary_classification',
  target_column = 'target',
  optimization_metric = 'auc',
  algorithms = ['logistic_regression', 'random_forest', 'gradient_boosting'],
  validation_strategy = 'stratified_kfold',
  n_folds = 3,
  max_trials = 15
);
DEPLOY MODEL vsupport_escalate FROM EXPERIMENT vsupport_escalate_exp;

Step 5: Create the semantic answer cache (low latency)

Front common spoken answers so repeated questions skip the LLM.

CREATE TABLE IF NOT EXISTS recipe_vsupport_cache (
  cache_id  INTEGER PRIMARY KEY,
  question  TEXT,
  answer    TEXT,
  embedding VECTOR(384)
);
INSERT INTO recipe_vsupport_cache (cache_id, question, answer) VALUES
 (1,'How do I reset my password?','Use Forgot Password on the sign-in screen to get an email link.'),
 (2,'Is the service down?','Check status.example.com for current service status.');
UPDATE recipe_vsupport_cache SET embedding = EMBED(question);

Step 6: On answer, recall the returning caller's context

Sam calls back; recall the open crash issue and the preference for quick answers.

SELECT content,
       COSINE_SIMILARITY(embedding, EMBED('app crashing on export, prefers quick answers')) AS relevance
FROM recipe_vsupport_memory
WHERE caller_id = 'caller-5'
ORDER BY relevance DESC
LIMIT 2;

Step 7: Route the spoken request to a skill

Sam says the app keeps crashing — route to tech_support by meaning.

SELECT skill_name,
       COSINE_SIMILARITY(embedding, EMBED('the app keeps crashing when I try to export my report')) AS match_score
FROM recipe_vsupport_skills
ORDER BY match_score DESC
LIMIT 1;

Step 8: Try the cache, then answer from the knowledge base (RAG)

Check the cache for an instant hit; on a miss, retrieve the fix into a context row, then generate a short spoken answer from it.

CREATE TABLE IF NOT EXISTS recipe_vsupport_kb_top (
  chunk_id  INTEGER PRIMARY KEY,
  content   TEXT,
  relevance DOUBLE
);
INSERT INTO recipe_vsupport_kb_top (chunk_id, content, relevance)
SELECT chunk_id, content,
       COSINE_SIMILARITY(embedding, EMBED('app crashes on export, how to fix')) AS relevance
FROM recipe_vsupport_kb
ORDER BY relevance DESC
LIMIT 1;
SELECT GENERATE(
  'Answer in ONE short spoken sentence using ONLY the context. Context: ' || content ||
  ' Caller asked: The app crashes when I export, how do I fix it? Spoken answer:') AS spoken_answer
FROM recipe_vsupport_kb_top;

Step 9: Score urgency to decide on escalation

Sam is a paying customer, frustrated, with prior calls — does this call need a human?

SELECT AUTOML.PREDICT('vsupport_escalate', 0, 1, 8, 3) AS escalate_probability,
       CASE WHEN AUTOML.PREDICT('vsupport_escalate', 0, 1, 8, 3) >= 0.6
            THEN 'TRANSFER to human' ELSE 'CONTINUE with agent' END AS action;

Step 10: Generate a personalized closing line

Combine the recalled name + the resolution into a warm, efficient sign-off.

SELECT GENERATE(
  'Write a one-sentence spoken closing for a support call. Address the caller as Sam, ' ||
  'confirm the export-crash fix (update to v4.2), and offer to follow up. Be quick and warm.') AS closing;

Cleanup (Optional)

DROP TABLE IF EXISTS recipe_vsupport_memory;
DROP TABLE IF EXISTS recipe_vsupport_skills;
DROP TABLE IF EXISTS recipe_vsupport_kb;
DROP TABLE IF EXISTS recipe_vsupport_kb_top;
DROP TABLE IF EXISTS recipe_vsupport_history;
DROP TABLE IF EXISTS recipe_vsupport_cache;

Expected Outcomes

  • Step 6 recalls Sam's open export-crash issue and "prefers quick answers" on call-answer.
  • Step 7 routes "the app keeps crashing on export" to tech_support by meaning.
  • Step 8 returns one spoken sentence with the real fix (update to v4.2) — grounded, not improvised.
  • Step 9 scores high escalation probability for the frustrated paying caller and recommends TRANSFER to human.
  • Step 10 delivers a warm, personalized closing using Sam's name and the resolution.

You've built a complete voice support agent — caller memory, real-time routing, RAG-grounded spoken answers, urgency scoring, and a semantic cache — on one database.

Use it from your agent (framework-agnostic — the DB is the brain, the voice stack is swappable)

The voice support brain is just five tables + a model, all queried the same way, driven from any audio runtime:

  • REST / SDKPOST /v1/query/execute (any language), or @synapcores/sdk client.executeQuery(...). Per turn your runtime runs recall → route → cache/RAG → urgency → close (Steps 6–10) and pipes the spoken text to TTS, transferring to a human when the model says so. Drop it into Vapi, LiveKit Agents, Pipecat, Twilio, or Retell.
  • MCP (native, on by default) — point your voice runtime's MCP client at ws://<your-instance>/mcp?token=<jwt> (JWT from one POST /v1/auth/loginaccess_token). The query tool recalls/routes/answers/scores; the execute tool writes new caller memories and cache entries after the call — the whole support loop as tool calls.
  • Any framework — the identical brain powers a phone line, a browser voice agent, or a text support bot; swap the STT/TTS and transport, keep the database. The database is the brain; the framework (and the voice stack) is swappable.

Key Concepts Learned

  • A voice support agent composes caller memory, real-time routing, RAG, an urgency model, and a semantic cache.
  • One engine serves all of it — no separate vector store, cache, model server, or graph DB to run on the hot path.
  • Urgency scoring turns "should I transfer to a human?" into a defensible, learned decision.
  • Because it's plain data ops (SQL + AutoML / REST / MCP), the voice support agent works with any STT/TTS stack — the database-as-the-brain pattern the whole voice cluster builds toward.

Tags

voice-agentvoice-supportragskill-routingsemantic-cacheautomlmcp

Run this on your own machine

Install SynapCores Community Edition free, paste the SQL or Cypher above into the bundled web UI, and watch it run.

Download Free CE