这道题其实问的是,[[RAG]]系统效果不好时,怎么快速定位到底是检索没找到对的文档,还是模型看了文档但没好好用。我的思路很简单:把两个模块解耦,先固定一个测另一个,别上来就两边一起调。
具体第一步,我会做黄金文档实验。把标准答案依赖的那部分文档,直接塞进生成模块的上下文,如果生成质量一下子好了,那问题基本就锁在检索侧。如果生成质量还是不行,那就说明生成模块或者prompt设计本身有问题。这个实验非常便宜,不需要任何额外标注,跑几轮就能下判断。
假设实验指向检索侧,我会先看召回率,就是Recall@K。比如Top-5召回率低于0.8,大概率是[[Embedding]]模型或者[[分块]]策略不够好。举个例子,客服退款场景里,用户问的是‘我买的东西降价了能退差价吗’,如果召回的是‘退货政策’而不是‘价格保护条款’,那分块粒度就偏了。这时候我会检查分块是不是把意思相近但不同的条款切到了一起,或者Embedding对价格、退款这类语义区分不够。如果召回率还行但排序靠后,那就说明需要加[[重排]]或者[[混合检索]],把关键词和向量结合起来。
反过来,如果黄金文档实验发现生成模块有问题,我会重点看[[忠实度]]。模型有没有忽略检索到的内容,去依赖自己的参数知识?典型的故障模式是,prompt里没强调‘严格基于上下文’,或者上下文太长模型注意力散了。我见过一个企业SOP合规场景,文档明明写了‘审批金额不超过五万’,模型却生成‘十万以下走简易流程’,这就是典型的[[幻觉]]。解法也很直接:prompt里加显式指令,要求每个答案必须引用来源段落,必要时做[[SFT]]强化引用格式。但这里有个前提:如果检索内容本身噪声很大,模型很难从中提炼正确信息,所以要先确保检索质量再调生成。
系统化追踪的话,我会用[[RAGAS]]或者LangSmith跑全链路trace,看每一步的输入输出。但说实话,自动化指标只能筛出明显的问题,真正决定效果上限的是人工bad case分析。我会按检索失败、理解失败、整合失败三类建个分类体系,每个case拆开看。
这里我多说一句:很多人一上来就调Embedding模型或者换大模型,其实更常见的问题是分块策略太粗糙。比如固定512字符切分,很容易把一句完整逻辑切散。我倾向于先做语义分块,用[[Parent Document]]结构保留上下文,这样召回时既能拿到高精度的小块,又能附上完整的父文档,对生成质量帮助很大。
所以我的整体判断是:优先保证检索的Recall,再优化生成的Faithfulness。两边不要同时动,否则变量混杂,你永远不知道是哪个改动起了作用。