436 lines
10 KiB
Markdown
436 lines
10 KiB
Markdown
# Easy RAG Service
|
||
|
||
一个高效、简洁的 RAG (Retrieval-Augmented Generation) 服务,基于 FastAPI 构建。
|
||
|
||
## TODO
|
||
|
||
- [ ] 提高检索准确度
|
||
- [ ] 知识库隔离
|
||
- [ ] 支持 doc
|
||
- [ ] 支持 docx
|
||
- [ ] 支持 excel
|
||
- [ ] 支持 csv
|
||
|
||
## 功能特性
|
||
|
||
- 🚀 **高性能 API 服务** - 基于 FastAPI 构建
|
||
- 📄 **多格式文档支持** - PDF、TXT 文档处理和向量化
|
||
- 🔍 **智能检索问答** - 基于向量相似度的文档检索
|
||
- 🌊 **流式响应支持** - 实时流式聊天问答体验
|
||
- 💾 **向量数据库** - ChromaDB 持久化存储
|
||
- 🤖 **多模型支持** - 支持多种 LLM 模型集成
|
||
- 📊 **RESTful API** - 标准化的 REST 接口
|
||
- 🧪 **完整测试套件** - 包含功能测试、并发测试、性能监控
|
||
- 🔧 **开发工具集成** - VS Code 任务、自动化脚本
|
||
- 📈 **性能监控** - 实时资源使用监控和报告生成
|
||
|
||
## 环境要求
|
||
|
||
- Python 3.8+
|
||
- pyenv (推荐)
|
||
- venv
|
||
|
||
## 快速开始
|
||
|
||
### 1. 环境设置
|
||
|
||
```bash
|
||
# 使用 pyenv 安装 Python (推荐)
|
||
pyenv install 3.12.0 # 或 3.11.5, 3.13.0 等
|
||
pyenv local 3.12.0 # 使用你安装的版本
|
||
|
||
# 使用自动化脚本设置环境
|
||
./setup.sh
|
||
|
||
# 或手动设置
|
||
# 创建虚拟环境
|
||
python -m venv venv
|
||
source venv/bin/activate # macOS/Linux
|
||
# venv\Scripts\activate # Windows
|
||
|
||
# 安装依赖
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. 配置环境变量
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# 编辑 .env 文件,设置你的 API 密钥
|
||
```
|
||
|
||
### 3. 启动服务
|
||
|
||
```bash
|
||
# 使用启动脚本
|
||
./start.sh
|
||
|
||
# 或手动启动
|
||
# 开发模式
|
||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||
|
||
# 生产模式
|
||
uvicorn main:app --host 0.0.0.0 --port 8000
|
||
```
|
||
|
||
## 测试
|
||
|
||
本项目包含完整的测试套件,支持多种测试场景。详细信息请参考 [TESTING_README.md](TESTING_README.md)。
|
||
|
||
### 快速测试
|
||
|
||
```bash
|
||
# 运行快速功能验证
|
||
python run_tests.py quick
|
||
|
||
# 运行轻量级并发测试
|
||
python tests/quick_test.py concurrent
|
||
|
||
# 运行所有测试
|
||
python run_tests.py all
|
||
```
|
||
|
||
### VS Code 集成测试
|
||
|
||
在 VS Code 中按 `Ctrl+Shift+P` (Mac: `Cmd+Shift+P`),选择 `Tasks: Run Task`,然后选择:
|
||
|
||
- **Run Quick Test** - 快速功能验证
|
||
- **Run Light Concurrent Tests** - 轻量级并发测试
|
||
- **Run Concurrent Tests** - 完整并发测试
|
||
- **Run Performance Monitor** - 性能监控测试
|
||
|
||
### 测试功能
|
||
|
||
- ✅ **API 功能测试** - 验证所有 API 端点
|
||
- ✅ **并发性能测试** - 高并发场景验证
|
||
- ✅ **快速验证测试** - 端到端功能检查
|
||
- ✅ **性能监控** - CPU/内存使用监控
|
||
- ✅ **自动化报告** - 测试结果自动生成报告
|
||
|
||
## API 接口
|
||
|
||
### 健康检查
|
||
|
||
```
|
||
GET /api/health
|
||
```
|
||
|
||
### 上传文档
|
||
|
||
```
|
||
POST /api/upload
|
||
Content-Type: multipart/form-data
|
||
|
||
参数:
|
||
- file: 文档文件 (PDF, TXT)
|
||
```
|
||
|
||
### 查询问答
|
||
|
||
```
|
||
POST /api/chat
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"question": "你的问题",
|
||
"top_k": 3, # 可选,检索文档数量,默认 3
|
||
"temperature": 0.7 # 可选,LLM 温度参数,默认 0.7
|
||
}
|
||
```
|
||
|
||
### 流式聊天问答 🆕
|
||
|
||
```
|
||
POST /api/chat/stream
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"question": "你的问题",
|
||
"top_k": 3, # 可选,检索文档数量,默认 3
|
||
"temperature": 0.7 # 可选,LLM 温度参数,默认 0.7
|
||
}
|
||
|
||
返回:流式响应 (Server-Sent Events)
|
||
- content: 文本内容片段
|
||
- is_final: 是否为最后一个数据块
|
||
- sources: 引用来源(仅在最后一个数据块中)
|
||
- processing_time: 处理时间(仅在最后一个数据块中)
|
||
```
|
||
|
||
### 获取文档列表
|
||
|
||
```
|
||
GET /api/documents
|
||
|
||
返回文档列表,包含文档ID、文件名、上传时间等信息
|
||
```
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
easy-rag/
|
||
├── main.py # FastAPI 应用入口
|
||
├── config.py # 项目配置文件
|
||
├── run_tests.py # 统一测试入口
|
||
├── setup.sh # 环境设置脚本
|
||
├── start.sh # 启动脚本
|
||
├── requirements.txt # 依赖包
|
||
├── .env.example # 环境变量模板
|
||
├── .python-version # Python 版本配置
|
||
├── .gitignore # Git 忽略文件
|
||
├── README.md # 项目说明
|
||
├── TESTING_README.md # 测试说明文档
|
||
├── models/ # 数据模型
|
||
├── services/ # 业务逻辑
|
||
│ ├── rag_service.py # RAG 核心服务
|
||
│ └── vector_store.py # 向量存储服务
|
||
├── utils/ # 工具函数
|
||
│ └── file_utils.py # 文件处理工具
|
||
├── tests/ # 完整测试套件
|
||
│ ├── __init__.py # 测试包初始化
|
||
│ ├── config.py # 测试配置
|
||
│ ├── utils.py # 测试工具函数
|
||
│ ├── test_api.py # 基础 API 测试
|
||
│ ├── test_concurrent.py # 并发测试套件
|
||
│ ├── quick_test.py # 快速功能验证
|
||
│ └── performance_monitor.py # 性能监控
|
||
├── test_reports/ # 测试报告输出目录
|
||
├── uploads/ # 文档上传目录
|
||
├── chroma_db/ # ChromaDB 数据库文件
|
||
├── .vscode/ # VS Code 配置
|
||
│ └── tasks.json # VS Code 任务配置
|
||
└── venv/ # Python 虚拟环境
|
||
```
|
||
|
||
## 技术栈
|
||
|
||
- **Web 框架**: FastAPI
|
||
- **ASGI 服务器**: Uvicorn
|
||
- **向量数据库**: ChromaDB
|
||
- **文档处理**: PyPDF2
|
||
- **向量模型**: Sentence Transformers
|
||
- **LLM 集成**: LangChain
|
||
|
||
## 使用示例
|
||
|
||
### 1. 上传文档并查询
|
||
|
||
```bash
|
||
# 1. 启动服务
|
||
./start.sh
|
||
|
||
# 2. 上传文档
|
||
curl -X POST "http://localhost:8000/api/upload" \
|
||
-H "accept: application/json" \
|
||
-H "Content-Type: multipart/form-data" \
|
||
-F "file=@your_document.pdf"
|
||
|
||
# 3. 查询问答
|
||
curl -X POST "http://localhost:8000/api/chat" \
|
||
-H "accept: application/json" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"question": "文档的主要内容是什么?",
|
||
"top_k": 3
|
||
}'
|
||
|
||
# 4. 流式聊天问答
|
||
curl -X POST "http://localhost:8000/api/chat/stream" \
|
||
-H "accept: text/plain" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"question": "详细解释一下文档的核心观点?",
|
||
"top_k": 3
|
||
}'
|
||
```
|
||
|
||
### 2. Python 客户端示例
|
||
|
||
```python
|
||
import requests
|
||
import json
|
||
|
||
# 上传文档
|
||
with open('document.pdf', 'rb') as f:
|
||
response = requests.post(
|
||
'http://localhost:8000/api/upload',
|
||
files={'file': f}
|
||
)
|
||
|
||
# 查询问答
|
||
response = requests.post(
|
||
'http://localhost:8000/api/chat',
|
||
json={
|
||
'question': '这个文档讲了什么?',
|
||
'top_k': 3
|
||
}
|
||
)
|
||
print(response.json())
|
||
|
||
# 流式聊天问答
|
||
def stream_chat(question):
|
||
response = requests.post(
|
||
'http://localhost:8000/api/chat/stream',
|
||
json={'question': question, 'top_k': 3},
|
||
stream=True
|
||
)
|
||
|
||
for line in response.iter_lines():
|
||
if line:
|
||
# 解析 Server-Sent Events 格式
|
||
if line.startswith(b'data: '):
|
||
data = json.loads(line[6:])
|
||
|
||
# 打印文本内容
|
||
if data.get('content'):
|
||
print(data['content'], end='', flush=True)
|
||
|
||
# 处理最终数据块
|
||
if data.get('is_final'):
|
||
print(f"\n\n处理时间: {data.get('processing_time', 0):.2f}秒")
|
||
print(f"参考来源: {len(data.get('sources', []))}个文档")
|
||
break
|
||
|
||
# 使用流式聊天
|
||
stream_chat("详细解释文档的主要观点")
|
||
```
|
||
|
||
### 3. JavaScript/前端示例
|
||
|
||
```javascript
|
||
// 流式聊天问答 - 前端实现
|
||
async function streamChat(question) {
|
||
const response = await fetch("/api/chat/stream", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
},
|
||
body: JSON.stringify({
|
||
question: question,
|
||
top_k: 3,
|
||
}),
|
||
});
|
||
|
||
const reader = response.body.getReader();
|
||
const decoder = new TextDecoder();
|
||
|
||
while (true) {
|
||
const { done, value } = await reader.read();
|
||
|
||
if (done) break;
|
||
|
||
const chunk = decoder.decode(value);
|
||
const lines = chunk.split("\n");
|
||
|
||
for (const line of lines) {
|
||
if (line.startsWith("data: ")) {
|
||
try {
|
||
const data = JSON.parse(line.slice(6));
|
||
|
||
// 显示文本内容
|
||
if (data.content) {
|
||
document.getElementById("chat-output").innerHTML += data.content;
|
||
}
|
||
|
||
// 处理最终数据块
|
||
if (data.is_final) {
|
||
console.log(`处理时间: ${data.processing_time}秒`);
|
||
console.log(`参考来源: ${data.sources.length}个文档`);
|
||
}
|
||
} catch (e) {
|
||
console.error("解析数据失败:", e);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用示例
|
||
streamChat("请解释文档的主要内容");
|
||
```
|
||
|
||
## 开发指南
|
||
|
||
### VS Code 开发环境
|
||
|
||
本项目已配置 VS Code 任务系统,可通过 `Ctrl+Shift+P` → `Tasks: Run Task` 执行:
|
||
|
||
- **Setup RAG Environment** - 设置开发环境
|
||
- **Start RAG Service** - 启动服务(后台)
|
||
- **Start RAG Service (Foreground)** - 启动服务(前台,查看日志)
|
||
- **Run All Tests** - 运行完整测试套件
|
||
- **Clean Test Data** - 清理测试数据
|
||
|
||
### 配置文件
|
||
|
||
主要配置在 `config.py` 中:
|
||
|
||
- LLM 模型配置
|
||
- 向量模型设置
|
||
- 数据库路径
|
||
- API 设置
|
||
|
||
## 故障排除
|
||
|
||
### 常见问题
|
||
|
||
1. **服务启动失败**
|
||
|
||
```bash
|
||
# 检查端口是否被占用
|
||
lsof -i :8000
|
||
|
||
# 检查依赖是否完整安装
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
2. **文档上传失败**
|
||
|
||
- 检查文件格式是否支持 (PDF, TXT)
|
||
- 确认文件大小不超过限制
|
||
- 检查磁盘空间是否充足
|
||
|
||
3. **查询响应慢**
|
||
|
||
- 检查向量数据库索引状态
|
||
- 考虑调整 `top_k` 参数
|
||
- 监控系统资源使用情况
|
||
|
||
4. **内存使用过高**
|
||
- 减少并发请求数量
|
||
- 调整模型配置
|
||
- 清理旧的向量数据
|
||
|
||
### 日志和调试
|
||
|
||
```bash
|
||
# 查看详细日志
|
||
python main.py --log-level DEBUG
|
||
|
||
# 运行测试诊断
|
||
python run_tests.py quick
|
||
|
||
# 性能监控
|
||
python tests/performance_monitor.py
|
||
```
|
||
|
||
## 贡献指南
|
||
|
||
1. Fork 项目
|
||
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||
5. 打开 Pull Request
|
||
|
||
## 许可证
|
||
|
||
本项目采用 MIT 许可证 - 详情请见 [LICENSE](LICENSE) 文件。
|
||
|
||
## 支持
|
||
|
||
如有问题或建议,请:
|
||
|
||
1. 查看 [TESTING_README.md](TESTING_README.md) 测试文档
|
||
2. 运行 `python run_tests.py quick` 进行快速诊断
|
||
3. 提交 Issue 或 Pull Request
|