趋近智
生产型的检索增强生成(RAG)系统中,发送给大型语言模型(LLM)的提示远不止一个简单的问题。它是一套精心设计的指令,一个小型程序,用于指引LLM在处理检索到的上下文时如何生成回答。生产环境要求对提示工程采取更精细的方法。高级方法将精确控制LLM的输出,提高事实依据,处理复杂情况,并确保提示可靠且易于维护。这些方法对于实现RAG系统生成部分所需的质量、准确性和效率非常重要。
摆脱问题和上下文的简单拼接,生产RAG系统中的高级提示通常采用结构化格式。这种清晰性有助于LLM区分指令、用户查询和检索到的文档,从而产生更可预测和可控的输出。
良好结构化提示的主要组成部分包括:
角色提示(身份设定): 指示LLM扮演特定角色或身份可以显著影响其语气、风格,甚至是其可能优先处理的特定领域知识(在其训练范围内)。例如:
明确指令: 清楚界定任务、期望的输出格式、任何限制,以及LLM应如何使用检索到的上下文。模糊的指令会导致多样且通常不理想的结果。
上下文分隔:
使用明确的标记来分隔提示的不同部分,特别是检索到的文档。这可以防止LLM将指令与上下文或用户查询混淆。常见方法包括类似XML的标签(例如,<documents>,</documents>)或Markdown围栏。
<system_instructions>
你是一名金融分析师。仅根据<documents>部分内的信息回答问题。
如果信息未找到,请说明“所提供的文档中没有可用信息。”
将你的回答格式化为JSON对象,包含“response”和“confidence_level”(高、中、低)键。
</system_instructions>
<documents>
[文档1文本]
---
[文档2文本]
...
</documents>
<user_query>
根据这些报告,公司第三季度的收入是多少?
</user_query>
JSON输出:
这种结构使LLM更容易解析输入,也使开发者更容易调试和迭代提示。
The following diagram illustrates the typical components of a structured prompt for an LLM in a RAG system.
一张图表,显示了高级LLM提示的常见构建块,包括系统指令、检索到的上下文和用户查询。
RAG系统的一个主要挑战是确保LLM的输出忠实地基于检索到的文档,而不是虚构,这通常被称为幻觉。高级提示工程提供了多种策略:
严格遵守来源: 明确指示LLM的回答仅基于所提供的文档。
引用说明: 要求LLM引用其信息的来源,通常通过引用文档ID或特定片段。这不仅鼓励事实依据,也有助于可验证性。
负面限制: 告诉LLM不要做什么。这可能会出乎意料地有效。
置信度评分提示: 要求LLM根据所提供的上下文,自我评估其回答的置信度。虽然不是完美的衡量标准,但它可以是一个指标。
这些技术结合使用时,可以显著提高RAG系统输出的可信度。
为了顺畅集成到应用程序中,LLM的输出通常需要遵守特定格式。提示是实现这一目标的有效方式:
请求结构化输出(例如,JSON,XML): 许多现代LLM在明确提示后可以生成JSON等结构化格式的文本。这对于下游的程序化使用很有价值。
示例指令:
将你的回答作为JSON对象提供。JSON对象必须包含以下键:
- "summary":对发现的简要总结。
- "key_entities":提及的重要实体列表。
- "source_documents":用于形成答案的文档ID列表。
指定长度和细节: 指导LLM关于期望的长度或细节程度。
思维链(CoT)和推理步骤: 尽管CoT通常与改善通用LLM任务中的推理能力相关联,但其某些方面可以适用于RAG。例如,你可以指示LLM首先从提供的上下文中提取与查询相关的句子或事实,然后仅基于这些提取的事实合成答案。这可以使生成过程更透明、更有依据。
分阶段推理指令:
1. 从提供的文档中识别并列出所有与回答用户问题直接相关的句子。在每个句子前加上其文档ID。
2. *仅*基于步骤1中识别出的句子,给出对用户问题的全面回答。
即使中间的“推理步骤”不显示给最终用户,这种结构化方法也可以提高最终答案的质量以及对源材料的忠实度。
生产RAG系统通常会检索多个文档,这些文档可能包含补充、冗余甚至矛盾的信息。提示可以指导LLM应对这种复杂性:
综合指令: 当多个文档共同形成答案时,指示LLM综合信息。
处理矛盾信息: 提供处理差异的策略。
信息优先级(谨慎使用): 如果你的检索或重排序阶段提供了关于文档重要性的信号(例如,时效性、来源权威性),你可以在提示中巧妙地暗示这一点。然而,过度依赖LLM仅从提示中推断复杂的优先级规则可能不可靠;明确的重排序通常更好。
提示并非一个“设置后就无需管”的组件。它们需要迭代开发、测试和优化,就像任何其他软件一样。
提示模板: 使用模板引擎(例如,Python的f-strings,Jinja2,Handlebars)来动态构建提示。这可以将静态指令逻辑与动态数据(查询、上下文)分离。
# 示例Python f-string模板
def create_rag_prompt(user_query, retrieved_docs_text, instructions):
return f"""
{instructions}
<retrieved_documents>
{retrieved_docs_text}
</retrieved_documents>
用户查询: {user_query}
回答:
"""
提示版本管理: 将你的提示模板视为代码。将它们存储在版本控制系统(如Git)中。这允许你跟踪更改、恢复到以前的版本,并管理不同的提示版本以进行A/B测试或特定使用场景。
系统化评估: 不要依赖轶事证据来判断提示的有效性。将提示更改与你的RAG评估框架结合(如第6章所述)。衡量提示修改对事实一致性、相关性和任务完成率等指标的影响。措辞上的微小改变有时会产生显著影响。
复杂任务的提示链: 对于高度复杂的任务,可以考虑将其分解为一系列LLM调用,每个调用都带有专门的提示。例如,一个提示可能从上下文中提取必要的事实,而随后的提示则可能使用这些事实来生成结构化报告。这种模块化方法可以提高控制和性能,但会增加系统架构的复杂性。
还有其他几个因素对于生产级提示很重要:
Token效率: LLM API调用通常按Token计费。提示应尽可能简洁且仍有效。过度冗长的指令或冗余的措辞会增加成本和延迟。定期审查提示以寻找在不牺牲性能的情况下简化它们的机会。
输入多样性的鲁棒性: 使用广泛的用户查询(包括模糊或措辞不当的查询)和不同类型的检索上下文来测试你的提示。适用于一种输入类型的提示可能不适用于另一种。目标是泛化能力强的提示。
处理上下文中的边缘情况: 考虑当检索到的上下文为空、非常短、嘈杂或无关紧要时,你的提示如何指导LLM。例如,你的指令应涵盖未找到相关文档的场景。
安全:缓解提示注入风险: 如果用户提供的文本未经适当清理或分隔就直接整合到LLM提示结构中,可能会造成提示注入等漏洞。在这种情况下,用户可能通过精心制作恶意查询来尝试覆盖你的系统指令。虽然完整讨论在第1章“生产RAG中的安全考量”中,但请确保用户输入明确分隔,并且你的系统指令具有权威性。例如,指示LLM始终将<user_query_tag>...</user_query_tag>中的文本视为用户输入,仅此而已。
掌握高级提示工程是一个持续的实验和优化过程。通过应用这些方法,你可以显著增强RAG系统生成器生成准确、可靠、格式良好且符合应用程序在生产环境特定需求的能力。对指令的精心编排,对于发挥LLM在RAG流程中的全部潜力非常重要。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造