问题出现得很突然,日志倒是留得挺全。客服 RAG 用 gpt-4o-mini 做 query 改写,第二轮用户问“那这个订单什么时候到”,模型把原话改写成“该订单的配送时间”,A12345 这个单号彻底消失,向量检索命中三篇通用说明,回答开始胡说。
刚开始盯着「改写结果直接替换原 query,没有保留任何原文信息」,折腾了半个多小时,排掉了。
排查方向其实有限,先把可能性排一排。改写提示里要求简洁,模型顺手把编号换成了代词。还有一种是历史只传了上一轮回答,没有把用户提到的实体带进去。
少数情况下是实体识别规则只匹配纯数字,带字母的单号被漏掉。
第一件事是把改写前后的 query 并排打日志
python -c "print({'raw':'那这个订单什么时候到','rewritten':'该订单的配送时间'})"
再往下在改写提示里明确要求保留单号、型号与日期
curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"model":"gpt-4o-mini","messages":[{"role":"system","content":"改写时保留所有订单号、型号、日期,不得用代词替换"},{"role":"user","content":"那这个订单什么时候到"}]}'"
然后把原 query 与改写结果拼成一次混合检索,保留兜底
python -c "print('query = raw if hit_count == 0 else rewritten')"
剩下的就是对没有命中的改写结果回退到原 query 再检索一次
python -c "print({'fallback':True,'use':'raw'})"
改完先别撤,确认这几项。带单号的追问能召回对应订单的物流段落,引用里出现 A12345,连续五轮对话的单号都没有被改写丢过一次。
容易忽略的是,改写提升的是检索表达力,不是替用户做归纳,凡是编号、型号、日期这类强实体,都应该在提示里点名保留,并在命中为空时回退原句。这类问题最好一次改到位,反复小改反而容易把原因搅混。
