多知识库检索增强生成系统

一个支持多知识库管理、渐进式文档提取、混合搜索和语义路由的检索增强生成系统,适用于企业知识管理和智能问答场景。

  • by Pond500
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Pond500/rag_mcp

使用说明

具有渐进式VLM提取的多KB RAG系统v2.1

生产就绪的多知识库RAG系统 具有2层渐进式文档提取(文档→ Gemini Pro VLM)、混合搜索(密集+稀疏BM25)、RRF融合、重新排序和通过模型上下文协议(MCP)的语义路由。通过Langfuse集成完全可观察到。


🌟 特性

核心能力

  • 🎯 多KB管理 -管理多个独立的知识库
  • 📄 渐进式文档提取 -双层战略(Docling→ Gemini Pro)
    • 第1层:文本PDF文档(免费,约10s/doc)
    • 第3级:Gemini Pro VLM(0.0013美元/页),适用于复杂/扫描的PDF
    • 基于质量的升级(5维评分)
    • 自动VLM成本跟踪(实际OpenRouter API成本)
  • � 混合搜索 -密集矢量(BAAI/bge-m3)+稀疏BM25(Qdrant/BM25)
  • 🔀 RRF融合 -基于互逆秩融合的最优结果融合
  • 🎓 重新排序 -用于精度的交叉编码器(BAAI/bge-ranker-v2-m3)
  • 🧭 语义路由 -基于查询语义的知识库自动选择
  • 💬 对话历史 -基于会话的聊天,具有上下文保留功能
  • � 完全可观察性 -Langfuse集成跟踪、成本和评估指标
  • 🤖 LLM集成 -OpenRouter API网关(Gemini、GPT-4、Claude、本地LLM)

建筑亮点

  • ✨ 整洁架构 -关注点分离(配置、模型、核心、服务、mcp、可观察性)
  • 🔌 延迟加载 -模型通过回退机制按需加载
  • ⚙️ 类型安全配置 -支持环境变量的Pydantic设置
  • 📊 生产测井 -彩色控制台+带请求跟踪的旋转文件日志
  • 📈 可观测性 -Langfuse跟踪与成本/延迟跟踪、评估分数
  • 🧪 综合测试 -所有层的单元和集成测试
  • 🚀 MCP协议 -带有13个MCP工具的FastAPI服务器+REST API端点
  • 💰 成本优化 -90%的文档使用免费层(文档),节省80%的成本

📋 目录


🚀 快速开始

先决条件

  • Python 3.10+
  • Docker(适用于Qdrant)
  • OpenRouter API密钥(用于VLM提取-可选)
  • Langfuse实例(用于可观察性-可选)

1.克隆和安装

git clone https://github.com/Pond500/rag-mcp-server.git
cd mcp_rag_v2

# Create virtual environment
python3 -m venv venv
source venv/bin/activate  # or `venv\Scripts\activate` on Windows

# Install base dependencies
pip install -r requirements.txt

# Install VLM dependencies (for progressive extraction)
pip install -r requirements_progressive.txt

2.启动Qdrant

docker-compose up -d

3.配置环境

cp .env.example .env
# Edit .env with your settings:
# - OPENROUTER_API_KEY (for VLM extraction)
# - LANGFUSE credentials (for observability)
# - LLM settings (OpenRouter models)

4.运行服务器

# Standard mode
python scripts/run_server.py

# With Ngrok tunnel (for external access)
bash scripts/start_with_ngrok.sh

# Or using uvicorn directly
uvicorn mcp.server:app --reload --port 8000

5.访问API

  • API: http://localhost:8000
  • OpenAPI文档: http://localhost:8000/docs
  • 健康检查: http://localhost:8000/tools/health
  • Langfuse仪表板: http://your-langfuse-host:3000(如果已配置)

📦 安装

选项1:标准安装(基本RAG)

# Install Python dependencies
pip install -r requirements.txt

# Start Qdrant
docker-compose up -d

# Verify installation
python test_config.py

