最近在搭一个简单的RAG问答,用的LangChain + OpenAI,文档是几十页的PDF。我现在的Prompt大概是“根据上下文回答,如果不知道就说不知道”,但效果不稳定——有些回答能引用原文,有些明显在脑补,甚至把不同段落的信息缝合在一起。我试过在上下文里加“请严格基于以下内容”之类的强调,也试过把相关段落用XML标签包起来,但还是偶尔翻车。想问下各位老哥,RAG系统的Prompt模板一般怎么设计?是需要在系统层面对检索到的chunk做处理,还是纯粹靠Prompt约束就够了?有没有什么更可落地的写法,最好能给出具体示例,谢谢。
RAG里Prompt模板怎么写才能让大模型老实引用原文而不是乱编?
全部回复
共 46 条光靠prompt真不够,得在检索端把chunk切细点,再让模型先摘录原文再回答,翻车率能降不少。
光靠prompt不够,检索到的chunk本身要带来源标识,让模型引用时带上编号,翻车率能降不少。
这问题我太有同感了,之前调RAG的时候也被这种“缝合怪”回答坑过。说实话,光靠Prompt约束确实有上限,模型对“严格基于”这种指令的理解远没你想的那么机械。我自己试下来比较有效的一个土办法是,在Prompt里把检索到的每个chunk标上序号,然后明确要求“回答时必须标注引用了第几段”,比如写成“根据[1][2]内容回答,禁止混用不同片段的信息”,这能让模型在生成时有个显式的溯源压力。另外你提到XML标签包起来,我觉得方向是对的但可以更狠一点,直接在系统提示里加一句“如果上下文互相矛盾或无法支撑问题,必须输出‘信息不足’并列出缺失的关键词”,这比单纯说“不知道”要具体得多。还有个容易忽略的点是chunk本身的预处理,比如把PDF转成文本后先清理掉页眉页脚和乱码,不然模型很容易被无关字符带偏。最后就是温度调低到0.1以下,贪婪解码对这类任务真的比采样稳定,翻车概率能降一大截。
光靠prompt不够,检索时给每个chunk加个编号,让模型引用时带编号,缝合了也能查出来。
光靠Prompt不够,得在检索后加个重排或相似度阈值过滤,把低分的chunk直接扔掉再喂给模型。
光靠prompt确实压不住,模型该缝还是缝。我一般会在检索后加一步重排或者相似度阈值过滤,把明显不相关的chunk先扔掉,不然上下文里混进噪音,再怎么强调“严格基于”也没用。另外可以试试让模型先输出引用片段再作答,比如要求它把用到的原句摘出来,这样脑补成本会高很多。LangChain里有现成的citation prompt模板,你可以翻翻看。