rag-mcp-server
Enables MCP clients to query a modular RAG knowledge hub with hybrid dense/sparse retrieval, reranking, multimodal image support, and traceable observability, all through natural language tools.
README
RAG-MCP-SERVER
一个可插拔、全链路可观测的模块化 RAG 检索服务。以 MCP(Model Context Protocol)工具的形式对外暴露检索能力,可被 Claude Desktop、GitHub Copilot 等 MCP Client 直接调用。
核心设计目标是解决 RAG 工程中两个具体痛点:
- 链路难定位 —— 检索结果不对,问题出在召回、融合还是重排?索引与查询两条链路共 10 个阶段逐阶段记录耗时、候选数、分数以及排名变化,Dashboard 可视化回溯。
- 调优靠感觉 —— 换个 Embedding 模型到底变好还是变坏?Hit Rate@K / MRR 与 Ragas Faithfulness / Context Precision 联合评估,基于固定测试集做回归,用指标而非主观判断校准。
目录
架构总览
┌──────────────────────────────────────────┐
文档 (PDF/DOCX/ │ Ingestion Pipeline │
MD/TXT) ───▶ │ load → split → transform → embed → │
│ upsert │
└────────────────┬─────────────────────────┘
│ SHA256 指纹 + SQLite 摄取历史
│ (文档级增量索引 / 幂等)
▼
┌──────────────────────────────────────────┐
│ ChromaDB (Dense) + BM25 (Sparse) │
└────────────────┬─────────────────────────┘
▼
┌──────────────────────────────────────────┐
查询 ───▶│ Query Engine │
│ query_processing → dense ┐ │
│ ├→ RRF fusion │
│ sparse ┘ │ │
│ ▼ │
│ rerank │
│ (失败回退至 RRF 顺序) │
└────────────────┬─────────────────────────┘
▼
┌───────────────┬───────────────┬──────────────────┐
│ MCP Server │ CLI Scripts │ Dashboard │
│ (3 tools) │ (5 scripts) │ (Streamlit 6页) │
└───────────────┴───────────────┴──────────────────┘
贯穿全程:TraceContext(trace → stage)写入 logs/traces.jsonl
可插拔底座
每个核心环节都定义了统一 Base 接口,通过 Factory + YAML 配置切换,替换组件零代码修改:
| 环节 | 接口 | 已实现的 Provider |
|---|---|---|
| LLM | BaseLLM |
openai / azure / deepseek / kimi / ollama |
| Vision LLM | BaseVisionLLM |
openai / azure / kimi |
| Embedding | BaseEmbedding |
openai / azure / siliconflow / bge / ollama |
| Vector Store | BaseVectorStore |
chroma |
| Splitter | BaseSplitter |
recursive |
| Reranker | BaseReranker |
llm / cross_encoder(BGE) |
| Evaluator | BaseEvaluator |
custom / ragas / composite |
| Loader | BaseLoader |
pdf / docx / markdown / text |
任何 OpenAI 兼容端点都可以走
provider: "openai"+ 自定义base_url接入,无需新增代码。
核心能力
混合检索:BM25 稀疏检索负责专有名词精确匹配,Dense 向量检索负责语义匹配,双路召回后 RRF 融合,再由 Reranker 精排。重排后端失败时自动回退到 RRF 融合顺序,不会让一次超时打断整条链路。
增量索引与幂等:SHA256 内容指纹 + SQLite ingestion_history 表实现文档级增量。重复摄取直接跳过,内容变更才重建,重复摄取不产生脏数据。
多模态:PyMuPDF 提取 PDF 内嵌图片并保留原始位置,Vision LLM 生成图片描述缝合进 Chunk,从而复用纯文本 RAG 链路实现"搜文字出图"。MCP 响应以 ImageContent 返回图片。
MCP 工具:
| Tool | 用途 |
|---|---|
query_knowledge_hub |
混合检索 + 重排,返回带引用的结果(含图片) |
list_collections |
列出所有集合及文档/分块统计 |
get_document_summary |
返回指定文档的摘要与分块概览 |
Dashboard(Streamlit 六页):系统总览 / 数据浏览 / 摄取管理 / 摄取追踪 / 查询追踪 / 评估面板。
快速开始
环境要求
Python ≥ 3.10。
安装
git clone <your-repo-url>
cd RAG-MCP-SERVER
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux / macOS
source .venv/bin/activate
pip install -e ".[dev]"
依赖全部带版本上界。
mcp锁在<2.0(2.x 重命名了CallToolResult.isError等字段),langchain-community锁在<0.4(0.4 移除了chat_models.vertexai,会导致 ragas 导入失败)。
配置
cp config/settings.yaml.example config/settings.yaml
编辑 config/settings.yaml 填入自己的 API Key。该文件已被 .gitignore 忽略,不要提交。
摄取文档
python scripts/ingest.py --path ./your_docs --collection my_kb
python scripts/ingest.py --path ./your_docs --collection my_kb --force # 强制重建
python scripts/ingest.py --path ./your_docs --dry-run # 只看会处理哪些文件
查询
python scripts/query.py -q "你的问题" -c my_kb --top-k 5 --verbose
--verbose 会打印 dense / sparse / fusion / rerank 每一步的中间结果。
启动 Dashboard
python scripts/start_dashboard.py
接入 MCP Client
以 Claude Desktop 为例,在 claude_desktop_config.json 中加入:
{
"mcpServers": {
"rag-mcp-server": {
"command": "<绝对路径>/.venv/Scripts/python.exe",
"args": ["<绝对路径>/main.py"]
}
}
}
配置说明
关键配置段(完整注释见 config/settings.yaml.example):
retrieval:
dense_top_k: 20
sparse_top_k: 20
fusion_top_k: 10
rrf_k: 60
# 路由开关,用于 A/B 基线:只测 dense 则 enable_sparse: false,反之亦然
enable_dense: true
enable_sparse: true
rerank:
enabled: true
provider: "llm" # 走已配置的 LLM,零额外依赖
# provider: "cross_encoder" # 本地 BGE cross-encoder,需 pip install sentence-transformers
top_k: 5
evaluation:
enabled: true
provider: "composite" # 同时跑检索指标与生成指标
backends: ["custom", "ragas"]
metrics: ["hit_rate", "mrr", "faithfulness", "context_precision"]
embedding.dimensions一旦首次摄取完成就不能再改 —— 已存在的 Chroma collection 与向量维度绑定。
可观测性
每次摄取和查询都会生成一条 trace 写入 logs/traces.jsonl,结构为 trace → stages[],每个 stage 记录 elapsed_ms 与该阶段的 data。
| 链路 | 阶段 |
|---|---|
| Ingestion | load → split → transform → embed → upsert |
| Query | query_processing → dense_retrieval → sparse_retrieval → fusion → rerank |
排名变化追踪
只记录每个阶段结束后的分数列表,无法回答"这一阶段到底改善了排序吗、改善了哪个分块"。因此 fusion 与 rerank 两个阶段额外记录排名变化(src/core/query_engine/rank_tracking.py):
- 约定 1-based,
rank_delta = rank_before - rank_after,正值表示排名上升 fusion的rank_before取该分块在双路中的最优排名,回答"RRF 是否把它提升到了单路召回之上";同时记录dense_rank/sparse_rank,显示它由哪条路召回rerank的rank_before是交给重排器的融合列表位置,精确显示重排器提升/打压了谁- 新进入的分块上报
None而非伪造的排名提升 - 阶段级汇总:
moved_up/moved_down/unchanged/new/max_gain/max_drop/dropped
实际 trace 片段:
stage=fusion elapsed=0.2ms
rank_changes: {moved_up: 3, moved_down: 1, unchanged: 1, max_gain: 2, dropped: 18}
rank=2 before=4 delta=+2 dense_rank=4 sparse_rank=4
stage=rerank elapsed=12231ms
rank_changes: {moved_up: 1, moved_down: 1, unchanged: 3, max_gain: 1}
rank=1 before=2 delta=+1
Dashboard 的「查询追踪」页会把这些渲染成阶段瀑布图 + 排名变化表。
评估体系
python scripts/evaluate.py --collection my_kb
python scripts/experiment.py --variants dense,sparse,hybrid,hybrid_rerank
- 检索指标(
CustomEvaluator):Hit Rate@K、MRR —— 需要测试集提供expected_chunk_ids作为 ground truth - 生成指标(
RagasEvaluator):Faithfulness、Answer Relevancy、Context Precision CompositeEvaluator同时跑两类后端并合并结果;每个后端各自从共享的metrics列表中挑出属于自己的指标,单个后端失败不影响其余
scripts/experiment.py 用于 A/B 对比不同检索变体,输出各变体的指标与延迟,用来回答"加上 rerank 到底值不值这 12 秒"。
测试
分层测试,共 1456 个用例:
pytest tests/unit # 1298 passed, 1 skipped
pytest tests/integration -m "not llm" # 94 passed, 10 skipped
pytest tests/e2e -m "not llm" # 30 passed, 2 skipped
-m "not llm" 排除需要真实 LLM API 调用的用例。缺少某个 Provider 的凭证时,相关用例会 skip 并给出原因,而不是失败。
关键分支都有针对性覆盖:
| 关注点 | 测试 |
|---|---|
| RRF 融合 | test_fusion_rrf.py |
| 重排降级路径 | test_reranker_fallback.py |
| 幂等写入 | test_vector_upserter_idempotency.py |
| 排名变化追踪 | test_rank_tracking.py |
| 分词器索引/查询一致性 | test_sparse_encoder.py / test_query_processor.py |
| Chroma 客户端并发构建 | test_chroma_client.py |
| 向量存储契约 | test_vector_store_contract.py |
项目结构
src/
├── core/
│ ├── query_engine/ # 混合检索:dense / sparse / RRF fusion / rerank
│ │ └── rank_tracking.py # 排名变化计算(融合与重排共用)
│ ├── response/ # 响应组装、引用生成、多模态拼装
│ ├── trace/ # TraceContext:trace → stage
│ ├── tokenization.py # BM25 分词器(索引端与查询端唯一实现)
│ └── settings.py # YAML 配置加载与校验
├── ingestion/
│ ├── chunking/ embedding/ storage/ transform/
│ ├── pipeline.py # 五阶段摄取流水线
│ └── document_manager.py # 文档删除(跨 Chroma / BM25 / 图片 / 摄取历史)
├── libs/ # 可插拔底座:base_*.py + *_factory.py
│ ├── llm/ embedding/ loader/ reranker/ splitter/ vector_store/ evaluator/
├── mcp_server/ # MCP 协议与 3 个 Tool
└── observability/
├── dashboard/ # Streamlit 六页
└── evaluation/ # ragas / composite / eval_runner
scripts/ ingest / query / evaluate / experiment / start_dashboard
config/ settings.yaml.example + prompts/
tests/ unit / integration / e2e
data/(Chroma、BM25 索引、抽取出的图片、摄取历史)与logs/(trace)都是运行时 生成的本地产物,已被.gitignore忽略,不随仓库分发;首次运行时会自动创建。
License
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.