选项2:完全安装(具有VLM+可观测性)

# Install base + VLM dependencies
pip install -r requirements.txt
pip install -r requirements_progressive.txt

# Start Qdrant
docker-compose up -d

# Configure Langfuse (optional)
# Set LANGFUSE_* variables in .env

# Run tests
python -m pytest tests/

⚙️ 配置

环境变量

创建一个 .env 文件(使用 .env.example 作为模板):

# Qdrant Settings
QDRANT_HOST=localhost
QDRANT_PORT=6333
QDRANT_TIMEOUT=30

# LLM Settings (OpenRouter)
OPENROUTER_API_KEY=sk-or-v1-...
OPENROUTER_MODEL=google/gemini-2.0-flash-exp:free
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1

# VLM Extraction Settings
ENABLE_PROGRESSIVE_EXTRACTION=true
OPENROUTER_VLM_MODEL_FREE=google/gemini-2.0-flash-exp:free
OPENROUTER_VLM_MODEL_PREMIUM=google/gemini-2.5-pro
IMAGE_DPI=200
TARGET_QUALITY=0.70

# Langfuse Observability (optional)
LANGFUSE_ENABLED=true
LANGFUSE_HOST=http://localhost:3000
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PROJECT=mcp-rag-v2
LANGFUSE_ENVIRONMENT=development

# Embedding Settings
EMBEDDING_MODEL=BAAI/bge-m3
EMBEDDING_DIMENSION=1024
SPARSE_EMBEDDING_MODEL=Qdrant/bm25

# Search Settings
SEARCH_TOP_K=5
SEARCH_RRF_K=60
RERANK_THRESHOLD=0.0

# Document Processing
CHUNK_SIZE=1000
CHUNK_OVERLAP=200

配置文件

  • src/config/settings.py -Pydantic设置类
  • src/config/prompts.yaml -系统提示和模板
  • .env -环境特定设置

🎯 用法

开发包

from src.config import get_settings
from src.services import RAGService

# Initialize service
settings = get_settings()
service = RAGService.from_settings(settings)

# 1. Create Knowledge Base
result = service.create_kb(
    kb_name="company_docs",
    description="Company documentation and policies",
    category="internal"
)

# 2. Upload Document (with Progressive VLM Extraction)
with open("policy.pdf", "rb") as f:
    result = service.upload_document(
        kb_name="company_docs",
        filename="policy.pdf",
        file_content=f.read()
    )

# Check extraction results
print(f"VLM Cost: ${result['vlm_cost']:.4f}")
print(f"Pages: {result['pages_processed']}")
print(f"Chunks: {result['chunks_created']}")
print(f"Extraction Quality: {result.get('extraction_quality', 'N/A')}")

# 3. Search
result = service.search(
    query="What is the vacation policy?",
    kb_name="company_docs",
    top_k=5
)

# 4. Chat with RAG
result = service.chat(
    query="How many vacation days do I get?",
    kb_name="company_docs",
    session_id="user_123"
)

print(result["answer"])

REST API

# Create KB
curl -X POST http://localhost:8000/tools/create_kb \
  -H "Content-Type: application/json" \
  -d '{
    "kb_name": "my_kb",
    "description": "My knowledge base",
    "category": "general"
  }'

# Upload Document
curl -X POST http://localhost:8000/tools/upload_document \
  -F "kb_name=my_kb" \
  -F "file=@document.pdf"

# Search
curl -X POST http://localhost:8000/tools/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Your question here",
    "kb_name": "my_kb",
    "top_k": 5
  }'

# Chat
curl -X POST http://localhost:8000/tools/chat \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Your question here",
    "kb_name": "my_kb",
    "session_id": "session_123"
  }'

📚 API文档

MCP工具(端点)

1. POST /tools/create_kb

创建新的知识库

{
  "kb_name": "string",
  "description": "string",
  "category": "general" | "dopa" | "fidf" | "contracts" | etc.,
  "enable_routing": true
}

2. POST /tools/delete_kb

删除知识库

