OpenWebUI 多源 RAG 实践指南

2025年5月19日

link:https://productiv-ai.guide/start/multi-source-rag-openwebui/

理解带混合搜索和重排序的多源 RAG

Retrieval-Augmented Generation (RAG) 是一种强大的技术,它通过将大型语言模型 (LLM) 的回应基于事实性、相关性信息来增强其能力。与仅仅依赖模型预训练的知识不同,RAG 从外部来源检索特定信息,并将其用作生成回应的上下文。

本实现通过三项关键增强将 RAG 提升到新的水平:

  1. 多源检索 (Multi-Source Retrieval):通过 Brave Search API 从本地知识库(您上传的文档)和网络中获取信息,使您的 AI 能够访问您的私人文档和最新的在线信息。
  2. 混合搜索 (Hybrid Search):结合了两种互补的搜索方法:
    • 稠密语义搜索 (Dense Semantic Search):使用向量嵌入捕捉概念相似性,即使关键词不完全匹配也能找到相关内容。
    • 稀疏关键词搜索 (Sparse Keyword Search):确保匹配重要的关键词,类似于传统的搜索引擎。
  3. 重排序 (Re-ranking):应用专门的模型根据检索到的信息与您特定问题的相关性对其进行评估和排序,确保优先考虑最相关的上下文。

这种方法提供了更准确、更可靠的 AI 回应,并具有以下优势:

  • 通过多样化的信息来源实现更好的事实基础。
  • 通过互补的搜索方法提高检索准确性。
  • 通过智能重排序增强相关性。
  • 通过提供高质量的上下文减少"幻觉"(模型编造信息)。
  • 通过来源引用提供可审计性。

RAG 流水线架构

以下是我们的多源 RAG 流水线的工作方式:

  1. 文档处理 (Document Processing):将文档上传到 Apache Tika,它从各种文件格式(PDF, DOCX, PPT 等)中提取文本和元数据。
  2. 文档嵌入 (Document Embedding):提取的文本被分块,并使用如 text-embedding-3-small 等模型转换为向量嵌入,然后存储在向量数据库中。
  3. 用户查询 (User Query):当您提出问题时,系统会通过多个检索路径处理它。
  4. 多源检索 (Multi-Source Retrieval)
    • 本地知识库 (Local Knowledge Base):使用混合搜索(稠密 + 稀疏)查找相关的文档块。
    • 网络搜索 (Web Search):选择性地使用 Brave Search API 从互联网检索信息。
  5. 重排序 (Re-ranking):所有检索到的结果都由一个交叉编码器重排序模型(如 bge-reranker-v2)根据其与您问题的相关性进行评分。
  6. Top-K 选择 (Top-K Selection):选择最相关的信息作为上下文提供给 LLM。
  7. 回应生成 (Response Generation):LLM 基于提供的上下文生成答案。
  8. 回应交付 (Response Delivery):您收到一个带有源文档引用的、上下文准确的答案。

在实现此 RAG 流水线之前,您需要:

  • 安装并设置 OpenWebUI 和 Ollama(请参阅我们之前的指南)。
  • 一个用于嵌入的 OpenAI API 密钥(或一个本地嵌入模型)。

实现步骤

让我们一步步构建我们的多源 RAG 流水线。

1. 设置 Apache Tika

首先,我们需要将 Apache Tika 添加到我们现有的 Portainer 堆栈中。Tika 将处理文档处理和文本提取。

  1. 在 Portainer 中,导航到我们之前创建的现有 Ollama/OpenWebUI 堆栈。

  2. 编辑堆栈配置并添加 Tika 服务:

    tika:
      image: apache/tika:latest-full
      container_name: tika
      restart: on-failure
      ports:
        - "9998:9998"
      networks:
        - docker_default
    

如果您的 ollama 配置了 Nvidia GPU,更新后的 docker 容器堆栈应类似于:

