这道题问[[RAG]]的流程和优化,我觉得本质上是问:怎么让大模型在不知道答案的时候,学会自己查资料,而且查得准、用得对。很多人一上来就讲检索、生成,但真正落地你会发现,每个环节都有坑,而且没有银弹。
先说文档预处理。很多人觉得[[分块]]很简单,固定切几百个token就行了,但实际场景里,比如企业做客服知识库,退款政策和满减活动经常混在一个文档里,固定切分会把语义切碎,检索时召回一堆不相关的内容。所以我更倾向用 语义分块,就是用模型识别主题边界,比如一个政策讲完退款,下一个讲满减,那就自然分成两块。另外,我会加元数据,比如来源、更新时间、类别,这样检索时可以先过滤,比如“只查2024年后的退款政策”,效率和准确率都能提升。
然后是[[向量化]]。Embedding模型直接拿来用,在通用领域还行,但到垂直领域,比如金融合同、医疗病历,效果会明显下降。所以前提是要有领域数据,做 对比学习 微调,不然向量距离不准,检索就是空中楼阁。这里有个常见失败场景:很多人花大量时间调检索参数,但其实问题出在Embedding没对齐业务语义。
检索环节,我通常会做 [[混合检索]],就是 [[BM25]] 关键词匹配加向量检索并行。为什么?因为向量检索擅长语义相似,但精确匹配比如订单号、错误码,它反而不如关键词。举个例子,用户问“订单12345退款到哪了”,向量检索可能找到一堆退款政策,但关键词直接命中那个订单的详情。两个结果合并后,再用 [[Rerank]] 模型精排,把最相关的那条顶上去。另外,查询扩展也很有用,比如用户说“退货”,LLM可以帮你扩展成“退货流程、退款周期、运费承担”,提高召回率。
生成阶段最大的问题是 [[Hallucination]]。我的做法是 上下文压缩,就是让LLM从检索到的文档里提取关键片段,而不是一股脑全塞进去,减少噪声干扰。同时强制要求 引用溯源,每个生成点必须标注来源段落,这样用户可以核查,也方便后续做 [[Faithfulness]] 评估。如果检索结果置信度很低,比如分数低于阈值,我会让模型直接说“信息不足”,而不是硬编答案。
整条链路跑通后,我会特别关注 评估闭环。上线前用 [[RAGAS]] 这类工具测答案相关性和忠实度,上线后埋点记录用户反馈,比如点不点赞、有没有追问,这些数据回流用来调排序权重和分块策略。另外,缓存也很关键,热门查询的结果直接缓存,能省掉70%的检索延迟。
其实还有一个延伸方向:当知识库更新频繁时,文档和向量之间的一致性怎么保证?比如政策改了,旧的文档要替换,但[[向量库]]里还有旧向量,检索时可能同时召回新旧版本,导致答案矛盾。这个场景下,我会考虑用 [[Parent Document]] 结构,保留父子关系,更新时原子级替换整个子树,再配合版本号做在线校验。
所以总的来说,RAG不是搭个流水线就行,每个环节都有前提条件和trade-off。我更倾向把RAG看成 一个持续优化的系统,而不是一次性工程,重点在数据质量和评估闭环上花功夫。