在第 1 章我们反复强调,大语言模型的本质是“高级概率接龙”。你给它一串 Token,它根据统计规律续写下去。这意味着你输入的 Prompt(提示词)直接定义了模型的输出空间——给它什么上下文,就在引导它往哪个概率方向走。提示工程(Prompt Engineering)就是系统性地设计和优化这个输入,让模型稳定、准确地输出你需要的结果,而不只是“撞大运”。
比起 24.3–24.4 节将要讨论的 Agent 与 RAG,提示工程是最轻量、最快速、最省钱的大模型应用方式。它不要求你微调权重,不依赖外部工具,唯一的投入就是你的思考与调试时间。
一、先认清一个事实:提示工程不是“玄学”,是“可控引导”
新手常把 Prompt 写成日常聊天:“帮我写个方案”“分析一下这段话”“你懂我的意思吧”。这本质上是把理解负担完全转嫁给模型。在一句话里,模型需要自行判断任务类型、输出格式、语气风格、是否需要推理……任何一维的歧义,都会让概率分布发散,导致输出不稳定。
提示工程的核心,就是把隐式的意图拆解为显式的约束。就像 API 调用一样,你要明确告诉模型:
- 角色(你是谁):“你是一名资深后端架构师。”
- 任务(要做什么):“请用 Python 实现一个线程安全的单例模式。”
- 输入数据(给什么):提供需要处理的文本、表格或 JSON。
- 输出规范(怎么输出):“只输出代码,不要解释。”
- 风格/语气:“代码需包含类型注解和 docstring。”
- 边界条件:“如果输入为空,返回空列表。”
这些信息你也许能在聊天场景下“顺带说一嘴”,但在工程化落地时,必须显式、完整地写进 Prompt 模板,否则就别指望模型在多轮调用中保持行为一致。
二、五种核心方法与递进关系
方法 1:零样本提示(Zero-shot Prompting)
直接给任务描述,不给示例。适用于模型训练数据中已有充分覆盖的模式。
示例:
“将以下英文翻译成中文:The quick brown fox jumps over the lazy dog.”
适用:简单分类、翻译、摘要、关键词抽取等成熟任务。
不适用:需要特定输出结构、冷门领域术语、复杂推理的任务。零样本下模型容易自由发挥,格式往往不是你想要的。
方法 2:少样本提示(Few-shot Prompting)
在 Prompt 中给出 2~5 个输入-输出范例,让模型通过上下文学习(In-Context Learning)推断模式。这是应对“模型不知道该用哪种格式回答”时的首选方案。
示例:
“将英文语句转为(情感,置信度)格式:
输入:I love this product.
输出:(积极,0.98)
输入:It's okay, not great.
输出:(中性,0.65)
输入:Totally broken and useless.
输出:(”
关键实践:
- 示例质量影响远大于示例数量,3 个高质量、覆盖边界情况的范例通常优于 10 个平庸范例;
- 范例顺序也很重要,把最典型的放在前面,可尝试把简单范例放在前面把复杂范例放在后面;
- 少样本的 Token 消耗会随示例数量线性增长,需要在效果与成本间权衡。
方法 3:思维链提示(Chain-of-Thought, CoT)
让模型“边思考边生成”,即显式输出中间推理步骤。这在数学题、逻辑谜题、多步决策任务上几乎是必选项,因为自回归模型把推理过程写出来,相当于为自己提供了正确的“上下文轨道”。
示例:
“问题:小明有 5 个苹果,给了小红 2 个后,又买了 3 个,现在有几个?
让我们一步步思考:
起初有 5 个。
给小红 2 个,剩下 5 - 2 = 3 个。
又买了 3 个,变成 3 + 3 = 6 个。
答案:6。”
零样本 CoT:只需在 Prompt 末尾加一句“Let's think step by step”,无需提供推理示例。少样本 CoT 则需给出带推理步骤的范例。
陷阱:有时模型在推理过程中会“强行制造合理的因果”,产生看似连贯但逻辑错误的中继结论。对于安全关键任务,CoT 应视为辅助,需人工校验。
方法 4:角色扮演与系统级指令
通过 System Prompt 或角色设定,约束模型的回答风格、知识范围和“人设”。这在对话类应用中至关重要。
系统 Prompt 示例:
“你是一名资深 Python 导师,只回答编程相关问题。如果用户询问无关话题,礼貌拒绝。回答时用中文,代码块标注语言。”
技巧:角色扮演是一种“软约束”,不是强制性的。如果用户刻意对抗,模型仍可能突破。生产环境需要配合安全层的输入输出过滤。
方法 5:结构化输出控制
要求模型按 JSON、XML、Markdown 表格等特定格式输出,这在构建 API 或自动化 Pipeline 时是刚需。闭源模型大多支持“JSON Mode”或“Function Calling”来约束输出,但对于不原生支持格式约束的模型,需要在 Prompt 中给出明确的 Schema。
示例:
“请以 JSON 格式输出,字段包括:
- name: str,人物姓名;
- age: int,年龄;
- email: str,邮箱。
只输出 JSON,不要任何额外文本。”
当使用开源模型时,可以在提示词末尾加上“@@SNAPSHOT_BLOCK_0@@
system_prompt = "你是一位{role},擅长{skills}。"
user_prompt = "请根据以下{context},回答用户问题:{query}。输出格式:{format_desc}"
```
迭代四个步骤:
- 设计初稿:依据本节原则写出模板;
- 小批量测试:用 20~50 条真实样本跑一遍,记录输出与预期不符的 case;
- 分析失败模式:是格式错误、回答过长、答非所问还是幻觉?针对性地调整指令、增加 Few-shot 或细化约束;
- 回归验证:确保修改后不会破坏原来能通过的样本,直至达到目标成功率。
黄金准则:当你发现自己在 Prompt 里塞了超过 1000 Token 的逻辑,应该考虑用微调、Agent 或多步流水线来替代。Prompt 过长不仅成本高、推理慢,还会因为模型注意力分散而效果恶化。
四、真实世界的最佳实践清单
| 实践 | 说明 |
|------|------|
| 给模型“出气口” | 对于不确定的信息,允许模型回答“不知道”或“信息不足”,避免强迫它编造 |
| 避免否定句式 | “不要回答政治敏感内容”往往不如“只回答技术问题”效果好,正向指令对概率引导更强 |
| 拆解复杂任务 | 把“分析客户评价并生成改进报告”拆成两步:先做情感-维度分析,再基于分析结果生成报告 |
| 使用分隔符 | 用 ### 输入开始 ### ... ### 输入结束 ### 明确划分指令与数据,防止注入 |
| 控制长度 | 明确指出“用不超过 200 字回答”或“列出 3 个要点”,否则模型可能输出冗长但重点分散的内容 |
| 关注 Token 边界 | 你的 Prompt 中那些拼写错误、emojis、特殊符号可能被 Tokenizer 切成意外的 Token,影响效果 |
| 版本管理 | Prompt 是代码的一部分,纳入 Git 管理,记录修改原因和评测指标,不是聊天记录里的随意备注 |
五、常见陷阱与排错指南
陷阱 1:“贪心写Prompt”导致注意力稀释
当 Prompt 长达几千字,包含大量背景、指令、示例时,低质量的模型(尤其 7B 以下)会“遗忘”前面指令,输出行为退化。排错方式:先测试精简版本,如果效果反而提升,说明原 Prompt 信息过载。可考虑把冗长背景整理成外部知识,通过 RAG 注入。
陷阱 2:过度依赖单个 Prompt 解决多步骤逻辑
让模型一次性完成“阅读长文档 → 提取关键实体 → 推理关系 → 生成 JSON”这种 4 步串行任务,中间任何一步出错都会污染后续。最佳实践是用分步流水线,每步单独 Prompt 甚至单独模型。
陷阱 3:忽视模型差异
同样一段精心设计的 Few-shot Prompt,在 GPT-4 上完美工作,拿到 Llama 3 8B 上可能完全失效。不同模型的指令遵循能力、对格式要求的敏感度、对 Few-shot 的利用效率均不同。跨模型部署时,必须针对每个目标模型做适配测试。
陷阱 4:用 Prompt 硬补模型知识短板
试图在 Prompt 里塞入一整本产品手册来代替 RAG,不仅消耗大量 Token,还容易因为上下文长度限制丢失关键信息。记住 1.1 节的话:LLM 没有硬盘,把事实性知识硬记在 Prompt 里远不如外挂检索来得可靠。
六、小结
提示工程不是“猜咒语”,而是通过对模型的概率机制施加结构化约束,来获得稳定、可行的输出。核心方法论就六个字:角色 + 任务 + 格式。
从零样本到思维链,再到模板化与流水线,每一步都在增加你对输出质量的控制力。当你开始把 Prompt 当作代码的一部分来严谨设计、测试、评审时,你就从“跟 AI 聊天的人”变成了“用 AI 构建系统的工程师”。
24.2 节,我们将进入 RAG(检索增强生成),用外部知识彻底解决大模型“知识静态且会胡说”的问题。那是提示工程一次质的升级:不只是让模型听懂你的话,而是让它能查阅现实世界的最新资料。