Skip to content

Neuro-Symbolic RAG

HyperMesh ships a verifiable Retrieval-Augmented Generation pipeline. On top of hypergraph retrieval it adds a deterministic, LLM-free reasoning stratum and a hallucination firewall, so every factual sentence the model returns is backed by a machine-checked proof that bottoms out in real stored hyperedges.

retrieve → reason → prove → generate (LLM) → firewall
(rules) (proof) (gate)

This section documents the feature end to end — concepts, every public function, the REST surface, and a runnable case study.

PageWhat it covers
Rules & rule storeRule schema, base predicates, safety, stratification, RuleStore
Reasoning enginefacts_from_edges, FactBase, SymbolicReasoner, stratify
Proofs & firewallbuild_proof, ProofTree, HallucinationFirewall
Pipeline, modes & LLMsRAGPipeline, RAGResult, LLMConfig, pluggable models
Python API referenceEvery public class & function, with signatures
REST API/v1/rules*, /v1/reason, /v1/rag/query
Case study (AML)Runnable, offline, end-to-end walkthrough

Ordinary RAG retrieves some text, stuffs it in a prompt, and hopes the model stays faithful. In regulated and high-stakes settings (finance, security, healthcare, defense) “hope” is not a control. Two failures keep RAG out of production:

  • Hallucination — the model asserts things the sources don’t support.
  • No audit trail — even when the answer is right, you can’t prove why.

HyperMesh closes both. It separates what is true (a deterministic symbolic proof over your data and your policy) from how it’s phrased (the LLM). The model is reduced to a writer that may only repeat what was already proven; the firewall enforces it.

Every factual sentence the user sees cites a tag (HEDGE-N / RULE-N / STEP-N) that exists in a machine-checked proof whose leaves are real stored hyperedges. Sentences that don’t are stripped; if proof is required and nothing was proved, the system abstains — it never guesses.

This holds regardless of which LLM you plug in, so a cheap or local model is safe to deploy behind the firewall.

Ordinary RAGHyperMesh verifiable RAG
Groundingprompt-only, best-effortenforced post-generation against a proof
Reasoninginside the LLM (opaque)explicit, deterministic, auditable rules
Output on weak evidenceconfident guessstrip unsupported claims / abstain
Explainabilitycitations, maybea proof DAG down to source hyperedges
Determinismnonesymbolic core is reproducible
  • Retrieve — pull the relevant hyperedges for the query (members, formation, weight, timestamp) using the standard HyperGraphRetriever.
  • Reason — forward-chain over facts derived from those hyperedges, using your rule base. Pure, deterministic, no model required.
  • Prove — each derived fact carries a proof tree whose leaves are bound to concrete hyperedges (HEDGE-N, verified: true).
  • Generate — the LLM is shown the proven facts (STEP-N / RULE-N) first and must cite them.
  • Firewall — any answer sentence that cites nothing in the proof/evidence set is stripped; with require_proof the pipeline abstains outright when nothing was proved.
  • symbolic — compliance/audit jobs where you need provable facts and no generative text at all. No LLM is called.
  • hybrid — user-facing answers that must read naturally and be provably grounded. This is the default for a product surface.
  • neuro — exploratory Q&A where guarantees aren’t required (classic RAG; no reasoning).

The reasoner does not build a separate graph. It reads the same hyperedges your ingestion pipeline produced. Each retrieved hyperedge E is projected into base facts — hyperedge(E), formation(E, F), weight(E, W), at(E, Ts), member(E, A), member_type(A, T) — and rules reason over exactly those. Proof leaves point back to the originating edge_idx, so explainability is in continuity with your stored data, not a parallel model of it.

import hypermesh as hm
from hypermesh.rag import RAGPipeline, LLMConfig
db = hm.connect("data/")
rule = {
"id": "rule:coordinated_threat",
"if": [
{"pred": "member", "args": ["?E", "?A"]},
{"pred": "member_type", "args": ["?A", "drone"]},
{"pred": "weight", "args": ["?E", "?W"]},
{"compare": ["?W", ">=", 0.8]},
],
"then": {"pred": "coordinated_threat", "args": ["?E"], "confidence": 0.95},
}
pipe = RAGPipeline(
db, table="DRONES",
mode="hybrid", # neuro | symbolic | hybrid
require_proof=True, # abstain unless something is proved
rules=[rule], # or persist them in the rule store
llm_config=LLMConfig.mock(), # deterministic, offline; swap for any model
)
result = await pipe.query("which edges are coordinated threats?")
print(result.answer)
for f in result.derived_facts:
print(f["fact"], f["confidence"], f["rule_tag"])
print(result.proofs[0]) # proof DAG with verified leaves
print(result.firewall) # {outcome, abstained, coverage, ...}

Continue with Rules & rule store, or jump to the runnable AML case study.