简单的本地RAG系统
一个具有FAISS矢量数据库的多模态检索增强生成(RAG)系统,具有Streamlit前端、FastAPI后端和MCP服务器集成。
📋 目录
✨ 特性
- PDF文档上传:在FAISS矢量数据库中上传PDF文档并建立索引
- 问答:根据索引文档提问并获得AI支持的答案
- 对话记忆:保持对话中多个问题的上下文
- 文档管理:列出并查看所有带有元数据的索引文档
- MCP服务器:将功能作为MCP工具展示给其他应用程序
- 永久存储:FAISS索引和元数据保存到磁盘以进行持久化
- 消息来源:答案包括对源文件的引用
🏗️ 建筑
高级体系结构
┌─────────────────┐
│ Streamlit UI │ ← User Interface
└────────┬────────┘
│ HTTP REST API
┌────────▼────────┐
│ FastAPI Backend│ ← Main API Server
└────────┬────────┘
│
┌────┴────┐
│ │
┌───▼───┐ ┌──▼──────┐
│ FAISS │ │ OpenAI │
│ Vector│ │ API │
│ Store │ │ │
└───────┘ └─────────┘
┌─────────────────┐
│ MCP Server │ ← External Integration
└─────────────────┘组件详细信息
1.后端(FastAPI)
后端为以下各项提供REST API端点:
- 文件上传和处理
- 文档列表
- 与RAG进行问答
- 会话管理
关键模块:
main.py:带有路由处理程序的FastAPI应用程序vector_store.py:FAISS矢量数据库操作pdf_processor.py:PDF文本提取和分块rag.py:使用对话记忆检索增强生成逻辑models.py:用于请求/响应验证的Pydantic模型
2.前端(Streamlit)
交互式web界面,具有:
- 文档上传界面
- 文档列表查看器
- 带有对话历史记录的聊天界面
- 源属性显示
3.MCP服务器
模型上下文协议服务器公开了三个工具:
list_documents:获取所有索引文档upload_document:上传并索引新文档ask_question:查询支持对话的文档
4.矢量存储(FAISS)
- 索引类型:L2距离与归一化向量(余弦相似度)
- 嵌入模型:OpenAI
text-embedding-3-small(1536个维度) - 存储:具有元数据的持久磁盘存储
5.RAG管道
- 文档处理:
- 从PDF中提取文本 - 拆分为重叠的块(1000个字符,200个重叠) - 为每个块生成嵌入 - 存储在FAISS索引中
- 查询处理:
- 为用户问题生成嵌入 - 在FAISS中搜索相似的块(top-k检索) - 检索对话历史记录(如果提供了会话_id) - 使用带有上下文的OpenAI LLM生成答案 - 更新对话历史记录
📁 项目结构
simple_local_rag/
├── backend/
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI application
│ │ ├── models.py # Pydantic models
│ │ ├── vector_store.py # FAISS operations
│ │ ├── pdf_processor.py # PDF processing
│ │ └── rag.py # RAG logic with memory
│ └── pyproject.toml # UV dependencies
├── frontend/
│ ├── streamlit_app.py # Streamlit UI
│ └── requirements.txt # Frontend dependencies
├── mcp/
│ ├── __init__.py
│ ├── server.py # MCP server
│ └── pyproject.toml # MCP dependencies
├── data/
│ ├── uploads/ # Temporary PDF storage
│ ├── faiss_index.index # FAISS vector index
│ ├── metadata.json # Document metadata
│ └── chunks.pkl # Chunk metadata
├── .env # Environment variables (create this)
├── .gitignore
└── README.md🔧 安装
先决条件
- Python 3.9或更高版本
- UV包管理器(从安装 )
- OpenAI API密钥
设置步骤
- 克隆或导航到项目目录:
cd simple_local_rag- 安装UV (如果尚未安装):
curl -LsSf https://astral.sh/uv/install.sh | sh- 创建虚拟环境并安装后端依赖项:
cd backend
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e .
cd ..- 安装前端依赖项:
cd frontend
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -r requirements.txt
cd ..- 安装MCP服务器依赖项 (可选):
cd mcp
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install -e .
cd ..- 创建
.env文件 在根目录中:
cp .env.example .env
# Edit .env and add your OpenAI API key⚙️ 配置
创建一个 .env 根目录中的文件,包含以下变量:
# OpenAI API Configuration
OPENAI_API_KEY=your_openai_api_key_here
# Backend API Configuration
API_HOST=0.0.0.0
API_PORT=8000
# Frontend Configuration
STREAMLIT_SERVER_PORT=8501
# MCP Server Configuration
MCP_SERVER_PORT=8001🚀 用法
启动后端
cd backend
source .venv/bin/activate # On Windows: .venv\Scripts\activate
python -m app.main或者直接使用uvicorn:
uvicorn app.main:app --host 0.0.0.0 --port 8000API将于 http://localhost:8000
启动前端
cd frontend
source .venv/bin/activate # On Windows: .venv\Scripts\activate
streamlit run streamlit_app.py用户界面将在 http://localhost:8501
启动MCP服务器
cd mcp
source .venv/bin/activate # On Windows: .venv\Scripts\activate
python server.pyMCP服务器将在 http://localhost:8001
📡 API终点
健康检查
- 获取
/health
- 返回API运行状况
上传文档
- 发布
/upload
- 上传PDF文件进行索引 - 请求:多部分表单数据 file 领域 - 回应:文档ID、文件名、块计数
列出文件
- 获取
/documents
- 获取所有索引文档的列表 - 回应:包含元数据的文档列表
查询文档
- 发布
/query
- 询问有关索引文档的问题 - 请求体:
{
"question": "What is the main topic?",
"conversation_id": "optional-conversation-id",
"top_k": 5
}- 回应:答案、对话id、相关块、来源
获取对话
- 获取
/conversation/{conversation_id}
- 获取完整的对话历史记录 - 回应:对话中的所有消息
🔌 MCP服务器
MCP服务器公开了三个工具:
1.列表_文档
列出所有带有描述的索引文档。
MCP呼叫示例:
{
"tool": "list_documents",
"arguments": {}
}2.上传文件
上传并索引新的PDF文档。
MCP呼叫示例:
{
"tool": "upload_document",
"arguments": {
"file_path": "/path/to/document.pdf",
"filename": "document.pdf"
}
}3.提问
询问有关具有对话支持的索引文档的问题。
MCP呼叫示例:
{
"tool": "ask_question",
"arguments": {
"question": "What is the main topic?",
"conversation_id": "optional-id",
"top_k": 5
}
}MCP HTTP端点
- 获取
/tools:获取可用的MCP工具 - 发布
/tools/call:执行MCP工具
💬 对话记忆
系统通过以下方式维护对话上下文 conversation_id:
- 第一个问题:没有
conversation_id需要-系统生成一个 - 后续问题:使用返回的
conversation_id为了上下文 - 上下文窗口:保留最后20条消息(10次交换)
- 存储:内存中(可以持久化到生产中的数据库中)
示例流程
# First question
response1 = ask_question("What is machine learning?")
conversation_id = response1["conversation_id"]
# Follow-up question (maintains context)
response2 = ask_question("Can you give examples?", conversation_id=conversation_id)
# Conversation history includes both questions and answers🛠️ 技术栈
- 后端框架:FastAPI
- 向量数据库:FAISS(CPU版本)
- 嵌入:OpenAI文本嵌入3-small
- LLM:OpenAI GPT-4o-mini
- PDF处理:PyPDF2
- 前端:流光灯
- 程序包管理器:紫外线
- 语言:Python 3.9+
📝 备注
- 内存限制:对话历史记录存储在内存中。对于生产环境,考虑使用数据库(Redis、PostgreSQL等)
- 矢量存储:FAISS索引存储在磁盘上,并在重新启动时持续存在
- 分块策略:文档分为1000个字符块,重叠200个字符
- 嵌入维度:1536(OpenAI文本嵌入3-small)
- 错误处理:实现基本错误处理;增强生产使用
🔒 安全注意事项
- 将API密钥安全地存储在
.env文件(从不提交版本控制) - 为生产部署添加身份验证/授权
- 验证文件上传(类型、大小限制)
- 对API端点实施速率限制
- 在生产环境中使用HTTPS
📚 额外资源
🤝 贡献
这是一个简单的本地RAG实现。您可以通过以下方式扩展它:
- 支持更多文档类型(DOCX、TXT等)
- 高级组块策略
- 对话的数据库持久性
- 用户认证
- 多租户支持
- 高级检索策略(重新排序、混合搜索)
📄 许可证
本项目按原样提供,用于教育和发展目的。