{
  "kb_name": "string"
}

3. GET /tools/list_kbs

列出所有知识库

答复:

{
  "success": true,
  "kbs": [
    {
      "name": "string",
      "description": "string",
      "category": "string",
      "document_count": 0,
      "vector_count": 0,
      "created_at": "2026-01-06T..."
    }
  ]
}

4. POST /tools/upload_document

上传带有渐进式VLM提取的文档(多部分/表单数据)

  • kb_name:string(必填)
  • file:文件(PDF、DOCX、TXT、XLSX、PPTX)
  • description:string(可选)

答复:

{
  "success": true,
  "vlm_cost": 0.0078,
  "pages_processed": 6,
  "chunks_created": 45,
  "document_name": "policy.pdf",
  "extraction_tier": "premium",
  "extraction_quality": 0.97,
  "processing_time_seconds": 368.5
}

5. POST /tools/search

混合搜索(密集+稀疏+重新排名)

{
  "query": "string",
  "kb_name": "string" | null,
  "top_k": 5,
  "use_routing": true,
  "use_reranking": true,
  "include_metadata": true,
  "deduplicate": true
}

答复:

{
  "success": true,
  "query": "string",
  "kb_name": "string",
  "total_results": 5,
  "results": [
    {
      "text": "string",
      "score": 0.95,
      "metadata": {...}
    }
  ],
  "metadata_summary": [...]
}

6. POST /tools/chat

与RAG聊天(有对话历史记录)

{
  "query": "string",
  "kb_name": "string" | null,
  "session_id": "string" | null,
  "top_k": 5,
  "use_routing": true,
  "use_reranking": true
}

答复:

{
  "success": true,
  "query": "string",
  "answer": "string",
  "kb_name": "string",
  "session_id": "string",
  "sources": [...],
  "documents_used": 3,
  "tokens": {
    "input": 150,
    "output": 200,
    "total": 350
  },
  "cost": 0.0005
}

7. POST /tools/clear_history

清除对话历史记录

{
  "session_id": "string"
}

8. GET /tools/health

健康检查

答复:

{
  "status": "healthy",
  "version": "2.1.0",
  "qdrant": "connected",
  "embedding_model": "BAAI/bge-m3",
  "langfuse": "enabled",
  "progressive_extraction": "enabled"
}

附加工具:

  • 9-13:文档管理(列表、获取、更新、删除、列出文档)

看 /docs API完整文档的终结点。


🏗️ 建筑

mcp_rag_v2/
├── src/
│   ├── config/              # Configuration (Pydantic Settings + YAML prompts)
│   │   ├── settings.py
│   │   └── prompts.yaml
│   ├── utils/               # Utilities (logging, helpers)
│   │   └── logger.py
│   ├── models/              # Model wrappers (embeddings, reranker, llm)
│   │   ├── embeddings.py
│   │   ├── reranker.py
│   │   └── llm.py
│   ├── core/                # Core business logic
│   │   ├── collection_manager.py        # KB CRUD
│   │   ├── document_processor.py        # Docling extraction (Tier 1)
│   │   ├── progressive_processor.py     # VLM orchestrator (Tier 2-3)
│   │   ├── openrouter_extractor.py      # OpenRouter VLM API
│   │   ├── quality_checker.py           # 5-dimension quality scoring
│   │   ├── metadata_extractor.py        # AI metadata extraction
│   │   ├── vector_store.py              # Qdrant operations
│   │   ├── retriever.py                 # Hybrid Search + RRF + Reranking
│   │   ├── router.py                    # Semantic routing
│   │   └── chat_engine.py               # LLM chat with history
│   ├── services/            # Service layer (RAG orchestrator)
│   │   └── rag_service.py
│   └── observability/       # Langfuse integration
│       ├── __init__.py
│       ├── tracer.py                    # Base tracer interface
│       ├── mcp_tracer.py                # MCP tool tracer
│       ├── langfuse_tracer.py           # Langfuse implementation
│       └── langfuse_config.py           # Langfuse configuration
├── mcp/                     # MCP Server (FastAPI)
│   └── server.py
├── scripts/                 # Utility scripts
│   ├── run_server.py
│   ├── start_with_ngrok.sh
│   ├── post_mock_scores.py              # Mock evaluation scores
│   └── test_chat_10queries.sh           # Batch testing
├── tests/                   # Tests
│   ├── unit/
│   └── integration/
├── docs/                    # Documentation
│   ├── PROGRESSIVE_EXTRACTION.md
│   ├── OPENROUTER_QUICKSTART.md
│   ├── LANGFUSE_MOCK_SCORES.md
│   └── archive/
├── docker-compose.yml       # Qdrant setup
├── requirements.txt         # Base dependencies
├── requirements_progressive.txt  # VLM dependencies
├── .env.example             # Environment template
└── README.md

