这道题我觉得本质是在问:[[RAG]]系统里,你怎么通过prompt设计让大模型真正「用」你给的资料,而不是「编」答案。说白了,就是怎么让模型在检索增强的框架下,做到既精准又可信。
我一般会从三个层面来拆。先看结构分层。我会把prompt分成三块:系统指令、检索上下文、用户查询。系统指令定规矩,比如「只用参考文档,不准用预训练知识,信息不足就说不知道」;检索上下文就是top-k片段,每条带上编号、来源、相关性分数;用户查询就是原始问题。这样模型能清楚知道哪些是事实,哪些是问题,不会把两者混在一起。
再看怎么防[[Hallucination]]。光分层不够,你还得在指令里加约束。比如我要求模型每个关键事实后面都标引用编号[1][2],如果某个观点没有引用支撑,那就必须标注「[推测]」。还有一个很实用的技巧:明确说「如果参考文档信息不足以回答,直接说根据现有资料无法确定,不要编」。这其实是把压力还给检索系统,而不是让模型去猜。
最后看实际落地中的坑。举个例子,客服退款场景,用户问「我退货运费谁出」,你可能检索到好几份政策文档,有的说「质量问题卖家出」,有的说「七天无理由买家出」,还有一份是边界提示。如果直接把这些都堆进prompt,模型可能会被冗余信息搞混。我的做法是:在prompt里加一句「若多片段内容重复,优先使用最新或最具体的来源」。另外,长上下文截断也是个问题,我会在检索后先按[[Rerank]]重排,然后截断到模型的有效窗口,并在prompt开头说「以下是最重要的N份资料」。
再举一个例子,企业SOP合规文档检索。如果用户问「合同审批流程」,你检索到5份文档,其中两份流程有冲突。这时候我会在prompt里激活一个对比分析子指令,要求模型「先分别列出[1]和[3]中的步骤,再指出差异点」,而不是让模型自己决定信哪个。
这里有个前提:你的检索质量得过关。如果top-k里全是噪声,prompt设计得再好也没用。所以上线前我会特别关注[[Faithfulness]]和[[Context Precision]]这两个指标,确保检索到的片段确实相关且无矛盾。常见失败场景是检索召回了一堆同名不同义的文档,比如「价格调整」在销售文档和财务文档里完全不是一个意思,模型可能就会混淆。
所以我的整体思路是:不要把prompt看成静态模板,而要根据检索结果的置信度动态调整。如果单文档置信度高,就用精简模板直接抽取;如果多文档冲突,就激活对比分析子模板;如果零相关文档,直接切换成拒绝回答模板。实际项目中我会用LangChain或LlamaIndex的提示模板引擎来实现这个动态切换。
不过有个延伸点我一直比较在意:当检索到的文档本身存在矛盾时,光靠prompt约束其实不够,因为模型可能在对比时自己「脑补」出新的冲突。所以我想,是不是可以引入一个额外的验证步骤,比如让模型先输出一个中间推理,再对照原始文档做一次[[Self-RAG]]式的自查。这个方向我觉得挺值得深挖的。
总的来说,我会把prompt设计看成RAG系统的「最后一道防线」。前面检索、重排做得再好,如果prompt没把规矩立好,模型还是可能跑偏。所以我更倾向用结构清晰、约束明确、且动态适配的模板,而不是一个通用的万能prompt。