RAG Prompt 模板设计陷阱
RAG 场景下整合 top-k 检索结果,引导 LLM 生成准确输出
原题:请阐述如何设计有效的prompt模板来引导大语言模型,使其能够整合检索到的top-k相关文本片段和文档信息,生成准确且相关的最终输出结果。
Prompt工程 · 商汤科技真题
30 秒回答
- 明确区分系统指令、检索上下文与用户查询三部分结构
- 设计防幻觉机制(如要求基于引用回答、不确定时声明)
- 处理长上下文截断与冗余去重策略
- 多片段排序与相关性加权提示
回答与解析
答案要点
- 明确区分系统指令、检索上下文与用户查询三部分结构
- 设计防幻觉机制(如要求基于引用回答、不确定时声明)
- 处理长上下文截断与冗余去重策略
- 多片段排序与相关性加权提示
- 输出格式约束(如带引用标记的结构化输出)
核心设计原则
RAG的prompt设计关键是清晰隔离信息源,让模型明确区分"已知事实"和"需要回答的问题"。
推荐模板结构
【系统指令】
你是一个基于检索文档回答问题的助手。严格遵循:
1. 仅使用提供的参考文档作答,禁止依赖预训练知识
2. 若文档信息不足,明确说明"根据现有资料无法确定"
3. 每个关键事实后标注引用编号[1][2]
【参考文档】
{循环插入top-k片段,带编号和来源}
[1] 来源: {doc_id} | 相关性: {score}
内容: {chunk_text}
[2] ...
【用户问题】
{query}
【输出要求】
- 先给出直接答案(2-3句话)
- 再补充详细推理过程
- 最后用"参考来源"列出使用的文档编号
关键技巧
| 问题 | 解决方案 |
|---|---|
| 文档冗余/重复 | prompt中加指令:"若多片段内容重复,优先使用最新/最具体的来源" |
| 长上下文截断 | 按相关性重排序后截断,prompt提示"以下是最重要的N份资料" |
| 跨文档推理 | 显式要求:"对比[1]和[3]的观点,指出差异" |
| 幻觉抑制 | 强制要求:"任何无引用支撑的内容标记为[推测]" |
进阶:动态模板
实际项目中建议用LangChain/LlamaIndex的提示模板引擎,根据检索结果动态调整:
- 高置信度单文档 → 精简模板,直接抽取
- 多文档冲突 → 激活"对比分析"子模板
- 零相关文档 → 切换"拒绝回答"模板
口语版讲法(约4分钟)
- 这道题在问RAG落地时prompt怎么设计才能让模型听话
- 先说结构分层:系统指令、检索上下文、用户查询要隔离
- 再讲防幻觉机制:强制引用、不确定时声明、标注推测
- 然后处理实际坑:长上下文截断、冗余去重、多文档冲突
- 最后动态模板思路,以及我倾向的判断
这道题我觉得本质是在问: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。
关键一句:当检索文档本身存在矛盾时,prompt约束可能不够,需要考虑引入验证步骤如Self-RAG。
面试官还可能这样问
- 问法 1 · 场景切入
假设我们在做电商客服助手,用户问“这个手机怎么样”,我们从知识库检索了5段相关评测。你怎么设计prompt,让模型能把这些片段整合成一段准确、不胡说八道的回答?
- 问法 2 · 层层追问
你平时做RAG怎么设计prompt的?……系统指令、检索上下文、用户问题这三块你放一起还是分开?如果检索到的片段有重复或者矛盾,你怎么让模型处理?
- 问法 3 · 直球架构
设计一个RAG系统的prompt模板,要求整合top-k检索片段并生成带引用的回答。请说明模板的组成部分、防止幻觉的机制,以及如何处理片段冗余和长上下文截断。