hybrid-rag-memory
English | 日本語
Hybrid RAG — エージェント長期記憶システム
高密度検索とスパース検索を組み合わせたハイブリッドRAGシステムで、タグベースの記憶メカニズム(重要度、knowledge_type ごとの陳腐化率、アクセス頻度)をリランキングに組み込んでいます。設計の根拠については hybrid_rag_agent_spec.en.md を参照してください。
MCPサーバーとして実行すると、Claude Code などのエージェントが「長期記憶」として直接利用できます。
このメカニズムの仕組み
仕様に従い、処理は2種類に分けられます。
分類 | 内容 | 実装 |
① モデル依存(推論) | 重要度タグ付け、クエリ拡張/十分性判断、オーケストレーション | エージェント側(LLMによる判断) |
② 構造依存(決定論的処理) | チャンキング、埋め込み生成、ハイブリッド検索、段階的リランキング、忘却/アーカイブ | RAG側(このライブラリ/MCPサーバー) |
「重要度」と「knowledge_type ごとの陳腐化率」は別々の軸として扱われ、単純な線形結合ではなく、① 重要度によるカットオフ → ② knowledge_type による時間減衰 → ③ アクセス頻度によるブースト の順に段階的に適用されます(詳細は仕様セクション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 は、チャンクの内容をLLMが判断するのではなく、取り込み元から決定論的に決定されるように設計されています(例:人間が明示的に登録した設計ドキュメント → principle、arXiv論文/技術記事 → paper、ニュース/Web検索結果 → news、実行ログ → experiment)。
注記:
principle(減衰なし)は、チャンクが「run_forgetting_batchによって決して忘却されない」ことを保証しません。段階的リランキングは最初に①の重要度カットオフを適用するため、knowledge_type=principleのチャンクでも、importanceが低く設定されimportance_thresholdを下回るとアーカイブ対象になり得ます(tests/test_archival.pyで確認済み)。「減衰なし」は②の時間減衰段階にのみ適用されるものであり、①②③のパイプライン全体を通した「決して忘却されない」保証ではありません。
注記: 記憶メカニズム(knowledge_type/重要度/段階的リランキング/忘却バッチ/MCPサーバー)は、FAISSバックエンド(
HybridRAGSystem)に対してのみ実装されています。Qdrant/Chroma/PostgreSQL版は、プレーンなハイブリッド検索ライブラリとしてのみ利用可能です。
Related MCP server: mnemostack
インストール
pip install -r requirements.txt開発/テスト用:
pip install -r requirements-dev.txt使用方法 ① MCPサーバーとして(推奨)
サーバーの起動
python mcp_server/server.pyストレージの場所は環境変数で設定できます(デフォルト: hybrid_rag.db / indices)。
HYBRID_RAG_DB_PATH=my_memory.db HYBRID_RAG_INDEX_PATH=my_indices python mcp_server/server.pyClaude Code への登録
プロジェクトルートの .mcp.json は以下のように設定済みです。Claude Code はこのリポジトリを開くと自動的に読み込みます。
{
"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"
}
}
}
}仮想環境を使用する場合は、command をvenv内のPythonインタープリタの絶対パスに書き換えてください(例: "command": "./.venv/Scripts/python.exe")。
提供されるツール
仕様セクション5で要求されている最小限の3ツール(①–③)に加えて、このサーバーはデータ取り込み、タグ付け、重複防止、忘却バッチ、ヘルスチェックのための10ツール(④–⑬、仕様拡張)を提供します。
# | ツール | 説明 |
① |
| 固定の埋め込みモデルでテキストをベクトル化します(決定論的処理) |
② |
| ハイブリッドベクトル+BM25検索。関連性リランキング(Cross-encoder)を通過済みのチャンクを返します。 |
③ |
| 段階的リランキング: 重要度カットオフ → |
④ |
| ドキュメントを取り込みます。 |
⑤ |
| 重要度タグを割り当て/ |
⑥ |
| 完全一致のタグ検索(セマンティック検索をバイパス)。同じソースのドキュメントがすでに取り込まれているかを確認するために使用します [仕様拡張] |
⑦ |
| 同じドキュメント内の隣接チャンクを取得します(セマンティック検索をバイパスする直接参照)。チャンク境界で失われたコンテキストを補います [仕様拡張] |
⑧ |
| ドキュメントとそのすべてのチャンクを削除します。再取り込み時の「置き換え」フローで使用します [仕様拡張] |
⑨ |
| 前回のインデックス更新以降に追加されたチャンクのみを増分的に組み込む軽量なインデックス更新 [仕様拡張、2026-07-30追加] |
⑩ |
| DB内のすべてのチャンクからFAISS/BM25インデックスを完全再構築します。削除(⑧または |
⑪ |
| 忘却/アーカイブのバッチジョブ。頻繁には実行しないことを想定しています [仕様拡張] |
⑫ |
| インデックスとDBの整合性をチェックして報告します(変更は行いません)。削除後に |
⑬ |
| DBの記憶メカニズムのタグ付けカバレッジを報告します(変更は行いません)。 |
④–⑬がない場合、①–③のツールだけではデータの取り込み、重要度タグの確定、同じソースからの重複登録の回避ができず、システムが実用的でないため、これらが追加されました。
多数のファイルを連続して取り込む際の注意(重要)
背景(2026-07-30 に修正された過去の問題): ingest は以前、デフォルトで「DB 内のすべてのチャンクを再埋め込みし、毎回インデックスを再構築する」という動作だったため、1 回の呼び出しコストがコーパスサイズに比例して増加し、ファイルを 1 つずつ連続で取り込むとタイムアウトしていました。ingest(rebuild_index=True)(デフォルト)は現在、内部で update_index() を呼び出します。これは増分アプローチで、前回の更新以降に追加された新しいチャンクのみを埋め込み、FAISS インデックスに .add() するため、コーパス全体のサイズに関係なく高速になりました(BM25 側は IDF 統計がコーパス全体に依存するため、毎回軽量な全再構築を行いますが、ニューラル埋め込みを伴わないためコストは低いです)。
とはいえ、ファイルごとに増分更新を実行するのは依然として無駄なオーバーヘッドです。そのため、多数のファイルを連続して取り込む場合は、各 ingest 呼び出しに rebuild_index=False を渡し、バッチの最後に update_index() を 1 回呼び出してすべてを一度に調整する方が良いです。.claude/agents/doc-to-memory.md と .claude/agents/session-to-memory.md はすでにこのパターンで実装されています。find_by_tag による DB の確認(重複防止・進捗確認用)は SQLite を直接クエリするため、インデックスの追いつきを待たずに動作します。
完全な rebuild_index() が必要な場合: バッチに delete_document 呼び出しが 1 つでも含まれる場合、または run_forgetting_batch によるアーカイブ処理(つまりベクトル削除)が含まれる場合です。増分追加(update_index)は FAISS への追加のみをサポートし、削除には対応していないため、削除を含むバッチは必ず完全な rebuild_index() で終了する必要があります。新しい追加のみで構成されるバッチは update_index() で問題ありません。
同じソースを再登録する際の重複防止
ingest はファイルの内容のハッシュから doc_id を導出するため、バイト単位で同一のコンテンツの再取り込みは自動的にスキップされます(差分ベースの更新)。ただし、同じソース(例: 同じセッション)が LLM によって毎回再要約され、再取り込みされる場合、毎回の要約テキストのわずかな変動により、別のドキュメントとして扱われ、重複が発生する可能性があります。
これを回避するには、一意の識別子タグ(例: session_id:xxx)と更新日時タグ(例: session_last_activity:2026-07-28T15:59:49Z)を付けて取り込み、以降の実行では:
find_by_tag("session_id:xxx")でドキュメントが既に存在するか確認する既存の更新日時タグが現在の値と一致する場合は、スキップ — 何もしない
異なる場合のみ(ソースが変更された場合)、
ingestする前にdelete_document(doc_id, rebuild_index=False)で古いものを削除してから新しいコンテンツを取り込む
この「変更がなければスキップ、変更があれば置き換え」パターンの実装を推奨します。.claude/agents/session-to-memory.md はこのパターンの参考実装です。
使用例(概念)
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)使用方法 ② Claude Code エージェントとして
.claude/agents/rag-memory.md は、このメモリメカニズムの「エージェント側(クラス①)」を担当するサブエージェント定義を提供します。.mcp.json を登録すると、Claude Code から次のように呼び出すことができます:
Use the rag-memory agent to look into past design decisions人間の意図確認が必要なアクションの運用ルール — 重要度タグ付け、knowledge_type の再タグ付け、忘却バッチの実行タイミングの決定 — もこのエージェント定義に記述されています。
さらに、.claude/agents/session-to-memory.md は、過去の Claude Code セッション(チャットのトランスクリプト)を要約し、knowledge_type="experiment" として長期メモリに取り込む専用エージェントです。コストを抑えるために Haiku モデルで実行され、同じセッションを再処理する際は、session_id/更新日時タグを介して既存のエントリと比較し、変更がなければスキップ、変更があれば置き換えます(前のセクションを参照)。呼び出し側は対象とするセッションを明示的に指定する必要があります。無制限にすべてのセッションを対象にすることはありません。
使用方法 ③ Python ライブラリとして直接
MCP サーバーを介さずに、Python コードから直接呼び出すこともできます。
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)CLI から忘却バッチを実行
頻度の低いバッチ実行を想定したスクリプト — 例: 3 か月周期、または新しいモデルがリリースされたとき(サーバー内で自動実行されることはありません)。
python scripts/run_forgetting_batch.py --dry-run
python scripts/run_forgetting_batch.py --score-threshold 0.1 --time-weight 0.8主なオプション: --db-path --index-path --archive-path --time-weight --freq-weight --importance-threshold --score-threshold --dry-run
アーカイブされたチャンクは archive/chunks_archive.jsonl(生テキスト + メタデータ + スコア + 削除理由 + 削除タイムスタンプ)に退避され、そのベクトル表現は破棄されます。
CLI から検索精度を自動評価
手動クエリと Cursor/Claude Code での目視確認に頼るのではなく、ゴールデンクエリセットに対する検索精度(Precision@k/Recall@k/MRR/NDCG@k/Hit Rate@k、権威ドキュメントのランク、ノイズ率)を再現可能な方法で測定するスクリプトです。
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_indices主なオプション: --db-path --index-path --golden-set(デフォルト eval/golden_queries.yaml) --k-values(デフォルト 1,3,5,10) --authority-window(デフォルト 20) --output
類似重複取り込みの監査
ingest の重複検出では、異なるファイル(異なるパス/ファイル名)を介して同一のコンテンツが入り込むケースを検出できません(上記の「同じソースを再登録する際の重複防止」を参照)。このスクリプトは、既存のコーパスにすでに取り込まれている類似重複をリストアップするだけです。何も削除しません。
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.json正規化されたコンテンツハッシュ(documents.content_hash)が一致するドキュメントをグループ化します。どれを保持するか — そして何かを削除するかどうか — はユーザーに委ねられます。delete_document(doc_id, rebuild_index=False) を手動で呼び出し(バッチの最後に必ず rebuild_index を呼び出してください)。
eval/golden_queries.yaml は、実際のコーパスに固有の doc_id を含む個人データであるため、.gitignore されています。レポートは eval/eval_report_<date>.md(および同名の .json)に書き出され、これらも同様に .gitignore されています(継続的な追跡のためにマシン上に残ります)。
メモリメカニズムのフィールド
ingest/Python API の metadata、またはチャンクごとに保持されるフィールド:
フィールド | 型 | 説明 |
|
|
|
|
| エージェントによって後から割り当てられる重要度。未設定( |
|
| 任意のタグ。 |
|
| アクセス頻度。クエリによってチャンクが実際に返されるたびに自動的にインクリメントされます |
|
| 最終アクセス/作成タイムスタンプ。時間減衰の基礎となります |
テスト
pytest tests/ -vtest_metadata_pipeline.py:knowledge_type/importance/tagsが ingest → build_index → query パイプラインを通過することを確認する回帰テストtest_memory_scoring.py: 段階的再ランキング(カットオフ、減衰、頻度ブースト)のユニットテストtest_archival.py: 忘却/アーカイブバッチのユニットテストtest_index_health.py:index_health(インデックス/DB の整合性チェック)のユニットテスト
他のテストファイルの完全なリストと役割については、ファイルレイアウト を参照してください。
ベースライブラリの機能(バックエンド共通)
基本的な RAG 機能 — 密/疎ハイブリッド検索、RRF、Cross-encoder 再ランキング、MMR 多様性選択、クエリ拡張、キャッシュなど — はすべてのバックエンド(FAISS/Qdrant/Chroma/PostgreSQL)で共通です。
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)側面 | FAISS | Qdrant | ChromaDB | PostgreSQL |
フィルタリング検索 | 後処理 | 高速(単一ステージ) | 後処理 | 後処理 |
サーバーが必要 | いいえ | いいえ | いいえ | はい |
スケール | 最大 ~20M | 最大 ~50M | 中規模 | 大規模 |
メモリメカニズム(この README) | ✓ | ✗ | ✗ | ✗ |
オプションのインストール: このリポジトリには pyproject.toml/setup.py がないため、pip install hybrid-rag[...] の形式では配布されません。Qdrant/Chroma/PostgreSQL バージョンを使用するには、対応するクライアントライブラリを直接インストールしてください(pip install qdrant-client / pip install chromadb / pip install "psycopg[binary]" pgvector — これらはすべて requirements.txt にすでに記載されているため、pip install -r requirements.txt だけでカバーされます)。
主な追加設定(FAISS バージョンの 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(デフォルト True)は、knowledge_type=principle のチャンク(または importance>=0.7 のチャンク)がそもそも検索候補プールに入らず、段階的再ランキングでも救済できないという問題(RAG_EVALUATION_REPORT_2026-07-30.md/RAG_精度テスト_2026-07-31.md で報告された「principle ドキュメントが埋もれる問題」)に対処します。これは、検索直後に一致するチャンクを常に候補プールに追加し、Cross-encoder にその関連性をスコアリングさせることで機能します。上位に強制するわけではありません。metadata_filters(filters)を渡す query()/hybrid_search 呼び出しは、このマージをスキップします。
ドキュメント(Sphinx)/ 図(PlantUML)
pip install sphinx sphinx-rtd-theme
python -m sphinx -b html docs/source docs/builddocs/uml/ は、クラス図、シーケンス図、状態遷移図の PlantUML ソースを置くことを意図しています(この記事の執筆時点ではまだ未作成です)。
ファイルレイアウト
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 configurationライセンス
MIT License
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