最近在搭一个简单的RAG系统(基于LangChain+GPT-4),检索到的文档片段大多能对上,但模型回答时经常“自由发挥”——比如原文说“价格是100元”,它给我输出“价格约100-120元”。我试过在System Prompt里写“请严格基于检索内容回答”,但效果不稳定。想请教一下大家:
1. 是不是应该在User Prompt里把检索到的片段和问题分开写?比如用“【参考文档】”标记?
2. 有没有什么特定的指令模板,比如“如果参考文档中没有明确信息,请直接说不知道”?
3. 用Few-shot示例会不会让模型更守规矩?还是说简单粗暴加temperature=0就行?
我现在主要卡在“忠实度”和“流畅性”的平衡上,求各位大佬指点!
RAG里Prompt怎么写才能让大模型老实引用原文,不乱编?
全部回复
共 5 条用分隔符把文档和问题隔开确实有用,我还会在每段前加【参考文档】并强调“禁止总结”。
这个问题我最近也踩了不少坑,说几个实测有效的点吧。第一,分段标记确实管用,但光加【参考文档】还不够,我习惯在用户prompt里用“以下文档是唯一依据:”这种明确指令,然后紧跟着把检索内容用引号包起来,模型会更倾向于直接复制引号内的文字。第二,temperature调成0是基础操作,但不要迷信,我试过即使temperature=0,如果prompt里没有明确拒绝推理的指令,它还是会脑补,比如你那个价格例子,它可能觉得100元太绝对就自动加了范围。第三,few-shot示例我试过,但效果反而有点不稳定,因为模型会试图去模仿示例的“格式”而不是“逻辑”,最后反而容易把示例里的输出风格套到所有问题上。我现在的做法是在system prompt里加一句“如果参考文档中未明确提及,请逐字输出‘未找到相关信息’”,同时把user prompt写成“基于以下唯一参考资料,回答用户的问题:\n参考资料:{docs}\n问题:{query}”,这样结构清晰很多。另外有个小技巧:在检索片段末尾加一句“请仅使用以上内容作答,不要添加额外解释”,对GPT-4的约束力比单纯说“严格基于”强不少。你试试看,应该能减少那种模棱两可的推断。
这个问题我上周刚踩过坑,说下我的实测经验。你在User Prompt里用标记把参考文档和问题隔开非常关键,我试过用【参考文档】和【用户问题】分开写,比混在一起让模型自己找要稳得多,尤其是文档里有多个片段时,模型更容易定位到具体句子。关于指令模板,我建议在System Prompt里加一句“如果参考文档中没有明确依据,必须回答‘根据现有资料无法确认’”,同时把temperature调到0.1,完全设成0有时候会让模型过度死板,连基本的同义转换都卡住。Few-shot我试过,但效果不太稳定,因为示例本身可能引导模型模仿句式而非逻辑,反而容易跑偏。另外我有个额外发现:把检索到的片段按相关性排序后,在【参考文档】里用编号标出,比如[1][2][3],然后在回答里要求模型必须引用对应编号,这样能明显减少编造细节的情况。你试过在返回的片段里加一些冗余上下文吗?有时候片段太短,模型抓不住语境也会自己补全。
把参考文档用【】框起来单独分段,再加一句“没写就是不知道”,比单纯调温度管用多了。
温度调低加few-shot确实管用,但我发现把原文用引号括起来再强调“逐字引用”效果更稳。