Blog / How-to guides

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

bash
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

A question becomes cited items and a verdict: starting points are found by name, keyword and meaning, the graph is walked out from them, what was gathered is ranked, and every returned item is cited, with a verdict on whether the question is covered.A question in plainwordsStarting points:names, keywords,meaningWalk the graph outfrom themRank what was gatheredItems, each citedA verdict: grounded,related, or not

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:

bash
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 in uncovered, 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:

bash
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

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.

Related