RAG 中如何设计 Prompt 来有效利用检索到的文档?

RAG 中如何设计 Prompt 来有效利用检索到的文档?

RAG 中如何设计 Prompt 来有效利用检索到的文档?

在 RAG 系统中,Prompt 的设计是连接“检索到的文档”与“最终生成答案”的关键桥梁。即使检索到高度相关的文档,如果 Prompt 未能有效引导模型利用这些信息,依然可能出现忽略文档、答非所问、幻觉等问题。

以下是如何设计 Prompt 来有效利用检索文档的核心原则与实用模板。


一、核心设计原则

原则说明错误示例正确做法
明确文档角色告诉模型检索到的文档是“唯一信息来源”,而非参考建议“根据以下资料回答”仅根据以下文档内容回答问题。如果文档中没有答案,请直接说‘未找到相关信息’,不要编造。”
结构化文档表示区分不同文档来源,防止模型混淆堆砌所有文本[文档1] [文档2]--- 分隔,标注来源
强调定位与引用要求模型指出答案依据哪篇文档“答案是X”“答案是X(依据文档3的第2段)”
处理无答案情况明确禁止幻觉无说明“如果文档不包含答案,输出‘无法回答’,绝不猜测”
指令与内容分离用特殊标记(如<context><question>)隔离上下文混合书写使用明确的 XML 标签或 Markdown 标题

二、基础 Prompt 模板

模板 1:标准问答(通用)

<context>
{% for doc in documents %}
[文档{{ loop.index }}] 来源:{{ doc.source }}
内容:{{ doc.content }}
---
{% endfor %}
</context>

<question>{{ user_query }}</question>

<instruction>
你是一个基于文档的问答助手。请严格执行以下规则:
1. 仅使用上面 <context> 中的信息回答问题
2. 如果问题无法从上下文中得到答案,请回复:“根据提供的文档,无法回答该问题”
3. 回答时请引用具体的文档编号(例如:根据文档2)
4. 不要添加任何外部知识或你的主观推测
</instruction>

<answer>

模板 2:多文档对比与综合

<context>
[文档A] 时间:2024-01-15 | 作者:张三
内容:公司计划2024年Q2推出新产品X...

[文档B] 时间:2024-10-20 | 作者:李四  
内容:因市场变化,新产品X推迟至2025年Q1发布...
</context>

<task>
请根据以上两篇文档回答用户问题。注意:
- 如果文档之间存在矛盾,请明确指出矛盾点及各自的来源
- 优先采用时间更新的文档作为最终结论
- 用表格对比不同文档的关键差异
</task>

<question>{{ query }}</question>

模板 3:带不确定性过滤(用于高风险场景)

<context>{{ retrieved_texts }}</context>

<task>
你需要判断以下两个问题:
1. 文档中是否包含足够信息来回答用户问题?(回答 YES/NO)
2. 如果 YES,给出答案并引用原文;如果 NO,输出“信息不足”

置信度阈值:如果关键信息在文档中只出现一次或表述模糊,请判定为 NO
</task>

<question>{{ query }}</question>

三、高级技巧

1. 强制“先思考后回答”(Chain-of-Thought)

引导模型在输出答案前先评估文档相关性:

<steps>
1. 逐一分析每个文档是否与问题相关
2. 提取相关文档中的证据句子
3. 判断证据是否足以回答整个问题
4. 基于以上分析给出最终答案
</steps>

2. 为文档添加摘要或标题

如果文档较长,可在 Prompt 中先提供每个文档的一行摘要,帮助模型快速定位:

文档摘要:
- 文档1:2024年财报摘要,营收增长15%
- 文档2:2025年市场预测,提到挑战
- 文档3:产品发布计划

详细内容:
[文档1] ...

3. 动态调整指令(根据查询类型)

针对事实性问题、推理问题、总结性问题使用不同 Prompt:

查询类型额外指令
事实型“请直接给出具体数值/日期,不要解释过程”
推理型“请基于文档中的证据进行三步推理”
总结型“请用3个要点总结文档中关于X的内容”

4. 加入“不相关文档”示例

Few-shot 示例中展示当文档无用时模型的正确行为:

示例:
<context>文档1:关于猫的饮食习惯</context>
<question>狗需要每天遛多久?</question>
<answer>根据提供的文档,无法回答该问题。文档内容仅涉及猫的饮食。

现在请回答真正的用户问题:
...

四、针对不同检索质量的策略

情况 1:检索结果可能包含噪音

在 Prompt 中要求模型忽略无关文档

“上下文中可能混有不相关的文档。请只使用与问题直接相关的部分。如果某文档与问题无关,直接忽略它,不要尝试硬解释。”

情况 2:检索结���不完整

引导模型承认知识边界

“如果上下文中只有部分答案,请说明:‘文档提供了关于X的信息,但没有提到Y,因此无法完全回答。’”

情况 3:多轮对话中的文档复用

为每轮对话重新注入当前相关的文档,但保留历史答案的简短记忆:

历史对话:用户问过A,助手回答B
当前上下文:与当前问题最相关的3篇文档
当前问题:C

五、实际代码示例(LangChain)

from langchain.prompts import ChatPromptTemplate

template = """
你是一个基于文档的问答系统。

<context>
{context}
</context>

<rules>
- 仅使用 <context> 中的信息回答
- 如果没有答案,回复:"根据文档无法回答"
- 引用文档编号:[文档X]
- 不要添加外部知识
</rules>

问题:{question}

回答:
"""

prompt = ChatPromptTemplate.from_template(template)

# 使用
docs = retriever.get_relevant_documents(query)
formatted_context = "\n---\n".join([f"[文档{i}] {doc.page_content}" for i, doc in enumerate(docs, 1)])
response = llm.invoke(prompt.format(context=formatted_context, question=query))

六、常见错误与调试

现象可能原因修复方法
模型忽略文档,凭自身知识回答Prompt 未强制“仅基于文档”加入 ONLY use the provided context,并用 few-shot 示例
答案虽正确但无法溯源未要求引用加入“请标注信息来源”指令
多文档矛盾时答案混乱未明确矛盾处理规则增加“遇到矛盾时优先最新/多数来源”规则
文档过长,模型遗漏关键信息未对长文档做摘要或分段先用 LLM 对每个文档提取与问题最相关的 2-3 句

总结

一个好的 RAG Prompt = 明确边界(仅用文档) + 结构化文档 + 引用要求 + 拒答机制 + 任务分解
设计时应始终自问:如果检索到的文档完全不相关,模型会诚实地拒绝回答,还是会编造? —— 后者的出现往往意味着 Prompt 对信息边界的约束不足。通过反复迭代上述模板与技巧,可以显著提升 RAG 系统的可靠性。

你是一个专业的知识助手。请仔细阅读以下参考文档,基于文档内容回答用户问题。

【重要规则】

  • 只使用文档中的信息回答
  • 如果文档中没有相关信息,明确告知用户
  • 尽可能引用具体的文档片段
  • 不要添加文档外的信息

【参考文档】

文档1:
{检索到的文档1}

文档2:
{检索到的文档2}

【用户问题】
{用户的问题}

请回答:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值