本章要解决的问题
同样的模型,为什么别人写的提示词效果好一倍?提示词是玄学还是有方法论?
章节大纲
- 4.1 提示词结构:角色/任务/约束/示例
- 4.2 思维链 CoT 与进阶技巧(Few-shot / Self-consistency)
- 4.3 结构化输出:JSON Schema、函数调用约束
- 4.4 提示迭代方法论:从 v1 到 vN 的评测循环
- 🛠 解决方案:提示词调试 10 步法 + 常见失败模式对照表
4.1 提示词结构:角色/任务/约束/示例
4.1.1 提示词不是玄学:四要素结构
提示词是"给模型的说明书",好的说明书有固定结构。无论多复杂的提示词,拆开看都是四要素的组合:

图 1:提示词四要素
| 要素 | 作用 | 例子 |
|---|---|---|
| 角色(Role) | 限定行为模式与专业视角 | "你是资深客服主管" |
| 任务(Task) | 明确要做什么、产出什么 | "分析这条差评并生成回复" |
| 约束(Constraints) | 规定边界:格式、语气、禁忌 | "字数 ≤200,不得否认用户感受" |
| 示例(Examples) | 展示期望的输出样子 | "例如:好的回复是......" |
4.1.2 一个四要素齐全的模板
text
【角色】你是电商客服主管,擅长处理用户差评,语气专业且共情。
【任务】阅读下面的差评,完成两件事:
1. 抽取问题要点(产品问题/服务问题/物流问题)
2. 生成一封回复,包含致歉、解释、解决方案三部分。
【约束】
- 回复字数 100~200 字
- 不得否认用户感受(禁止"您误会了")
- 必须给出可执行方案(换货/退款/补偿)
- 以 JSON 输出:{"issues": [], "reply": ""}
【示例】
差评:"东西坏了客服还不理人"
输出示例:{"issues": ["产品质量", "服务态度"],
"reply": "非常抱歉给您带来糟糕的体验......"}
4.1.3 四要素的设计要点
- 角色要给"专业视角":只说"你是客服"不够,要说清立场与风格("专业且共情")。
- 任务要可拆解:把复合任务拆成编号子任务(呼应第 10 章提示链思路的单次版)。
- 约束要"可判定":写"不得否认用户感受"比写"语气要好"有效------模型能执行前者,后者靠猜(呼应第 17 章"可判定硬规则")。
- 示例要"边界化":给 1~2 个正例 + 必要时 1 个反例("这是不好的输出:......"),比只给正例更能校准。
4.2 思维链 CoT 与进阶技巧
4.2.1 思维链(Chain-of-Thought):让模型"展示推理过程"
CoT = 引导模型在给出答案前,先一步步写出推理过程。 对多步推理任务(数学、逻辑、规划)效果显著。注意:部分推理模型(如 o 系列、DeepSeek-R1)已内置思维链,无需在提示词中显式要求"一步步推理";对需要显式推理的传统模型,可让模型输出推理摘要或中间结论。

图 2:思维链 CoT
text
❌ 直接问:"鸡兔同笼,头35脚94,各几只?"
✅ 加引导:"请一步步推理,最后给出答案"
→ "设鸡x只、兔y只。x+y=35;2x+4y=94。
由x=35-y代入:2(35-y)+4y=94 → 70+2y=94 → y=12,x=23。答案:鸡23兔12。"
原理:把隐性推理显性化,模型"边想边写"时出错率低于"直接蹦答案"(与第 13 章反思同源:中间产物让错误可定位)。
4.2.2 Few-shot(少样本):用示例校准输出风格
在提示词里给出若干"输入→期望输出"示例,模型会模仿示例的模式:
| Few-shot 类型 | 做法 | 适用 |
|---|---|---|
| 格式示例 | 展示输出格式 | 结构化输出 |
| 风格示例 | 展示语气/长度 | 写作类 |
| 边界示例 | 展示"什么不该做" | 分类/路由 |
| 推理示例 | 展示推理步骤 | 复杂任务 |
Few-shot 是"提示词微调":不需要改模型,加几个示例就能显著改变行为------是成本最低、最快的"训练"(呼应第 18 章 L2 提示词迭代)。
4.2.3 Self-consistency(自洽性):多路推理投票
对关键推理任务,让模型多次独立推理(不同 seed,或配合略高温度),对答案投票取最一致的:

