使用说明
具有渐进式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服务器URLLANGFUSE_PUBLIC_KEY-公共API密钥LANGFUSE_SECRET_KEY-秘密API密钥LANGFUSE_PROJECT-项目名称LANGFUSE_ENVIRONMENT-环境(开发/生产)
📄 许可证
MIT许可证-有关详细信息,请参阅许可证文件
🙏 致谢
- Qdrant -支持混合搜索的矢量数据库
- OpenRouter -通用LLM API网关
- 廊坊 -开源LLM可观测性平台
- 多语文档 -文档布局分析和提取
- 快速嵌入 -快速嵌入模型
- 句子转换 -重新排列模型
- 快速API -现代异步web框架
- 谷歌双子座 -视觉语言模型
📧 联系
- github: @Pond500
- 存储库: rag mcp服务器
🗺️ 路线图
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日