Graph RAG that says when it does not know: context that is cited, grounded, or refused
12 October 2026 · Semurg · 4 min read · Markdown
Verified: every command below ran on a fresh node of r11.78.20261012.bc0d94f (how)
graph-ragragmemoryagentscitations
Retrieval for an agent has two jobs: find what the store knows about a question, and say honestly when it does not know. Most retrieval stacks do the first with a vector search and leave the second to the model, which then answers anyway. Semurg's memory_context does both: it gathers the facts and passages around a question from several directions at once, cites each one, and says which words of your question the store holds nothing about.
Store something to ask about
export SEMURG_API_TOKEN=<your token>
curl -sS http://localhost:4000/v1/memory/remember \
-H "Authorization: Bearer $SEMURG_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"scope": "rag-intro", "source": "support ticket 4471",
"facts": {"entities": [{"name": "Northwind Retail", "type": "Company"},
{"name": "Invoice export", "type": "Feature"}],
"relations": [{"source": "Northwind Retail", "target": "Invoice export", "type": "REPORTED_BUG_IN"}]},
"passages": [{"text": "Northwind Retail reports that the invoice export drops the currency column for orders in euros.",
"mentions": ["Northwind Retail", "Invoice export"]}]}'Expected: the facts and the passage are stored
Ask a question
memory_context takes a question in plain words. It first finds where to start: the names the question mentions, exact and close spellings, the kinds of thing it asks about, the keywords it shares with stored passages, and its meaning where an embedding model is installed. Then it walks the graph out from those starting points, up to three steps. It ranks what it gathered and returns the best of it, each item cited:
export SEMURG_API_TOKEN=<your token>
curl -sS http://localhost:4000/v1/memory/context \
-H "Authorization: Bearer $SEMURG_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"scope": "rag-intro", "query": "What does Northwind Retail report about the invoice export?", "k": 8, "hops": 2}'Expected: the passage about the currency column comes back, cited, and the verdict is grounded
The verdict, and what it does and does not mean
Every answer carries grounding.state, so an agent can tell a covered question from an uncovered one before it writes a word:
grounded: every content word of your question is covered by what came back, and at least one item can be cited.related: at least one content word of your question is covered by nothing that came back; the reply lists those words inuncovered, with the stored names that did match.uncited: something matched, but nothing it can cite.nothing_stored: nothing in this scope matches.could_not_judge: a stage could not run, and the answer names which.
Now ask about something the store holds nothing on, the export's deadline, and the verdict says so:
export SEMURG_API_TOKEN=<your token>
curl -sS http://localhost:4000/v1/memory/context \
-H "Authorization: Bearer $SEMURG_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"scope": "rag-intro", "query": "What does Northwind Retail report about the invoice export deadline?", "k": 8, "hops": 2}'Expected: the verdict is related, and it names "deadline" as the word nothing stored covers
Nothing stored mentions a deadline, so the verdict says related and names the word, while the rest of the question is still covered. That is the point of the verdict: it tells an agent which part of the question the store cannot speak to. It is a check on your question's words, not proof that an answer is right, so read the cited items before you answer from them.
What it does not do yet
- Search by meaning on a node without an embedding model, for example a node run in Docker without one installed: it then finds by name, keyword and the graph only, and says so.
- Answer as of a past date.
- We do not yet publish a measured grounded-answer rate: it appears here, linked to its release gate row, once a published release measures it.
Next
- A knowledge graph your agents build as they work: how the graph this walks is built.
- Give your agent persistent memory with MCP in five minutes: the same calls over MCP.
How these commands were checked
Our test farm ran each of the 5 command blocks marked runnable, exactly as written, with the answer checked against the expectation printed under it, against a fresh node of the published release r11.78.20261012.bc0d94f. A post is published only when every one of them passed there.