关键设计模式

  • 整洁架构:分层(可观察性、模型、核心、服务、api)
  • 两级渐进战略:成本优化的文档提取(文档处理→ Gemini Pro)
  • 依赖注入:服务通过构造函数接收依赖关系
  • 延迟加载:模型在首次使用时通过回退机制加载
  • 单例模式:服务和设置使用单例模式
  • 存储库模式:VectorStore抽象Qdrant操作
  • 观察者模式:整个堆栈的Langfuse跟踪

🔍 渐进式提取和混合搜索的工作原理

渐进式文档提取(双层策略)

User Upload PDF
    ↓
Tier 1: FAST (Docling - NO OCR)
├─ Cost: $0.00 (FREE)
├─ Time: ~5-10 seconds
├─ Quality Target: ≥ 0.70
└─ Works on: PDFs with text layer
    ↓ (if quality < 0.70 or empty)
Tier 3: PREMIUM (Gemini Pro VLM)
├─ Cost: $0.0013/page
├─ Time: ~60 seconds/page
├─ Quality Target: ≥ 0.95
└─ Works on: Scanned PDFs, complex documents, Thai language
    ↓
Quality Check (5 dimensions)
├─ text_quality (0.25 weight)
├─ word_quality (0.20 weight)
├─ consistency (0.15 weight)
├─ structure_quality (0.20 weight)
└─ content_density (0.20 weight)
    ↓
Auto Cost Tracking → Langfuse

备注:由于速率限制问题,第2层(Gemini Flash Free)已禁用。

混合搜索管道

User Query
    ↓
1. Embedding (Dense + Sparse)
    ├─ Dense: BAAI/bge-m3 (1024-dim vector)
    └─ Sparse: BM25 (keyword matching)
    ↓
2. Parallel Search
    ├── Dense Search (Cosine Similarity)
    └── Sparse Search (BM25 Score)
    ↓
3. RRF Fusion (Reciprocal Rank Fusion)
    Formula: score(d) = Σ 1/(k + rank_i(d))
    ↓
4. Reranking (CrossEncoder)
    Model: BAAI/bge-reranker-v2-m3
    ↓
5. Deduplication (optional)
    ↓
6. Top-k Results → LLM Context
    ↓
7. Answer Generation (OpenRouter)
    ↓
8. Full Trace → Langfuse Dashboard

🛠️ 发展

项目结构

src/
  config/     - Configuration management
  utils/      - Shared utilities
  models/     - ML model wrappers
  core/       - Business logic
  services/   - High-level orchestration
mcp/          - API layer
tests/        - Test suites

添加新功能

1.添加新的模型包装

# src/models/your_model.py
class YourModel:
    def __init__(self, config):
        self.config = config
        self._model = None
    
    def _load(self):
        # Lazy loading logic
        pass

2.添加新的核心模块

# src/core/your_module.py
class YourModule:
    def __init__(self, dependencies):
        self.deps = dependencies
    
    def process(self, data):
        # Business logic
        pass

3.添加新的API端点

# mcp/server.py
@app.post("/tools/your_tool")
async def your_tool(request: YourRequest):
    service = get_service()
    result = service.your_method(...)
    return JSONResponse(content=result)

