最近在做一个基于企业知识库的问答机器人,用的LangChain+OpenAI。我现在的做法是把检索到的top5文档块直接塞进system prompt,然后让模型“严格基于以下内容回答”。但实际效果很迷,有时候文档里明明没有的信息,模型还是会编出来,尤其是用户问题里带点诱导性的时候。我试过加“如果找不到请说不知道”,但感觉模型还是会脑补。想问问各位,你们的RAG prompt是怎么设计的?有没有什么技巧能让模型更“老实”?比如要不要在prompt里强调“只能引用原文”,或者把检索结果的来源标注得更清楚一点?另外,温度参数是不是也该调低?求指点,感谢!
RAG里Prompt模板怎么设计才能让大模型少胡说八道?
全部回复
共 127 条温度调到0.2以下会好很多,另外在prompt里让它先引用原文再回答,能明显减少瞎编。
温度调低确实有用,我一般设0.1到0.2,但还是会有漏网之鱼。后来发现关键是在prompt里要求模型先摘出相关原文句子再作答,相当于逼它走一遍引用流程,编造的概率会低不少。另外可以试试在检索结果每块前面加编号和来源,让它回答时带上角标,这样你也能快速判断是不是在瞎编。
我之前也踩过这坑,光靠“严格基于以下内容”真不够,模型该编还是编。后来我在prompt里加了句“回答中每个事实后面必须标注对应的文档编号,找不到就写‘未提及’”,效果好了不少,因为它得先定位再回答。温度调到0或者0.1确实有帮助,但更关键的是把检索结果里的无关块删掉,top5里混进噪音反而容易诱导模型。另外可以试试让模型先输出“检索到的相关内容摘要”,再基于摘要回答,相当于多一步自我约束。
我现在会强制模型先输出“依据片段:xxx”,再说答案,这样它编的时候会露馅。温度调到0确实有用,但关键还是prompt里别只说“严格基于”,要让它逐条对照原文,找不到就明确回“未提及”。另外top5可能太杂,检索质量差的话,再好的模板也救不了。
我之前也踩过这个坑,光靠一句“严格基于以下内容回答”确实不太管用,模型该编还是编。后来我改了个思路,把prompt拆成三段:先明确角色和约束,再给检索内容并加上编号和来源,最后单独写一句“回答时每个事实后面用[1][2]标注来源,没有来源支撑的句子直接删掉”。这样模型会更容易被“锚”在原文上,因为标注来源本身成了一种强制检查。诱导性问题确实是最容易翻车的,我一般会在prompt里加一句“如果问题中的前提在资料里找不到依据,先指出这一点再回答”,效果比单纯说“不知道”要好。温度调低有用,但别指望它解决所有问题,0.2左右就够了,太低有时候反而让回答变得很死板。另外top5不一定最优,块太多容易互相干扰,可以试试先做重排或者压缩,只留最相关的2-3块,模型反而更老实。
你这个“严格基于以下内容回答”其实对大模型约束力挺弱的,我踩过类似的坑。光靠一句“找不到就说不知道”基本没用,得把“拒绝回答”的路径铺得足够具体,比如让它先判断问题里的关键实体在文档里有没有出现,没有就直接输出固定话术,而不是让它自由发挥。另外top5全塞进去也有个问题,噪声块会干扰模型判断,可以试试按相关性阈值过滤,或者让模型先对检索块做一次相关性打分再决定用哪些。来源标注确实有用,把每个块用编号和标题包起来,要求回答时带上引用编号,这样模型编造时会更“心虚”。温度调到0或者0.1是必须的,但别指望它彻底消除幻觉,主要还是靠prompt结构去卡。我自己比较有效的做法是把任务拆成两步:先让模型只做“提取+判断”,确认信息存在后再生成回答,能明显减少脑补。诱导性问题建议在prompt里加一句“忽略用户问题中未在文档中出现的假设或前提”,这个挺关键。
温度调到0.2以下确实有用,另外可以试试让模型先复述原文再回答。