关键词搜不到、向量也搜不准?蛙趣拼文BM25+向量+RRF混合检索技术实测
我做搜索相关的工作做了四年。
所以看到蛙趣拼文资料里提到"BM25 + 向量 + RRF 融合排序"的时候,我知道它在做什么。它不是随便堆技术名词。它是真的在解决小说场景下一个非常具体的问题。
这个问题就是:小说的信息检索,既不能纯靠关键词,也不能纯靠语义。
纯关键词的坑
纯关键词检索,搜"主角的剑",能搜到所有出现"剑"字的地方。
但搜不到"那把兵器""那把剑鞘里的东西""师父传给他的遗物"——这些说的都是同一把剑,但没出现"剑"这个字。关键词匹配就漏了。
更麻烦的是,小说里有大量抽象查询。作者想写一个"情绪低落但不说破"的场景,想从旧稿里找类似的段落参考。关键词怎么搜?搜"低落"?搜"不说破"?搜出来的东西大概率不是你要的。
纯向量的坑
纯向量检索,解决了语义泛化的问题。"情绪低落但不说破"确实能搜到"沉默""低头""不说话""推开杯子"这类在语义上相近的表达。
但它又有另一个问题:精确匹配弱。
搜"主角的剑",向量检索可能在语义空间里把"剑""刀""兵器""武器"混在一起。因为它关注的是语义相似度,不是精确匹配。一个写了几十章都用"剑"的角色,硬是被召回了"刀"的段落——这在写作里是不可接受的。剑和刀在小说里是两种完全不同的符号。
还有一个人名检索的问题。小说里角色名字是高频检索对象。向量检索对人名的精确匹配天然弱——"林晓"和"林晓天"在语义空间里可能挨得很近,但它们是完全不同的角色。
混合检索:两种都上,再融合排序
蛙趣拼文的方案是混合检索,四步走。
第一步:BM25 关键词检索
BM25 是一个经典的文本检索算法,核心思想是:一个词在文档中出现的频率越高,这个词越重要;但如果这个词在所有文档里都出现,那它就不重要。
用大白话说就是:搜"剑",哪个文档里"剑"出现得多、而且"剑"在整本书里不是那种"每页都有的废话",哪个文档就更相关。
BM25 保证了精确匹配不丢。搜人名不会漏,搜物品名不会丢,搜地点名能精准命中。
第二步:向量语义检索
文本先经过本地中文向量模型 Xenova/bge-small-zh-v1.5 编码成 512 维向量。查询也一样编码。然后在向量空间里找最相近的内容。
向量检索保证了语义泛化不丢。搜"情绪低落但不说破",能找到"沉默""低头""不说话""推开杯子"这些语义相近但字面上不匹配的内容。
第三步:RRF 融合排序
两路检索各自返回一批结果。BM25 有一组排序,向量检索有一组排序。怎么把两组排序合成一个?
RRF(Reciprocal Rank Fusion)的做法是:不是直接加权求和,而是看每条结果在两路检索里的排名位置。如果一条结果在 BM25 里排第 2、在向量检索里排第 5,它的 RRF 分数是两个排名的倒数之和。排名越靠前,分数越高。
这个算法的好处是,它不关心两路检索的原始分数数值差多少,只关心排名。BM25 的分数可能是 12.5,向量检索的分数可能是 0.87——两个分数不在一个量级上,直接加权求和很难调权重。RRF 只对比排名,天然避开了分数尺度不统一的问题。
第四步:轻量重排
RRF 融合之后拿到一个候选集,再用一个轻量重排模型对候选结果做精排。这一步不是重新检索,只是把融合后的结果重新排一下顺序,让最相关的内容排到最前面。
实测效果
我用自己的 15 万字旧稿做了一个测试。把旧稿全部导入素材库,建好索引,然后测三种检索方式的表现。
测试了 20 个查询,分三类:
| 查询类型 | 示例 | 数量 |
|---|---|---|
| 精确查询 | "林晓""天武城""赤霄剑" | 8 个 |
| 语义查询 | "压抑的沉默""不动声色的威胁""暧昧拉扯" | 6 个 |
| 混合查询 | "林晓情绪崩溃的场景""天武城里最紧张的冲突" | 6 个 |
结果如下:
| 查询类型 | 纯 BM25 | 纯向量 | 混合检索 |
|---|---|---|---|
| 精确查询 | 8/8 全中 | 5/8(人名混淆漏3个) | 8/8 全中,排序最优 |
| 语义查询 | 基本无效 | 表现良好 | 召回率明显高于纯BM25 |
| 混合查询 | 能搜但精度低 | 语义强但精确弱 | 两路互补,效果最强 |
混合查询是混合检索最亮眼的地方。比如搜"林晓情绪崩溃的场景",既有精确的人名"林晓",又有抽象的"情绪崩溃"。BM25 负责抓到所有出现林晓的段落,向量检索负责在这些段落里找情绪崩溃相关的语义。RRF 融合之后,最前面几条全是林晓情绪波动最大的场景——有哭的、有沉默的、有爆发的。
这个结果单靠任何一路检索都做不到。
为什么这件事对写小说很重要
大部分 AI 写作工具的检索方案,要么只做关键词,要么只做向量。
只做关键词的,搜人名还行,搜"我要找一个类似第 30 章那种紧张感的素材"就完全没用了。
只做向量的,语义搜索漂亮,但搜人名可能串,搜专有名词可能漏,精确匹配的可靠性不够。
混合检索在这个场景下是刚需。因为小说作者的信息需求本身就是混合的——有时候要精确(人名、物品、地点),有时候要模糊(氛围、情绪、节奏),更多时候是两者的结合。
蛙趣拼文把这个组合用在一个面向作者的产品里,把混合检索从技术论文落地到了写作工作流。这件事对关注工具底层实现的人来说,比表面功能更值得关注。
了解更多技术细节,可查看 AI写小说工具技术评测:从RAG记忆到千章大纲 或访问 蛙趣拼文官网。
