完整题目
请详细说明在RAG系统中,如何利用嵌入模型将查询和文档映射到向量空间,并结合相似度计算方法(如余弦相似度)实现相关文档的高效语义召回,要求阐述技术流程、关键组件作用及实际应用中的优化考量。
本文目录
核心流程
1. 文档向量化(离线)
- 文档分块:按语义/固定长度切分,控制chunk大小(通常256-512 tokens)
- Embedding编码:用预训练模型(如BGE、M3E、OpenAI-ada)将文本映射为稠密向量
- 关键:领域数据建议微调Embedding模型,解决分布偏移
2. 向量索引构建
- 存储:向量数据库(Milvus、Faiss、Pinecone)或近似最近邻索引(HNSW、IVF)
- HNSW:图索引,查询快、精度高,适合动态更新场景
3. 查询检索(在线)
- 查询向量化:同一Embedding模型编码,保证查询-文档同空间
- ANN检索:Top-K近似最近邻,非暴力全量计算
- 相似度计算:余弦相似度 = (A·B)/(||A||·||B||),值域[-1,1],实际取Top-K
关键优化点
| 优化方向 | 具体手段 |
|---|---|
| 召回质量 | 混合检索(向量+关键词BM25)、查询改写、多向量表示 |
| 精度提升 | 两阶段检索(粗排+精排/Cross-Encoder重排序) |
| 效率优化 | 量化(FP32→FP16/INT8)、索引分区、缓存热点查询 |
| 领域适配 | Embedding微调、Hard Negative Mining |
余弦相似度的选择逻辑
- 归一化后等价于点积,计算高效
- 对向量长度不敏感,适合语义匹配(关注方向而非幅度)
- 替代方案:欧氏距离或内积;内积本身不要求归一化,只有用它模拟余弦时需把query和document两端单位化。度量应匹配模型训练方式。
学习建议
建议先掌握向量嵌入和余弦相似度的基本概念,再结合RAG架构理解检索流程,通过动手实践使用Sentence-BERT等模型进行文本编码和相似度计算来加深理解。
参考资料
换一种问法,检查是否真正理解
场景切入
假设你在做电商客服的智能问答系统,用户问“我昨天买的手机怎么还没到”,系统需要从海量售后文档里找到相关回答。你会怎么把用户的查询和文档都变成向量,然后高效地召回最相关的几条?
层层追问
RAG里怎么做语义召回?……你先说说怎么把文档和查询转成向量?……那向量化之后怎么快速找到最相似的?……如果用余弦相似度,为什么选它而不是欧氏距离?
直球架构
请详细说明RAG系统中,如何用嵌入模型映射查询和文档到向量空间,并结合余弦相似度实现高效语义召回?包括技术流程、关键组件作用和实际优化点,比如索引、分块、精度效率平衡。
练习口述回答 · 约4分钟
- 本质定位:端到端语义匹配
- 流程拆解:离线分块+向量化,在线检索+重排
- 落地优化:混合检索、领域微调、效率取舍
- 风险与边界:分块策略、模型失配、上线校验
这道题其实问的是怎么用向量把文本变成数学上可比较的东西,再快速找到最相关的文档。说白了,就是怎么把语义匹配工程化。核心就是三件事:先把文档和查询都映射到同一个向量空间,然后用近似搜索代替暴力比对,最后在精度和效率之间做取舍。
先说流程。离线阶段,我会把文档按语义[[切块]],比如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、图和元数据;速度收益需有匹配算子并实测。但量化会损失精度,需要评估是否在可接受范围。另外,热点查询可以缓存,比如常见问题直接返回预计算结果,不用每次都跑检索。