事情本身不复杂,线索都在日志里。把 RAG 的 top_k 从 5 调到 20,答案开始出现另一份旧制度的内容,准确率从 0.81 掉到 0.64,检索回来的 20 条里有 11 条相似度在 0.72 以上。
第一反应是「没有重排,向量相似与业务相关并不等价」,验证下来不成立。
真正麻烦的地方在于,几个原因的现象几乎一样。低相关片段进入上下文,模型更愿意引用靠前但过时的段落。还有一种是相似度没做阈值截断,20 条一股脑塞进提示词。
还有一种情况,上下文变长后关键片段被挤到中部,注意力反而下降。
动手时先看分数分布确定阈值截在哪
python -c "import numpy as np;s=np.array([0.82,0.79,0.72,0.68,0.41]);print(round(float(np.percentile(s,50)),3),s.min())"
接着加一层分数阈值再送模型
python -c "print([x for x in [(1,0.82),(2,0.68)] if x[1]>=0.7])"
再往下开重排后只保留前五条
python -c "from FlagEmbedding import FlagReranker;r=FlagReranker('BAAI/bge-reranker-v2-m3',use_fp16=True);print(sorted(zip(r.compute_score([['退款','退款规则']]*3),[1,2,3]),reverse=True)[:2])"
末了用同一批问题做分组对照
python -c "import pandas as pd;print(pd.read_csv('eval.csv').groupby('top_k').acc.mean())"
恢复的判定其实很直接。top_k=20 配 0.7 阈值加重排后准确率回到 0.83 以上,进提示词的条数稳定在 5 条,答案里不再出现旧制度。
容易忽略的是,top_k 是召回上限不是答案条数,真正决定进提示词的是阈值和重排,这两个参数要一起调。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
