RAG/README.md

19 KiB
Raw Blame History

RAG API - 本地化检索增强生成系统

一个基于 LlamaIndex、ChromaDB 和 Ollama 的本地化 RAG检索增强生成系统提供流式 API 接口供其他平台调用。

功能特性

  • 🔍 智能检索: 使用 LlamaIndex 和 ChromaDB 实现高效的向量检索
  • 💾 数据同步: 自动同步 MySQL 数据库数据到 ChromaDB 向量库
  • 🗄️ 多数据库支持: 支持从多个 MySQL 数据库同步数据到统一的知识库
  • 🌊 流式输出: 基于 FastAPI 的流式响应,支持实时对话
  • 🤖 本地 LLM: 集成 Ollama 本地部署的 qwen3:1.7b 模型(文本生成)和 qwen3-embedding:0.6b 模型(向量化)
  • 高并发: 支持多用户同时访问
  • 🔄 自动同步: 支持定时自动同步和手动触发同步
  • 🐳 Docker 部署: 使用 Docker Compose 一键部署
  • ⚙️ 统一配置: 所有配置统一在 .env 文件中管理,方便不同机器之间移植

技术栈

  • RAG 框架: LlamaIndex
  • 向量数据库: ChromaDB
  • 关系数据库: MySQL
  • API 框架: FastAPI
  • LLM: Ollama (qwen3:1.7b 用于文本生成qwen3-embedding:0.6b 用于向量化)
  • 语言: Python 3.8+
  • 容器化: Docker & Docker Compose

快速开始

前置条件

  1. DockerDocker Compose 已安装
  2. MySQL 数据库已安装并运行(可在主机或远程服务器)
  3. Ollama 服务已安装并运行(可在主机或远程服务器),且已下载以下模型:
    • qwen3:1.7b - LLM模型用于文本生成
    • qwen3-embedding:0.6b - Embedding模型用于向量化

检查 Ollama

# 检查 Ollama 是否运行
curl http://localhost:11434/api/tags

# 下载所需的模型(如果未下载)
ollama pull qwen3:1.7b              # LLM模型用于文本生成
ollama pull qwen3-embedding:0.6b    # Embedding模型用于向量化

安装步骤

  1. 克隆或进入项目目录:

    cd 项目目录
    
  2. 配置环境变量:

    # 复制环境变量示例文件
    cp .env.example .env
    
    # 编辑 .env 文件,配置以下参数:
    

    必须配置的参数:

    # MySQL 配置
    MYSQL_HOST=localhost          # 如果 MySQL 在主机上,使用 localhosthost 网络模式)
    MYSQL_PORT=3306
    MYSQL_USER=root
    MYSQL_PASSWORD=your_password  # 修改为你的 MySQL 密码
    MYSQL_DATABASE=forgeplus      # 修改为你的数据库名
    
    # ChromaDB 配置Docker 模式,使用 host 网络)
    CHROMA_SERVER_HOST=localhost
    CHROMA_SERVER_PORT=8000
    
    # Ollama 配置(使用 host 网络模式)
    OLLAMA_BASE_URL=http://localhost:11434
    OLLAMA_MODEL=qwen3:1.7b
    OLLAMA_EMBEDDING_MODEL=qwen3-embedding:0.6b
    

    可选配置:

    # 多数据库配置(如果同一 MySQL 服务器中有多个数据库需要同步)
    MYSQL_DATABASES_CONFIG=./databases_config.json
    
    # API 端口(默认 8001
    API_PORT=8001
    

    重要: 所有配置都可以在 .env 文件中统一管理,方便不同机器之间移植。只需复制 .env 文件到新机器并修改相应的配置即可。

  3. 准备 MySQL 数据表:

    CREATE DATABASE IF NOT EXISTS forgeplus CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    
    USE forgeplus;
    
    CREATE TABLE IF NOT EXISTS documents (
        id INT PRIMARY KEY AUTO_INCREMENT,
        title VARCHAR(255),
        content TEXT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    );
    
    -- 插入测试数据
    INSERT INTO documents (title, content) VALUES
    ('测试文档1', '这是第一个测试文档的内容。'),
    ('测试文档2', '这是第二个测试文档的内容。');
    
  4. 启动服务:

    # 构建并启动所有服务ChromaDB + RAG API
    # docker-compose 会自动读取 .env 文件中的配置
    docker-compose up -d
    
    # 查看日志
    docker-compose logs -f rag-api
    
  5. 验证服务: 服务启动后,可以通过以下方式访问:

  6. 测试服务:

    # 健康检查
    curl http://localhost:8001/health
    
    # 查询接口(流式)
    curl -X POST "http://localhost:8001/query" \
      -H "Content-Type: application/json" \
      -d '{"query": "什么是RAG", "stream": true}' \
      --no-buffer
    
    # 检索接口(仅检索)
    curl -X POST "http://localhost:8001/retrieve" \
      -H "Content-Type: application/json" \
      -d '{"query": "什么是RAG", "top_k": 5}'
    
    # 或使用 Python 测试
    python test_client.py
    

