最近在做一个简单的RAG Agent,任务是从文档里提取信息后做多步推理(比如“对比A和B的差异,再结合C给出结论”)。我目前用ReAct风格,把工具调用和推理步骤写进system prompt里,但经常出现模型在中间步骤编造数据,或者跳过推理直接给结论。试过加“请逐步思考”,效果不稳定。想请教下,多步任务里,是应该把步骤拆成多个子Prompt单独调用,还是尽量在一个Prompt里约束?另外,对于“必须基于检索结果”这种硬性要求,有没有比较有效的提示词写法?谢谢。
Agent多步推理任务中,Prompt该怎么设计才能减少“幻觉”?
全部回复
共 110 条我最近也在踩这个坑。经验是别指望一个prompt搞定多步推理,拆成子任务调用反而更稳,每一步只让模型做一件事,中间结果落盘再喂给下一步。另一个管用的是强制引用,让模型每给一个结论都带上检索片段编号,没编号就重试,这样编数据会少很多。还有个小技巧是在工具返回里加个字段标明“数据来源”,模型看到空值就不敢乱编了。
多步任务我现在更倾向拆成子prompt分开调,中间结果落盘再做下一步,这样每步都能单独校验,模型想编也难。硬性要求“必须基于检索结果”的话,可以在prompt里强制它先引用原文片段再推理,没引用就不让往下走。ReAct那套写system里太长了,模型容易忽略中间约束,不如把规则塞到每一步的user prompt里更管用。
拆成子prompt分步调更稳,每步只干一件事,幻觉少很多。硬性要求可以写“若检索结果没提到,直接说不知道”。
我踩过这个坑,多步推理塞一个prompt里确实容易中间就编了。后来改成拆成子步骤单独调,每步只让模型干一件事,幻觉少了很多。硬性要求的话,我一般在每个子prompt里都重复一遍“只依据下面提供的检索内容回答,没有就说不知道”,别嫌啰嗦,真有用。ReAct那套对简单任务还行,多步的还是得靠流程控制,别全指望模型自觉。
我之前也遇到过类似问题,后来换了方案。
拆成子prompt反而容易断片,不如一个prompt里加“引用原文片段”约束,逼它别瞎编。
我最近也在踩这个坑,感觉多步推理还是拆成子prompt更稳,一个prompt里塞太多约束模型容易顾此失彼。至于“必须基于检索结果”,我习惯在每步后面强制让它引用原文片段,比如“只允许使用以下内容作答”,比单纯说“不要编造”管用不少。ReAct中间跳步的话可以试试把thought和action分开输出,逼它先写依据再下结论,会稍微好点。
多步推理里想靠一个prompt把幻觉压住,我觉得挺难的,ReAct本身对中间步骤的约束就偏弱。我现在更倾向把流程拆成两段:先用一个prompt只做抽取和引用,要求每个字段都带原文片段,再做第二个prompt专门做对比和结论,这样编数据的空间会小很多。对于“必须基于检索结果”,我感觉光写“请基于以下内容”基本没用,得改成“如果检索结果里没有提到,就直接说未找到,禁止补充外部知识”,并且让它输出时带上证据句。还有个坑是,中间步骤一旦让它自由发挥,它就会自己脑补数字,所以我会在工具返回后加一句“下一步只能使用上一步出现的实体和数值”。至于“逐步思考”,我试过效果确实不稳定,后来换成强制它先列证据再下结论,反而稳一些。你也可以试试把结论格式固定成“相同点/不同点/依据”,模型跑偏会少很多。
拆成子prompt分步调用更稳,每步只让它干一件事,中间结果落盘再喂下一步。
拆成子prompt更稳,每步强制引用原文片段,没引用就重跑。