Objective
Agents reason far better over a graph of entities and relationships than over a wall of raw
text — but building that graph by hand doesn't scale. Here you'll turn unstructured notes into
a knowledge graph automatically: use GENERATE() to extract the entities and relations from
text, then store them as a Cypher graph the agent can query for multi-hop answers. One engine
does the extraction and the storage — no NLP pipeline, no separate graph DB. The same graph
works from any framework or a voice agent — see Use it from your agent at the end.
Step 1: Create a staging table for raw text
Drop the unstructured notes the agent has collected — meeting notes, emails, docs.
CREATE TABLE IF NOT EXISTS recipe_kg_text (
doc_id INTEGER PRIMARY KEY,
content TEXT
);
Step 2: Load the raw text
A few sentences of company knowledge an agent would otherwise have to re-read every time.
INSERT INTO recipe_kg_text (doc_id, content) VALUES
(1,'Acme Corp acquired Beta Labs in 2025. Beta Labs builds the Pulse analytics product.'),
(2,'Jane Doe is the CEO of Acme Corp. She previously founded Beta Labs.'),
(3,'The Pulse product integrates with the Acme billing platform.');
Step 3: Use GENERATE to extract entities and relations
Ask the model to read each document and return relationship triples — the raw material of a graph.
SELECT doc_id,
GENERATE('Extract relationships from this text as a list of "Entity -> RELATION -> Entity" triples, one per line, using only entities named in the text. Text: ' || content) AS triples
FROM recipe_kg_text
ORDER BY doc_id;
Step 4: Build the knowledge graph (Cypher)
Materialize the extracted entities and relationships as graph nodes and edges the agent can traverse.
MERGE (acme:Company {name: 'Acme Corp'})
MERGE (beta:Company {name: 'Beta Labs'})
MERGE (pulse:Product {name: 'Pulse'})
MERGE (billing:Product {name: 'Acme Billing'})
MERGE (jane:Person {name: 'Jane Doe'})
MERGE (acme)-[:ACQUIRED]->(beta)
MERGE (beta)-[:BUILDS]->(pulse)
MERGE (jane)-[:CEO_OF]->(acme)
MERGE (jane)-[:FOUNDED]->(beta)
MERGE (pulse)-[:INTEGRATES_WITH]->(billing);
Step 5: Query the graph for a direct fact
Ask the graph what an agent would need to know — who leads the company that acquired Beta Labs?
MATCH (p:Person)-[:CEO_OF]->(c:Company)-[:ACQUIRED]->(target:Company {name: 'Beta Labs'})
RETURN p.name AS leader, c.name AS acquirer, target.name AS acquired;
Step 6: Multi-hop reasoning the raw text couldn't give directly
Connect the CEO to a product through two relationships — a fact never stated in a single sentence.
MATCH (p:Person {name: 'Jane Doe'})-[:FOUNDED]->(c:Company)-[:BUILDS]->(prod:Product)
RETURN p.name AS person, c.name AS company, prod.name AS product_they_enabled;
Step 7: Ground a natural-language answer in a graph fact
Pull a fact from the graph and let GENERATE() phrase it for the user.
SELECT GENERATE('Phrase this fact as a one-sentence answer for a user: Jane Doe founded Beta Labs, which builds the Pulse product.') AS answer;
Cleanup (Optional)
DROP TABLE IF EXISTS recipe_kg_text;
MATCH (n:Company) DETACH DELETE n;
MATCH (n:Product) DETACH DELETE n;
MATCH (n:Person) DETACH DELETE n;
Expected Outcomes
- Step 3 returns relationship triples (e.g. "Acme Corp -> ACQUIRED -> Beta Labs") extracted straight from the text by
GENERATE(). - Step 5 answers "Jane Doe leads Acme Corp, which acquired Beta Labs" — a fact assembled from the graph.
- Step 6 connects Jane Doe to the Pulse product across two hops — knowledge never written in one sentence.
- Step 7 returns a clean natural-language answer grounded in the graph fact.
You now have a pipeline that turns plain text into a queryable knowledge graph an agent can reason over — extraction and storage in one engine.
Use it from your agent (framework-agnostic — this is the whole point)
Graph construction is just GENERATE for extraction + Cypher for storage, so any agent uses it with no framework lock-in:
- REST / SDK —
POST /v1/query/execute(any language), or@synapcores/sdkclient.executeQuery(...). Your agent ingests text, runs the Step-3 extraction, writes the triples asMERGEstatements (Step 4), then queries the graph for answers. - 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 the extractionGENERATE; theexecutetool writes the Cypher graph and runs the walks — "learn this document" becomes tool calls, no graph framework required. - Any framework — OpenClaw, LangChain / LlamaIndex graph builders, a custom loop, or a voice agent all populate and query the same graph. The database is the brain; the framework is swappable.
Key Concepts Learned
GENERATE()can extract entities and relationship triples from unstructured text — the hard part of graph-building.- Cypher
MERGEmaterializes those triples as a graph the agent can traverse for multi-hop answers. - A graph encodes facts that never appear in a single sentence — the agent reasons across hops instead of re-reading text.
- Because it's plain data ops (GENERATE + Cypher / REST / MCP), text-to-graph works for any agent — the agent-agnostic backend pattern this cluster builds on.