Skip to content

Deepseek+RAGFlow 从0搭建自己的本地知识库和Agent智能体

  • RAG基本概念
  • RAGFlow简介和部署
  • RAGFlow构建知识库和智能体

RAG基本概念

一、RAG由来及定义

  1. 2020年,Meta公司在“Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”论文中提出了一种称为检索增强生成(RAG)的框架。
  2. RAG可以使模型访问超出其训练数据范围之外的信息,使得模型在每次生成时可以检索外部更专业、更准确的知识,从而更好的回答用户问题。

二、为什么需要RAG

  1. 大模型的知识更新问题

    大模型并不具备在环境不断变化的场景中回答特定问题所需全面知识,例如DeepSeek-R1语料库时间截止2023年6月份,无法准备输出之后的实时性问题,这正是现代大模型所面临的知识更新困境。

    RAG可以使模型访问超出其训练数据范围之外的信息。

  2. 大模型的训练成本问题

    对于大模型来说,更新基础模型知识库是非常困难的事情,首先保证预训练数据的质量,其次更新知识库后模型通常需要重新训练,新旧数据按照比例混合训练等,需要大量算力。

    RAG无需微调模型,成本低,具有很强的扩展性,只需要更新检索部分的数据,就可以使模型适应新的知识领域。

  3. 大模型生成结果的不可解释性

    在大模型领域中,模型基本都基于Transformer的解码器架构,因此大模型的生产结果仍然存在不可解释性问题,无法引用你的专有数据,缺乏可信来源,甚至产生答案幻觉。

    RAG相较于纯粹的大模型生成,RAG具有更强的可解释性,高质量的答案生成,并告诉我们答案来源。

三、RAG工作流程

​ 数据准备 --> 数据召回 --> 答案生成

  1. 数据准备:包括识别数据源,从数据源(文本、图像、影音等)中提取数据、切割数据并将其转换(Embdding)存储到数据库(向量、搜索引擎、图)中。
  2. 数据召回:从数据库中检索(候选重排、大模型辅助召回)与用户输入相关的信息(Embdding)。
  3. 答案生成:检索到用户问题相关的数据片段,RAG系统将其与用户的问题和相关数据一起传递给LLM。LLM利用检索到的数据和用户的查询生成输出。输出的质量取决于数据的质量/检索策略/大模型参数。

四、RAG缺点

  1. 依赖于检索模块
  2. 依赖现有知识库
  3. 推理耗时
  4. 上下文窗口Token限制

五、RAG与模型微调的对比

对比项RAG模型微调
定义将知识库检索与大模型生成相结合。检索相关文档并使用它们生成答案使用数据集细化针对特定任务的预训练模型。调整模型的权重以使其更适用于特性任务
优点可以用到外部知识可以在特定任务上获得不错的效果,尤其是在监督数据充足的情况下
挑战需要可靠的召回系统数据不足时存在过拟合风险,模型只能处理训练数据截止日期之前的场景
场景数据经常更新的智能问答场景利用模型完成特定任务,例如情感分类、意图识别等

六、RAG应用场景

  1. 知识库检索
  2. 智能搜索
  3. 智能客服
  4. 智能问答
  5. 数据分析

最终目标:在一个理想的RAG流程中,我们期望一个小参数量的LLM结合一个大型的外挂知识库,可以达到一个超大参数量的模型的效果。

RAGFlow简介和部署

RAGFlow 是一款基于深度文档理解构建的开源 RAG(Retrieval-Augmented Generation)引擎。RAGFlow 可以为各种规模的企业及个人提供一套精简的 RAG 工作流程,结合大语言模型(LLM)针对用户各类不同的复杂格式数据提供可靠的问答以及有理有据的引用。

官方文档:https://ragflow.io/docs/v0.17.2/

Github:https://github.com/infiniflow/ragflow

前置条件

  • CPU >= 4 核

  • RAM >= 16 GB

  • Disk >= 50 GB

  • Docker >= 24.0.0 & Docker Compose >= v2.26.1

