RAGBrain
The Open-Source Bi-Temporal RAG Framework for AI Agents. Prove what your AI knew, and when.
RAGBrain is a long-term memory and retrieval layer for LLM agents. It pairs retrieval-augmented generation with a temporal knowledge graph, so an agent can answer what is true now, what was true on any past date, and what the system believed at a past moment before a correction arrived.
Any document in, a cited and temporally-correct answer out, plus the capability the rest of the field lacks: replay what the system believed at any past moment, without leaking later corrections into the past.
agent memory · LLM long-term memory · temporal knowledge graph · point-in-time queries
· GraphRAG · vector search · grounded answers · provenance and audit · MCP server
· self-hosted
Quick start · Architecture · Benchmarks · API · Documentation
Why RAGBrain
Every fact is stored on two independent time axes: when it was true in the world (event time) and when the system learned it (system time). The second axis is what makes answers defensible rather than merely plausible.
Consider one fact that changed: Acme Corp's HQ was Boston (2019 filing), then Denver (2022 filing).
| Question | Vector RAG | Valid-time RAG | RAGBrain |
|---|---|---|---|
| Where is Acme HQ now? | ✅ Denver | ✅ Denver | ✅ Denver |
| Where was it in 2020? | ❌ | ✅ Boston | ✅ Boston |
| What did we believe in 2021, before the 2022 filing? | ❌ | ❌ | ✅ Boston, Denver un-known |
| Show the timeline and what superseded what | ❌ | ⚠️ partial | ✅ full provenance and audit |
The third row is system-time replay. It requires an independent record of when each fact was learned, and the discipline never to let a later correction leak into a past belief state: the un-knowing invariant, enforced in CI against a live graph store.
Capabilities
- Bi-temporal knowledge graph. Four timestamps per fact (
valid_at,invalid_at,created_at,expired_at) in FalkorDB or Neo4j. - As-of retrieval. Ask any question as of any instant; context is validity-filtered before ranking.
- System-time replay and audit. Reconstruct what the system believed at any past moment; a live web scrubber makes it visible.
- Supersession with provenance. A correcting fact expires the old one and stamps a
superseded_byback-link at write time; every answer carries citations. - Checked generation. Answers are verified claim-by-claim against the served facts after generation; unsupported claims are flagged, never silently shipped.
- Pluggable everything. Embedder, reranker, generation model, and graph backend are config-selected and fail loud; bring hosted APIs or fully local models.
- Secure by default. Bearer-token auth, token-scoped sessions, rate limits, upload caps.
- Multi-replica ready. Shared session state and a shared durable write-back journal, proven by a two-replica test; a metrics endpoint for operations.
- Self-hostable end to end. Your documents, your models, your infrastructure.
What you can build with it
- Agent memory that survives the session. Give an LLM agent long-term memory over your documents and its own observations, with citations attached to every fact it recalls.
- Compliance and audit copilots. Answer "what did our policy say in March, and what did we believe at the time?" with a defensible provenance trail rather than a plausible guess.
- Financial, legal, and medical retrieval where a superseded fact is not merely stale but wrong, and where the correction history itself is part of the record.
- Enterprise knowledge bases that change constantly: pricing, org charts, contracts, specifications, SOPs. Corrections supersede instead of silently overwriting.
- Hallucination and grounding checks. Answers are constrained to retrieved context and verified claim by claim; unsupported claims are flagged, never quietly shipped.
- RAG evaluation and regression testing against a corpus whose truth changes over time.
Where RAGBrain fits
The agent-memory and RAG ecosystem is crowded, and most of it is complementary rather than competing. Roughly how the categories divide:
| Category | Examples | What they optimise for |
|---|---|---|
| Memory layers for agents | Mem0, Zep, Letta | extracting, consolidating and recalling user-level memory |
| RAG frameworks | LangChain, LlamaIndex, Haystack | orchestration, connectors, retrieval pipelines |
| Temporal knowledge graphs | Graphiti, cognee | storing facts with time attached |
| RAGBrain | this project | auditable temporal correctness: as-of retrieval, system-time replay, and provenance you can defend |
RAGBrain is built on a temporal graph substrate (Graphiti on FalkorDB or Neo4j) and focuses on the layer above it: enforcing that a replay of the past cannot be contaminated by facts learned later, and exposing that guarantee through an auditable API. It is designed to sit underneath an agent framework, not to replace one.
Measured comparisons against LlamaIndex, LangChain, Haystack, and a temporal-graph ablation are in Benchmarks, with a reproduce command. Systems not listed there have not been benchmarked here, and no claim is made about them.
Quick start
No Docker, no database, no API keys. Just:
pip install ragbrain
from ragbrain import MemoryLedger
db = MemoryLedger()
db.remember("Acme HQ is Boston", key="acme.hq", valid_at="2019-01-01")
db.remember("Acme HQ is Denver", key="acme.hq", valid_at="2022-01-01") # supersedes
db.answer("Where is Acme HQ?") # Acme HQ is Denver
db.answer("Where is Acme HQ?", as_of="2020-01-01") # Acme HQ is Boston
db.replay("2021-06-01")[0].statement # Acme HQ is Boston
That third line is the one nothing else does. Replaying to June 2021 returns Boston with no end date, because the 2022 correction had not been learned yet. The past is reconstructed as it was believed, not as it was later revised.
MemoryLedger is a real bi-temporal ledger, not a demo prop: it passes the same substrate
conformance suite as the graph backends and shares their replay code. It runs in one process
with lexical matching and no persistence, so use FalkorDB or Neo4j (below) for semantic
retrieval, extraction, and durability.
The full platform, with a graph backend and the web UI
Prereqs: Docker. No API keys required for the demo.
git clone https://github.com/Nagendhra-Madishetti/ragbrain && cd ragbrain
docker compose up -d --build
bash scripts/demo.sh
The demo seeds the Acme scenario and asserts four answers:
now -> Denver
as of 2020 -> Boston
replay(2021) -> Boston (the 2022 Denver correction is un-known)
timeline -> Boston (2019 report) superseded by Denver (2022 press release)
Open the live scrubber at http://localhost:3000/playground and drag the system-time slider across 2022; the answer flips in front of you:
Try it live: drag the system-time slider yourself
Install as a library
pip install ragbrain # import ragbrain
pip install "ragbrain[all,serve]" # backends + the platform API
Architecture
The bi-temporal model
- Event time
[valid_at, invalid_at): when the fact was true in the world. Answers "as of 2020". - System time
[created_at, expired_at): when the system learned or retracted it. Answers "what did we believe at S" and powers the un-knowing replay. - A correction supersedes: the old fact receives
invalid_at(event) andexpired_at(system) plus asuperseded_byback-link, stamped at write time. - Replay to S drops everything learned after S, including the knowledge that a fact was
later corrected. That is the invariant, enforced two ways: as pure deterministic tests and
live against a FalkorDB service in CI (
tests/integration/test_replay_seeded.py).
Benchmarks
All published numbers come from live, reproducible runs on a fictional corpus (invented companies, dates only in metadata), so no model can answer from training. Results carry a content hash and a reproduce command; scores are claims exactly the size of the measurement.
| Comparison | Chart |
|---|---|
| As-of questions vs LlamaIndex, LangChain, Haystack, and a temporal-graph ablation | |
| Current-fact questions (the honest tie) |
Reproduce: python demo/benchmark_frameworks.py. Full per-question answers, methodology,
and the measured evaluation floors (verify recall, faithfulness checker precision and recall)
are in the web app's Benchmark page and PROJECT_STATUS.md.
API
Every route except /api/health requires a bearer token (RAGBRAIN_API_TOKENS; the compose
stack provisions ragbrain-demo-token). A session is scoped to the token that created it.
TOKEN=ragbrain-demo-token
API=http://localhost:8000
H="Authorization: Bearer $TOKEN"
curl -H "$H" -X POST "$API/api/demo/seed"
curl -H "$H" "$API/api/audit/current?session_id=demo_acme"
curl -H "$H" "$API/api/audit/event?session_id=demo_acme&as_of=2020-06-01"
curl -H "$H" "$API/api/audit/replay?session_id=demo_acme&system_time=2021-06-01"
curl -H "$H" "$API/api/audit/timeline/demo-belief-boston?session_id=demo_acme"
curl -H "$H" -H 'Content-Type: application/json' -X POST "$API/api/context" \
-d '{"session_id":"mine","query":"Where is Acme headquartered?","as_of":"2020-06-01"}'
Ingest your own documents (local; data never leaves your environment):
cp .env.example .env # provider keys for generation and semantic retrieval
curl -H "$H" -F session_id=mine -F reference_time=2019-01-01 \
-F file=@your_report.pdf "$API/api/ingest"
For semantic retrieval configure a real embedder: RAGBRAIN_EMBEDDER=bge-m3-local
(key-free, requires the [embeddings] extra) or RAGBRAIN_EMBEDDER=bge-m3 with
RAGBRAIN_EMBEDDER_API_KEY. The key-free boot default (hash) is lexical and states so
loudly in every response until a real embedder is configured.
Deployment
- Local and trusted environments:
docker compose up -d --build. - Multi-replica:
docker compose -f docker-compose.yml -f docker-compose.replicas.yml up -dwithRAGBRAIN_SHARED_STATE=1; verify withbash scripts/two_replica_proof.sh. - Operations: an authenticated
/metricsendpoint exposes per-replica counters. - Security posture, scope, and the operator checklist: SECURITY.md. Project status and measured evaluation floors: PROJECT_STATUS.md. Defect ledger: docs/KNOWN_ISSUES.md.
Documentation
| Topic | Where |
|---|---|
| Context-serving API | docs/CONTEXT_API.md |
| Audit and replay | docs/AUDIT_DASHBOARD.md |
| Document ingestion | docs/DOCUMENT_INGESTION.md |
| Embedders | docs/EMBEDDERS.md |
| Generation and faithfulness | docs/GENERATION.md |
| Extending without touching core | docs/EXTENDING.md, CONTRIBUTING.md |
FAQ
What is bi-temporal RAG? Retrieval-augmented generation where every fact carries two independent time axes: event time (when it was true in the world) and system time (when the system learned it). That second axis is what lets you ask "what did we believe last March?" and get an answer that excludes everything learned since.
How is this different from a vector database? A vector store answers "what is semantically similar". It has no notion of a fact being superseded, so a corrected document and its replacement both remain retrievable with no ordering between them. RAGBrain keeps the correction history and filters by validity before ranking, so an as-of query cannot return a fact that was not yet true.
Can I use it as memory for an LLM agent?
Yes. That is the primary use case. Facts can be written by ingestion or by the agent itself
via record_observation, and served back through a context API, an MCP server, or the HTTP
API, each answer carrying citations and validity windows.
Does it work with LangChain or LlamaIndex? Yes. RAGBrain is a memory and retrieval layer, not an agent framework. It ships a LlamaIndex bridge, and the HTTP and MCP surfaces work with any orchestrator.
Which LLM and embedding models does it support?
Any OpenAI-compatible endpoint for generation, and local (bge-m3) or hosted embedders.
Every plug is config-selected and fails loud rather than silently degrading. There is a
key-free deterministic default so the demo runs with no API keys.
Do I have to send my data to a third party? No. The whole stack is self-hostable: FalkorDB or Neo4j for storage, local embedding and reranking models, and your own inference endpoint.
Is it production ready? It is early. The core contracts, replay invariant, and multi-replica behaviour are covered by 164 tests in CI including a live graph database. Read PROJECT_STATUS.md for measured evaluation floors and docs/KNOWN_ISSUES.md for the open defect ledger before deploying.
How does it prevent hallucinations? Generation is constrained to the served context, then every claim in the answer is checked back against those facts. Unsupported claims are flagged or the answer is declined, depending on the configured mode. It reduces unsupported output; it does not eliminate it.
Development
pip install -e ".[dev]"
ruff check .
pytest
License
Metadata
Release files for ragbrain 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ragbrain-0.1.1.tar.gz | 2.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ragbrain-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / ragbrain-0.1.1.tar.gz
| Download URL | ragbrain-0.1.1.tar.gz |
|---|---|
| Size | 2.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d6c246f57a90e6d3ace05d4c58b71a1509589f3c98d1707fc4baee4ee118b3f1
|
|
BLAKE2b-256 checksum How to use checksums |
855bfaa4f35c438438bc4c6ca2074b3737c45749817ef01e6cf43f46b479cda6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency logRelease files / ragbrain-0.1.1-py3-none-any.whl
| Download URL | ragbrain-0.1.1-py3-none-any.whl |
|---|---|
| Size | 103.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c4527b8ede2b16b6579ababc433bc508fdf191acc4fdffdf83db1e4465f0386
|
|
BLAKE2b-256 checksum How to use checksums |
b71d13625f1999c9f69e73944a2f42cd9184b6ad698e8d058c0d1905c1c0d0f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 20, 2026.
Transparency log