最近在搭一个简单的RAG问答系统,用的是LangChain + OpenAI的embedding,检索效果还行,但LLM回答时总喜欢“自由发挥”——比如用户问“张三在2023年说过什么政策”,明明库里只有一段原文,它非要自己总结一遍,甚至加些原文没有的细节。我试过在system prompt里写“请严格引用原文回答”,但效果不稳定,有时候还是乱编。想请教下大家,有没有什么prompt技巧或者模板能让模型更“死板”一点?另外,如果原文很长,是不是应该把检索到的片段分段塞进prompt,还是直接整段放进去比较好?感谢!
RAG系统里prompt怎么写才能让LLM更准确引用原文?
全部回复
共 141 条我也遇到过同样的问题,后来发现光靠prompt不够,得在指令里明确要求“逐字引用”外加格式限定,比如让模型用引号把原文括起来,再配合few-shot示例会稳很多。另外长文本分段确实比整段扔进去效果好,但注意别切得太碎,我一般是按段落或语义断句,每段前面加个小标题提示一下上下文。
试试在prompt里加一句“如果原文没有,就说不知道”,同时把长原文按段落拆开并标注来源位置。
试试在prompt里加一句“如果找不到直接对应的原文,就回答不知道”,能明显减少胡编的情况。
我也遇到过这个问题,后来试了在prompt里明确要求“把原文完整复制到回答中,再基于引文做解释”,效果比只说“严格引用”好不少。另外原文太长的话,建议分段塞进去,每段前面加个小标题或编号,模型更容易定位具体内容。你用的retriever返回的chunk数量是多少?有时候把top_k调小一点,只给最相关的1-2段,反而能减少幻觉。
试试把原文用引号括起来,再加一句“如果找不到对应内容就说不知道”,能压住不少幻觉。
试试把原文用引号括起来,然后加一句“请逐字引用引号内原文”,效果会好很多。
这个问题我正好也踩过坑,分享点实战经验。系统prompt里单纯写“严格引用”确实不够,我后来在user prompt里加了个结构化指令,比如“请用双引号标注原文,如果原文没有相关信息,直接说‘未找到对应内容’”,效果好了不少。另外,原文太长的话分段塞进去比整段扔进去好,因为大模型对中间内容的注意力会衰减——我一般把最相关的片段放开头和结尾,中间补充上下文,这样引用准确率能提到八成以上。不过有个疑问:你检索回来的片段之间如果有重复内容,会不会让模型更倾向于自己总结?我试过去重后反而更稳定。还有个小技巧,可以在prompt末尾加一句“如果引用内容超过50字,请先写原文再标注页码”,模型执行起来会死板很多。
试试在prompt里加一句“如果原文没有则回答不知道”,另外长文本分段加引用标记效果会好很多。
可以试试在prompt里加一句“如果原文没有相关信息,直接说不知道”,能减少不少幻觉。
可以试试在prompt里明确要求“逐字引用原文,禁止改写”,同时把原文用引号标出来。长文本分段放效果更好,能减少模型遗漏细节。
我最近也遇到这个问题,试过在prompt里加“如果找不到原文对应内容,直接说不知道”之类的约束,效果稍微好一点。另外分段塞确实比整段放要好,尤其是原文长的时候,模型更容易聚焦。不过说真的,有时候感觉跟模型较劲不如直接在后端做个引用匹配,强制它输出时带上原文片段,省心不少。
同感,这个问题我也踩过坑。试过加“逐字引用”和用XML标签把原文包起来,比如
试试在prompt里加个“如果原文没有对应内容,直接说不知道”,再限制每段答案必须带引号引用原文。
我也遇到过这个问题,后来试了下在prompt里加一句“如果没有对应原文支撑,就说找不到相关信息”,效果好了不少,不过还是得配合few-shot示例才稳。长文本的话,我个人倾向分段塞进去,再让LLM分别引用,整段放容易让它挑重点时自己发挥。对了,你们检索的chunk size设多大?有时候chunk太长了也会影响引用准确度。
可以试试在 prompt 里加一句“如果原文没有,就说不知道”,能压住不少幻觉。长文本分段放比整段效果好,上下文窗口别撑太满。
可以试试在prompt里加一句“如果无法直接引用原文,请回答‘未找到相关信息’”,效果会好很多。
我之前也踩过这个坑,后来发现光是“严格引用”不够,得把原文按段落拆开,每段前面标个编号,然后让模型必须用[1][2]这种形式标注来源,它就会老实很多。原文太长的话建议分段塞,不然中间位置的内容模型容易忽略。还有一个土办法是让模型先复述原文再回答,哪怕多一步token也能减少幻觉。
你这问题我试过在prompt里加“如果原文没有对应内容,请直接说不知道”,效果比单纯要求引用强。另外可以试试把检索片段按相关性排序,最相关的放最前面,模型对开头的注意力会高一些。分段塞确实比整段好,但别分太多段,3-4段左右比较稳。
要不要试试把原文直接放在user message里而不是system里?我之前这么改完,模型引用准确率高了不少。另外可以给每条检索结果加个“以下是第N段原文”的前缀,帮模型建立对应关系。分段塞是对的,但记得把最相关的排前面,不然模型容易被不相关的信息带偏。
试试在prompt里加一句“如果原文没有,就直接说不知道”,比硬要求引用管用多了。
试试把原文切成小块,每块前面加编号,让模型回答时带上编号引用,比单纯说“引用原文”管用多了。
我自己也踩过这个坑,后来发现光靠system prompt压不住,得在user prompt里把原文用引号框起来,再明确加一句“只能引用引号内的内容,禁止改写”。另外分段塞确实比整段塞好,尤其原文长的时候,我会按语义切成几块,每块前标注来源编号,让模型回答时带上编号,这样它就不太敢乱发挥了。