这道题其实问的是怎么用向量把文本变成数学上可比较的东西,再快速找到最相关的文档。说白了,就是怎么把语义匹配工程化。核心就是三件事:先把文档和查询都映射到同一个向量空间,然后用近似搜索代替暴力比对,最后在精度和效率之间做取舍。
先说流程。离线阶段,我会把文档按语义[[切块]],比如256到512个token一段,太短上下文不够,太长噪音多。然后用同一个[[Embedding]]模型,比如BGE或者M3E,把每段文本编码成稠密向量。这里有个前提:如果领域很特殊,比如金融合同或者医疗病历,通用模型可能有分布偏移,先建立领域评估集,再比较直接使用、数据清洗、微调等候选,不能预设必须微调。切块也不是一刀切,固定长度适合通用场景,但要是文档结构性强,像操作手册或者法律条款,我会优先用语义切分,按段落或者标题来,避免把完整的概念切碎。
向量存进[[向量数据库]],比如[[Faiss]]或者Milvus。索引我一般选[[HNSW]],图结构,查询快、精度高,支持增量添加;删除/修改能力取决于实现,例如Faiss HNSW不支持直接remove,需要逻辑失效与重建或其它数据库机制。但HNSW内存消耗大,如果向量几十亿,就得用[[IVF]]加量化来压缩,不过精度会掉一点。
在线阶段,用户查询进来,用同样的Embedding模型编码,然后做[[ANN]]搜索,也就是近似最近邻,不用跟所有文档比。相似度我常用余弦相似度,因为它关注方向,对向量长度不敏感,适合语义匹配。但有一点要注意:如果模型输出的向量已经归一化了,那余弦和点积等价,选计算更快的就行。
但纯向量检索有硬伤:对同义词或者拼写错误还行,但精确匹配比如订单号、错误码就抓瞎。所以真正落地我会上[[Hybrid Search]],向量加关键词,比如[[BM25]],两条路都跑,结果融合。举个例子,客服场景用户说“我退款了但没到账”,向量能召回相似语义的退款政策,BM25能精确命中“退款”这个词。如果只做向量,那精确信息的召回率会低得没法用。
还有一个常见失败场景:查询很短,比如就一个词“退款”,向量召回的结果可能偏,因为语义太宽。这时候我会加查询改写,用大模型把查询扩写成更具体的句子,或者用多向量表示,让查询和文档多角度匹配。
精度方面,检索完会有一个[[重排]]阶段。向量检索是[[Bi-Encoder]],速度快但精度一般;重排用[[Cross-Encoder]],把查询和每个候选文档拼在一起算分,精度高但慢。所以我会先向量粗召回几百个,再用Cross-Encoder精排到Top-10。重排是性价比很高的优化,能显著提升最终效果。
效率上,向量可以量化,从FP32降到FP16甚至INT8,裸向量每维从4字节降到2或1字节,总索引还含ID、图和元数据;速度收益需有匹配算子并实测。但量化会损失精度,需要评估是否在可接受范围。另外,热点查询可以缓存,比如常见问题直接返回预计算结果,不用每次都跑检索。
对了,还有一个容易被忽视的点:分块策略对召回影响很大。比如固定切分可能把一句话拆到两块里,导致检索时上下文丢失。我会把零重叠、短窗口与较长窗口作为候选,用同一评测集比较边界证据完整率、召回、存储与去重成本。重叠会增加索引与去重成本,具体增幅取决于窗口和步长,不一律翻倍。这个其实牵涉到文档结构和模型上下文长度,挺有意思的,可以展开聊聊。
最后说我的判断:[[RAG]]不是银弹,它可为知识密集任务提供外部证据,也能结合IRCoT等迭代检索服务多步推理;是否有效需分解检索与推理失败。如果知识库频繁更新,或者查询高度依赖精确匹配,我会搭配关键词或者甚至用微调模型。上线前我会特别关注召回率指标,比如Recall@K,还有延迟,确保在用户容忍范围内。如果效果不行,优先查分块策略和Embedding模型是否匹配领域,而不是盲目调参数。