Skip to content

RAG 知识库

虾饺内置生产级 RAG(Retrieval-Augmented Generation)系统。上传文档,Agent 自动索引,提问时通过 Tool Calling 中的 rag_query 检索——你的文档变成 Agent 的"大脑"。与 Agent 持久记忆 搭配:RAG 管文档事实,记忆管用户偏好与历史。

RAG 知识库检索

Agent 从知识库检索信息并以结构化格式呈现。

为什么需要 RAG?

LLM 的知识有两个局限:

  1. 截止日期 — 训练数据有截止日期,不知道最新信息
  2. 私有数据 — 不知道你公司的 API 文档、产品手册等

RAG 通过"检索+生成"解决这些问题:先从你的文档中找到相关段落,再让 LLM 基于这些段落回答。

没有 RAG有 RAG
"我不知道你们的 API 格式""根据你的 API 文档,认证使用 Bearer Token..."
可能编造答案(幻觉)基于真实文档回答
无法引用来源可以指出信息出自哪个文档

检索管线(三阶段)

虾饺的 RAG 采用三阶段检索管线,层层过滤,确保最终注入 LLM 的内容高度相关:

┌─────────────────────────────────────────────────────┐
│                                                     │
│  用户提问                                            │
│     ↓                                               │
│  ┌──── 第一阶段:双路检索 ────┐                       │
│  │                           │                      │
│  │  BM25           向量检索   │                      │
│  │ (关键词匹配)   (语义匹配)  │                       │
│  │     ↓              ↓      │                      │
│  │     候选集 A   候选集 B    │                      │
│  └──────────┬────────────────┘                      │
│             ↓                                       │
│  ┌──── 第二阶段:RRF 融合 ────┐                      │
│  │  合并两路结果               │                     │
│  │  互惠排名融合排序           │                      │
│  │  去重                      │                     │
│  └──────────┬────────────────┘                      │
│             ↓                                       │
│  ┌──── 第三阶段:LLM 重排序 ──┐                      │
│  │  LLM 对 Top-N 结果评分      │                     │
│  │  按相关性重新排序            │                     │
│  │  取 Top-K 注入上下文         │                     │
│  └──────────┬────────────────┘                      │
│             ↓                                       │
│  注入 Agent 上下文 → Agent 回答                       │
│                                                     │
└─────────────────────────────────────────────────────┘

第一阶段:双路检索

同时使用两种互补的检索策略:

BM25(关键词检索)

查询:"API 认证方式"
→ 精确匹配包含"API"和"认证"的文档片段
→ 适合:精确术语、代码函数名、特定词汇

向量检索(语义检索)

查询:"怎么鉴权"
→ embedding 相似度匹配,找到语义相近的"认证"、"授权"、"Token"相关段落
→ 适合:意图理解、同义词、模糊表述

为什么要双路?

单用 BM25,搜"鉴权"找不到"认证";单用向量,搜"getUserById"可能匹配到不相关的函数。双路互补,既精确又智能。

第二阶段:RRF 融合

Reciprocal Rank Fusion 是一种经过实践验证的融合排序算法:

RRF Score = Σ 1 / (k + rank_i)

其中 k 是常数(通常为 60),rank_i 是文档在第 i 路检索中的排名。

效果:在两路检索中都排名靠前的文档,融合后排名更高。

第三阶段:LLM 重排序

融合排序后,取 Top-N 候选结果,让 LLM 做精细评分:

System: 请评估以下文档片段与查询的相关性,给出 0-10 分。
Query: "API 认证方式"

文档 1: "所有 API 请求需要在 Header 中携带 Bearer Token..." → 9 分
文档 2: "API 返回 JSON 格式..." → 3 分
文档 3: "认证模块使用 JWT,过期时间 24 小时..." → 8 分

最终取最高分的 Top-K 结果注入 Agent 上下文。

分层分块策略

文档切片是 RAG 质量的关键。虾饺采用分层分块策略:

双层设计

┌────────────────────────────────────┐
│  大块 (Parent Chunk, ~800 字)      │
│                                    │
│  ┌──────────┐  ┌──────────┐       │
│  │ 小块 200字│  │ 小块 200字│  ... │
│  └──────────┘  └──────────┘       │
│                                    │
└────────────────────────────────────┘
  • 小块(~200 字):用于检索,粒度细,命中率高
  • 大块(~800 字):用于上下文,信息完整,不断章取义

