目录标题
-
-
- 一、知识库检索
- 二、混合检索重点分析
-
- [疑问1: 是不是全文查出来是段落,语义查出来都是向量?rerank怎么区分两个结果选择,他们没法公用一套打分吧](#疑问1: 是不是全文查出来是段落,语义查出来都是向量?rerank怎么区分两个结果选择,他们没法公用一套打分吧)
-
- 第一步:不用分数,用排名来合并(RRF)
- [第二步:Rerank 用一套统一标准重新打分](#第二步:Rerank 用一套统一标准重新打分)
- 总结
- [疑问2: 混合检索,如果不用rerank,用权重,那score阈值怎么设置,全文减速和语义检索没有一套同意打分,怎么设置阈值啊。](#疑问2: 混合检索,如果不用rerank,用权重,那score阈值怎么设置,全文减速和语义检索没有一套同意打分,怎么设置阈值啊。)
-
- 一、为什么不能直接设阈值(先看问题)
- [二、第一步:各自归一化到 0,1](#二、第一步:各自归一化到 [0,1])
- 三、第二步:加权融合
- 四、第三步:对「融合分」设阈值
- 总结两个疑问
- 三、dify的知识库创建
-
一、知识库检索
知识库检索有全文检索、语义检索、混合检索三种方式
全文检索:基于关键词+倒排索引技术。
语义检索:基于向量+相似度计算。 余弦相似度
混合检索:将全文检索和语义检索的结果进行汇总,再次排序,得到最终检索结果
全文检索线:
离线:文档 → 分词 → 建倒排索引
在线:query → 分词 → 查倒排索引 → 打分(BM25) → 结果
全文检索是一种能够直接从海量的非结构化文本数据(如文章、报告、邮件等)中快速查找出包含特定词汇或短语的信息的技术。它的核心思想类似于书籍末尾的索引,通过预先建立"词汇-文档"的映射关系,实现高效的内容搜索。
全文检索系统的工作流程可以概括为两个核心阶段:索引构建 和 查询检索:
索引构建 (Indexing):这是搜索前的准备工作,也是最关键的一步。系统会对待搜索的文档集合进行处理:
- 分词:首先,将连续的文本切分成有意义的词汇单元。这对于中文尤为关键,例如,将"全文检索技术很棒"切分为"全文"、"检索"、"技术"、"很棒"。
- 创建倒排索引:建立一个"倒排索引"。这就像一本书的索引表,记录每个词语出现在哪些文档中,以及出现的位置和频率。当用户搜索时,系统无需扫描所有文档,只需直接查找这个索引表,就能瞬间知道哪些文档包含关键词。
查询检索 (Search):当用户输入查询关键词时,系统执行以下操作:
- 查询处理:对查询词进行同样的分词处理。
- 索引查找:在倒排索引中查找这些分词后的词汇,找到包含它们的文档集合。
- 相关性排序:最后,系统使用相关性排序算法(如 BM25)对结果进行评分排序,将最符合用户需求的文档排在前面
语义检索线:
离线:文档 → 切块 → embedding模型编码 → 存向量库
在线:query → embedding编码 → 向量相似度检索 → 结果
混合检索:
就是同时执行全文检索和向量检索
从查询结果中选择匹配用户问题的最佳结果。 混合的策略一般分两种
权重:用户自己通过数值设定关键词和语义的比重,在进行一次排序
rerank:通过rerank模型,把两种检索方法检索到的结果进行混合,再进行一次排序。

用一个类比帮你记
- 全文检索 = 图书馆的关键词卡片目录:按"书名里有没有这个词"找书。快、准(对专有名词/编号),但不懂同义词。
- 语义检索 = 一个读过所有书的馆员:你说"讲孤独的书",他能找到《百年孤独》即使书里没"孤独"二字。懂语义,但可能召回不准、成本高。
- 混合检索 = 卡片目录 + 馆员一起上,结果合并。
二、混合检索重点分析
疑问1: 是不是全文查出来是段落,语义查出来都是向量?rerank怎么区分两个结果选择,他们没法公用一套打分吧
全文检索和语义检索返回的"东西"本质上是一样的:都是文档片段(段落/Chunk)。区别只在于它们内部计算相似度的方式:全文检索靠词频统计(BM25),语义检索靠向量距离。最终返回给下一环节的,都是带有一个分数的候选段落列表。
至于 Rerank 如何区分并选择:你说得对,它们确实没法公用一套原始打分。所以标准做法是分两步走:先用一种"不看分数只看排名"的方法把两路结果粗粗合并,再用 Rerank 模型对合并后的候选段落重新打一套统一的、真正可比的分数。
第一步:不用分数,用排名来合并(RRF)
既然 BM25 的分数(可能无上界)和向量余弦相似度(0~1)没法直接比大小,就先别比分数了。业界通用的 RRF(倒数排名融合) 只看排名位次。
它的逻辑很朴素:一个文档如果在全文检索里排第 1,在语义检索里排第 3,那它大概率不错;另一个文档如果只在全文检索里排第 20,那它大概率不如前者。RRF 给每个文档算一个融合分: 1 / ( k + 排名 ) 1 / (k + 排名) 1/(k+排名),排名越靠前,贡献越大,然后把两边的贡献加起来。这样就能把两路结果合并成一个候选段落列表(比如取前 20~30 个),完全绕开了"分数不可比"的问题。
第二步:Rerank 用一套统一标准重新打分
拿到合并后的候选列表后,Rerank 模型登场。它和前面两种检索都不一样:它把用户问题和每一个候选段落放在一起,同时输入模型进行深度比对(Cross-Encoder 架构)。
这时,模型输出的就是一个统一的、绝对的相关性分数(比如 0 到 1),表示"这个段落到底能不能回答这个问题"。这个分数是 Rerank 模型自己算的,跟 BM25 无关,也跟向量相似度无关,全场只有这一套标准,所以可以直接用来排序和筛选,挑出最靠前的几个段落送给大模型。
总结
全文和语义检索负责广撒网 ,捞出可能相关的段落;RRF 负责不分、只比名次 地把两路结果粗粗混在一起;Rerank 负责用一套新标准对混好的候选段落做最终的精挑细选。这样就不需要让 BM25 和向量分数去"硬融"了。
疑问2: 混合检索,如果不用rerank,用权重,那score阈值怎么设置,全文减速和语义检索没有一套同意打分,怎么设置阈值啊。
BM25 分数和向量相似度分数不在一个尺度上,不能直接设一个统一阈值。 所以做法不是"设一个阈值",而是先各自归一化到同一尺度,再加权融合,最后对融合分设阈值。
举个例子:
一、为什么不能直接设阈值(先看问题)
假设用户 query 是"如何重置路由器密码"。
全文检索(BM25)返回的原始分数:
| 段落 | BM25 分 |
|---|---|
| 段落A | 18.3 |
| 段落B | 12.1 |
| 段落C | 5.4 |
BM25 分数无上界 ,取决于词频、文档长度、语料统计,可能 5 分也可能 50 分,没有绝对含义。
语义检索(余弦相似度)返回的原始分数:
| 段落 | 余弦相似度 |
|---|---|
| 段落A | 0.82 |
| 段落C | 0.76 |
| 段落B | 0.61 |
余弦相似度在 -1~1(实际常 0~1),尺度完全不同。
问题:你能设"阈值 = 0.7"吗? 对余弦可以,对 BM25 完全没意义(18.3 和 0.7 没法比)。所以原始分不能直接加权,也不能直接设阈值。
二、第一步:各自归一化到 0,1
对每一路结果内部做 Min-Max 归一化(只用本次召回的这批候选,不是全局):
s ′ = s − s m i n s m a x − s m i n s' = \frac{s - s_{min}}{s_{max} - s_{min}} s′=smax−smins−smin
全文检索归一化(min=5.4, max=18.3):
| 段落 | 原始 BM25 | 归一化 |
|---|---|---|
| A | 18.3 | (18.3-5.4)/(18.3-5.4) = 1.00 |
| B | 12.1 | (12.1-5.4)/12.9 = 0.52 |
| C | 5.4 | 0.00 |
语义检索归一化(min=0.61, max=0.82):
| 段落 | 原始余弦 | 归一化 |
|---|---|---|
| A | 0.82 | 1.00 |
| C | 0.76 | (0.76-0.61)/0.21 = 0.71 |
| B | 0.61 | 0.00 |
现在两路分数都在 0,1,尺度统一了,可以比较、可以加权、可以设阈值。
⚠️ 注意: Min-Max 依赖"本批候选的 max/min",如果某路只召回 1 条,max=min 会除零,实践中要加保护(如固定用历史分位数,或对单条直接给 1.0)。
三、第二步:加权融合
设权重:全文 0.4,语义 0.6(语义通常权重高些,但可调)。
f i n a l = w 全文 ⋅ s 全文 ′ + w 语义 ⋅ s 语义 ′ final = w_{全文} \cdot s'{全文} + w{语义} \cdot s'_{语义} final=w全文⋅s全文′+w语义⋅s语义′
| 段落 | 全文归一化 | 语义归一化 | 融合分 = 0.4×全文 + 0.6×语义 |
|---|---|---|---|
| A | 1.00 | 1.00 | 0.4×1.0 + 0.6×1.0 = 1.00 |
| B | 0.52 | 0.00 | 0.4×0.52 + 0.6×0 = 0.21 |
| C | 0.00 | 0.71 | 0.4×0 + 0.6×0.71 = 0.43 |
排序:A(1.00) > C(0.43) > B(0.21)。
四、第三步:对「融合分」设阈值
现在融合分在 0,1,这才是有意义、可设阈值的分数。
- 设阈值 0.4 → 保留 A、C,丢弃 B。
- 设阈值 0.5 → 只保留 A。
阈值怎么定? 不是拍脑袋,常用方法:
- 离线调参:在验证集上,用标注的"相关/不相关"段落,画 Precision-Recall 曲线,选使 F1 或 Recall@K 最优的阈值。
- 按 Top-K 兜底:不设绝对阈值,直接取融合分最高的 K 条(如 K=5),避免"全被阈值滤掉"导致空结果。
- 分位数阈值:取本批融合分的第 70 百分位作为动态阈值。
总结两个疑问
无论是用"权重融合"还是用"Rerank",本质上都是在做重排(Re-ranking / 重新排序),只是它们重排所依赖的"打分标准"不同。
权重:用权重加法公式做重排
rerank: 用神经网络模型做重排。
三、dify的知识库创建
选择数据源

分段模式
通用模式
系统按照用户自定义的规则将内容拆分为独立的分段。当用户输入问题后,系统自动分析问题中的关键词,并计算关键词与知识库中各内容分段的相关度。根据相关度排序,选取最相关的内容分段并发送给 LLM,辅助其处理与更有效地回答。

在该模式下,你需要根据不同的文档格式或场景要求,参考以下设置项,手动设置文本的分段规则。
- 分段标识符 ,默认值为
\n,即按照文章段落进行分块。 - 分段最大长度,指定分段内的文本字符数最大上限,超出该长度时将强制分段。默认值为 500 Tokens,分段长度的最大上限为 4000 Tokens;
- 分段重叠长度,指的是在对数据进行分段时,段与段之间存在一定的重叠部分。这种重叠可以帮助提高信息的保留和分析的准确性,提升召回效果。建议设置为分段长度 Tokens 数的 10-25%;
文本预处理规则,过滤知识库内部分无意义的内容。提供以下选项:
- 替换连续的空格、换行符和制表符
- 删除所有 URL 和电子邮件地址
配置完成后,点击"预览区块"即可查看分段后的效果。你可以直观的看到每个区块的字符数。如果重新修改了分段规则,需要重新点击按钮以查看新的内容分段。
父子模式
与通用模式相比,父子模式采用双层分段结构来平衡检索的精确度和上下文信息,让精准匹配与全面的上下文信息二者兼得。

父子分段:
子区块(Child-chunk)则是较小的文本单位(如句子),用于精确检索。
系统首先通过子区块进行精确检索以确保相关性,然后获取对应的父区块来补充上下文信息,
从而在生成响应时既保证准确性又能提供完整的背景信息。
用户问题 用子块匹配
返回给大模型是 父块
索引方法
经济模式
在经济模式下,每个区块内使用 10 个关键词进行检索,降低了准确度但无需产生费用。对于检索到的区块,仅提供倒排索引方式选择最相关的区块。
高质量索引
使用 Embedding 嵌入模型将已分段的文本块转换为数字向量,帮助更加有效地压缩与存储大量文本信息;使得用户问题与文本之间的匹配能够更加精准