🧪 测试

运行所有测试

# Unit tests
python -m pytest tests/unit/

# Integration tests
python tests/integration/test_core_workflow.py
python tests/integration/test_phase4.py
python tests/integration/test_rag_service.py

# MCP Server tests (requires running server)
python tests/integration/test_mcp_server.py

测试覆盖率

  • ✅ 模型包装器(嵌入、重新链接、llm)
  • ✅ 核心模块(收集、文档、渐进提取、元数据、矢量存储)
  • ✅ 高级模块(检索器、路由器、聊天引擎)
  • ✅ 服务层(具有VLM成本跟踪的RAG编排器)
  • ✅ MCP服务器(13个API端点)
  • ✅ 可观察性(Langfuse追踪、成本追踪)
  • ✅ 质量评分(5维提取质量)

测试脚本

# Unit tests
python -m pytest tests/unit/

# Integration tests
python tests/integration/test_core_workflow.py
python tests/integration/test_phase4.py
python tests/integration/test_rag_service.py
python tests/integration/test_mcp_server.py

# Full system test
python tests/full_system_test.py

# Batch chat testing (10 queries)
bash scripts/test_chat_10queries.sh

# Mock evaluation scores (Langfuse)
python scripts/post_mock_scores.py

🚀 部署

Docker部署

# Build image
docker build -t mcp-rag-v2 .

# Run with docker-compose
docker-compose -f docker-compose.prod.yml up -d

环境特定设置

# Development
export ENV=development

# Production
export ENV=production
export OPENAI_API_KEY=your-prod-key
export QDRANT_HOST=qdrant.production.internal

生产清单

  • []设置强 OPENROUTER_API_KEY
  • []配置Langfuse以实现可观察性
  • []配置Qdrant持久卷
  • []设置日志聚合
  • []启用HTTPS/TLS
  • []配置速率限制
  • []设置监控(健康检查+廊坊)
  • []配置备份策略
  • []检查安全设置
  • []设置VLM提取层策略(成本与质量)
  • []配置ngrok以进行外部访问(可选)

🐛 故障排除

常见问题

1.Qdrant连接错误

Error: [Errno 61] Connection refused

解决方案:使用以下命令启动Qdrant docker-compose up -d

2.VLM提取失败

Error: OpenRouter API rate limit exceeded

解决方案:

  • 系统自动从第1级(文档)升级到第3级(高级)
  • 由于速率限制,第2层(Gemini Flash Free)当前已禁用
  • 向OpenRouter帐户添加积分以获得高级等级
  • 目标质量较低,更频繁地使用第1层(文档)

3.未找到嵌入模型

Model BAAI/bge-m3 is not supported

解决方案:系统使用回退嵌入。对于生产,请安装兼容的fastembed版本或使用不同的型号。

4.导入错误

ImportError: cannot import name 'RAGService'

解决方案:确保PYTHONPATH包括项目根:

export PYTHONPATH=/path/to/mcp_rag_v2:$PYTHONPATH

5.廊坊连接失败

Error: Failed to connect to Langfuse

解决方案:

  • 检查LANGFUSE_HOST是否正确
  • 验证LANGFUSE_PUBLIC_KEY和LANGFUSE_SECRET_KEY
  • 确保Langfuse服务器正在运行
  • 如果不需要,将LANGFUSE_ENABLED=false设置为禁用

6.VLM成本显示为0.00美元

Warning: VLM cost tracking returned None

解决方案:确保OpenRouter API响应包括 usage.total_cost 现场。系统现在从API中提取实际成本。

7.延迟显示0秒

Warning: Trace latency is 0s

解决方案:确保Langfuse生成生命周期正确(start_generation→ 工具执行→ end).已在v2.1中修复。


📝 配置参考

VLM提取设置

  • ENABLE_PROGRESSIVE_EXTRACTION (默认值:true)-启用2层提取
  • TARGET_QUALITY (默认值:0.70)-最低可接受质量分数
  • IMAGE_DPI (默认值:200)-DPI用于PDF到图像的转换
  • OPENROUTER_VLM_MODEL_PREMIUM (默认:谷歌/双子座-2.5-pro)

