这道题问的是搭建领域[[RAG]]的完整流程,其实本质就是一件事:把外挂知识库里的信息准确找出来,再让大模型读明白、说人话。它不是微调模型学知识,而是查文档加读文档的工程化。
先说数据准备。很多人一上来就[[向量化]],其实质量天花板在数据清洗和[[分块]]。清洗不难,去重去噪、统一格式就行,但领域数据有个坑:专业术语容易被通用[[分词器]]切碎。比如医学里的“非小细胞肺癌”,拆成“非”“小细胞”“肺癌”就丢语义了。所以前提是建一个领域词典,把这类复合词保留。
分块才是真正的难点。固定长度切分最简单,但容易把一个完整条款砍成两半,比如法律合同里“甲方有权……但乙方除外”,断开后模型就断章取义。我更倾向按语义切分,用BERT-based句子嵌入判断边界,把语义完整的段落保持在一起。块大小与重叠窗口我都会准备多组候选,用同一评测集比较证据完整率、召回、索引体积和去重成本后再定。说白了,分块策略要根据文档类型调,代码按函数切,合同按条款切,没有万能方案。
然后是向量化。Embedding模型选型上,通用场景用BGE-M3或E5就够了,但垂直领域我建议微调。微调不复杂,用领域内的query和doc正例对,加上in-batch负采样,让模型更懂你的语义。不过这里有个风险:如果领域数据量不够,微调反而会过拟合,召回变差。所以我会先拿小样本试一下,不显著提升就不微调,直接用通用模型。
检索策略我走的是多路召回加精排。具体来说,一条路是向量检索,找语义相似的;另一条是关键词检索,用[[BM25]]兜底专有名词,比如订单号或错误码,向量搜不到但关键词一找一个准。两条路的结果合并后,再用一个[[Cross-Encoder]][[重排]]模型精排,把相关性低的过滤掉。这样既保证召回率,又提升精度。你可以这么理解:向量检索像模糊匹配,BM25像精确匹配,两者互补。真正上线时,我会特别关注Query改写,比如用户说“退款没到”,我会用HyDE技术先生成一个伪文档,再拿去检索,效果提升很明显。
生成阶段,核心是上下文压缩和Prompt设计。检索回来的Top-K文档可能有很多冗余,直接全塞进Prompt会稀释关键信息,还浪费token。我会先用LLM做一次摘要,或者只保留和query最相关的片段。Prompt里要明确要求模型引用来源,比如“根据文档第三段……”,并且强制模型说“不知道就拒绝”,不能瞎编。这里有个常见失败场景:模型看到多个相似文档,会把不同条款混在一起,产生[[Hallucination]]。我的对策是让模型先判断文档一致性,不一致就输出“文档冲突,请人工核实”。
最后是效果评估和迭代。我不会只盯着一个指标,而是分三层:检索层看Recall@K和MRR,生成层看[[忠实度]],端到端看用户满意度。忠实度可以用[[RAGAS]]框架里的Faithfulness指标自动评估,但人工抽检还是少不了。上线后我会建一个Bad case库,每周分析一次,看是检索漏了还是模型读错了,再针对性优化。比如发现很多case是分块不合理导致的,就回头调分块策略。
另外,当知识库频繁更新时,比如电商每天上架新商品,传统RAG的索引重建成本很高。我倾向用增量更新加双缓冲索引,但一致性校验是个坑,比如旧索引里删了某条数据,新索引还没建好,查询时就会返回过时结果。这块我还在探索更稳定的方案。
所以整体上,我更倾向把RAG看成一套持续迭代的系统,而不是一次搭完就完事。数据质量、检索策略、模型调优,每个环节都要根据业务反馈不断调整。