services:
  ollama:
    volumes:
      - ollama:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    container_name: ollama
    pull_policy: always
    tty: true
    restart: unless-stopped
    ports:
      - 11434:11434
    image: ollama/ollama:${OLLAMA_DOCKER_TAG-latest}
    networks:
      - docker_default
  open-webui:
    image: ghcr.io/open-webui/open-webui:dev-cuda
    container_name: open-webui
    volumes:
      - open-webui:/app/backend/data
    depends_on:
      - ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    ports:
      - ${OPEN_WEBUI_PORT-3000}:8080
    environment:
      - "OLLAMA_BASE_URL=http://ollama:11434"
      - "WEBUI_SECRET_KEY="
      - host.docker.internal:host-gateway
    restart: unless-stopped
    networks:
      - docker_default
  tika:
    image: apache/tika:latest-full
    container_name: tika
    restart: unless-stopped
    ports:
      - 9998:9998
    networks:
      - docker_default
volumes:
  ollama:
  open-webui:
networks:
  docker_default:
    external: true

如果您因为没有 Nvidia GPU 而未部署 ollama,您的堆栈应类似于:

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:latest
    container_name: open-webui
    volumes:
      - open-webui:/app/backend/data
    ports:
      - ${OPEN_WEBUI_PORT-3000}:8080
    environment:
      - "WEBUI_SECRET_KEY="
      - host.docker.internal:host-gateway
    restart: unless-stopped
    networks:
      - docker_default
  tika:
    image: apache/tika:latest-full
    container_name: tika
    restart: unless-stopped
    ports:
      - 9998:9998
    networks:
      - docker_default
volumes:
  open-webui:
networks:
  docker_default:
    external: true
  1. 部署更新后的堆栈。
  2. 通过检查 Portainer 中的容器状态来验证 Tika 是否正在运行。

(图片:包含 Tika 的 Portainer 堆栈)

2. 在 OpenWebUI 中配置文档处理

现在,让我们配置 OpenWebUI 使用 Tika 进行文档处理:

  1. 登录 OpenWebUI。
  2. 点击左下角的用户头像。
  3. 导航到 设置 (Settings) → 管理员设置 (Admin Settings) → 文档 (Documents)。
  4. 配置以下设置:
    • 内容提取引擎 (Content Extraction Engine):选择"Tika"。
    • Tika URLhttp://tika:9998
    • 文本分割器 (Text Splitter):"Token (Tiktoken)"。
    • 块大小 (Chunk Size):500。
    • 块重叠 (Chunk Overlap):100。

这些设置决定了文档如何被处理并分割成可管理的块。块大小 500 个 token 并重叠 100 个 token 在上下文保留和检索粒度之间提供了良好的平衡。

3. 设置嵌入

接下来,配置嵌入设置:

  1. 在同一个 文档 (Documents) 设置页面,向下滚动到 嵌入 (Embedding) 部分。
  2. 配置以下内容:
    • 嵌入模型引擎 (Embedding Model Engine):选择"OpenAI"。
    • OpenAI API URLhttps://api.openai.com/v1
    • 嵌入模型 (Embedding Model)text-embedding-3-small
    • 嵌入批处理大小 (Embedding Batch Size):1。

嵌入模型将文本块转换为捕捉语义意义的向量表示,从而实现基于相似性的检索。

4. 配置检索设置

现在,设置混合搜索和重排序功能:

  1. 向下滚动到 检索 (Retrieval) 部分。

  2. 配置以下设置:

    • 全上下文模式 (Full Context Mode):禁用。
    • 混合搜索 (Hybrid Search):启用(这将同时激活稠密搜索和稀疏搜索)。
    • Top K:20(初始检索的候选数量)。
    • Top K Reranker:10(重排序后的候选数量)。
    • 相关性阈值 (Relevance Threshold):0(或根据您的需求调整)。
  3. 对于重排序配置,根据您的硬件情况有两种选择:

选项 A: 本地重排序(需要 Nvidia GPU)

  • 重排序引擎 (Reranking Engine):"Default (SentenceTransformers)"。
  • 重排序模型 (Reranking Model)BAI/bge-reranker-v2-m3

此选项使用您的本地 GPU 运行重排序模型,可以提供更快的处理速度,但这要求您拥有所需的硬件并已按照 Nvidia GPU 设置进行。这是推荐的解决方案。

  • 注意:幸运的是,重排序器很小,只消耗大约 1GB 的 GPU VRAM。

(图片:Sentence Transformer 重排序设置)

