rag-mcp-server

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.

Category
访问服务器

README

RAG-MCP-SERVER

一个可插拔、全链路可观测的模块化 RAG 检索服务。以 MCP(Model Context Protocol)工具的形式对外暴露检索能力,可被 Claude Desktop、GitHub Copilot 等 MCP Client 直接调用。

核心设计目标是解决 RAG 工程中两个具体痛点:

  1. 链路难定位 —— 检索结果不对,问题出在召回、融合还是重排?索引与查询两条链路共 10 个阶段逐阶段记录耗时、候选数、分数以及排名变化,Dashboard 可视化回溯。
  2. 调优靠感觉 —— 换个 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

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选