配置说明

环境变量配置

所有配置参数都统一在 .env 文件中管理,包括:

  • API 配置: API_HOST, API_PORT, API_TITLE, API_VERSION
  • ChromaDB 配置: CHROMA_SERVER_HOST, CHROMA_SERVER_PORT, CHROMA_COLLECTION_NAME
  • MySQL 配置: MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_CHARSET
  • Ollama 配置: OLLAMA_BASE_URL, OLLAMA_MODEL, OLLAMA_EMBEDDING_MODEL
  • RAG 配置: EMBEDDING_DIMENSION, CHUNK_SIZE, CHUNK_OVERLAP, TOP_K
  • 同步配置: SYNC_INTERVAL, AUTO_SYNC
  • 多数据库配置: MYSQL_DATABASES_CONFIG

配置移植

在不同机器之间移植时,只需:

  1. 复制 .env 文件到新机器
  2. 修改相应的配置(如 MySQL 地址、密码等)
  3. 启动服务: docker-compose up -d

所有配置都会自动从 .env 文件读取,无需修改 docker-compose.yml

多数据库配置

系统支持从一个 MySQL 服务器连接中同步多个数据库database的数据到 ChromaDB 知识库。

注意: 所有数据库必须使用同一个 MySQL 连接(相同的 host、port、user、password

配置方式

方式1: 使用配置文件(推荐)

  1. 复制示例配置文件:

    cp databases_config.example.json databases_config.json
    
  2. 编辑 databases_config.json,配置你的多个数据库(只需要配置数据库名称和表结构,连接信息在.env中配置

    [
      {
        "name": "db1",
        "database": "database1",
        "table_name": "documents",
        "id_column": "id",
        "content_column": "title,content",
        "title_column": "title",
        "metadata_columns": "created_at,updated_at"
      },
      {
        "name": "db2",
        "database": "database2",
        "table_name": "articles",
        "id_column": "article_id",
        "content_column": "body",
        "title_column": "title",
        "metadata_columns": "author,category"
      }
    ]
    
  3. .env 文件中设置:

    MYSQL_DATABASES_CONFIG=./databases_config.json
    

方式2: 使用环境变量JSON字符串

.env 文件中直接设置 JSON 字符串:

MYSQL_DATABASES_CONFIG=[{"name":"db1","database":"database1","table_name":"docs","id_column":"id","content_column":"content","title_column":"title"}]

方式3: 单数据库配置(向后兼容)

如果不设置 MYSQL_DATABASES_CONFIG,系统会使用传统的单数据库配置(.env 中的 MYSQL_* 配置项)。

配置参数说明

每个数据库配置包含以下参数:

参数 说明 必填 默认值
name 数据库标识名称(用于区分不同数据库) -
database MySQL 数据库名称 -
table_name 要同步的表名 documents
id_column ID 列名 id
content_column 内容列名(可以是单个列名,或逗号分隔的多个列名) content
title_column 标题列名(可选) title
file_column 文件列名(可选) -
metadata_columns 元数据列名(逗号分隔,可选) null
content_separator 多个 content 列之间的分隔符(可选) \n (换行符)
updated_at_column 更新时间字段(用于增量同步,可选) null

注意:

  • hostportuserpasswordcharset.env 文件中统一配置(MYSQL_* 配置项)
  • 所有数据库使用同一个 MySQL 连接

多列内容配置

如果你的表中有多个列都需要参与检索,例如 titlecontentdescription,你可以将这些列都配置为 content_column,系统会自动合并它们的内容用于向量化。 若表中存在文件标识符列,如file_identifiers, 要使系统能够解析并合并附件内容, 则需要在content_column中新增文件标识符列列,并配置 file_column配置示例:

{
  "name": "db1",
  "database": "forgeplus",
  "table_name": "issues",
  "id_column": "id",
  "content_column": "title,content,description,file_identifiers",
  "file_column": "file_identifiers",
  "title_column": "title",
  "metadata_columns": "created_at,updated_at",
  "content_separator": "\n"
}

工作原理:

  1. 系统会从 MySQL 查询所有指定的 content 列
  2. 使用指定的分隔符(默认 \n)将多个列的内容合并
  3. 合并后的内容被用于向量化和存储到 ChromaDB
  4. 检索时使用合并后的完整内容进行相似度匹配

注意事项:

  • 列顺序:多个列会按照配置中的顺序合并
  • 空值处理:如果某个列为 NULL 或空字符串,会被跳过
  • 分隔符:选择合适的分隔符很重要,建议使用 \n(换行符)以保持可读性
  • 向后兼容:如果只指定一个列名(如 "content_column": "content"),行为与之前完全一致

项目结构

RAG/
├── api/                    # FastAPI 应用
│   ├── __init__.py
│   └── main.py            # API 主程序
├── database/              # 数据库模块
│   ├── __init__.py
│   └── sync.py           # MySQL 同步模块
├── rag/                   # RAG 核心模块
│   ├── __init__.py
│   ├── vector_store.py   # 向量存储管理
│   ├── document_processor.py  # 文档处理
│   └── rag_engine.py     # RAG 引擎
├── config.py             # 配置管理
├── sync_service.py       # 同步服务
├── main.py              # 程序入口Docker 使用)
├── requirements.txt     # 依赖包
├── Dockerfile          # Docker 镜像定义
├── docker-compose.yml  # Docker Compose 配置
├── .env.example        # 环境变量示例
├── databases_config.example.json  # 多数据库配置示例
└── README.md           # 项目文档

API 接口

查询接口(检索 + LLM 生成)

POST /query
Content-Type: application/json

{
    "query": "你的问题",
    "stream": true
}

检索接口(仅检索,不生成)

POST /retrieve
Content-Type: application/json

{
    "query": "你的问题",
  "top_k": 5
}

同步接口

POST /sync

健康检查

GET /health

系统统计

GET /stats

完整 API 文档: http://localhost:8001/docs端口可通过 API_PORT 配置)

系统架构

核心组件

  1. FastAPI - Web框架处理HTTP请求和流式响应
  2. LlamaIndex - RAG核心框架负责文档索引和检索
  3. ChromaDB - 向量数据库,存储文档向量
  4. Ollama - 本地LLM服务使用qwen3:1.7b模型文本生成和qwen3-embedding:0.6b模型(向量化)
  5. MySQL - 关系数据库,存储原始文档数据

数据流

MySQL数据库 
    ↓ (同步服务)
文档处理与分块
    ↓
向量化 (Ollama Embedding)
    ↓
ChromaDB向量存储
    ↓ (检索)
LlamaIndex检索增强
    ↓
Ollama LLM生成
    ↓
FastAPI流式输出

模块说明

1. API层 (api/main.py)

  • 职责: 处理HTTP请求提供RESTful API接口
  • 主要功能:
    • /query - 查询接口(支持流式和非流式)
    • /retrieve - 检索接口(仅检索,不生成)
    • /sync - 手动触发数据同步
    • /health - 健康检查
    • /stats - 系统统计信息

2. 数据库层 (database/sync.py)

  • 职责: 从MySQL读取文档数据
  • 主要功能:
    • 连接MySQL数据库
    • 获取所有文档或增量文档
    • 支持按更新时间增量同步
    • 支持多数据库配置

3. RAG核心层

vector_store.py

  • 职责: 管理ChromaDB向量存储
  • 主要功能:
    • 初始化ChromaDB客户端和集合
    • 添加/删除文档向量
    • 提供检索器Retriever

document_processor.py

  • 职责: 处理文档转换和分块
  • 主要功能:
    • MySQL文档转换为LlamaIndex Document
    • 文档分块处理
    • 元数据提取
    • 多列内容合并

rag_engine.py

  • 职责: RAG查询和生成
  • 主要功能:
    • 构建查询引擎
    • 流式和非流式查询
    • 集成Ollama LLM生成回答

4. 同步服务 (sync_service.py)

  • 职责: 协调MySQL和ChromaDB之间的数据同步
  • 主要功能:
    • 全量同步
    • 增量同步
    • 自动定时同步
    • 多数据库支持

并发处理

异步支持

  1. FastAPI异步路由: 所有API端点使用async def定义
  2. 异步生成器: 流式响应使用AsyncIterator
  3. 线程池: 同步操作(如非流式查询)使用asyncio.to_thread包装

性能优化

  1. 连接池: MySQL和ChromaDB使用连接池管理
  2. 向量索引: ChromaDB自动创建向量索引加速检索
  3. 文档分块: 大文档分块处理,提高检索精度
  4. 增量同步: 只同步新增或更新的文档

生产环境部署

使用 Docker Compose推荐

# 1. 配置 .env 文件(复制 .env.example 并修改)
cp .env.example .env
# 编辑 .env 文件,配置 MySQL、Ollama 等连接信息

# 2. 构建并启动服务
docker-compose up -d --build

# 3. 查看服务状态
docker-compose ps

# 4. 查看日志
docker-compose logs -f rag-api

# 5. 停止服务
docker-compose down

# 6. 重启服务
docker-compose restart rag-api

配置说明

  • 网络模式: 使用 host 网络模式容器可以直接访问宿主机上的服务MySQL、Ollama
  • 端口: RAG API 使用 8001 端口(可通过 API_PORT 配置ChromaDB 使用 8000 端口
  • 数据持久化: ChromaDB 数据存储在 ./chroma_db_data 目录
    • 会话/SQLite 持久化: API 会将会话数据存储在 ./data/sessions.db,请在使用 Docker Compose 时把宿主机的 ./data 目录挂载到容器内(示例 docker-compose.yml 已包含该挂载)。
    • 权限提示: 确保宿主机上 ./data./chroma_db_data 目录可被 Docker 进程读写(通常 chownchmod 为容器用户设置适当权限)。
  • 配置管理: 所有配置统一在 .env 文件中管理,方便不同机器之间移植

配置移植

在不同机器之间移植时:

  1. 复制配置文件:
   # 复制 .env 文件
   cp .env 新机器路径/.env
   
   # 复制 databases_config.json如果使用多数据库配置
   cp databases_config.json 新机器路径/
  1. 修改配置: 编辑 .env 文件,修改相应的配置(如 MySQL 地址、密码等)

  2. 启动服务:

   docker-compose up -d

所有配置都会自动从 .env 文件读取,无需修改 docker-compose.yml

常见问题

1. 容器无法连接 MySQL/Ollama

错误: Connection refusedFailed to connect

解决:

  • 确保 MySQL 和 Ollama 服务正在运行
  • 检查 .env 中的 MYSQL_HOSTOLLAMA_BASE_URL 配置
  • 使用 host 网络模式时,应使用 localhost 访问宿主机服务

2. 端口冲突

错误: Address already in use

解决:

  • 检查端口是否被占用: netstat -tlnp | grep 8001
  • 修改 .env 文件中的 API_PORT 配置

3. 同步失败

错误: No documents foundSync failed

解决:

  • 检查 MySQL 表中是否有数据
  • 验证数据库和表名配置是否正确
  • 查看容器日志: docker-compose logs rag-api

4. 容器启动失败

错误: 容器不断重启

解决:

  • 查看详细日志: docker-compose logs rag-api
  • 检查 .env 文件中的环境变量配置是否正确
  • 确保所有必需的服务MySQL、Ollama都已启动

5. 多数据库配置问题

错误: 某个数据库连接失败

解决:

  • 检查该数据库的连接信息是否正确
  • 确认网络连接和权限
  • 系统会跳过失败的数据库,继续处理其他数据库

性能优化建议

1. 调整配置参数

根据实际需求调整 .env 中的参数:

  • CHUNK_SIZE: 文档分块大小默认1024
  • CHUNK_OVERLAP: 分块重叠默认200
  • TOP_K: 检索文档数量默认5
  • SYNC_INTERVAL: 同步间隔默认300秒

2. 数据库优化

  • 为 MySQL 表的 updated_at 字段创建索引
  • 定期清理 ChromaDB 中的过期数据
  • 监控向量数据库大小

扩展性

添加新数据源

  1. database/目录创建新的同步模块
  2. 实现类似MySQLSync的接口
  3. sync_service.py中集成

更换LLM模型

  1. 修改.env中的OLLAMA_MODEL配置
  2. 或修改rag/rag_engine.py中的LLM初始化

自定义提示词

修改rag/rag_engine.py中的qa_prompt模板

开发

本地开发(可选)

如果需要本地开发(不使用 Docker 运行 rag-api但仍需要 Docker 运行 ChromaDB

前置条件

  1. Docker 已安装(用于运行 ChromaDB
  2. MySQL 服务已运行(可在主机或远程服务器)
  3. Ollama 服务已运行(可在主机或远程服务器)

启动步骤

# 1. 创建虚拟环境
uv venv --python 3.13.9
source .venv/bin/activate # Windows: venv\Scripts\activate

# 2. 安装依赖
uv pip install -r requirements.txt

# 3. 启动 ChromaDB 服务(必须)
docker-compose up -d chromadb

# 4. 配置 .env 文件(确保使用 HttpClient 模式)
# 在 .env 文件中设置:
# CHROMA_SERVER_HOST=localhost
# CHROMA_SERVER_PORT=8000
# OLLAMA_BASE_URL=http://localhost:11434
# MYSQL_HOST=localhost
# ... 其他配置

# 5. 验证 ChromaDB 服务运行
curl http://localhost:8002/docs

# 6. 启动 RAG API 服务
python main.py

注意事项

  • ChromaDB 必须通过 Docker 运行,因为系统已改为 HttpClient 模式
  • 如果不想使用 Docker可以修改 .env 文件,注释掉 CHROMA_SERVER_HOST系统会自动切换到本地文件模式PersistentClient
  • 确保 MySQL 和 Ollama 服务在配置的地址上运行

许可证

MIT License