工作流程

  1. 检索时搜索小块 → 精确定位
  2. 命中小块后,扩展到对应的大块 → 获得完整上下文
  3. 大块注入 LLM → Agent 理解前因后果

为什么不直接用大块检索?

大块包含多个主题,embedding 向量是这些主题的"平均",搜索精度下降。小块单一主题,检索更准确。

支持的文档格式

格式说明解析方式
PDF最常用pdf-parse 提取文本
TXT纯文本直接读取
Markdown文档直接读取,保留结构
其他纯文本.log / .csv 等直接读取

使用方式

上传文档

通过 Web 界面上传文档到指定 Agent 的工作区:

  1. 进入 Agent 设置
  2. 在知识库区域上传文件
  3. 系统自动完成:解析 → 分块 → embedding → 索引

Agent 检索

Agent 通过 rag_query 工具(见 Tool Calling)自动检索:

你:@代码助手 我们的支付接口怎么调用?
代码助手:[调用 rag_query: "支付接口调用方式"]
→ 从你上传的 API 文档中检索
→ 基于检索结果回答

与其他 RAG 方案的对比

虾饺 RAGDify RAGLangChain RAG
检索方式BM25 + 向量 + LLM 重排向量 + 关键词可配置
分块策略分层(小块检索+大块上下文)固定大小可配置
向量存储SQLite(零依赖)Qdrant / WeaviateFAISS / Pinecone
部署复杂度npm startDocker Compose需自行编排
外部依赖需要向量数据库需要向量数据库

虾饺的 RAG 可能不如专用系统灵活,但它的优势是零外部依赖——所有组件内置在一个 Node.js 进程中,SQLite 做向量存储,不需要额外部署 Qdrant / Milvus / Pinecone。

调优建议

1. 文档质量很重要

  • 结构清晰:用标题、段落、列表,不要一堆连续文字
  • 信息密度:去掉废话、重复内容
  • 格式统一:保持术语一致

2. 分块长度

当前使用默认的 200/800 分层策略。如果你的文档每段很长,可以考虑源码层面调整分块参数。

3. embedding 模型

默认使用 text-embedding-3-small。如果你用通义千问等国产模型,系统会使用对应 Provider 的 embedding 模型。中文文档建议使用中文优化的 embedding 模型。

4. 搜索关键词技巧

RAG 的 BM25 路依赖关键词匹配。如果搜索"支付怎么用"没结果,试试文档中的原始术语"payment API"。

5. 什么文档效果好 / 不好

效果好效果差
API 文档(结构化、术语清晰)扫描版 PDF(OCR 质量差)
技术规范(段落分明)表格密集的 Excel 导出
产品手册(问答式)纯图片的 PPT 导出
Markdown 笔记(天然结构化)法律合同(长句、嵌套引用)

实际检索效果示例

以下是一个真实的 RAG 检索过程——从用户提问到 Agent 给出答案:

用户:@代码助手 我们的订单状态有哪些?

系统内部流程:
┌─ BM25 路:FTS5 搜索 "订单 状态"
│  结果 1: "订单状态包括:pending、paid、shipped、completed、cancelled" (score: 8.2)
│  结果 2: "创建订单接口 POST /api/orders" (score: 3.1)

├─ 向量路:embedding("订单状态有哪些") → 余弦相似度搜索
│  结果 1: "enum OrderStatus { PENDING, PAID, SHIPPED... }" (sim: 0.89)
│  结果 2: "订单状态流转:待支付→已支付→已发货→已完成" (sim: 0.85)

├─ RRF 融合:合并两路结果,取 Top-5

└─ LLM 重排:对 5 个候选评分
   最终注入 Agent 上下文的 3 个 chunk

代码助手回复:
"根据你的文档,订单状态共有 5 种:
1. pending(待支付)
2. paid(已支付)
3. shipped(已发货)
4. completed(已完成)
5. cancelled(已取消)

状态流转规则:pending → paid → shipped → completed
任何状态可以直接 → cancelled

参考来源:API 文档 v2.3 第 4.2 节"

相关文档

基于 MIT 协议开源 · GitHub · 社区