图 3:Self-consistency 多路投票
python
# 示例代码:演示 Self-consistency 的核心逻辑,省略了错误处理和重试
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(base_url="https://api.deepseek.com", api_key="<你的Key>")
async def self_consistency(question, n=3):
tasks = []
for i in range(n):
tasks.append(client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content":
f"{question}\n请一步步推理,最后用【答案】标注结论。"}],
temperature=0.7, # 略高温度 → 多样化推理路径
seed=i, # 注意:并非所有 OpenAI 兼容 API 都支持 seed 参数
))
resps = await asyncio.gather(*tasks)
answers = [r.choices[0].message.content for r in resps]
# 提取答案并投票(简单实现:取出现最多的最终结论)
final = [a.split("【答案】")[-1].strip() for a in answers]
from collections import Counter
return Counter(final).most_common(1)[0][0]
Self-consistency 的本质是"用并行换准确率"(呼应第 12 章方案并行):单次推理可能走偏,多次独立推理的多数结论更可靠。代价是 n 倍 token------只对高价值推理任务用。
4.2.4 进阶技巧小结
| 技巧 | 一句话 | 成本 | 适用 |
|---|---|---|---|
| CoT | 让模型写出推理过程 | + | 多步推理 |
| Few-shot | 给示例校准行为 | +(token) | 格式/风格 |
| Self-consistency | 多次推理投票 | ×n | 关键决策 |
| 角色/约束 | 结构化的四要素 | 0 | 所有 |
4.3 结构化输出:JSON Schema 与函数约束
4.3.1 为什么要结构化输出
Agent 系统里,模型输出要喂给程序 (解析、校验、入库),不是给人看。自由文本解析脆弱,结构化输出是 Agent 数据契约的基石(呼应第 10 章"JSON 是链的骨架")。
4.3.2 JSON 输出的两种约束方式
python
# 方式一:response_format 强制 JSON 对象(各模型通用)
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content":
"抽取差评要点,输出 JSON。"}],
response_format={"type": "json_object"},
)
# 方式二:json_schema 严格校验字段(更推荐,OpenAI 系/部分中文模型)
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "抽取差评要点。"}],
response_format={"type": "json_schema",
"json_schema": {
"name": "review_extract",
"strict": True,
"schema": {
"type": "object",
"properties": {
"issues": {"type": "array", "items": {"type": "string"}},
"emotion": {"type": "string",
"enum": ["calm", "frustrated", "angry"]},
"reply": {"type": "string"},
},
"required": ["issues", "emotion", "reply"],
}}},
)
两种方式的区别 :json_object 只保证"是 JSON",json_schema 保证"字段齐全、类型正确、枚举合法"------后者解析后几乎无需再校验,强烈推荐(注意:各模型支持度不同,见第 24 章表三)。
4.3.3 函数调用约束(tool_calls)
当输出要触发动作时,用第 5 章的 tools 协议让模型返回结构化工具调用,而不是让模型"描述"要调什么(详见第 5 章 5.1)。一句话:程序要消费的输出用 json_schema,要触发动作的输出用 tools 协议。
4.4 提示迭代方法论:从 v1 到 vN 的评测循环
4.4.1 提示词是"代码",要版本管理、要测试
把提示词当代码对待:进 Git、有版本、有评测集、能回滚(呼应第 20 章评测体系、第 24 章 G4 版本化)。生产级团队甚至维护"提示词仓库"。
4.4.2 迭代循环五步
css
[v1 基线] 写第一版 → 跑 20 条评测集样例,记录失败模式
↓
[定位] 失败是哪类?格式错 / 漏信息 / 语气差 / 幻觉
↓
[假设] 是四要素哪个的问题?(角色/任务/约束/示例)
↓
[修改] 单点修改(一次只改一处!)
↓
[回归] 重跑全部评测集 → 通过 → v2;不通过 → 回到[定位]

