日期:2026-09-25
某企业内部知识库直接拿用户的原问题去向量检索,结果很尴尬。员工问年假怎么算,文档里写的是带薪年休假天数按累计工作年限确定,字面碰不上,召回要么空要么跑偏到无关制度。口语化问法和书面文档之间隔着一道墙,员工查两次查不到就放弃,宁可跑去问同事,知识库成了摆设。我们进场时,这个库的自主查询率很低,员工宁可排队等人工答复。
当时他们以为问题是向量模型不够好,想换更大的 embedding,但我们看日志发现,八成的失败是问法和文档写法对不上,根本不是检索能力的事。结论很清楚,先改写在检索,比换模型划算得多。这个项目让我看清,RAG 的瓶颈常常在入口,不在检索器。
新方案在检索前加了一道 query 改写,用户的原问题先过一个小模型,扩写成一两句更贴近文档表述的检索式,再做向量检索。同义缩写也归一,员工打的年假、调休、OA 审批这类口语,会被映射到文档里的规范术语。多路召回并行跑,向量召回和关键词召回各取一部分,再融合重排,最后给答案。
低置信有兜底,三路都拿不到高相关结果时,系统直接说没查到并建议换种问法,而不是硬编一个答案。员工自助查询率因此慢慢涨上来,问人的压力小了。上线后我们抽看了工单,关于年假、报销这类高频制度的咨询,自助解决的比例从两成出头爬到了七成,人工坐席终于不用反复答同一个问题。
query 改写最怕改歪,小模型把年假怎么算扩写成如何申请年假旅游,反而离题。我们用一批真实问答对做了指令微调,限定改写只做同义展开和术语归一,不做语义发散,改写后的检索式反而更准。同义缩写归一靠一张业务词典,把企业内部的黑话和简称映射到规范词,这张表是人工补出来的,机器代替不了。
多路召回融合难在分数不可比,向量分和关键词分量纲不同,我们做了归一加权,向量占大头、关键词做兜底补刀,权重按场景调。低置信兜底要敢说不知道,我们给融合分设了阈值,低于就走兜底,比编造答案安全得多,也省了后续纠错成本。
改写与融合的关键配置如下,权重和阈值都要按场景调:
retrieval:
rewrite:
mode: synonym_expand + term_normalize # 禁止语义发散
dict: business_term_map # 人工维护黑话映射
fusion:
vector_weight: 0.7
keyword_weight: 0.3
low_conf_threshold: 0.35 # 低于走兜底检索召回率从原来的四成出头提到八成多,员工问的问题大部分能找到对应文档,空召回率降了一大半。答案命中率提升明显,因为改写后的检索式更贴文档,召回的片段本身就是对的。员工自助查询率从低位涨到六成以上,人工答复的排队时长随之缩短。
我们做过一轮抽样,一百个真实问题改写前后对比,改写后能在前三召回命中的从四十三个涨到八十二个,这个增幅比换 embedding 模型实测高得多,投入却小一个量级。上线一个季度后,知识库月活从几百人涨到两千多,员工是真的用起来了,而不是应付考核。
我们把改写模型本身也接了反馈,员工点了没帮助的答案会被记下来,反向去补业务词典,词典从两百多条长到五百多条。这个飞轮转起来后,新上线的制度文档几乎不用人工调就能被查到,因为黑话映射越全,改写越准。我们还顺手把高频问题做成引导式提问,员工输两个关键字就给候选问法,进一步降低了查不到的门槛。我们复盘时发现,知识库真正的利用率拐点不在换模型,而在改写加词典这套组合,它把人和文档之间的语言墙拆掉了一大半。
我们还把改写能力做成了一键纠偏,员工觉得召回跑偏可以直接标注正确的文档,系统据此补一条映射,下次同类问法就走对了。这种众包式的纠正比纯人工维护词典省力,也更快响应业务变化,新制度上线当天就能被查到。我们事后承认,最早想靠一劳永逸的大模型解决问题,是走了弯路的,真正管用的是小模型加人补的飞轮。
用户问法和文档写法往往两码事,先改写在检索,召回能上一个台阶,我们一开始也迷信换大模型,绕了弯路才回来做改写。改写模型要约束只做同义展开,别让它自由发挥,改歪比不改还坑。业务词典得人工补,机器分不清企业黑话,这一步偷不得懒。敢说不知道比硬编答案重要,低置信兜底省下的纠错成本远超那点召回。我们当时想直接上更大向量模型,是日志把真相拍在脸上才掉头。下一步想把改写和用户的点击反馈接成闭环,让词典自己长大。
案例片段(已脱敏): query 改写:原问题过小模型做同义展开 + 术语归一(限定不语义发散),再向量检索;多路召回(向量 + 关键词)归一加权融合重排;融合分低于阈值走兜底。某轮 100 个真实问题抽样:前三召回命中由 43 个增至 82 个;检索召回率 82%(原 43%);空召回率降 58%;员工自助查询率 61%(原低位);知识库月活由数百涨至 2000+。