代码生成场景提示(Code Generation Prompts)
通过结构化提示词策略引导 LLM 生成高质量、可运行的代码
通过结构化提示词模板,让 LLM 基于给定信息准确回答问题、减少幻觉
内容摘要
QA Prompt Templates(问答提示模板)是一类专为"问答"场景设计的提示词结构,核心目标是让大语言模型基于你提供的信息来回答问题,而不是靠猜。你给模型一段参考资料 + 一个问题,模型在资料范围内作答——这就是知识问答场景的基本逻辑。
QA Prompt Templates(问答提示模板)是一类专为"问答"场景设计的提示词结构,核心目标是让大语言模型基于你提供的信息来回答问题,而不是靠猜。你给模型一段参考资料 + 一个问题,模型在资料范围内作答——这就是知识问答场景的基本逻辑。
为什么需要专门的模板?因为直接把问题扔给 LLM,模型会用自己"记住"的知识回答,而这些知识可能过时、不准确,甚至是模型编造的(这就是所谓的 Hallucination,幻觉)。问答模板通过明确的结构——角色定义、参考资料、回答规则、输出格式——把模型的回答行为框定在可控范围内。
在实际 Agent 应用中,知识问答模板是最常用的提示词类型之一。无论是 RAG(Retrieval-Augmented Generation,检索增强生成)系统中的答案生成环节,还是企业客服机器人、文档助手,底层都在用某种形式的 QA 模板来组织提示词。
一个完整的 QA 提示模板由四层结构组成,缺一不可:
| 结构层 | 作用 | 缺失后果 |
|---|---|---|
| 角色定义(Role) | 告诉模型"你是谁",设定回答的语气和专业度 | 回答风格不稳定,时而口语化时而学术化 |
| 上下文(Context) | 提供参考资料、检索文档或对话历史 | 模型只能靠自己的"记忆"回答,幻觉风险飙升 |
| 回答规则(Instructions) | 约束模型的回答行为,比如"只基于资料回答""不知道就说不知道" | 模型可能编造信息或偏离主题 |
| 输出格式(Format) | 规定回答的结构,比如纯文本、JSON、带引用标注 | 输出格式随机,后续系统无法解析 |
角色定义放在 System Prompt(系统提示词)中,是整个对话过程中保持不变的指令。它回答的是"模型应该扮演谁"这个问题。
一个好的角色定义包含三个层面:身份("你是一个法律领域的知识助手")、能力边界("你只能基于提供的文档回答")、行为准则("如果文档中没有相关信息,明确告知用户")。角色定义越具体,模型的行为越稳定。
上下文是模型回答问题的"原材料"。根据场景不同,上下文可能是:
上下文的质量直接决定回答质量——垃圾进、垃圾出。
回答规则是防止模型"跑偏"的关键。常见规则包括:
输出格式决定了回答的可用性。常见的格式约束:
QA 提示模板的工作原理可以用一句话概括:通过结构化的提示词,将模型的注意力锚定在给定的上下文上,使其在回答时优先参考上下文内容,而不是依赖自身参数中存储的知识。
具体的工作流程分四步:
第 1 步:信息准备。 根据用户问题,从外部知识库检索相关文档(RAG 场景),或者加载对话历史(多轮对话场景)。这一步决定了模型能"看到"什么信息。
第 2 步:模板填充。 将角色定义、检索到的上下文、回答规则、用户问题按固定顺序组装成完整的提示词。顺序通常是:角色 → 规则 → 上下文 → 问题。
第 3 步:模型推理。 LLM 接收完整提示词后,在上下文范围内寻找与问题相关的信息,生成回答。由于提示词中明确要求"基于文档回答",模型会优先引用上下文中的内容。
第 4 步:输出格式化。 模型按照模板中指定的格式输出结果。如果要求 JSON 格式,后续系统可以直接解析;如果要求带引用标注,用户可以追溯信息来源。
关键点:模板中"不知道就说不知道"这条规则非常重要。没有这条规则,当上下文中找不到答案时,模型会倾向于用自己的知识"补上"一个听起来合理的答案——这正是幻觉的来源。
图中最关键的分支在"上下文中有答案?"这个判断节点。一个好的 QA 模板必须同时覆盖两条路径:有答案时准确回答,没答案时明确拒绝。很多初学者只设计了"有答案"的路径,忽略了"没答案"时的降级处理,导致模型在信息不足时编造内容。
以下示例展示三种最常用的 QA 模板结构——基础问答、带引用问答和多轮对话问答。
# 基于 openai>=1.0.0 验证(截至 2026-03)
import os
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# ========== 模板 1:基础 RAG 问答 ==========
# 四层结构:角色 + 规则 + 上下文 + 问题
system_prompt = """你是一个技术文档助手。
规则:
1. 只基于【参考资料】中的内容回答
2. 如果参考资料中没有相关信息,回答"根据现有资料无法回答此问题"
3. 用简洁的中文回答"""
context = """【参考资料】
[文档1] Python 列表推导式比等价的 for 循环快约 50%,因为列表推导式在底层使用了优化的 C 代码。
[文档2] NumPy 数组运算速度是纯 Python 列表的 10-100 倍,原因是 NumPy 使用连续内存布局和向量化操作。"""
user_message = f"""{context}
问题:Python 中有哪些提升性能的方法?"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message}
],
temperature=0.3 # 低温度 = 更确定性的回答
)
print(response.choices[0].message.content)
# ========== 模板 2:带引用标注的问答 ==========
# 在规则中要求标注来源编号
system_prompt_cited = """你是一个学术助手。
规则:
1. 基于提供的参考资料回答问题
2. 在每条信息后用 [文档X] 标注来源
3. 如果多个文档信息冲突,分别列出各文档的观点
4. 回答末尾列出引用的文档清单"""
# 调用方式与模板 1 相同,只是 system_prompt 不同
# ========== 模板 3:多轮对话问答 ==========
# 对话历史作为上下文,模型能理解指代关系
messages = [
{"role": "system", "content": "你是一个 Python 编程助手。基于对话上下文回答问题。"},
{"role": "user", "content": "Python 的装饰器是什么?"},
{"role": "assistant", "content": "装饰器是一种用 @符号标记的语法糖,本质是一个接收函数并返回新函数的高阶函数。"},
# 第二轮:用户说"它",模型需要从历史中理解"它"指装饰器
{"role": "user", "content": "它和中间件有什么区别?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
temperature=0.5
)
print(response.choices[0].message.content)
三个模板的差异集中在 System Prompt 的规则部分:模板 1 强调"不知道就说不知道",模板 2 增加了引用标注要求,模板 3 依靠对话历史实现上下文理解。实际项目中,这三种模板经常组合使用——比如 RAG 系统中同时要求基于文档回答(模板 1)并标注引用(模板 2)。
| 概念 | 与 QA 模板的区别 | 更适合关注的重点 |
|---|---|---|
| RAG(检索增强生成) | RAG 是一套完整的技术架构(检索 + 生成),QA 模板只是其中"生成"环节的提示词设计 | RAG 关注整个链路,QA 模板关注提示词结构 |
| Few-Shot Prompting(少样本提示) | Few-Shot 通过示例教模型"怎么做",QA 模板通过上下文告诉模型"基于什么回答" | Few-Shot 适合格式引导,QA 模板适合知识约束 |
| System Prompt(系统提示词) | System Prompt 是 QA 模板的一个组成部分(角色定义层),不是全部 | System Prompt 是通用概念,QA 模板是特定场景的应用 |
核心区别:
| 常见误区 | 正确理解 |
|---|---|
| "把检索到的文档全部塞进提示词就行" | 文档数量和质量需要平衡。过多文档会稀释重点、增加成本,模型对靠前的文档关注度更高(位置偏见)。通常选 Top 3-5 篇最相关的文档即可。 |
| "写了'不要编造'模型就不会编造" | 这条规则能降低幻觉概率,但不能完全消除。模型仍可能在"部分相关"的场景下过度推断。关键文档不存在时,建议在应用层增加二次校验。 |
| "QA 模板 = RAG" | QA 模板只是提示词层面的设计,RAG 还包含检索、向量化、重排序等工程组件。一个优秀的 RAG 系统需要检索和生成两端都优化,只优化提示词是不够的。 |
| "多轮对话只要保留全部历史就好" | 对话历史越长,token 消耗越大,且模型对早期对话的"记忆"会衰减。实际项目中需要对历史进行摘要压缩或滑动窗口截断,在完整性和成本之间取平衡。 |
参考答案:
四层结构:角色定义(Role)、上下文(Context)、回答规则(Instructions)、输出格式(Format)。去掉回答规则后,模型不再受"只基于文档回答"的约束,当上下文中信息不足时,模型会倾向于用自己的知识"补充"答案,导致幻觉风险大幅增加。同时,模型也不知道在"不知道"的情况下该如何处理,可能给出含糊或错误的回答。
参考答案:
三个优化方向:(1) 在回答规则中将引用要求前置并加粗强调,比如"每一条法律建议后面必须紧跟 [条文X] 标注,没有标注的建议视为无效";(2) 在输出格式中指定 JSON 结构,将 citations 作为必填字段,后端校验缺失引用时自动拒绝并重新请求;(3) 用 Few-Shot 方式给 1-2 个带引用的回答示例,让模型从示例中"看到"引用格式长什么样。三种方法组合使用效果最好。
参考答案:
可能原因分三类。属于 QA 模板问题的:(1) 回答规则过于严格,比如要求"完全匹配"才回答,而文档中的表述和用户问题用词不同;(2) 上下文组织不当,相关文档放在了提示词末尾,被模型忽略(位置偏见)。不属于 QA 模板问题的:(1) 检索环节没有召回正确文档(检索算法或向量化模型的问题);(2) 文档分块(Chunking)不合理,相关信息被切断在两个块中,单个块信息不完整;(3) 文档内容本身表述不清,模型理解有偏差。排查时应先确认检索环节是否返回了正确文档,再检查模板设计。
优先展示同分类且标签更接近的内容,方便继续串联学习。
通过结构化提示词策略引导 LLM 生成高质量、可运行的代码
在运行时动态组装最优上下文,让 LLM 在正确的信息环境中完成任务
用结构化模板帮助 LLM 从原始数据中提取洞察、生成图表描述和分析报告的提示词设计方法