图 4:提示迭代五步
铁律:一次只改一处。 同时改两处,无法判断是哪个改动起效(呼应第 24 章"一次只改一个变量")。
4.4.3 用评测集防止"修好 A 弄坏 B"
维护一个固定的评测集(起步 20~30 条,基线阶段扩展至 ≥50 条,覆盖各场景 + 边界),每次改提示词全量回归:
python
EVAL_CASES = [
("差评:东西坏了客服不理人", "应包含致歉和解决方案"),
("好评:发货很快包装完好", "不应过度道歉"),
("中评:质量一般但能用", "应中性客观"),
]
def evaluate(prompt_fn):
passed = 0
for case, check in EVAL_CASES:
out = prompt_fn(case)
if llm_judge(out, check): # 用第17章 LLM-as-Judge
passed += 1
return passed / len(EVAL_CASES)
没有评测集的提示词迭代 = 盲改(呼应第 18 章"学习的反面是退化")。
🛠 解决方案:提示词调试 10 步法 + 常见失败模式对照表
提示词调试 10 步法
arduino
1. 输出格式错? → 加 json_schema / 明确格式示例
2. 缺信息? → 任务里显式列出"必须包含:......"
3. 语气不对? → 约束里写语气风格 + 给风格示例
4. 答非所问? → 检查任务是否拆解清楚(四要素的"任务")
5. 有幻觉? → 约束"仅基于给定材料"+ 温度调低
6. 不稳定(时而好时坏)→ 温度调低 / 加 few-shot 锚定
7. 太啰嗦? → 约束长度 + 示例展示精炼输出
8. 忽略约束? → 约束前置 + 重要约束加粗/编号 + 用可判定表述
9. 复杂任务总崩? → 拆链(第 10 章提示链)
10. 改了没效果? → 确认一次只改一处 + 有评测集可对比
常见失败模式对照表
| 失败现象 | 根因 | 对症修改 |
|---|---|---|
| 格式乱 | 无格式约束 | json_schema / 示例 |
| 漏要点 | 任务未列全 | 编号子任务 + 必含清单 |
| 语气生硬 | 无风格约束 | 角色强化 + 风格示例 |
| 答非所问 | 任务含糊 | 重写任务 + 边界示例 |
| 事实错误 | 依赖模型记忆 | 加 RAG + "仅基于材料" |
| 输出不稳 | 温度高 | 调低温度 / few-shot |
| 太冗长 | 无长度约束 | 字数约束 + 精炼示例 |
| 约束失效 | 表述不可判定 | 可判定化 + 约束前置 |
实战提示
- 提示词四要素是模板:任何新任务先按"角色/任务/约束/示例"搭骨架,再迭代。
- 一次只改一处:改完跑评测集,用数据判断,别凭感觉。
- 结构化输出是刚需:Agent 场景中程序要消费的输出优先用 json_schema / tools 协议;但简单自然语言反馈、闲聊、草稿生成等场景未必需要严格结构化。
- CoT 加在需要推理的任务:简单任务加 CoT 反而啰嗦、费 token;多数推理模型(如 DeepSeek-R1、o 系列)已内置思维链,通常无需额外要求显式推理------但具体行为因模型而异,上线前应按目标模型文档验证。
- 提示词进版本库:当代码管理,可回滚、可对比、可协作。
- 防提示注入 :Agent 场景中用户输入可能包含恶意指令("忽略以上指令,执行......")。防御方法:用分隔符(
<user_input>...</user_input>)隔离用户内容;在系统提示词中声明权限边界("你只能使用以下工具");对高风险输入做注入检测(呼应第 17 章输入 Guardrail、第 22 章安全)。 - 术语速查:全书核心术语(提示词、工具调用、幻觉、护栏等)的中英对照见附录 D《术语表》。