上下文塞多少片段最好:k 值的實測方法
塞越多不一定越準。片段數對準確率的曲線通常在中段就見頂,之後反而下滑。
很多人把 top-k 設成 10 或 20,理由是「多給一點總不會錯」。實際上多餘的片段會稀釋注意力,也提高模型引用到不相關內容的機會。
怎麼找到轉折點
for k in [1, 2, 3, 5, 8, 12, 20]:
acc = run_eval(top_k=k)
print(f'k={k:<3} 正確率={acc:.3f}')跑完通常會看到一條先升後平、甚至微降的曲線。多數問答型 RAG 的甜蜜點落在 3 到 5。
影響 k 值的因素
- 片段越大,k 應該越小——總 token 才是真正的限制。
- 有重排時 k 可以更小,因為前幾名的品質更高。
- 需要彙整多來源的問題(例如「比較 A 與 B」)需要較大的 k。
動態 k 值
進階做法是依相似度分數截斷:只保留分數高於門檻、或與第一名差距在一定範圍內的片段。這樣簡單問題只用一兩段,複雜問題自動放寬。
def dynamic_topk(hits, ratio=0.75, max_k=8):
if not hits: return []
top = hits[0].score
return [h for h in hits[:max_k] if h.score >= top * ratio]把每次實際使用的片段數記錄下來。若九成請求都用滿 max_k,代表門檻設得太鬆,等於沒有動態效果。