幕僚算力虚机参数:

  • 镜像:conda3_25.1.1_3.10.16-ubuntu22.04_12.6

    • GPU:2卡 (4090)

    • 数据盘:100G(原50GB,另外扩容50GB)

    • ollama:deepseek-r1:32b(4-bit 量化-Q4_K_M

    量化类型显存占用(32B)精度保留适用硬件
    FP16(原始)~64GB100%A100/H100
    Q4_0~16GB较低RTX 3090/4090
    Q4_K_M~16GB中高RTX 4090
    Q5_K_M~20GBRTX 4090/A100
    Q8_0~32GB接近FP16A100 40GB

从0开始部署RAGFlow

  1. 安装docker

    在Ubuntu 20.04上安装Docker可以通过以下步骤完成:

    更新软件包索引,以确保你的软件包索引是最新的

    bash
    sudo apt-get update
    sudo apt-get update

    安装一些必要的软件包,以便apt能够通过HTTPS使用仓库

    bash
    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

    开启学术加速

    bash
    export http_proxy=http://10.132.19.35:7890
    export https_proxy=http://10.132.19.35:7890
    export http_proxy=http://10.132.19.35:7890
    export https_proxy=http://10.132.19.35:7890

    添加Docker的官方GPG密钥

    bash
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

    添加Docker的APT仓库

    bash
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

    再次更新软件包索引,因为你刚添加了一个新的仓库,所以需要再次更新软件包索引

    bash
    sudo apt-get update
    sudo apt-get update

    创建docker数据目录(幕僚平台算力市场中镜像deepseek-r1-32b_ragflowv0.17.2,因需要保存为原始镜像,所以没有这一步;用户自己根据本文安装部署需要修改docker数据目录

    bash
    mkdir /data/docker
    mkdir /data/docker

    从新添加的仓库中安装Docker CE

    bash
    sudo apt-get -y install docker-ce
    sudo apt-get -y install docker-ce

    安装完成后,运行下面的命令来验证Docker是否安装成功

    bash
    sudo docker --version
    sudo docker --version

    查看docker运行状态

    bash
    sudo systemctl status docker
    sudo systemctl status docker

    配置代理和修改数据目录,vim /etc/docker/daemon.json

    bash
    "proxies": {
    "http-proxy": "http://10.132.19.35:7890/proxy.pac",
    "https-proxy": "http://10.132.19.35:7890/proxy.pac",
    "no-proxy": "localhost"
    },
    "data-root":"/data/docker"
    "proxies": {
    "http-proxy": "http://10.132.19.35:7890/proxy.pac",
    "https-proxy": "http://10.132.19.35:7890/proxy.pac",
    "no-proxy": "localhost"
    },
    "data-root":"/data/docker"

    卸载apparmor

    bash
    apt remove apparmor -y
    apt remove apparmor -y

    重启docker

    bash
    systemctl daemon-reload
    systemctl restart docker
    systemctl daemon-reload
    systemctl restart docker

    查看docker 版本

    bash
    docker info
    docker info

    查看docker compose 版本

    bash
    docker compose version
    docker compose version
  2. 安装nvidia-docker

    设置仓库和GPG密钥

    bash
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
             && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
             && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
                   sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
                   sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
             && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
             && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
                   sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
                   sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

    部署 nvidia-container-toolkit 包

    bash
    apt-get update
    apt-get install -y nvidia-container-toolkit
    apt-get update
    apt-get install -y nvidia-container-toolkit

    runtime配置

    bash
    nvidia-ctk runtime configure --runtime=docker
    nvidia-ctk runtime configure --runtime=docker

    重启

    bash
    systemctl restart docker
    systemctl restart docker
  3. 部署RAGFlow

    参考 https://github.com/infiniflow/ragflow/blob/main/README_zh.md ,修改系统配置文件/etc/sysctl.conf参数vm.max_map_count,RAGFlow安装过程中会安装ElasticSearch,对于像 Elasticsearch 这样的应用,内存映射文件(mmap)被广泛用于提高索引和搜索性能。如果 vm.max_map_count 设置得太低,Elasticsearch 可能会遇到内存不足的问题,导致异常行为或错误。

    bash
    vim /etc/sysctl.conf
    vim /etc/sysctl.conf

    添加如下参数

    bash
    vm.max_map_count = 262144
    vm.max_map_count = 262144

    使生效

    bash
    sysctl -p
    sysctl -p

    下载源码(找到最新release版本,开启学术加速

    git clone https://github.com/infiniflow/ragflow.git
    cd ragflow/docker
    git checkout -f v0.17.2
    git clone https://github.com/infiniflow/ragflow.git
    cd ragflow/docker
    git checkout -f v0.17.2

    修改RAGFLOW部署配置

    vim .env
    vim .env

    修改镜像版本,选择包含embedding模型的镜像

    RAGFLOW_IMAGE=infiniflow/ragflow:nightly
    RAGFLOW_IMAGE=infiniflow/ragflow:nightly

    修改端口映射,改为幕僚对外暴露的端口(使用幕僚算力实例需要修改)

    SVR_HTTP_PORT=8890
    SVR_80_PORT=8891
    SVR_443_PORT=8892
    SVR_HTTP_PORT=8890
    SVR_80_PORT=8891
    SVR_443_PORT=8892

    修改文档引擎改为infinity

    DOC_ENGINE=${DOC_ENGINE:-infinity}
    DOC_ENGINE=${DOC_ENGINE:-infinity}

    修改docker-compose端口映射(使用幕僚算力实例需要修改)

    vim docker-compose-gpu.yml
    vim docker-compose-gpu.yml

    修改内容如下:

    ports:
      - ${SVR_HTTP_PORT}:9380
      - ${SVR_80_PORT}:80
      - ${SVR_443_PORT}:443
    ports:
      - ${SVR_HTTP_PORT}:9380
      - ${SVR_80_PORT}:80
      - ${SVR_443_PORT}:443

    修改上传文件大小(和nginx也有关系,需要更大的需要更改nginx配置文件)

    environment:
      - MAX_CONTENT_LENGTH=100000000
    environment:
      - MAX_CONTENT_LENGTH=100000000

    运行RAGFlow,注意使用CPU还是GPU去执行embedding和DeepDoc任务(1张卡用CPU、2张卡可以选用GPU)

    docker compose -f docker-compose-gpu.yml up -d
    docker compose -f docker-compose-gpu.yml up -d

    通过docker ps查看服务启动信息

    docker ps
    docker ps

    image-20250425095226039

    访问RAGFlow(通过幕僚暴露的公网端口即可访问)

    ragflow的web页面的默认端口是80,我们通过参数修改为SVR_80_PORT=8891,8891对应的公网端口可以从控制台预留端口进行查询。此时就可以通过muliao.com的对外IP及对外映射端口登录ragflow的web地址了。

    登录用户名:admin@example.com

    登录密码:admin123456

    image-20250425095647529

用户可在登录后点击右上角头像自行修改用户名及密码:

image-20250425112814923

image-20250425112836859

RAGFlow构建知识库和智能体

构建知识库

在RAGFlow中构建个人知识库并实现基于个人知识库的对话问答。

  • 配置模型提供商-配置模型-Chat模型和Embedding模型(RGFlow自带)

    image-20250425104120489

    image-20250425114049743

    image-20250425114357445

  • 创建知识库

    image-20250425114534236

    配置保持默认即可

    image-20250425140014744

    添加数据集,以解析Nvidia H100白皮书文件为例

    image-20250425142709085

  • 创建聊天助手

    image-20250425143525402

    image-20250425143426787

  • 开始对话,验证:

    shell
    # Nvidia H100白皮书
    问题1:Nvidia H100简介
    # Nvidia H100白皮书
    问题1:Nvidia H100简介

image-20250425144229736

image-20250425144341195

数据集解析时可能会报错:

NCCL Error 2: unhandled system error

ERROR: max retry times, still cannot process batch, please check your GPU memory

解决办法:

shell
# 停止ragflow服务
cd /data/sourcecode/ragflow/docker
docker compose down 

# 修改ragflow使用显卡的编号
vim docker-compose-gpu.yml
# 添加内容如下:
    environment:
      - NCCL_DEBUG=INFO
      - CUDA_VISIBLE_DEVICES=0

# 启动ragflow服务 
docker compose -f docker-compose-gpu.yml up -d
# 停止ragflow服务
cd /data/sourcecode/ragflow/docker
docker compose down 

# 修改ragflow使用显卡的编号
vim docker-compose-gpu.yml
# 添加内容如下:
    environment:
      - NCCL_DEBUG=INFO
      - CUDA_VISIBLE_DEVICES=0

# 启动ragflow服务 
docker compose -f docker-compose-gpu.yml up -d

构建Agent智能体

  • 部署mysql

    bash
    # 创建mysql外部挂载数据目录
    mkdir -p /root/mysql/data
    # 创建mysql外部挂载数据目录
    mkdir -p /root/mysql/data

    启动mysql容器

    bash
    # 注意端口改为幕僚端口
    docker run -d \
      --name agent-mysql \
      -p 8894:3306 \
      -e MYSQL_ROOT_PASSWORD=root@111 \
      -v /root/mysql/data:/var/lib/mysql \
      mysql:8.0.39
      
    # 修改权限
    docker exec -it agent-mysql bash
    mysql -u root -p
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    
    create database dbtest;
    
    # 本地工具连接
    # 注意端口改为幕僚端口
    docker run -d \
      --name agent-mysql \
      -p 8894:3306 \
      -e MYSQL_ROOT_PASSWORD=root@111 \
      -v /root/mysql/data:/var/lib/mysql \
      mysql:8.0.39
      
    # 修改权限
    docker exec -it agent-mysql bash
    mysql -u root -p
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    
    create database dbtest;
    
    # 本地工具连接

    导入数据:

    • merchants.sql

    • products.sql

    • users.sql

  • 上传知识库

    • 创建知识库DDL,并上传 DDL.txt 文件,修改切片方法,最后解析文件

      image-20250425155015091

      image-20250425155306827

    • 创建知识库Q->SQL,上传question_to_sql.csv文件,修改修片方法,最后解析文件

      image-20250425160142859

    • 创建知识库DB Description,上传 DB Description.txt 文件,修改切片方法,最后解析文件

      image-20250425160236613

      image-20250425160736013

  • 创建Agent

    image-20250425144812638

    image-20250425170135616

    DB Assistant测试

    sql
    -- 查询苹果旗舰店的所有商品
    SELECT * FROM products 
    WHERE merchant_id = (
      SELECT id FROM merchants WHERE name = '苹果旗舰店'
    );
    
    -- 查询2024年6月创建的商品及其商家信息
    SELECT p.name AS product_name, m.name AS merchant_name 
    FROM products p
    JOIN merchants m ON p.merchant_id = m.id
    WHERE p.create_time BETWEEN '2024-06-01' AND '2024-06-30';
    
    -- 查询用户与商家的注册时间分布
    SELECT 'users' AS type, DATE_FORMAT(create_time, '%Y-%m') AS month, COUNT(*) 
    FROM users GROUP BY DATE_FORMAT(create_time, '%Y-%m')
    UNION ALL
    SELECT 'merchants', DATE_FORMAT(create_time, '%Y-%m'), COUNT(*) 
    FROM merchants GROUP BY DATE_FORMAT(create_time, '%Y-%m');
    -- 查询苹果旗舰店的所有商品
    SELECT * FROM products 
    WHERE merchant_id = (
      SELECT id FROM merchants WHERE name = '苹果旗舰店'
    );
    
    -- 查询2024年6月创建的商品及其商家信息
    SELECT p.name AS product_name, m.name AS merchant_name 
    FROM products p
    JOIN merchants m ON p.merchant_id = m.id
    WHERE p.create_time BETWEEN '2024-06-01' AND '2024-06-30';
    
    -- 查询用户与商家的注册时间分布
    SELECT 'users' AS type, DATE_FORMAT(create_time, '%Y-%m') AS month, COUNT(*) 
    FROM users GROUP BY DATE_FORMAT(create_time, '%Y-%m')
    UNION ALL
    SELECT 'merchants', DATE_FORMAT(create_time, '%Y-%m'), COUNT(*) 
    FROM merchants GROUP BY DATE_FORMAT(create_time, '%Y-%m');

    image-20250425173145217