备注:级别2(平衡/自由)已禁用。只有Tier 1(Docling)和Tier 3(Premium)处于活动状态。

搜索设置

  • SEARCH_TOP_K (默认值:5)-最终结果数量
  • SEARCH_LIMIT_MULTIPLIER (默认值:2)-搜索RRF输入的倍数
  • SEARCH_RRF_K (默认值:60)-RRF常数
  • RERANK_THRESHOLD (默认值:0.0)-最低重新评级分数

文档设置

  • CHUNK_SIZE (默认值:1000)-每块字符数
  • CHUNK_OVERLAP (默认值:200)-块之间的重叠
  • MAX_FILE_SIZE_MB (默认值:50)-最大上传大小

聊天设置

  • MEMORY_TOKEN_LIMIT (默认值:3000)-最大对话历史令牌数
  • SYSTEM_PROMPT -LLM的默认系统提示

廊坊设置

  • LANGFUSE_ENABLED (默认值:false)-启用可观察性
  • LANGFUSE_HOST -Langfuse服务器URL
  • LANGFUSE_PUBLIC_KEY -公共API密钥
  • LANGFUSE_SECRET_KEY -秘密API密钥
  • LANGFUSE_PROJECT -项目名称
  • LANGFUSE_ENVIRONMENT -环境(开发/生产)

📄 许可证

MIT许可证-有关详细信息,请参阅许可证文件


🙏 致谢

  • Qdrant -支持混合搜索的矢量数据库
  • OpenRouter -通用LLM API网关
  • 廊坊 -开源LLM可观测性平台
  • 多语文档 -文档布局分析和提取
  • 快速嵌入 -快速嵌入模型
  • 句子转换 -重新排列模型
  • 快速API -现代异步web框架
  • 谷歌双子座 -视觉语言模型

📧 联系


🗺️ 路线图

v2.1(当前)✅

  • [x] 渐进式VLM提取(2层策略:Docling→ Gemini Pro)
  • [x] Langfuse可观测性集成
  • [x] 来自OpenRouter API的实际VLM成本跟踪
  • [x] 5维质量评分
  • [x] 所有操作的延迟跟踪
  • [x] 模拟评估分数生成
  • [x] 批量测试脚本
  • [x] 13个MCP工具+REST端点
  • [x] 由于速率限制,第2层(免费VLM)已禁用

v2.2(计划中)

  • []基于模式的文档规范化
  • []智能组块(结构感知)
  • []多模式支持(图像、表格提取)
  • []高级缓存策略
  • []流媒体响应
  • []批处理API
  • []多语言支持(泰语优化)
  • []RAGAS实时评估
  • []成本优化仪表板

v3.0(未来)

  • []GraphRAG集成
  • []高级查询重写
  • []代理RAG工作流程
  • []自定义评估指标UI
  • []A/B测试框架
  • []多租户支持

📊 性能指标

提取性能(v2.1)

层级 PDF类型 页面 时间 成本 质量
快速 文本PDF 6 ~ 9秒 0.00美元 0.75-0.85
高级 扫描/复杂 6 ~360秒 0.0078美元 0.90-0.97

备注:由于速率限制,第2层(平衡/双子座无闪存)已禁用。

搜索性能

  • 混合搜索:每个查询约100-200ms(5个结果)
  • 重新排名:每次查询约200-300ms
  • 聊天(RAG):每个响应约1-2s(包括LLM)

成本优化

  • 90%的文件:使用免费等级(文档)处理
  • 10%的文件:对扫描/复杂的PDF使用高级层
  • 平均成本:0.0003美元/页(与直接VLM相比节省80%)
  • 二级残疾人:由于速率限制,Gemini Flash Free VLM已禁用

建于❤️ 用于生产RAG系统

版本2.1.0 |最后更新日期:2026年1月6日