hybrid-rag-memory
English | 日本語
Hybrid RAG — Agent Long-Term Memory System
Ein hybrides RAG-System, das dichte und sparse Retrieval kombiniert, mit einem tag-basierten Speichermechanismus (Wichtigkeit, Veraltungsrate pro knowledge_type und Zugriffshäufigkeit), der in das Re-Ranking integriert ist. Zur Design-Begründung siehe hybrid_rag_agent_spec.en.md.
Betreiben Sie es als MCP-Server, und Agenten wie Claude Code können es direkt als „Langzeitgedächtnis" nutzen.
So funktioniert dieser Mechanismus
Gemäß der Spezifikation wird die Verarbeitung in zwei Arten aufgeteilt.
Klasse | Inhalt | Implementierung |
① Modellabhängig (Reasoning) | Wichtigkeitstaggung, Query-Expansion / Suffizienz-Urteil, Orchestrierung | Agentenseite (LLM-Urteil) |
② Strukturabhängig (deterministische Verarbeitung) | Chunking, Embedding-Erzeugung, hybride Suche, gestuftes Re-Ranking, Vergessen/Archivierung | RAG-Seite (diese Bibliothek / MCP-Server) |
„Wichtigkeit" und „Veraltungsrate pro knowledge_type" werden als getrennte Achsen behandelt; statt einer einfachen linearen Kombination werden sie stufenweise angewendet: ① Cutoff nach Wichtigkeit → ② Zeitabklingung nach knowledge_type → ③ Boost nach Zugriffshäufigkeit (Details siehe Spezifikationsabschnitt 2.3).
principle : no decay (MBSE design principles, math/algorithms)
paper : re-evaluated roughly every half year (papers, technical articles)
news : decays significantly over weeks to months (news, model-release info)
experiment : decays according to project duration (experiment logs, run records)knowledge_type ist so konzipiert, dass es deterministisch aus der Aufnahmequelle bestimmt wird und nicht von einem LLM anhand des Chunk-Inhalts beurteilt wird (z. B. ein von einem Menschen explizit registriertes Designdokument → principle; ein arXiv-Paper/technischer Artikel → paper; Nachrichten/Web-Suchergebnisse → news; ein Ausführungsprotokoll → experiment).
Hinweis:
principle(keine Abklingung) garantiert nicht, dass ein Chunk „nie vonrun_forgetting_batchvergessen wird". Da das gestufte Re-Ranking zuerst den ① Wichtigkeits-Cutoff anwendet, kann ein Chunk mitknowledge_type=principledennoch ein Archivierungsziel werden, wenn seineimportanceniedrig gesetzt ist und unterimportance_thresholdfällt (bestätigt durchtests/test_archival.py). „Keine Abklingung" gilt nur für die ② Zeitabklingungs-Stufe — es ist keine „nie vergessen"-Garantie über die gesamte ①②③-Pipeline.
Hinweis: Der Speichermechanismus (knowledge_type/importance/gestuftes Re-Ranking/Forgetting-Batch/MCP-Server) ist nur für das FAISS-Backend (
HybridRAGSystem) implementiert. Die Qdrant/Chroma/PostgreSQL-Versionen sind nur als reine Hybrid-Suchbibliothek verfügbar.
Related MCP server: mnemostack
Installation
pip install -r requirements.txtFür Entwicklung/Tests:
pip install -r requirements-dev.txtVerwendung ① Als MCP-Server (empfohlen)
Server starten
python mcp_server/server.pyDie Speicherorte können über Umgebungsvariablen festgelegt werden (Standardwerte: hybrid_rag.db / indices).
HYBRID_RAG_DB_PATH=my_memory.db HYBRID_RAG_INDEX_PATH=my_indices python mcp_server/server.pyBei Claude Code registrieren
.mcp.json im Projektstamm ist bereits wie folgt eingerichtet. Claude Code erkennt es automatisch, wenn es dieses Repository öffnet.
{
"mcpServers": {
"hybrid-rag-memory": {
"type": "stdio",
"command": "python",
"args": ["mcp_server/server.py"],
"env": {
"HYBRID_RAG_DB_PATH": "hybrid_rag.db",
"HYBRID_RAG_INDEX_PATH": "indices"
}
}
}
}Wenn Sie eine virtuelle Umgebung verwenden, schreiben Sie command auf den absoluten Pfad des Python-Interpreters in Ihrer venv um (z. B. "command": "./.venv/Scripts/python.exe").
Bereitgestellte Tools
Zusätzlich zu den minimalen 3 Tools (①–③), die in Spezifikationsabschnitt 5 gefordert sind, bietet dieser Server 10 weitere Tools (④–⑬, Spezifikationserweiterungen) für Datenaufnahme, Tagging, Duplikatvermeidung, Forgetting-Batches und Health-Checks.
# | Tool | Beschreibung |
① |
| Vektorisiert Text mit einem festen Embedding-Modell (deterministische Verarbeitung) |
② |
| Hybride Vektor+BM25-Suche. Gibt Chunks zurück, die bereits ein Relevanz-Re-Ranking (Cross-Encoder) durchlaufen haben. Mit |
③ |
| Gestuftes Re-Ranking: Wichtigkeits-Cutoff → Zeitabklingung pro |
④ |
| Nimmt Dokumente auf. |
⑤ |
| Weist Wichtigkeitstags zu / taggt |
⑥ |
| Exakte Tag-Suche (umgeht die semantische Suche). Wird verwendet, um zu prüfen, ob ein Dokument aus derselben Quelle bereits aufgenommen wurde [Spezifikationserweiterung] |
⑦ |
| Ruft benachbarte Chunks innerhalb desselben Dokuments ab (eine direkte Suche, die die semantische Suche umgeht). Kompensiert Kontextverlust an Chunk-Grenzen [Spezifikationserweiterung] |
⑧ |
| Löscht ein Dokument und alle seine Chunks. Wird im „Ersetzen"-Ablauf beim erneuten Aufnehmen verwendet [Spezifikationserweiterung] |
⑨ |
| Ein leichtgewichtiges Index-Update, das inkrementell nur die Chunks einbezieht, die seit dem letzten Index-Update hinzugefügt wurden [Spezifikationserweiterung, hinzugefügt 2026-07-30] |
⑩ |
| Führt einen vollständigen Neuaufbau der FAISS/BM25-Indizes aus jedem Chunk in der DB durch. Erforderlich nach Löschungen (⑧ oder |
⑪ |
| Der Vergessens-/Archivierungs-Batch-Job. Nur für seltene Ausführung gedacht [Spezifikationserweiterung] |
⑫ |
| Prüft die Konsistenz zwischen Index und DB und meldet sie (nimmt keine Änderungen vor). Erkennt „im Index, aber nicht in der DB"-Schutt (durch Vergessen, |
⑬ |
| Meldet die Tagging-Abdeckung des Speichermechanismus der DB (nimmt keine Änderungen vor). Während |
Ohne ④–⑬ können die ①–③-Tools allein weder Daten aufnehmen, Importance-Tags finalisieren noch Doppelregistrierungen aus derselben Quelle vermeiden — was das System unpraktikabel macht, weshalb sie hinzugefügt wurden.
Ein Hinweis zum Aufnehmen vieler Dateien hintereinander (wichtig)
Hintergrund (ein früheres Problem, behoben am 2026-07-30): ingest standardmäßig auf „jeden Chunk in der DB neu einbetten und den Index bei jedem Aufruf neu aufbauen“ eingestellt, sodass die Kosten eines einzelnen Aufrufs linear mit der Korpusgröße wuchsen und das Ingestieren von Dateien einzeln nacheinander zu Timeouts führte. ingest(rebuild_index=True) (die Standardeinstellung) ruft jetzt intern update_index() auf – einen inkrementellen Ansatz, der nur die neu hinzugefügten Chunks seit dem letzten Update einbettet und sie per .add() zum FAISS-Index hinzufügt –, sodass es jetzt unabhängig von der Gesamtkorpusgröße schnell ist (die BM25-Seite macht weiterhin bei jedem Mal einen leichten vollständigen Neuaufbau, da ihre IDF-Statistiken vom gesamten Korpus abhängen, aber das ist günstig, da keine neuronale Einbettung involviert ist).
Das heißt, ein inkrementelles Update für jede einzelne Datei auszuführen ist immer noch verschwendeter Overhead. Wenn man also viele Dateien hintereinander ingestiert, ist es besser, bei jedem ingest-Aufruf rebuild_index=False zu übergeben und am Ende des Batches einmal update_index() aufzurufen, um alles auf einmal abzugleichen. .claude/agents/doc-to-memory.md und .claude/agents/session-to-memory.md sind bereits mit diesem Muster implementiert. Das Überprüfen der DB über find_by_tag (zur Duplikatvermeidung / Fortschrittsprüfung) fragt SQLite direkt ab, funktioniert also, ohne auf den Index warten zu müssen.
Wann ein vollständiges rebuild_index() erforderlich ist: immer dann, wenn der Batch auch nur einen einzigen delete_document-Aufruf oder einen Archivierungsdurchlauf von run_forgetting_batch enthält (d. h. jede Vektorlöschung). Inkrementelles Hinzufügen (update_index) unterstützt nur das Hinzufügen zu FAISS, nicht das Entfernen daraus. Jeder Batch, der Löschungen enthält, muss daher mit einem vollständigen rebuild_index() enden. Ein Batch, der ausschließlich aus neuen Hinzufügungen besteht, ist mit update_index() in Ordnung.
Duplikate beim erneuten Registrieren derselben Quelle verhindern
Da ingest die doc_id aus einem Hash des Dateiinhalts ableitet, wird das erneute Ingestieren byte-identischer Inhalte automatisch übersprungen (ein diff-basiertes Update). In Fällen jedoch, in denen dieselbe Quelle (z. B. dieselbe Sitzung) jedes Mal von einem LLM neu zusammengefasst und erneut ingestiert wird, führen geringfügige Abweichungen im Zusammenfassungstext dazu, dass sie als anderes Dokument behandelt wird – was Duplikate erzeugt.
Um dies zu vermeiden, ingestiere mit einem eindeutigen Identifikator-Tag (z. B. session_id:xxx) und einem Aktualisiert-am-Tag (z. B. session_last_activity:2026-07-28T15:59:49Z), und bei späteren Ausführungen:
Prüfe, ob das Dokument bereits über
find_by_tag("session_id:xxx")existiert.Wenn das vorhandene Aktualisiert-am-Tag mit dem aktuellen Wert übereinstimmt, überspringe – tue nichts.
Nur wenn es sich unterscheidet (die Quelle hat sich geändert), entferne das alte mit
delete_document(doc_id, rebuild_index=False), bevor du den neuen Inhalt peringesteinfügst.
Die Implementierung dieses Musters „überspringen, wenn unverändert, ersetzen, wenn geändert“ wird empfohlen. .claude/agents/session-to-memory.md ist eine Referenzimplementierung dieses Musters.
Verwendungsbeispiel (konzeptionell)
1. ingest(["design_doc.md"], metadata={"knowledge_type": "principle", "tags": ["mbse"]})
2. hybrid_search("about consistency between requirements and architecture", top_k=5)
-> [{"doc_id": ..., "chunk_index": ..., "content": ..., "knowledge_type": "principle",
"importance": null, "access_count": 0, "score": 0.87}, ...]
3. set_chunk_tags(doc_id, chunk_index, importance=0.9)
4. rerank(chunks, time_weight=0.5, freq_weight=0.1, importance_threshold=0.3)
-> chunks reordered along the memory axis (staleness, frequency, importance)Verwendung ② Als Claude-Code-Agent
.claude/agents/rag-memory.md enthält eine Sub-Agent-Definition, die für die „Agent-Seite (Klasse ①)“ dieses Speichermechanismus verantwortlich ist. Sobald .mcp.json registriert ist, kannst du ihn aus Claude Code wie folgt aufrufen:
Use the rag-memory agent to look into past design decisionsDie Betriebsregeln für Aktionen, die eine Bestätigung durch menschliche Absicht erfordern – Wichtigkeit-Tagging, knowledge_type-Neutagging, Entscheidung, wann der Vergessens-Batch ausgeführt wird – sind ebenfalls in dieser Agent-Definition festgehalten.
Zusätzlich ist .claude/agents/session-to-memory.md ein dedizierter Agent, der vergangene Claude-Code-Sitzungen (Chat-Transkripte) zusammenfasst und sie als knowledge_type="experiment" in das Langzeitgedächtnis ingestiert. Er läuft auf einem Haiku-Modell, um die Kosten niedrig zu halten, und vergleicht bei der erneuten Verarbeitung derselben Sitzung den bestehenden Eintrag über die session_id/Aktualisiert-am-Tags – überspringt, wenn unverändert, ersetzt, wenn geändert (siehe vorheriger Abschnitt). Der Aufrufer muss explizit angeben, welche Sitzungen Ziel sein sollen; er zielt niemals ohne Begrenzung auf alle Sitzungen.
Verwendung ③ Direkt als Python-Bibliothek
Du kannst es auch direkt aus Python-Code aufrufen, ohne den MCP-Server zu durchlaufen.
from hybrid_rag import HybridRAGSystem
rag = HybridRAGSystem(db_path="hybrid_rag.db", index_path="indices")
rag.ingest_documents(
["design_doc.md"],
metadata={"knowledge_type": "principle", "importance": 0.9, "tags": ["mbse"]},
)
result = rag.query(
"about consistency between requirements and architecture",
top_k=5,
enable_memory_rerank=True, # enable the memory mechanism's staged reranking
memory_time_weight=0.5,
memory_freq_weight=0.1,
memory_importance_threshold=0.3,
)
print(result["context"])
# assign an importance tag after the fact (no vector rebuild needed)
rag.set_chunk_tags(doc_id="design_doc_xxxx", chunk_index=0, importance=0.9)
# forgetting/archival batch (normally run infrequently)
report = rag.run_forgetting_batch(score_threshold=0.05, dry_run=True)Ausführen des Vergessens-Batches über die CLI
Ein Skript, das für seltene Batch-Ausführungen gedacht ist – z. B. in einem 3-Monats-Zyklus oder wenn ein neues Modell veröffentlicht wird (es wird niemals automatisch innerhalb des Servers ausgeführt).
python scripts/run_forgetting_batch.py --dry-run
python scripts/run_forgetting_batch.py --score-threshold 0.1 --time-weight 0.8Hauptoptionen: --db-path --index-path --archive-path --time-weight --freq-weight --importance-threshold --score-threshold --dry-run
Archivierte Chunks werden nach archive/chunks_archive.jsonl evakuiert (Rohtext + Metadaten + Score + Löschgrund + Löschzeitstempel), und ihre Vektorrepräsentationen werden verworfen.
Automatisches Bewerten der Retrieval-Genauigkeit über die CLI
Ein Skript, das die Retrieval-Genauigkeit gegen einen goldenen Query-Satz misst (Precision@k/Recall@k/MRR/NDCG@k/Hit Rate@k, Rang des Autoritätsdokuments, Rauschrate) auf reproduzierbare Weise, anstatt sich auf manuelle Abfragen und das Überprüfen von Ergebnissen über Cursor/Claude Code zu verlassen.
cp eval/golden_queries.example.yaml eval/golden_queries.yaml # once, at first use — rewrite the doc_ids for your own corpus
python scripts/run_evaluation.py --db-path mcp_server/hybrid_rag.db --index-path mcp_server/hybrid_rag_indicesHauptoptionen: --db-path --index-path --golden-set (Standard eval/golden_queries.yaml) --k-values (Standard 1,3,5,10) --authority-window (Standard 20) --output
Prüfen auf nahezu doppelte Ingeste
Die Duplikaterkennung von ingest kann Fälle nicht abfangen, in denen identischer Inhalt über eine andere Datei (einen anderen Pfad/Dateinamen – siehe „Duplikate beim erneuten Registrieren derselben Quelle verhindern“ oben) eingeht. Dieses Skript listet lediglich nahezu doppelte Einträge auf, die bereits in einem bestehenden Korpus gelandet sind. Es löscht niemals etwas.
python scripts/find_near_duplicates.py --db-path mcp_server/hybrid_rag.db
python scripts/find_near_duplicates.py --db-path mcp_server/hybrid_rag.db --output eval/duplicates_report.jsonEs gruppiert Dokumente, deren normalisierter Inhalts-Hash (documents.content_hash) übereinstimmt. Die Entscheidung, welches behalten werden soll – und ob überhaupt etwas gelöscht wird – bleibt dem Benutzer überlassen; rufe delete_document(doc_id, rebuild_index=False) manuell auf (und stelle sicher, dass du am Ende des Batches rebuild_index aufrufst).
eval/golden_queries.yaml ist .gitignored, da es persönliche Daten mit doc_ids enthält, die für deinen tatsächlichen Korpus spezifisch sind. Berichte werden nach eval/eval_report_<date>.md geschrieben (plus eine gleichnamige .json), die ebenfalls .gitignored sind (sie bleiben für laufende Verfolgung auf deinem Rechner).
Speichermechanismus-Felder
Felder, die in den metadata von ingest/der Python-API oder pro Chunk getragen werden:
Feld | Typ | Beschreibung |
|
|
|
|
| Wichtigkeit, die nachträglich vom Agenten zugewiesen wird. Nicht gesetzt ( |
|
| Beliebige Tags. Werden verwendet, um Ergebnisse über das |
|
| Zugriffshäufigkeit. Wird jedes Mal automatisch erhöht, wenn ein Chunk tatsächlich von einer Abfrage zurückgegeben wird |
|
| Zeitstempel des letzten Zugriffs / der Erstellung. Dienen als Grundlage für den Zeitabfall |
Tests
pytest tests/ -vtest_metadata_pipeline.py: ein Regressionstest, dassknowledge_type/importance/tagsdie ingest → build_index → query-Pipeline überlebentest_memory_scoring.py: Unit-Tests für das gestufte Re-Ranking (Cutoff, Abfall, Häufigkeits-Boost)test_archival.py: Unit-Tests für den Vergessens-/Archivierungs-Batchtest_index_health.py: Unit-Tests fürindex_health(Index/DB-Konsistenzprüfung)
Siehe Dateilayout für die vollständige Liste und Rolle der anderen Testdateien.
Basisbibliotheks-Funktionalität (gemeinsam über Backends)
Die Basis-RAG-Funktionalität – dichte/spärliche Hybridsuche, RRF, Cross-Encoder-Re-Ranking, MMR-Diversitätsauswahl, Query-Expansion, Caching usw. – ist für jedes Backend (FAISS/Qdrant/Chroma/PostgreSQL) gemeinsam.
from hybrid_rag import create_rag_system
rag = create_rag_system(backend="faiss") # "qdrant" / "chroma" / "postgres" are also available
rag.ingest_documents(["document1.pdf", "document2.md"])
result = rag.query("What is machine learning?", top_k=5)Aspekt | FAISS | Qdrant | ChromaDB | PostgreSQL |
Gefilterte Suche | Nachbearbeitung | schnell (einstufig) | Nachbearbeitung | Nachbearbeitung |
Server erforderlich | nein | nein | nein | ja |
Skalierung | bis zu ~20M | bis zu ~50M | mittelgroß | großskalig |
Speichermechanismus (diese README) | ✓ | ✗ | ✗ | ✗ |
Optionale Installationen: Dieses Repository hat keine pyproject.toml/setup.py, daher wird es nicht in der Form pip install hybrid-rag[...] verteilt. Um die Qdrant/Chroma/PostgreSQL-Versionen zu verwenden, installiere die entsprechende Client-Bibliothek direkt (pip install qdrant-client / pip install chromadb / pip install "psycopg[binary]" pgvector – alle sind bereits in requirements.txt aufgeführt, sodass pip install -r requirements.txt allein sie abdeckt).
Wichtige zusätzliche Einstellungen (eine Teilmenge der Konstruktorargumente der FAISS-Version von HybridRAGSystem):
rag = HybridRAGSystem(
dense_model="paraphrase-multilingual-MiniLM-L12-v2",
rerank_model="BAAI/bge-reranker-v2-m3",
max_chunk_size=512,
index_type="hnsw", # "flat" / "ivf" / "hnsw"
enable_mmr=True, mmr_lambda=0.6,
enable_cache=True, cache_ttl_seconds=3600,
query_expander=None, # pass a QueryExpander instance for LLM-based query expansion
memory_half_life_overrides=None, # override the half-life (days) per knowledge_type
enable_guaranteed_candidates=True, # always add principle/high-importance chunks to the candidate pool (default True)
guaranteed_knowledge_types=None, # defaults to ["principle"]
guaranteed_importance_threshold=0.7,
guaranteed_candidates_limit=50,
)enable_guaranteed_candidates (Standard True) adressiert ein Problem, bei dem knowledge_type=principle-Chunks (oder Chunks mit importance>=0.7) nie in den Kandidatenpool der Suche gelangten und das gestufte Re-Ranking sie nicht retten konnte (das in RAG_EVALUATION_REPORT_2026-07-30.md/RAG_精度テスト_2026-07-31.md gemeldete Problem „Prinzip-Dokumente werden vergraben“). Es funktioniert, indem es passende Chunks direkt nach der Abfrage immer zum Kandidatenpool hinzufügt und den Cross-Encoder ihre Relevanz bewerten lässt – es erzwingt nicht, dass sie nach oben kommen. Aufrufe von query()/hybrid_search, die metadata_filters (filters) übergeben, überspringen diese Zusammenführung.
Dokumentation (Sphinx) / Diagramme (PlantUML)
pip install sphinx sphinx-rtd-theme
python -m sphinx -b html docs/source docs/builddocs/uml/ ist dafür gedacht, PlantUML-Quellen für Klassendiagramme, Sequenzdiagramme und Zustandsdiagramme zu enthalten (zum Zeitpunkt dieses Schreibens noch nicht befüllt).
Dateilayout
hybrid_rag_agent_spec.md # design spec for the memory mechanism
.mcp.json # MCP server registration for Claude Code
.claude/agents/rag-memory.md # sub-agent definition for Claude Code
mcp_server/
└── server.py # the MCP server itself (13 tools, see the table above)
scripts/
├── run_forgetting_batch.py # CLI for the forgetting/archival batch
├── run_evaluation.py # CLI that automatically evaluates retrieval accuracy against a golden query set
├── find_near_duplicates.py # CLI that audits near-duplicate ingests in the existing corpus (report-only, never deletes)
├── backfill_source_date.py # bulk-backfills source_date on existing chunks
├── list_md_files.py # lists candidate Markdown files for ingestion
├── manage_ingest_status.py # tracks ingest progress against list_md_files.py's listing
├── manage_conv_ingest_status.py # tracks ingest progress against convert_conversations.py's output
└── convert_conversations.py # converts a Claude.ai export (JSON) into Markdown
hybrid_rag/
├── __init__.py
├── ingestion.py # document processing
├── chunking.py # semantic chunking
├── indexing.py # dense & sparse index (FAISS)
├── indexing_bm25.py # BM25 index
├── indexing_sparse_tfidf.py # TF-IDF sparse index (shared by the Chroma/Postgres/Qdrant backends)
├── indexing_qdrant.py / indexing_chroma.py / indexing_postgres.py
├── retrieval.py # RRF search
├── reranking.py # Cross-encoder reranking (relevance axis)
├── memory_scoring.py # staged reranking (memory axis: importance/decay/frequency)
├── archival.py # forgetting/archival batch processing
├── index_health.py # index/DB consistency checking (backs the ⑫ index_health tool)
├── caching.py / embedding_cache.py
├── context.py / diversity.py / evaluation.py
├── storage.py # SQLite database (including memory-mechanism fields)
├── query_expansion.py
├── rag_system.py # main orchestrator (FAISS version, implements the memory mechanism)
├── _rag_system_indexing.py # ^ ingest/build/incremental-update/load (mixin)
├── _rag_system_query.py # ^ query pipeline (mixin)
├── _rag_system_memory.py # ^ tags/neighboring chunks/forgetting batch (mixin)
├── _rag_system_stats.py # ^ stats & cache management (mixin)
├── _rag_system_docops.py # ^ embedding/delete/lightweight search (mixin)
├── rag_system_base.py # base class shared by the Chroma/Postgres/Qdrant backends
├── rag_system_qdrant.py / rag_system_chroma.py / rag_system_postgres.py
└── rag_system_factory.py
tests/
├── test_metadata_pipeline.py # metadata regression test across ingest → build_index → query
├── test_memory_scoring.py # unit tests for staged reranking
├── test_archival.py # unit tests for the forgetting/archival batch
├── test_incremental_index.py # unit/integration tests for update_index (incremental updates)
├── test_index_health.py # unit tests for index_health (index/DB consistency check)
├── test_result_dedup.py # unit tests for RRF fusion-key stability and search-result dedup
├── test_diversity.py # unit tests for MMR diversity selection
├── test_reranking.py # unit tests for Cross-encoder reranking stats
├── test_retriever_shutdown.py # tests for RRFRetriever resource cleanup (thread leaks)
├── test_indexing_bm25.py # unit tests for the BM25 index
├── test_storage_concurrency.py # unit tests for concurrent SQLite writes
├── test_source_date.py # unit tests for source_date derivation (time-decay reference point)
├── test_document_chunks.py # unit tests for get_document_chunks (fetching neighboring chunks)
├── test_evaluation.py # unit tests for RAGEvaluator (Precision@k, etc.)
├── test_database_stats.py # unit tests for get_database_stats / duplicate-ingest detection
├── test_guaranteed_candidates.py # unit tests for guaranteed candidate-pool merging (the fix for principle burial)
├── test_rag_system_factory.py # unit tests for create_rag_system (backend switching)
└── conftest.py # shared pytest configurationLizenz
MIT-Lizenz
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.
Shared long-term memory vault for AI agents with 20 MCP tools.
Related MCP Servers
- AlicenseBqualityFmaintenancePersistent memory, teams, and projects for AI agents. 76 MCP tools for storing, recalling, and sharing knowledge across sessions with 4-strategy hybrid search.332301MIT
- AlicenseAqualityAmaintenanceDurable hybrid memory for AI agents. Combines vector search, BM25, temporal retrieval, and optional Memgraph knowledge graph via reciprocal rank fusion. 6 MCP tools: health, search, answer, feedback, graph_query, graph_add_triple. Self-hosted with Qdrant backend.77Apache 2.0
- AlicenseNot gradedqualityAmaintenanceProvides AI agents with persistent knowledge storage, enabling them to store, search, and retrieve text, documents, and files using semantic and keyword search via MCP tools.32Apache 2.0
- AlicenseNot gradedqualityDmaintenanceLocal-first AI memory layer with hybrid retrieval and brain-inspired namespaces. Enables agents to save, search, and manage memories directly via MCP tools.5MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/masaki-kato-119/hybrid-rag-memory'
If you have feedback or need assistance with the MCP directory API, please join our Discord server