Objective
A real support agent needs five things at once: it must remember the customer's past tickets, answer from your help docs (RAG), route the request to the right queue, score urgency, and understand how the customer relates to accounts and products. Teams usually stitch a vector store + a cache + a graph DB + a model server + glue to get there. Here you'll build the whole agent on one database, composing the building-block recipes from this cluster into a working support brain. The same brain drives any framework or a voice agent — see Use it from your agent at the end.
Step 1: Create the support knowledge base (for RAG)
Help-doc chunks the agent answers from, embedded for retrieval.
CREATE TABLE IF NOT EXISTS recipe_support_kb (
chunk_id INTEGER PRIMARY KEY,
source TEXT,
content TEXT,
embedding VECTOR(384)
);
INSERT INTO recipe_support_kb (chunk_id, source, content) VALUES
(1,'refunds.md','Refunds are available within 30 days of purchase to the original payment method.'),
(2,'login.md','If you are locked out, use Forgot Password on the sign-in page to reset via email.'),
(3,'billing.md','To update your card, go to Settings > Billing and edit the payment method.'),
(4,'outage.md','Service status and incident history are posted at status.example.com.'),
(5,'data.md','Export your data anytime from Settings > Privacy as a JSON download.');
UPDATE recipe_support_kb SET embedding = EMBED(content);
Step 2: Create the intent router (labeled examples)
A few examples per support intent so the agent can route by meaning.
CREATE TABLE IF NOT EXISTS recipe_support_intents (
example_id INTEGER PRIMARY KEY,
intent TEXT,
utterance TEXT,
embedding VECTOR(384)
);
INSERT INTO recipe_support_intents (example_id, intent, utterance) VALUES
(1,'billing','I was charged twice and need a refund.'),
(2,'billing','How do I update my credit card?'),
(3,'access','I can''t log in, I''m locked out.'),
(4,'access','Reset my password please.'),
(5,'outage','Is the service down right now?'),
(6,'outage','Everything is timing out for my whole team.');
UPDATE recipe_support_intents SET embedding = EMBED(utterance);
Step 3: Create the customer memory (past tickets)
Per-customer ticket history, embedded so the agent recalls relevant prior issues.
CREATE TABLE IF NOT EXISTS recipe_support_memory (
ticket_id INTEGER PRIMARY KEY,
customer_id TEXT,
summary TEXT,
embedding VECTOR(384)
);
INSERT INTO recipe_support_memory (ticket_id, customer_id, summary) VALUES
(1,'cust-7','Reported slow report exports; resolved by enabling pagination.'),
(2,'cust-7','Asked about upgrading to the Pro plan for more projects.'),
(3,'cust-7','Had trouble logging in after changing email; resolved via password reset.');
UPDATE recipe_support_memory SET embedding = EMBED(summary);
Step 4: Train a priority-scoring model (AutoML)
Learn which ticket features predict an urgent (P1) ticket from past resolutions.
CREATE TABLE IF NOT EXISTS recipe_support_history (
hist_id INTEGER PRIMARY KEY,
affects_team INTEGER, -- 1 if multiple users impacted
is_paying INTEGER, -- 1 if on a paid plan
mins_blocked INTEGER, -- minutes the user has been blocked
prior_tickets INTEGER, -- how many tickets this customer filed before
urgent INTEGER -- label: 1 = P1
);
INSERT INTO recipe_support_history
(hist_id, affects_team, is_paying, mins_blocked, prior_tickets, urgent) VALUES
(1,1,1,120,3,1),(2,0,0,5,0,0),(3,1,1,200,5,1),(4,0,1,15,1,0),
(5,1,1,90,2,1),(6,0,0,3,0,0),(7,1,1,150,4,1),(8,0,1,10,1,0),
(9,1,1,75,2,1),(10,0,0,8,0,0),(11,1,1,180,6,1),(12,0,1,20,1,0),
(13,1,1,110,3,1),(14,0,0,4,0,0),(15,1,1,140,5,1),(16,0,1,12,1,0),
(17,1,1,95,2,1),(18,0,0,6,0,0),(19,1,1,160,4,1),(20,0,1,18,1,0);
CREATE EXPERIMENT support_priority_exp AS
SELECT affects_team, is_paying, mins_blocked, prior_tickets, urgent AS target
FROM recipe_support_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 support_priority FROM EXPERIMENT support_priority_exp;
Step 5: Build the customer graph (relationships)
Who the customer is, the account they belong to, and the product they use — for relationship-aware handling.
MERGE (c:Customer {id: 'cust-7', name: 'Dana'})
MERGE (a:Account {id: 'acct-9', tier: 'Pro'})
MERGE (p:Product {name: 'Analytics'})
MERGE (c)-[:MEMBER_OF]->(a)
MERGE (a)-[:USES]->(p)
MERGE (c)-[:OPENED]->(t:Ticket {id: 'T-100', topic: 'login'});
Step 6: A ticket arrives — route it by intent
Classify the incoming message so it lands in the right queue.
SELECT intent, AVG(similarity) AS confidence
FROM (
SELECT intent,
COSINE_SIMILARITY(embedding, EMBED('my whole team is getting timeouts, nothing loads')) AS similarity
FROM recipe_support_intents
ORDER BY similarity DESC
LIMIT 4
)
GROUP BY intent
ORDER BY confidence DESC
LIMIT 1;
Step 7: Score the ticket's priority
Use the trained model to decide whether this is a P1 — team-wide outage, paying customer, long block.
SELECT AUTOML.PREDICT('support_priority', 1, 1, 130, 3) AS p1_probability;
Step 8: Recall the customer's relevant history
Pull the prior tickets that bear on this issue so the agent doesn't ask the customer to repeat themselves.
SELECT summary,
COSINE_SIMILARITY(embedding, EMBED('cannot access the service, timeouts and login trouble')) AS relevance
FROM recipe_support_memory
WHERE customer_id = 'cust-7'
ORDER BY relevance DESC
LIMIT 2;
Step 9: Answer from the help docs (RAG) with full context
Retrieve the right doc chunks into a context row, then generate a grounded reply that uses the customer's history.
CREATE TABLE IF NOT EXISTS recipe_support_top (
doc_id INTEGER PRIMARY KEY,
content TEXT,
relevance DOUBLE
);
INSERT INTO recipe_support_top (doc_id, content, relevance)
SELECT chunk_id, content,
COSINE_SIMILARITY(embedding, EMBED('service is timing out and I cannot log in')) AS relevance
FROM recipe_support_kb
ORDER BY relevance DESC
LIMIT 2;
CREATE TABLE IF NOT EXISTS recipe_support_ctx (id INTEGER PRIMARY KEY, context TEXT);
INSERT INTO recipe_support_ctx (id, context)
SELECT 1, GROUP_CONCAT(content, ' ') FROM recipe_support_top;
SELECT GENERATE(
'You are a support agent. Use ONLY the context to answer, and acknowledge the customer''s history. Context: ' ||
context ||
' Customer history: previously had login trouble resolved via password reset.' ||
' Question: The service is timing out and I cannot log in, what should I do? Answer:') AS reply
FROM recipe_support_ctx;
Step 10: Use the graph to escalate the right way
Check the customer's tier and product so escalation goes to the correct team.
MATCH (c:Customer {id: 'cust-7'})-[:MEMBER_OF]->(a:Account)-[:USES]->(p:Product)
RETURN c.name AS customer, a.tier AS tier, p.name AS product;
Cleanup (Optional)
DROP TABLE IF EXISTS recipe_support_kb;
DROP TABLE IF EXISTS recipe_support_intents;
DROP TABLE IF EXISTS recipe_support_memory;
DROP TABLE IF EXISTS recipe_support_history;
DROP TABLE IF EXISTS recipe_support_top;
DROP TABLE IF EXISTS recipe_support_ctx;
MATCH (n:Customer) DETACH DELETE n;
MATCH (n:Account) DETACH DELETE n;
MATCH (n:Product) DETACH DELETE n;
MATCH (n:Ticket) DETACH DELETE n;
Expected Outcomes
- Step 6 routes the team-wide timeout to the outage queue by meaning.
- Step 7 scores the ticket a high P1 probability — team impact + paying customer + long block.
- Step 8 recalls the customer's prior login/password-reset ticket, so the agent doesn't re-ask.
- Step 9 returns a grounded reply that cites the reset flow and acknowledges the history.
- Step 10 returns the customer's Pro tier and Analytics product, so escalation is routed correctly.
You've built a complete support agent — memory, RAG, intent routing, priority ML, and a customer graph — on one database, no five-service stack.
Use it from your agent (framework-agnostic — this is the whole point)
The support brain is just five tables/graphs + the same data ops, so any agent shell drives it with no framework lock-in:
- REST / SDK —
POST /v1/query/execute(any language), or@synapcores/sdkclient.executeQuery(...). Your agent runs route → score → recall → RAG → graph (Steps 6–10) per ticket and returns the reply + priority + escalation target. - MCP (native, on by default) — point any MCP client (Claude Code, Cursor, a custom loop, a voice runtime) at
ws://<your-instance>/mcp?token=<jwt>(JWT from onePOST /v1/auth/login→access_token). Thequerytool runs routing/scoring/RAG; theexecutetool runs Cypher for the graph and writes new ticket memories — the whole support loop as tool calls. - Any framework — OpenClaw, a LangGraph support workflow, a custom loop, or a voice support line all call the same brain; the channel changes, the database doesn't. The database is the brain; the framework is swappable.
Key Concepts Learned
- A complete agent is a composition of the building blocks: memory + RAG + routing + ML scoring + graph.
- One engine serves all five surfaces, so there's no five-service stack to operate or keep in sync.
- The brain is channel-agnostic: the same queries power a web widget, a Slack bot, or a voice line.
- Because it's plain data ops (SQL + Cypher + AutoML / REST / MCP), the support agent works from any framework — the agent-agnostic backend pattern this cluster builds on.