Modular RAG MCP Server
README.md
# Modular RAG MCP Server
> 面向 DIY 留学服务团队内部顾问的留学申请知识检索与可观测 RAG 基础设施
Modular RAG MCP Server 是一个本地优先、可插拔、可观测的检索增强生成(RAG)服务。系统通过 Model Context Protocol(MCP)向 AI 客户端提供知识检索能力,并通过 Streamlit Dashboard 管理文档、摄取任务、查询链路与评估结果。
本项目源于大学期间的实际协作场景:学院内的 DIY 留学服务团队为同学提供海外高校申请协助,本系统用于解决顾问在院校要求、申请材料、流程规范和历史经验之间反复查找、难以追溯来源的问题。目前系统已完成团队内部部署;公开仓库仅提供匿名合成样例,不包含真实学生资料、内部文档或运行数据。
仓库中的示例资料均应使用匿名合成数据;系统输出是供顾问核验的检索依据,不替代顾问判断,也不构成院校、签证或法律建议。
## 目录
- [业务背景](#业务背景)
- [系统边界](#系统边界)
- [核心能力](#核心能力)
- [系统架构](#系统架构)
- [数据与存储一致性](#数据与存储一致性)
- [MCP Tools](#mcp-tools)
- [Dashboard](#dashboard)
- [快速开始](#快速开始)
- [质量保障](#质量保障)
- [安全与运营约束](#安全与运营约束)
- [当前状态与演进计划](#当前状态与演进计划)
## 业务背景
DIY 留学顾问在处理申请时,需要同时查阅学校官网说明、项目手册、材料模板、内部操作清单和历史案例。原始资料通常以 PDF 形式分散保存,且存在以下问题:
- 同一要求可能以不同措辞出现在多份资料中,纯关键词搜索容易漏召回。
- 院校、专业、学位和入学季等专有名词需要精确匹配,单纯向量检索容易误召回。
- PDF 中的表格、流程图和截图包含重要信息,纯文本解析会丢失上下文。
- 顾问需要知道答案来自哪一份资料、哪一个片段,并判断资料是否仍然有效。
- 文档更新后,向量库、BM25 索引、图片索引和摄取记录必须保持一致。
- 检索效果需要通过稳定测试集回归,而不是依赖主观体验。
系统服务对象是团队内部顾问。典型工作流包括:
1. 将院校项目资料、内部清单和匿名案例摄取到指定 Collection。
2. 通过 MCP Client 或命令行提交自然语言问题。
3. 系统执行 Dense + BM25 双路召回、RRF 融合和可选 Rerank。
4. 返回带来源引用的文本片段,并在命中图片时返回多模态内容块。
5. 通过 Dashboard 检查摄取过程、召回结果、耗时和评估指标。
## 系统边界
本项目负责知识摄取、检索、引用、评估与链路观察,不负责:
- 代替顾问作出选校、录取概率或签证结论。
- 自动提交申请、发送邮件或修改学生材料。
- 提供学生端账户、CRM、支付或申请进度管理。
- 自动抓取并宣称掌握最新院校政策。
- 在缺少来源支撑时生成确定性业务结论。
## 核心能力
| 能力域 | 当前实现 |
|---|---|
| 数据摄取 | PDF → Markdown → Chunk → Transform → Embedding → Upsert |
| 混合检索 | Dense Embedding + BM25 双路召回,RRF 融合 |
| 精排 | Cross-Encoder 或 LLM Rerank,可配置降级 |
| 多模态 | PDF 图片提取、Image Captioning、图文联合检索与 MCP 多模态返回 |
| 存储协同 | Chroma、BM25、SQLite 摄取历史、图片文件与图片索引 |
| 增量处理 | SHA256 去重、稳定 Chunk ID、幂等 Upsert、协调删除 |
| 协议接口 | MCP Stdio Server 与三个知识库 Tools |
| 管理平台 | Streamlit 六页面 Dashboard |
| 可观测性 | Ingestion 与 Query 两条链路的结构化 Trace |
| 质量评估 | Custom Evaluator、Ragas、Golden Test Set |
| 工程结构 | Unit、Integration、E2E 三层测试 |
| 可插拔接口 | LLM、Embedding、Splitter、Reranker、Evaluator、VectorStore |
## 系统架构
```mermaid
flowchart LR
A["PDF 业务资料"] --> B["Ingestion Pipeline"]
B --> C["Chroma 向量库"]
B --> D["BM25 索引"]
B --> E["SQLite 摄取历史"]
B --> F["图片文件与索引"]
G["顾问 / MCP Client"] --> H["MCP Server"]
H --> I["Query Processor"]
I --> J["Dense Retrieval"]
I --> K["Sparse Retrieval"]
J --> L["RRF Fusion"]
K --> L
L --> M["Optional Rerank"]
M --> N["Response + Citations + Images"]
B --> O["Ingestion Trace"]
I --> P["Query Trace"]
O --> Q["Streamlit Dashboard"]
P --> Q
```
核心目录:
```text
src/
├── core/ # 数据契约、查询编排、响应构建、Trace、配置
├── ingestion/ # Chunk、Transform、Embedding、Storage 与 Pipeline
├── libs/ # LLM/Embedding/Loader/Reranker/Splitter/VectorStore 抽象
├── mcp_server/ # MCP 协议处理、Server 与 Tools
└── observability/ # Dashboard、评估与结构化日志
scripts/ # ingest、query、evaluate、Dashboard 启动入口
config/ # Provider、检索、重排、评估与摄取配置
tests/ # Unit、Integration、E2E 测试与固定样例
```
详细的接口、数据流和模块约束见 [DEV_SPEC.md](DEV_SPEC.md)。
## 数据与存储一致性
一次摄取会协调多个存储后端:
| 存储 | 责任 |
|---|---|
| Chroma | Chunk 文本、Dense Vector 与 Metadata |
| BM25 | 稀疏检索倒排索引 |
| SQLite ingestion history | SHA256、处理状态、Collection 与时间 |
| 图片目录 | 从 PDF 提取的原始图片 |
| SQLite image index | 图片、文档、页码与 Collection 的关联 |
文件完整性检查使用 SHA256 跳过已成功处理且未变化的文件。Chunk ID 由来源、位置与内容稳定生成,重复摄取采用幂等 Upsert。`DocumentManager` 负责跨 Chroma、BM25、摄取历史和图片索引进行协调删除,并返回部分失败信息。
## MCP Tools
当前 Server 暴露四个 Tools。前三个通用 Tool 原样保留,第四个是留学业务适配层:
| Tool | 用途 | 主要输入 |
|---|---|---|
| `query_knowledge_hub` | 执行混合检索、可选重排并返回引用 | `query`、`top_k`、`collection` |
| `list_collections` | 列出可查询的 Collection 及统计信息 | `include_stats` |
| `get_document_summary` | 获取指定文档的摘要、标签与来源 | `doc_id`、`collection` |
| `search_admissions_knowledge` | 复用完整混合检索链路,增加留学元数据与时效筛选 | `query`、业务筛选字段、`as_of_date`、`include_expired` |
MCP 使用 Stdio Transport。`stdout` 专用于 JSON-RPC,运行日志写入 `stderr`,避免破坏协议帧。
`search_admissions_knowledge` 默认查询 `admissions_knowledge`,且始终限定 `business_domain=study_abroad_admissions`。它支持按国家、院校、项目、学位层级、入学季、申请轮次和来源类型精确筛选;默认排除 `valid_until` 早于查询业务日期的资料。缺少或无法解析有效期的资料会标记为 `needs_review`,不会被静默视作现行规则。业务 Tool 只是参数与响应适配层,底层仍执行 Dense + BM25、RRF、Cross-Encoder/LLM Rerank、引用和多模态返回。
## Dashboard
Dashboard 保持六页面结构:
1. **Overview**:组件配置、数据资产、运行状态,以及留学资料的现行、待复核和过期统计。
2. **Data Browser**:文档、Chunk、Metadata 和关联图片;支持国家、院校、项目、学位、入学季、申请轮次、来源类型和时效状态组合筛选。
3. **Ingestion Manager**:触发摄取、查看进度并协调删除文档。
4. **Ingestion Traces**:摄取阶段、处理方法、耗时和异常。
5. **Query Traces**:Dense/Sparse 召回、融合、重排与最终结果。
6. **Evaluation Panel**:执行评估并查看指标与历史结果。
## 快速开始
### 1. 环境准备
要求 Python 3.10–3.12。
```bash
git clone https://github.com/xiaoxinbuxingyeyuan/MODULAR-RAG-MCP-SERVER.git
cd MODULAR-RAG-MCP-SERVER
python -m venv .venv
```
Windows PowerShell:
```powershell
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
macOS / Linux:
```bash
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
> `pyproject.toml` 已固定本项目当前验证使用的直接依赖版本。升级 MCP、Ragas、LangChain 或存储组件时,应单独升级并重新执行离线与在线回归。
### 2. 配置 Provider
编辑 `config/settings.yaml`,配置 LLM、Embedding、Vision LLM、VectorStore、Reranker 与评估后端。API Key 应通过安全配置注入,不应提交到仓库。
本地无模型服务时,可关闭非必要的 LLM 增强与 Rerank,用于验证不依赖外部服务的基础链路。
### 3. 摄取文档
```bash
python scripts/ingest.py \
--path tests/fixtures/sample_documents/simple.pdf \
--collection admissions_knowledge
```
目录摄取:
```bash
python scripts/ingest.py \
--path tests/fixtures/sample_documents/ \
--collection admissions_knowledge
```
使用留学业务 Manifest 摄取:
```bash
python scripts/ingest.py \
--path examples/documents/synthetic/ \
--collection admissions_knowledge \
--manifest examples/admissions_manifest.example.jsonl
```
Manifest 使用 UTF-8 JSONL,每行对应一份 PDF。相对 `document_path` 以 Manifest 所在目录为基准解析;必填字段为 `document_path`、`title`、`country` 和 `source_type`。可选字段包括 `institution`、`program`、`degree_level`、`intake`、`application_round`、`published_at`、`valid_until`、`language`、`tags` 与 `access_scope`。完整示例见 [`examples/admissions_manifest.example.jsonl`](examples/admissions_manifest.example.jsonl)。
传入 Manifest 后,每份待摄取 PDF 都必须有唯一匹配项。未知字段、重复路径、非法枚举和日期倒置会在写入存储前失败。Manifest 元数据会由 Document 传播到 Chunk 与 Chroma 记录;Chunk 级 LLM 标题和标签不会覆盖 `document_title` 与 `business_tags`。
增量判断同时比较 PDF SHA256 与规范化业务元数据 SHA256:两者都未变化才跳过;只修改 Manifest 会自动重新摄取并覆盖稳定 Chunk ID 对应的元数据。PDF 内容变化时,系统先写入新版本,再按旧 `doc_hash` 清理 Chroma Chunk、图片和旧摄取记录;BM25 按稳定来源路径前缀替换 postings。旧版 SQLite 摄取历史会自动增加 `metadata_hash` 字段,无需手工迁移。`--force` 仍可用于显式重建,但不再是应用 Manifest 更新的必要条件。
仓库提供三份完全虚构、无个人信息的业务样例,分别覆盖现行资料、有效期缺失和已过期资料,其中课程指南包含一张用于多模态链路验证的流程图。需要重新生成样例 PDF 时运行:
```bash
python examples/generate_synthetic_admissions_pdfs.py
```
### 4. 命令行查询
```bash
python scripts/query.py \
--query "申请材料需要包含哪些证明?" \
--collection admissions_knowledge \
--verbose
```
### 5. 启动 Dashboard
```bash
python scripts/start_dashboard.py
```
默认地址为 `http://localhost:8501`。
### 6. 启动 MCP Server
```bash
python -m src.mcp_server.server
```
不同 MCP Client 的配置格式略有差异,核心进程配置如下:
```json
{
"command": "<project>/.venv/Scripts/python.exe",
"args": ["-m", "src.mcp_server.server"],
"cwd": "<project>"
}
```
macOS / Linux 将 Python 路径替换为 `<project>/.venv/bin/python`。
### 7. 执行评估
```bash
python scripts/evaluate.py \
--test-set examples/admissions_golden_test_set.json \
--collection admissions_knowledge
```
无外部检索环境时可运行:
```bash
python scripts/evaluate.py --no-search
```
## 质量保障
项目采用三层测试结构:
- **Unit**:数据契约、算法、Factory、Tool Handler 与存储适配器。
- **Integration**:摄取、混合检索、MCP、Provider 和 Trace 组合行为。
- **E2E**:CLI 摄取、MCP Client、Dashboard smoke 与 Recall 回归。
```bash
python -m pytest tests/unit
python -m pytest tests/integration
python -m pytest tests/e2e
python -m pytest
```
以上命令默认跳过所有标记为 `online` 的用例,不会主动调用真实 Provider。需要真实 Azure、OpenAI 或 Ollama 服务时,在对应凭据和服务可用的环境中显式运行:
```bash
python -m pytest --run-online -m online
```
OpenAI 兼容网关可通过 `OPENAI_API_KEY`、`OPENAI_BASE_URL` 和 `OPENAI_MODEL` 注入,不需要修改仓库配置或提交凭据。未配置的 Provider 用例应保持跳过状态。
只检查在线用例是否正确归类、但不发起调用时,可运行 `python -m pytest --collect-only -m online`。离线与在线结果应分开记录;`--run-online` 只解除跳过限制,不会替代 Provider 配置。
评估层继续支持 Custom Evaluator 与 Ragas。业务 Golden Test Set 额外记录组合筛选、业务日期、过期策略、期望来源和参考答案;离线业务验收同时检查这些字段与 MCP 业务适配器的时效行为。通用评估接口和原有 Golden Test Set 均未修改。
## 安全与运营约束
- 默认采用本地 Stdio 和本地存储,不开放网络端口。
- 不在日志、Trace、测试固定数据或 Git 历史中保存 API Key 与学生个人信息。
- 业务资料进入知识库前应完成授权确认和隐私脱敏。
- 检索结果必须保留来源引用,无法找到可靠依据时应返回空结果或提示人工核验。
- 院校要求具有时效性;业务 Tool 默认排除已过 `valid_until` 的资料,并显式提示有效期缺失项,但顾问仍必须核对官方来源。
- 当前架构是单用户本地服务,不提供身份认证、权限隔离或多租户保证。
## 当前状态与演进计划
现有 `main` 已具备完整的通用 RAG、MCP、Dashboard、Trace 和评估骨架。留学领域改造按增量方式推进,不能删除或简化现有技术能力。
| 阶段 | 状态 | 内容 |
|---|---|---|
| 通用 RAG 基线 | 已存在 | 摄取、混合检索、重排、多模态、多存储、Trace、评估与三层测试 |
| 业务化文档 | 已完成 | 公开叙事、系统边界与工程规格已改为内部顾问知识检索场景 |
| 依赖基线稳定化 | 已完成 | 固定已验证的直接依赖版本,默认跳过真实 Provider 测试并提供显式在线入口 |
| 留学文档清单 | 已完成 | JSONL Schema、严格校验、路径匹配、CLI 摄取入口及 Chunk/Chroma 元数据传播 |
| 元数据增量更新 | 已完成 | PDF SHA256 + 规范化元数据 SHA256、SQLite 自动迁移与内容版本协调替换 |
| 业务 MCP Tool | 已完成 | 保留原三个 Tool,新增 `search_admissions_knowledge`、组合 Metadata Filter、时效状态与业务引用元数据 |
| Dashboard 业务字段 | 已完成 | 保持六页面结构,仅在 Overview 和 Data Browser 增加业务元数据、组合筛选与时效统计 |
| 合成业务评估集 | 已完成 | 三份虚构 PDF、可重生成脚本、Manifest 与七类 Golden Test Case |
| 业务回归验收 | 已完成 | 新增离线 fixture、时效、组合筛选与图片提取 smoke;不改核心检索链路 |
任何阶段的实现都必须保留 PDF 全链路摄取、Dense + BM25、RRF、Rerank、多模态、多存储协同、增量与删除、原有三个 MCP Tools、六页面 Dashboard、双链路 Trace、Custom + Ragas、三层测试及全部可插拔接口。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues