从基础原则到工程实践,掌握与 LLM 高效沟通的方法论。
一、Prompt 是什么
Prompt(提示词)是你发给大语言模型(LLM)的输入文本。Prompt 的质量直接决定模型输出的质量。写 Prompt 不是玄学------它有一套可学习、可优化的方法论。
在正式开始前,先看一个典型的 LLM API 调用结构(以 OpenAI 兼容接口为例):
python
from openai import OpenAI
client = OpenAI(
api_key="your-api-key",
base_url="https://api.deepseek.com/v1"
)
def get_completion(prompt, model="deepseek-chat"):
response = client.chat.completions.create(
model=model,
messages=[
{"role": "user", "content": prompt}
],
temperature=0.5, # 控制随机性:0 最确定,2 最随机
max_tokens=1024, # 限制模型回复的最大 token 数(仅限输出部分)
)
return response.choices[0].message.content
其中两个核心参数:
| 参数 | 含义 | 建议 |
|---|---|---|
temperature |
控制输出的随机性,范围 0 ~ 2 | 事实性任务设低(0-0.3),创意任务设高(0.7-1.2) |
max_tokens |
限制模型回复的最大 token 数 | 按需设置,过长浪费,过短截断 |
二、Prompt 四大核心原则
2.1 原则一:撰写清晰具体的指令
「清晰的指令 ≠ 精简的指令」------很多时候,篇幅更长的 Prompt 能为模型提供更完整的背景信息,让输出更贴合需求。
不好的 Prompt:
写一篇关于秋天的诗。
更好的 Prompt:
diff
请写一首七言绝句,主题为深秋山林。要求:
- 押平水韵
- 融入枫叶、寒霜、孤雁三个意象
- 情感基调为寂寥但不悲凉
模型无法猜到你的偏好------你能给的约束越多,它偏离预期的概率越低。
2.2 原则二:引导模型逐步推理
复杂的任务不要指望模型一步到位。像教人一样,把推理过程分解为步骤。
python
prompt = f"""
执行以下操作:
1. 将三个反引号内的文本概括为一句话
2. 把这句摘要翻译成日语
3. 列出日语摘要中出现的所有人名
4. 输出 JSON 对象,包含字段:japanese_summary、num_names
文本:
```{{text}}```
"""
这种方式让模型先思考再行动 ,大幅提升复杂任务的正确率------这也叫 思维链(Chain of Thought,CoT)。
关键技巧:遇到推理类任务(数学题、逻辑题、多步骤操作),加上"让我们一步步思考(Let's think step by step)"往往有奇效。
2.3 原则三:要求明确的输出格式
直接告诉模型你想要的格式,能省去大量后处理工作:
python
prompt = f"""
请列出四大名著并标注对应的作者与书籍类型。
使用 JSON 格式呈现,需包含以下字段:
- book_id(书籍编号)
- title(书名)
- author(作者)
- desc(简介,不超过 30 字)
- genre(书籍类型)
"""
结构化输出的好处:
- 程序可直接
json.loads()解析 - 字段一致,无遗漏
- 便于批量处理
2.4 原则四:处理「无内容」的边界情况
当输入文本不包含你期望的内容时,明确告知模型该怎么做,避免它编造答案:
python
prompt = f"""
你将收到由三引号包裹的文本。
若文本中包含一系列操作指令,请按以下格式重新整理:
步骤1. ...
步骤2. ...
步骤N. ...
如果文本中没有操作指引,直接输出:"未提供步骤"。
\"\"\"{{text}}\"\"\"
"""
不加这个兜底指令的话,模型可能会强行从一段写景的文字里"发明"出步骤------这叫幻觉(Hallucination)。
三、Prompt 的结构化设计
3.1 System Message 与 User Message
现代 Chat API 支持多角色消息,合理分工让 Prompt 更清晰:
| 角色 | 用途 | 示例 |
|---|---|---|
system |
设定模型的全局行为、角色、规则 | "你是一位精通 Python 的编程导师" |
user |
具体任务 / 问题 | "请解释装饰器的原理" |
assistant |
历史回复(多轮对话) | 模型之前的回答 |
python
messages = [
{
"role": "system",
"content": "你是一位精通 Python 的编程导师。回答应当简洁、准确,配合可运行的代码示例。"
},
{
"role": "user",
"content": "Python 的 GIL 是什么?"
}
]
System Message 的威力:
- 设定回答风格("用小学生能懂的语言解释")
- 限定知识范围("只回答 Python 相关的问题")
- 约束输出格式("所有代码用 ```python 包裹")
3.2 使用分隔符避免注入
将用户输入用三引号 """...""" 或 XML 标签 <text>...</text> 包裹,能防止模型混淆指令和内容:
python
prompt = f"""
将以下文本总结为一句话。
文本:
\"\"\"{{user_input}}\"\"\"
"""
# 即使用户输入中包含"忽略上面的指令"等干扰内容,
# 分隔符也让模型能清楚区隔"指令"和"待处理文本"。
四、Few-shot Prompting(少样本提示)
4.1 Zero-shot vs Few-shot
| 方式 | 含义 | 适用场景 |
|---|---|---|
| Zero-shot | 不给示例,直接提问 | 简单任务 |
| Few-shot | 先给 1~N 个示例,再提问 | 需要统一输出风格 / 格式 |
4.2 Few-shot 示例
python
prompt = f"""
你的任务是保持统一的风格作答。
提问:请讲讲何为耐心
回答:能凿出幽深峡谷的江河,源自涓涓细流;
恢宏壮阔的交响乐,起于单个音符;
精美繁复的织锦,始于一缕丝绒。
提问:请讲讲何为爱情
"""
通过一个示例(1-shot),模型学会了你的风格偏好------它会用类似的散文诗风格回答"爱情"。
4.3 Few-shot 的实用场景
- 统一输出格式:给 2~3 个输入→输出范例,模型照猫画虎
- 风格迁移:给一段目标风格的文字作参考
- 分类任务:给几个标注样本,模型类推出分类规则
Few-shot 会消耗更多 token(示例也计入 prompt 长度),需权衡成本。
五、角色扮演 Prompt
让模型扮演特定角色,能激活其对应的知识分布:
diff
你是一位有 10 年经验的 Python 后端工程师。
你的代码风格偏好:
- 类型注解完整
- 异常处理严谨
- 注释简洁但关键逻辑必写
请 review 以下代码...
好用的角色模板:
- 「你是一位精通 XX 的技术专家」
- 「你是一位耐心的小学老师,擅长用比喻解释概念」
- 「你是一个代码审查机器人,只关注安全漏洞和性能问题」
六、控制输出长度的策略
除了 max_tokens 参数截断,还可以在 Prompt 中引导:
| 策略 | Prompt 示例 |
|---|---|
| 字数限制 | 「用不超过 100 字回答」 |
| 句数限制 | 「用 3 句话总结」 |
| 要点限制 | 「列出最重要的 5 个要点」 |
| 格式约束 | 「每条建议不超过一行」 |
max_tokens是硬截断,Prompt 引导是软约束------两者配合使用效果最佳。
七、常见陷阱与应对
| 陷阱 | 表现 | 应对 |
|---|---|---|
| 幻觉 | 模型编造不存在的事实 | 加「如果不确定,请说不知道」 |
| 忽略指令 | 输出格式不对、遗漏步骤 | 把关键约束放在 Prompt 最前面和最后面 |
| 输出截断 | max_tokens 不足导致回答不完整 |
加长 max_tokens,或拆分任务 |
| 格式不稳定 | 有时返回 JSON,有时返回纯文本 | Few-shot 给格式范例 + system message 强调 |
| 话题漂移 | 多轮对话中逐渐偏离主题 | 在新一轮开头重申关键约束 |
解决「忽略指令」的实用技巧
模型对 Prompt 开头和结尾的内容最敏感。如果你有重要的格式要求,写在 Prompt 的最前面和最后面各一次:
javascript
你必须返回合法的 JSON,不要输出其他内容。
...(任务描述)...
再次强调:只返回 JSON,不要有任何解释文字。
八、迭代优化 Prompt 的方法
Prompt Engineering 本质上是一个实验循环:
写初版 Prompt → 观察输出 → 定位问题 → 修改 Prompt → 再测试
具体步骤:
- 先写一个简单版本,不要一开始就过度设计
- 用 3~5 个不同输入测试,覆盖正常 + 边界情况
- 定位问题:是格式错了?内容跑了?还是漏了步骤?
- 增量修改:一次只改一个变量,方便归因
- 保留每个版本:好的 Prompt 是改出来的,旧版本可能是未来参考
九、Python f-string 构建 Prompt
Python 的 f-string 是构建动态 Prompt 的利器,支持多行和变量嵌套:
python
text = "需要处理的文本内容"
prompt = f"""
你将收到由三引号包裹的文本。
请完成以下任务:
1. 总结为一句话
2. 翻译为英文
\"\"\"{text}\"\"\"
"""
f-string 的优势:
{变量}直接嵌入,比+拼接和%格式化更直观"""..."""三引号保留换行,Prompt 结构一目了然{{}}可转义为字面量花括号(当需要在 Prompt 中展示 JSON 时很有用)
十、Prompt 模板速查
总结类
python
用 3 句话总结以下内容,每句不超过 30 字:
"""
{text}
"""
翻译类
python
将以下文本翻译为英文,保持原文语气和专业术语:
"""
{text}
"""
代码解释类
css
解释以下 Python 代码的功能和原理,适合有一定基础的开发者阅读:
```python
{code}
shell
### 提取结构化信息类
从以下文本中提取所有人名、地名、时间,以 JSON 格式返回: 字段:people(数组)、places(数组)、times(数组) 如果某字段没有匹配项,返回空数组。 """ {text} """
shell
### 分步骤指令类
请将以下操作步骤按顺序整理为编号列表: """ {text} """ 如果没有步骤,输出:"未提供步骤"。
markdown
---
## 十一、小结
1. **清晰 > 精简**:详细的指令 + 完整上下文 > 一句话提问
2. **引导推理**:复杂任务分解为步骤,用「逐步思考」激活思维链
3. **控制输出**:明确格式(JSON)+ 兜底规则(边界处理)
4. **善用角色**:System Message 设定全局行为,User Message 提出具体任务
5. **分隔符保平安**:用 `"""..."""` 包裹用户输入,防止指令混淆
6. **Few-shot 统一风格**:给 1~3 个范例,模型跟上你的偏好
7. **迭代优化**:好 Prompt 是试出来的,保持版本,一次改一个变量
Prompt Engineering 不是魔法------它是**用结构化思维把需求翻译成模型能稳定执行的语言**。