提示工程基础
掌握提示工程的基础知识是使用 LLM 的第一步。本章介绍 Prompt 的结构组成、核心设计原则和常用技巧,帮助你建立稳固的基础。
Prompt 结构
一个完整的 LLM 对话由以下几个部分组成:
系统提示(System Prompt)
系统提示是在对话开始前设定的背景指令,通常由开发者而非用户编写。它定义了:
- 模型的角色和身份("你是一位专业的医学信息助手")
- 行为规范("始终以中文回复"、"不得提供具体的医疗建议")
- 背景知识(公司产品信息、知识库内容)
- 输出格式要求
系统提示示例:
你是一位专业的 Python 代码审查助手。
你的任务是:
1. 指出代码中的 Bug 和潜在问题
2. 给出改进建议,遵循 PEP 8 规范
3. 仅针对 Python 代码提供建议,其他语言礼貌拒绝
回复使用中文,代码示例使用代码块格式。
用户消息(User Message)
用户的实际输入,可以包含:
- 问题或任务描述
- 需要处理的文本或数据
- 约束条件和期望输出格式
助手消息(Assistant Message)
之前的对话历史,也可以用于助手预填(Prefill):强制模型从特定内容开始回复。
# Anthropic Claude API 中的助手预填
messages = [
{"role": "user", "content": "用 JSON 格式返回以下产品的信息:苹果手机"},
{"role": "assistant", "content": "{"} # 预填 "{" 强制输出 JSON
]
预填技巧在 Anthropic Claude 中尤其有效,可以避免模型在 JSON 前面加入无用的解释文字。
清晰性原则
清晰性是所有提示工程技巧中最重要的原则。模糊的指令必然产生模糊的输出。
具体化指令
| 模糊指令 | 清晰指令 |
|---|---|
| "总结这篇文章" | "用 3 个要点总结这篇文章,每点不超过 30 字,面向没有技术背景的读者" |
| "翻译这段文字" | "将以下段落从英文翻译为正式的中文,保留专业术语的英文原文并在括号中注明" |
| "写一个函数" | "用 Python 3.10 写一个函数,接受一个整数列表,返回其中所有质数的列表,需要包含类型注解和文档字符串" |
避免歧义
歧义通常来自:
- 省略关键信息:"翻译这个" → 翻译成什么语言?翻译风格要求?
- 双重含义词:"简单"可以指"易于理解"或"简洁短小"
- 否定叠加:"不要不正式" → 要正式还是随意?
处理歧义的最佳方式是提供具体示例(see: Few-shot 章节)。
上下文提供策略
LLM 的输出质量强烈依赖于输入的上下文信息。上下文包括:
背景信息
告诉模型任务发生的场景:
背景:我们是一家面向企业用户的 SaaS 公司,主要产品是项目管理软件。
目标受众:非技术背景的中小企业主管
任务:写一封产品更新通知邮件
受众信息
明确受众的知识水平影响输出的技术深度:
- "解释给一位高中生听"
- "面向资深后端工程师,可以使用技术术语"
- "解释给我的祖父母,他们不懂任何技术"
约束条件
清晰列出限制:
- 字数限制:"控制在 200 字以内"
- 格式要求:"使用 Markdown 格式,包含二级标题"
- 内容禁区:"不要提及竞争对手品牌"
任务分解
复杂任务往往难以在单个 Prompt 中完美完成,任务分解是关键策略:
顺序分解
将大任务分解为有序的小步骤:
任务:分析一份商业计划书并给出投资建议
分解为:
步骤1:提取商业计划书的核心数据(市场规模、财务预测、团队背景)
步骤2:识别主要风险点(3-5个)
步骤3:评估竞争优势(与市场对手对比)
步骤4:综合以上分析,给出是否建议投资及理由
角色分离
不同子任务由不同角色处理:
先以"批评者"角色找出计划书的5个最大弱点,
再以"支持者"角色找出5个最强优势,
最后以"公正评估者"角色综合两方意见。
流水线(Pipeline)
在应用层面,多步骤 LLM 调用组成处理流水线:
- 第一个 LLM 调用:从原始文档提取关键信息
- 第二个 LLM 调用:基于提取的信息进行分析
- 第三个 LLM 调用:生成最终报告
输出格式控制
明确指定输出格式,减少后处理成本:
JSON 格式
请以 JSON 格式返回分析结果,格式如下:
{
"sentiment": "positive|negative|neutral",
"confidence": 0.0-1.0,
"key_points": ["要点1", "要点2"],
"summary": "一句话总结"
}
只返回 JSON,不要添加任何解释。
Markdown 格式
请以 Markdown 格式输出报告:
- 使用 ## 作为二级标题
- 关键数据用**加粗**
- 使用无序列表列举要点
- 代码示例使用代码块
结构化列表
请以以下格式输出 3 个方案:
方案一:[名称]
- 优点:...
- 缺点:...
- 适用场景:...
方案二:...
负面指令 vs 正面指令
正面指令(告诉做什么)通常比负面指令(告诉不要做什么)更有效:
| 负面指令 | 正面指令 |
|---|---|
| "不要使用复杂的词汇" | "使用简单、日常的词汇,适合初中生阅读" |
| "不要太长" | "控制在 150 字以内" |
| "不要不相关的内容" | "只回答与 Python 编程相关的问题" |
负面指令容易让模型"记住"要避免的内容,有时反而会过度强调;正面指令直接告诉模型期望的行为,执行更准确。
迭代优化流程
没有人能一次写出完美的 Prompt,迭代是必然过程:
- 初稿:写出最直觉的 Prompt,先运行看结果
- 识别问题:分析输出的具体哪里不符合预期
- 定向修改:针对具体问题修改,每次只改一处(避免无法确定哪个改动有效)
- 多样本测试:在多个不同输入上测试修改效果,确保不过拟合单一案例
- 记录版本:保存每个版本的 Prompt 和对应的测试结果
- 重复:直到输出质量满足要求
常见陷阱:针对一个测试案例优化了 Prompt,却导致其他案例的效果变差(过拟合)。始终在一组多样化的测试案例上评估。