这道题其实问的是,当你把一个[[RAG]]系统从能跑到跑好,你会从哪里下手。本质上,RAG的迭代不是把每个环节单独调到最优,而是在检索精度、生成质量和系统延迟之间找平衡。我一般会沿着检索、[[重排序]]、上下文融合、生成这条线走,但真正落地时很多决策是耦合的。
先说检索。很多人一上来就堆向量,但实际业务里,向量检索对高频实体和精确匹配反而弱。比如客服场景里,用户问‘订单号12345退款失败’,关键词[[BM25]]直接命中订单号,向量可能因为语义偏移排到后面。所以我会优先做[[Hybrid Search]],把向量和关键词结合。具体来说,索引侧我会做[[Embedding]]微调,用领域数据,比如退款、满减这类客服语料;查询侧做query改写,比如用户说‘钱没退回来’,我会通过[[Self-RAG]]生成一个假设文档再检索。这里有个前提:你得有足够的高质量领域数据做微调,否则Embedding可能还不如通用模型。风险是混合检索的权重调参很敏感,上线后我会监控召回率,如果某个召回源一直空结果,要降权甚至关掉。
检索出来Top100,不能直接塞给大模型。重排序的核心是做漏斗。第一步用BM25或[[Bi-Encoder]]粗排,快速过滤到Top20,第二步用[[Cross-Encoder]]精排到Top10。Cross-Encoder精度高但慢,所以漏斗能兼顾延迟和效果。这里有个坑:如果精排模型没针对你的文档领域微调,排序结果可能还不如粗排。所以我会在离线用领域数据做[[Distillation]],或者干脆用[[ColBERT]]这种延迟交互方案,效率更高。
然后是上下文融合。大模型有‘Lost in Middle’问题,中间的内容容易被忽略。我会把关键信息放在首尾,中间压缩掉。比如用LLMLingua做选择性压缩,只保留与query最相关的句子。多文档场景下,比如企业SOP文档,不同条款互相引用,我会先做去重合并,再按相关性加权,最后构建成结构化上下文,比如表格或树状结构,让模型一眼看清依赖关系。前提是你的文档结构要清晰,如果全是散乱的段落,结构化反而引入噪音。
生成环节,我倾向用Self-RAG,模型生成时自己检索验证,而不是一次生成完再查。比如客服回答退款时效,模型会先检索最新政策,再生成答案,最后用[[Faithfulness]]校验事实一致性。如果置信度低,我会拒绝回答或让用户确认。这里有个风险:Self-RAG会增加延迟和成本,所以只适用于高精度场景,比如风控合同审核,而普通问答用[[Naive RAG]]就够了。
另外,系统级迭代里,我特别关注检索空结果率。如果空结果率高,说明索引或query改写有问题,我会反过来调检索策略。比如结合[[Knowledge Graph]]做[[实体链接]],把‘退款失败’映射到具体错误码,再精准检索。这块其实可以做成一个闭环:空结果触发自动query改写,改完再试一次,还不成功就报人工。
所以整体上,我更倾向于把RAG看成一个检索和生成的闭环,而不是独立模块。我的取舍是:优先保证检索的召回率,再通过重排序和生成验证来兜底精度。如果面试官有兴趣,我可以再聊聊离线评估的[[RAGAS]]指标和在线A/B测试的设计。