选项 B: 外部重排序 API(无需 GPU)

  1. Jina AI 创建一个免费账户。
  2. 登录后,前往 API 密钥管理器 并复制您的 API 密钥。
  3. 导航到 Reranker 页面 并记下重排序模型和 API URL。
  4. 在 OpenWebUI 中,配置:
    • 重排序引擎 (Reranking Engine):"External"。
    • 重排序引擎 URL (Reranking Engine URL)https://api.jina.ai/v1/rerank
    • 重排序模型 (Reranking Model)jina-reranker-v2-base-multilingual
    • 在密码字段中输入您的 Jina API 密钥。

(图片:Jina 重排序仪表板)

(图片:Jina 重排序检索设置)

这种外部重排序选项无需本地 GPU 资源即可提供高质量的重排序功能。权衡之处在于处理速度较慢,并且我们的流水线依赖于另一个外部源。

这两种选项都创建了一个两阶段的检索过程:首先通过混合搜索收集潜在匹配项,然后使用重排序模型精炼结果。

完成后,您的 OpenWebUI 文档设置应类似于:

(图片:OpenWebUI 文档设置)

按保存并确认没有遇到任何错误。

5. 设置 Brave Search 进行网络检索

要启用网络搜索作为附加信息源:

  1. https://brave.com/search/api/ 获取 Brave Search API 密钥。
  2. 在 OpenWebUI 中,导航到 设置 (Settings) → 管理员设置 (Admin Settings) → 网络搜索 (Web Search)。
  3. 配置以下内容:
    • 启用网络搜索 (Enable Web Search)(切换为开启)。
    • 网络搜索引擎 (Web Search Engine):"brave"。
    • Brave Search API Key:输入您的 API 密钥。
    • 搜索结果数量 (Search Result Count):3。
    • 并发请求 (Concurrent Requests):10。
    • 可选:如果您想将网络搜索限制在特定站点,可以添加域名过滤器。

启用网络搜索后,您的 RAG 系统现在可以从本地知识库和互联网中检索信息。

(图片:Brave Search 设置)

创建您的第一个知识库

现在我们已经设置了 RAG 流水线的所有组件,让我们创建一个包含实际内容的知识库:

1. 下载并提取 OpenWebUI 文档

  1. 从 GitHub 下载最新文档:https://github.com/open-webui/docs/archive/refs/heads/main.zip
  2. 将 main.zip 文件解压到您计算机上的某个位置。
  3. 导航到解压后的文件夹结构,它应该看起来像:docs-main/docs/ 或类似结构。

(图片:OpenWebUI 文档文件)

  1. 最里面的 docs 文件夹就是我们需要的——它包含了所有将构成我们知识库的 markdown (.md 和 .mdx) 文件。
  2. 这些 markdown 文件以适合我们的 RAG 系统的格式包含了官方的 OpenWebUI 文档。

2. 在 OpenWebUI 中创建知识库

  1. 导航到 工作区 (Workspace) > 知识 (Knowledge) > + 创建知识库 (+ Create a Knowledge Base)。
  2. 命名:输入"Open WebUI Documentation"。
  3. 用途 (Purpose):选择"Assistance"。
  4. 点击"创建知识 (Create Knowledge)"。

(图片:知识库创建界面)

3. 上传文档文件

  1. 点击最右侧的"+"按钮添加内容。
  2. 从下拉菜单中选择"上传目录 (Upload directory)"。

(图片:上传知识文件夹)

  1. 导航到包含 markdown 文件的最里面的 docs 目录。
  2. 选择该文件夹并点击"选择文件夹 (Select Folder)"。

(图片:选择文件夹)

  1. 等待系统上传和处理所有文档(您会看到一个上传进度指示器,显示正在处理的文件数量)。

(图片:上传进度)

  • 在后台,Apache Tika 正在根据您配置的设置解析 markdown 文档。
  • 系统正在对内容进行分块,使用您配置的嵌入模型生成向量嵌入,并将这些嵌入存储在向量数据库中。
  • 系统会自动处理子目录中的所有文件,例如 features, getting-started 等。

创建一个启用 RAG 的自定义模型

创建知识库后,下一步是创建一个将使用此知识库启用 RAG 的自定义模型:

1. 导航到模型

  1. 前往 工作区 (Workspace) > 模型 (Models) > + 添加新模型 (+ Add New Model)。

2. 配置模型

  1. 名称 (Name):输入"GPT 4.1 with OpenWebUI RAG"。
  2. 基础模型 (Base Model):选择"GPT 4.1"(或您选择的其他模型)。
  3. 知识源 (Knowledge Source):从下拉菜单中选择"Open WebUI Documentation"。
  4. 保存模型 (Save the Model)。

(图片:自定义模型创建)

此配置将您选择的 LLM 与我们刚刚创建的知识库连接起来,从而启用我们已设置的 RAG 功能。

测试您的多源 RAG 流水线

现在让我们用一些示例查询来测试我们的实现:

1. 开始新的聊天

  1. 导航到 新聊天 (New Chat)。
  2. 选择我们刚刚创建的自定义模型:"GPT 4.1 with OpenWebUI RAG"。

2. 示例查询

  1. 尝试询问:"如何配置环境变量?"

系统会根据我们知识库中提取的相关来源,回应与 OpenWebUI 中配置环境变量相关的、具有上下文感知能力的详细信息。

(图片:环境变量聊天示例)

3. 理解正在发生什么

  1. 当您提出问题时,系统使用混合搜索(稠密 + 稀疏)在您的知识库中找到相关内容。
  2. 重排序器根据您的查询评估并优先排序最相关的块。
  3. LLM 使用检索到的上下文生成回应。
  4. 提供引用以便您可以验证来源。

您可以通过点击回应末尾的参考链接之一来查看引用。引用按相关性得分排序,得分最高的来源排在最前面。

(图片:引用弹出窗口)

相关性得分(0-1)表示每个文档块与您的查询的匹配程度:

  • 较高得分 (0.8-1.0):强相关,包含直接回答您问题的信息。
  • 中等得分 (0.5-0.8):部分相关,提供支持性上下文。
  • 较低得分 (低于 0.5):相关性较弱,可能包含关键词但直接相关性较低。

此评分系统帮助您验证来源质量,区分主要信息和补充信息,并理解为什么某些内容在回应中被优先排序。

4. 测试多源检索

  1. 通过点击聊天界面中的"网络搜索 (Web Search)"按钮(地球图标)启用网络搜索。

(图片:网络搜索开关)

  1. 您可以在对话期间随时切换网络搜索的开启或关闭状态。
  • 网络搜索开启时:系统将从您的知识库和互联网中检索信息。
  • 网络搜索关闭时:系统将仅使用您的本地知识库。
  1. 尝试在启用网络搜索的情况下提问一个您的知识库中可能没有的问题。
  2. 注意回应如何结合来自两个来源的信息并带有适当的引用。

这种灵活性使您可以精确控制每次查询想要使用的信息来源。对于技术文档或私人信息,您可能更倾向于只使用知识库。对于当前事件或一般知识,启用网络搜索可以提供更全面、实时的回应。

高级配置和优化

为了最大程度地发挥您的 RAG 流水线的潜力,请考虑以下优化:

调整块大小和重叠

  • 较小的块(200-300 个 token)更适合精确的事实检索。
  • 较大的块(800-1000 个 token)为复杂主题保留更多上下文。
  • 对于信息密集、相互关联的文档,增加重叠

微调检索参数

  • 增加 Top K 以获得更广泛的覆盖范围,但这会增加处理时间。
  • 调整相关性阈值以过滤掉相关性较低的结果。
  • 针对您的特定用例试验不同的重排序模型

针对不同文档类型进行优化

  • 技术文档得益于较小的块和较高的 Top K 值。
  • 叙事性内容更适合较大的块和更多的重叠。

您现在已经在 OpenWebUI 中实现了一个复杂的多源 RAG 流水线,该流水线集成了混合搜索和重排序。这个系统提供了:

  • 更准确、更可靠的 AI 回应。
  • 从本地文档和网络检索信息的灵活性。
  • 通过互补的搜索方法增强检索能力。
  • 通过智能重排序提高相关性。

此实现相较于基本的 RAG 系统是一个显著的进步,为知识密集型 AI 应用提供了强大的基础。在未来的文章中,我们将探讨如何通过自定义工具和代理来扩展此系统,以实现更多功能。