知识库搜索架构:向量搜索+全文搜索+Rerank 三层流水线设计理念
简介
RAG(检索增强生成)是一种基本架构模式,用于抑制 LLM 幻觉并根据公司特定知识生成答案。然而,这并不像“引入 RAG 会提高准确性”那么简单。 **如果搜索准确性较低,传递给 LLM 的上下文将不准确,答案质量也会恶化。 **
Dify 的知识库搜索架构使用三层管道:矢量搜索、全文搜索和重新排序。在这篇文章中,我们将以搜索公司文档为例来解释为什么这三层是必要的,以及每层解决什么样的问题。
1.三层管道整体图
graph TB
Q[ユーザークエリ] --> P[クエリ前処理]
P --> VS[Vector Search<br/>意味的類似性]
P --> FTS[Full-Text Search<br/>キーワード一致]
VS --> M[Merge<br/>候補統合]
FTS --> M
M --> RR[Rerank Model<br/>関連度再スコアリング]
RR --> TOP[Top-K 選択]
TOP --> LLM[LLM<br/>回答生成]
style VS fill:#4a9,stroke:#333,color:#fff
style FTS fill:#49a,stroke:#333,color:#fff
style RR fill:#a49,stroke:#333,color:#fff
1.1 为什么单一的搜索方法是不够的
企业文档查询具有以下不同特点:
| 查询类型 | 示例 | 最佳搜索技巧 |
|---|---|---|
| 语义搜索 | “退休时需要办理哪些手续?” | 矢量搜索 |
| 关键词搜索 | “ERR-4052 的原因” | 全文搜索 |
| 混合型 | “根据第24条处理个人信息” | 混合+重新排名 |
| 暧昧的表达 | 《如何请假》 | 矢量搜索 |
| 技术术语 | “FISC 安全措施标准第 9 章” | 全文搜索 |
原则上,用单一的搜索方法很难涵盖所有这些。
2.第一层:向量搜索
2.1 工作原理
矢量搜索将文本转换为高维向量(嵌入)并利用向量空间中的距离计算相似度(例如余弦相似度):
graph LR
subgraph "インデックス構築時"
D1[文書チャンク] --> E1[Embedding Model]
E1 --> V1[ベクトル<br/>0.12, -0.34, ..., 0.56]
V1 --> VDB[(Vector DB)]
end
subgraph "検索時"
Q[クエリ] --> E2[Embedding Model]
E2 --> V2[クエリベクトル]
V2 --> S[類似度計算]
VDB --> S
S --> R[Top-K 候補]
end
2.2 矢量搜索擅长什么
- 吸收表达差异:确定“退休程序”和“退出公司时要做的事情”的含义相似。
- 口语问题回答:将自然语言编写的问题与正式文档相匹配
- 多语言支持:使用多语言嵌入模型,您可以用日语问题搜索英语文档。
2.3 向量搜索的局限性
| 限制 | 具体例子 | 影响 |
|---|---|---|
| 弱精确关键词匹配 | 即使您搜索“ERR-4052”,顶部也会出现另一个含义相似的错误代码 | 技术文件的精确度降低 |
| 不擅长处理数字和代码 | “24条”与“23条”文件高度相似 | 法律文件的可靠性下降 |
| 取决于Embedding模型的质量 | 日语技术术语可能无法正确矢量化 | 特定领域文档的准确性降低 |
| 短查询的意图估计不稳定 | 光是“费用”就让人不清楚到底是申请方式、规定还是支付方式 | 搜索结果的变化 |
2.4 嵌入模型选择
Dify 支持多种嵌入模型,允许您根据您的用例进行选择:
| 型号 | 维数 | 日本表演 | 成本 | 应用场景 |
|---|---|---|---|---|
| 文本嵌入-3-小 (OpenAI) | 1536 | 1536好 | 低 | 一般内部文件 |
| 文本嵌入 3-large (OpenAI) | 3072 | 3072好 | 中等 | 当需要高精度时 |
| 多语言-e5-大 | 1024 | 1024好 | 免费(本地) | 封闭网络/成本导向 |
| Cohere 嵌入-多语言-v3 | 1024 | 1024好 | 中等 | 多语言混合环境 |
| BGE-M3 | 1024 | 1024优秀 | 免费(本地) | 日本强调/封闭网络 |
3.第二层:全文检索
3.1 工作原理
全文搜索使用 TF-IDF 和 BM25 算法来计算标记化(形态分析)文本的关键字匹配:
graph LR
subgraph "インデックス構築時"
D1[文書チャンク] --> T1[トークナイザー<br/>形態素解析]
T1 --> I1[転置インデックス]
I1 --> FTI[(全文検索<br/>インデックス)]
end
subgraph "検索時"
Q[クエリ] --> T2[トークナイザー]
T2 --> K[キーワード抽出]
K --> S[BM25 スコアリング]
FTI --> S
S --> R[Top-K 候補]
end
3.2 全文搜索擅长什么
- 关键字精确匹配:错误代码、条款号、产品型号、人名精确匹配
- 搜索技术术语:支持行业特定缩写和内部术语
- 快速响应:倒排索引快速搜索
- 可解释性:清楚为什么返回结果(关键字匹配)
3.3 全文搜索的局限性
| 限制 | 具体例子 | 影响 |
|---|---|---|
| 措辞上的弱点 | “退休”和“离职”被视为不同的事情 | 相关文件被忽视 |
| 需要处理同义词 | “个人电脑”、“个人电脑”、“电脑” | 同义词词典的运算负载 |
| 日语形态分析的准确性 | 新词、自造词、片假名分词错误 | 搜索遗漏 |
| 忽略上下文含义 | 分不清“苹果”是水果还是公司 | 噪音增加 |
3.4 日语全文检索的特点
与英语不同,日语的单词之间没有空格,因此词法分析器的质量与搜索准确性直接相关:
入力: 「個人情報保護法に基づくデータ取扱規定」
MeCab/Sudachi の解析結果:
個人情報 / 保護法 / に / 基づく / データ / 取扱 / 規定
N-gram (bi-gram) の場合:
個人 / 人情 / 情報 / 報保 / 保護 / 護法 / 法に / ...
对于公司文档,通常通过在形态分析器中添加内部词典来提高准确性,但 Dify 旨在通过将其与矢量搜索相结合来弥补形态分析的弱点。
4.第三层:重新排序
4.1 为什么需要重新排序?
矢量搜索和全文搜索都有不同的评分逻辑。简单地合并两个结果并不会产生最佳顺序:
graph TB
subgraph "Rerank なしの問題"
VS_R[Vector Search 結果<br/>スコア: 0.89, 0.85, 0.82, ...]
FTS_R[Full-Text Search 結果<br/>スコア: 12.3, 8.7, 6.2, ...]
VS_R --> MERGE[単純マージ]
FTS_R --> MERGE
MERGE --> PROB[問題: スコアの尺度が異なる<br/>どちらを優先すべきか不明]
end
subgraph "Rerank ありの解決"
CAND[統合候補リスト]
CAND --> RR[Rerank Model<br/>クエリと各候補の<br/>関連度を直接評価]
RR --> SORTED[統一スコアで再ソート]
end
style PROB fill:#f99,stroke:#333
style SORTED fill:#9f9,stroke:#333
4.2 重新排序模型的工作原理
Rerank 模型使用 Cross-Encoder 直接对查询和文档对的相关性进行评分:
# Rerank の概念モデル
def rerank(query: str, documents: list[str], model: str) -> list[RerankResult]:
"""
各文書をクエリとの関連度で再スコアリング。
Cross-Encoder は Bi-Encoder (Embedding) より精度が高いが、
計算コストが高いため、候補を絞った後に適用する。
"""
results = []
for doc in documents:
# クエリと文書を連結して入力し、関連度スコアを出力
score = cross_encoder.predict(f"{query} [SEP] {doc}")
results.append(RerankResult(document=doc, score=score))
return sorted(results, key=lambda x: x.score, reverse=True)
4.3 Rerank解决的问题
| 问题 | 通过重新排序解决 |
|---|---|
| 矢量/全文分数范围的差异 | 统一相关性评分重新评估 |
| 表面相关但实质无关的文件 | 精确评估查询的上下文一致性 |
| 候选人太多时的噪音 | 通过仅将顶尖候选人传递给LLM来提高背景质量 |
| 长块的部分匹配 | 评估整个块与查询的相关性 |
4.4 重新排序模型选项
| 型号 | 供应商 | 日语支持 | 成本 | 特点 |
|---|---|---|---|---|
| Cohere 重新排名 v3 | 连贯 | 多语言支持 | API计费 | 精度高、安装方便 |
| bge-reranker-v2-m3 | bge-reranker-v2-m3 | 巴爱 | 多语言支持 | 免费(本地) |
| 交叉编码器/ms-marco | 拥抱脸 | 主要是英语 | 免费(本地) | 对于英文文件 |
| Jina reranker v2 | Jina | 多语言支持 | API计费 | 高速 |
5.混合搜索:三层集成
5.1 Dify 混合搜索设置
Dify 允许您在创建知识库时选择以下搜索方式:
| 搜索方式 | 配置 | 应用场景 |
|---|---|---|
| 矢量搜索 | 仅矢量搜索 | 以语义搜索为中心的常见问题 |
| 全文搜索 | 仅全文搜索 | 技术文档关键字搜索 |
| 混合搜索 | 矢量+全文+重新排名 | 通用公司文件(推荐) |
5.2 混合搜索处理流程详情
sequenceDiagram
participant U as ユーザー
participant API as Dify API
participant VS as Vector Search
participant FTS as Full-Text Search
participant RR as Rerank Model
participant LLM as LLM
U->>API: クエリ送信
API->>API: クエリ前処理
par 並列検索
API->>VS: Embedding + ANN検索
VS-->>API: Vector候補 (Top-N)
API->>FTS: トークン化 + BM25検索
FTS-->>API: Full-Text候補 (Top-N)
end
API->>API: 候補の統合・重複排除
API->>RR: 統合候補リスト + クエリ
RR-->>API: 再ランキング結果
API->>API: Top-K 選択
API->>LLM: クエリ + Top-K 文書チャンク
LLM-->>API: 回答生成
API-->>U: 回答返却
5.3 权重设置的概念
使用混合搜索,您可以调整矢量搜索和全文搜索之间的权重分配。 Dify 有一个滑块,可以设置为 0.0 到 1.0:
| 体重设定 | 矢量:全文 | 适用场景 |
|---|---|---|
| 1.0 : 0.0 | 仅矢量 | 内部FAQ,主要是自由文字查询 |
| 0.7 : 0.3 | 面向矢量 | 一般内部文件(推荐初始值) |
| 0.5 : 0.5 | 甚至 | 当需要混合查询时 |
| 0.3 : 0.7 | 全文 | 如果有很多型号/代码搜索 |
| 0.0 : 1.0 | 仅全文 | 错误代码搜索、法规文章搜索 |
6. 索引设计:搜索准确性的初步阶段
6.1 分块策略
搜索精度很大程度上取决于索引阶段使用的分块方法:
| 分块方法 | 说明 | 优势 | 缺点 |
|---|---|---|---|
| 定长除法 | 分为 500 个代币单位 | 简单一致 | 上下文被分割 |
| 分离器事业部 | 按标题/换行符划分 | 维护文档结构 | 块大小不均匀 |
| 语义分割 | 语义分割 | 高品质搜索单元 | 加工成本高 |
| 亲子块 | 小块搜索,返回父块 | 平衡搜索准确性和上下文 | 实施复杂度 |
Dify 支持多种分块方法,可以根据文档类型进行选择。
6.2 选择索引方法
Dify 提供两种类型的索引方法:
graph TB
subgraph "高品質モード (Recommended)"
HQ_D[文書] --> HQ_C[チャンク分割]
HQ_C --> HQ_E[Embedding Model<br/>ベクトル化]
HQ_E --> HQ_V[(Vector Index)]
HQ_C --> HQ_F[(Full-Text Index)]
HQ_V --> HQ_H{Hybrid Search<br/>+ Rerank}
HQ_F --> HQ_H
end
subgraph "経済モード"
EC_D[文書] --> EC_C[チャンク分割]
EC_C --> EC_K[キーワードインデックス]
EC_K --> EC_S{キーワード検索のみ}
end
style HQ_H fill:#4a9,stroke:#333,color:#fff
- 高质量模式:构建嵌入+全文索引。提供混合搜索+重新排名。它价格昂贵,但精度很高。
- 经济模式:仅关键字索引。嵌入模型 API 成本是不必要的,但语义搜索是不可能的。
7. 公司文档搜索准确性的实际考虑
7.1 按文档类型推荐的设置
| 文件类型 | 推荐搜索方式 | 重量 | 重新排名 | 原因 |
|---|---|---|---|---|
| 公司规定/用工规定 | 混合动力 | 0.5:0.5 | 有效 | 条款编号和含义搜索均需 |
| 技术手册 | 混合动力 | 0.3:0.7 | 已启用 | 错误代码和参数的关键字搜索很重要 |
| 常见问题解答资料 | 矢量 | 1.0:0.0 | 任意 | 问题的措辞差异很大 |
| 合同 | 混合动力 | 0.5:0.5 | 有效 | 条款编号+法律概念含义搜索 |
| 分钟 | 矢量 | 0.7:0.3 | 有效 | 口语表达很多,意思搜索很有效 |
| API 文档 | 混合动力 | 0.3:0.7 | 已启用 | 端点名称与参数名称精确匹配 |
7.2 调整点以提高准确性
graph TB
subgraph "チューニングの4つのレバー"
A[1. チャンキング<br/>サイズ・方式の調整] --> E[検索精度]
B[2. Embedding Model<br/>モデル選択・ファインチューニング] --> E
C[3. 検索 Weight<br/>Vector vs Full-Text の比率] --> E
D[4. Rerank<br/>モデル選択・Top-K 設定] --> E
end
E --> F[LLM への入力品質]
F --> G[最終回答品質]
- 调整块大小:太小,上下文会丢失;太大,搜索将变得粗粒度。一般300-500个代币是起点。
- 嵌入模型的选择:如果主要使用日语文档,请考虑支持多种语言的高质量模型(text-embedding-3-large、BGE-M3)。
- 权重调整:分析搜索日志并根据用户查询模式进行调整。
- Top-K for Rerank:根据 LLM 上下文长度(通常为 3-5 个块)确定重新排名后要传递的块数。
7.3 如何评估搜索准确性
| 指标 | 定义 | 目标值 |
|---|---|---|
| 回忆@K | Top-K 中包含的正确文档的百分比 | > 0.85 |
| 精度@K | Top-K 中正确文档的百分比 | > 0.70 |
| MRR(平均倒数排名) | 正确文档排名的平均倒数 | > 0.75 |
| NDCG@K | 考虑排名的相关性得分 | > 0.80 |
8.三层管道设计理念
8.1 为什么是“三层”:设计原则
Dify 的三层管道基于以下设计原则:
| 原则 | 描述 |
|---|---|
| 回应不同的询问 | 语义搜索与关键词搜索相辅相成 |
| 准确度逐步提高 | 广泛收集(Recall)并精确聚焦(Precision) |
| 计算成本优化 | 通过轻量级搜索缩小候选者范围,并仅对候选者应用大量重新排名 |
| 可配置性 | 可以根据用例调整权重、Top-K 和 Rerank 的 ON/OFF |
8.2 “先回忆再精确”模式
三层管道的本质是“首先收集广泛的候选者(高召回率),然后精确缩小范围(高精确度)**”的模式:
| 舞台 | 加工 | 回忆 | 精密 | 计算成本 |
|---|---|---|---|---|
| 第一阶段 | 矢量+全文(并行) | 高 | 中等 | 低到中 |
| 第二阶段 | 重新排名 | 维护 | 高 | 中到高 |
| 第三阶段 | Top-K精选 | 维护 | 最高 | 无 |
这种逐渐缩小范围的结果是均衡的搜索结果,既不是“广泛收集但准确性低”,也不是“高度准确但经常错过”。
总结
Dify 的知识库搜索架构结合了三个互补的搜索层来解决企业文档搜索的基本挑战:
- 矢量搜索:基于语义相似性的搜索,以适应表达式的变化和模糊的用户查询。
- 全文搜索:根据精确的关键字匹配进行搜索,包括型号、文章编号和技术术语。
- 重新排名:整合不同的评分方案并精确评估与查询的上下文相关性
这些不仅仅是一堆算法,而是一种分工,旨在响应企业文档搜索中不同类型的查询。通过调整每层的权重、Top-K 和 Rerank 模型的选择,可以根据文档特征和用户查询模式进行优化。
参考资料
-インデックス方法と検索設定を指定 - Dify Docs -ハイブリッド検索 - Dify Legacy Docs -Re-ranking - Dify Legacy Docs -世界一わかりやすい Dify 初心者のための RAG 完全ガイド -徹底解説 Dify でのナレッジの使い方