Semantic Tool Routing (function-calling without a framework)

Route an AI agent's request to the right tool by meaning — semantic function-calling with vector embeddings in plain SQL, no framework, no brittle keyword rules. Works with Claude Code, OpenClaw, LangChain, or a voice agent.

All recipes· agents· 12 minutesintermediateen
Instance: localhost:8080

Opens your running SynapCores (Semantic Tool Routing (function-calling without a framework) will be staged for a preview — nothing runs until you click Run). No instance yet? Install free in ~30s.

Share

Objective

When a user says "I can't log in," the agent has to pick the right tool — reset_password, not cancel_subscription. Hard-coded keyword routers break the moment someone phrases it differently, and full LLM function-calling is slow and costly for every turn. Here you'll route by meaning: store each tool's description as an embedding, match the user's request to the nearest tool with one query, and confirm with a confidence gate. No framework, no rules engine. The same router works from any framework or a voice agent — see Use it from your agent at the end.

Step 1: Create the tool registry

Each row is a tool the agent can call, described in natural language and embedded for matching.

CREATE TABLE IF NOT EXISTS recipe_agent_tools (
  tool_id     INTEGER PRIMARY KEY,
  tool_name   TEXT,                                  -- the function the agent would invoke
  description TEXT,                                  -- what the tool does, in plain language
  embedding   VECTOR(384)
);

Step 2: Register the agent's tools

A realistic toolbox for a SaaS support agent.

INSERT INTO recipe_agent_tools (tool_id, tool_name, description) VALUES
 (1,'reset_password','Reset or recover a user account password; help when a user cannot log in or is locked out.'),
 (2,'cancel_subscription','Cancel a paid subscription or stop recurring billing for the account.'),
 (3,'check_order_status','Look up the shipping status and delivery estimate of an existing order.'),
 (4,'update_billing','Update the credit card or billing address on file for the account.'),
 (5,'create_support_ticket','Open a support ticket for a problem that needs a human agent.'),
 (6,'check_usage','Report the account''s current API usage and remaining quota for the month.');

Step 3: Embed the tool descriptions

The embedding model runs in-database; this is the index the router searches.

UPDATE recipe_agent_tools SET embedding = EMBED(description);

Step 4: Route a request to the best tool

Match the user's message to the nearest tool by meaning — no shared keywords required.

SELECT tool_name, description,
       COSINE_SIMILARITY(embedding, EMBED('I keep getting locked out and can''t sign in')) AS match_score
FROM recipe_agent_tools
ORDER BY match_score DESC
LIMIT 3;

Step 5: Pick the single tool to call, with a confidence gate

Return the top tool only when it clears a confidence threshold — otherwise the agent should ask a clarifying question.

SELECT tool_name, match_score,
       CASE WHEN match_score >= 0.35 THEN 'CALL' ELSE 'ASK_CLARIFY' END AS decision
FROM (
  SELECT tool_name,
         COSINE_SIMILARITY(embedding, EMBED('I want to stop being charged every month')) AS match_score
  FROM recipe_agent_tools
  ORDER BY match_score DESC
  LIMIT 1
);

Step 6: Route an ambiguous request and let the gate catch it

A vague message scores low against every tool, so the gate routes to clarification instead of guessing.

SELECT tool_name, match_score,
       CASE WHEN match_score >= 0.35 THEN 'CALL' ELSE 'ASK_CLARIFY' END AS decision
FROM (
  SELECT tool_name,
         COSINE_SIMILARITY(embedding, EMBED('hey, quick question about my thing')) AS match_score
  FROM recipe_agent_tools
  ORDER BY match_score DESC
  LIMIT 1
);

Cleanup (Optional)

DROP TABLE IF EXISTS recipe_agent_tools;

Expected Outcomes

  • Step 4 ranks reset_password first for "locked out / can't sign in" — by meaning, with no keyword overlap.
  • Step 5 returns cancel_subscription with a CALL decision for "stop being charged."
  • Step 6 returns ASK_CLARIFY for the vague message, because no tool clears the confidence gate.

You now have a semantic function-router: requests map to the right tool by meaning, with a built-in "ask first when unsure" guardrail — no framework and no keyword rules.

Use it from your agent (framework-agnostic — this is the whole point)

The router is just a tool table + one match query, so any agent uses it with no framework lock-in:

  • REST / SDKPOST /v1/query/execute (any language), or @synapcores/sdk client.executeQuery(...). Before each action, your agent runs the Step-5 query, reads tool_name + decision, and either invokes that function or asks a clarifying question.
  • 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 one POST /v1/auth/loginaccess_token). The query tool returns the routed tool name; your agent maps that to its real function call — semantic routing without a routing framework.
  • Any framework — OpenClaw, LangChain's tool/agent executors, a custom loop, or a voice agent all use the same registry to decide which tool to fire. The database is the brain; the framework is swappable.

Key Concepts Learned

  • Embedding tool descriptions turns "which function?" into a nearest-neighbor search — robust to phrasing.
  • A confidence threshold on the top match gives a free "ask before acting" guardrail.
  • This is function-calling without a framework: the registry lives in SQL and any agent queries it.
  • Because it's plain data ops (SQL / REST / MCP), semantic routing works for any agent — the agent-agnostic backend pattern this cluster builds on.

Tags

ai-agenttool-routingfunction-callingsemantic-routingvectorembeddingsmcp

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