提示词工程
前面 LLM 介绍 讲了 LLM 是什么 / 能做什么,LLM 工作原理 讲了它怎么"猜下一个词"。这一篇换一个角度:既然我们没法轻易改模型参数,那"怎么和模型说话"本身就成了一门工程学科——这就是提示词工程(Prompt Engineering)。本文围绕三件事展开:它是什么、它用在哪些场景、具体的提示词长什么样。怎么把一个烂提示词系统化地优化成一个好提示词那块内容较重,单独成篇放在 提示词优化,本文末尾只放一个跳转。
1. 什么是提示词工程
1.1 一句话本质
提示词工程 = 用结构化、可控的方式告诉 LLM "你想要什么 / 不想要什么 / 应该怎么输出",在不修改模型权重的前提下,最大化其输出质量。
它是 LLM 落地最便宜、性价比最高、最容易被低估的杠杆:不动模型一行,只动输入的一段文本,就能把输出从"胡说八道"拉升到"基本可用",甚至接近 SOTA。
1.2 为什么"和模型说话"也需要工程
直觉上,LLM 对自然语言很能聊,直接问就好了。但在真实业务里,会有大量"光问不行"的情况:
| 痛点 | 现象 |
|---|---|
| 回答不稳定 | 同一个问题,有时答得好,有时胡编,跑批跑出来的结果方差极大 |
| 格式不合规 | 让模型输出 JSON,它有时给你一段中文带反引号的 JSON 解释 |
| 越权 / 跑题 | 多轮对话几轮后开始答非所问,或者越过系统设定的角色 |
| 幻觉难控 | 编造不存在的 API、不存在的论文、不存在的判例 |
| 业务规则丢失 | "请按我们的合同模板起草",模型完全不理你给的 schema |
| 成本与延迟 | 不知道怎么"让它少说话",每次调用都把上下文撑到上限 |
| 难以评测 | 提示词改了/没改、哪个版本更好,没有量化指标只能凭感觉 |
提示词工程解决的就是上面这堆问题。它的核心目标是把"凭感觉调 prompt"变成"有方法、有评测、有迭代"。
1.3 它和"微调 / RAG / Agent"的关系
很常见的一个误解:把提示词工程当成"调 prompt 文案"。其实它是整个 LLM 应用迭代环路里最内层、变化最快、成本最低的旋钮。和它经常一起出现的三个上位概念的关系是:
| 手段 | 改的是什么 | 典型成本 | 适合时机 |
|---|---|---|---|
| 提示词工程 | 输入文本(只改输入不动模型) | 几乎为零 | 任何时候都该先做;大多数场景做这一步就够了 |
| RAG(检索增强) | 输入上下文(动态塞入外部知识) | 中(向量库 + 检索代码) | 需要基于私有/时效/事实性文档作答 |
| Agent / 工具调用 | 让模型能"动起来"(多轮规划 + 调用外部工具) | 中高(工程复杂度大) | 任务有"做事"动作而非单轮问答 |
| 微调(Fine-tune / LoRA) | 模型参数本身 | 较高(数据 + 训练 + 评测) | 同一类任务量大、对一致性/风格/延迟有严格要求 |
经验顺序:提示词工程 → RAG → Agent → 微调。越往右,成本越高、改动越大。能用提示词解决的,先不要上微调;提示词 + RAG 满足不了,再考虑 Agent / 微调。
1.4 几个常被混淆的概念
| 概念 | 是什么 | 和"提示词工程"的关系 |
|---|---|---|
| Prompt | 用户输入给模型的整段文本(问题 + 上下文 + 约束 + 示例) | 提示词工程的"工件" |
| Prompt Engineering | 设计、迭代、评测 Prompt 的方法学 | 本篇主题 |
| System Prompt / System Message | 放在对话最前面、用来定义角色、规则、输出格式的稳定指令 | 提示词工程的主战场之一 |
| Few-shot | 在 Prompt 中给出几个"输入→期望输出"的样例,让模型按样例回答 | 提示词工程里常用的"模板化"技术 |
| In-context Learning | 模型不改权重、只靠上下文"学会"新任务的能力 | Few-shot 之所以有效的理论基础 |
| Chain-of-Thought(思维链) | 在 Prompt 中显式要求模型"一步一步想" | 提升推理/复杂任务表现的常用技巧 |
| Temperature / Top-p | 推理时控制随机性的采样参数 | 提示词工程的"另一只手" |
2. 提示词工程的应用场景
提示词工程不是"任何场景都有效"——它的性价比在不同任务上有明显差异。下面按场景分组,大致从"几乎必用"到"锦上添花"排列。
2.1 高价值场景(几乎必用)
文本生成与改造
- 营销文案 / 邮件 / 公告 / 公告模板:对风格、长度、受众有强约束,适合用 few-shot 锁定文风。
- 翻译 + 术语一致性:把术语表作为硬约束塞进 Prompt,比让模型自己学准得多。
- 摘要 / 改写 / 润色 / 校对:用角色 + 风格 + 输出格式三件套稳定输出。
编程辅助
- 代码补全 / 单测生成 / 注释 / 重构:把"项目代码片段 + 风格约定 + 测试框架"作为上下文。
- SQL / 正则 / 配置生成:用 few-shot 锁定输出格式。
- Code Review / Bug 定位:让模型扮演"严厉的 reviewer",逐条给意见而不是"我觉得还可以"。
结构化抽取
- 从非结构化文本中抽 JSON:合同条款解析、简历字段抽取、表格 OCR 后转结构化数据。
- 分类 / 打标 / 情感分析:用 few-shot + 严格 schema,比微调小模型性价比高得多。
- 命名实体识别 / 关系抽取:把 schema 当作强约束。
RAG 与问答
- 基于私域文档的回答:问题改写(query rewriting)、文档分块的相关性排序、prompt 中的"上下文引用规范"。
- 多文档综合 / 对比:让模型"先列要点,再综合,最后给结论",降低幻觉。
2.2 中等价值场景(推荐但非必须)
角色扮演 / 客服 / 教学
- 一致的人设 + 边界设定:把"什么人 / 不会做什么 / 超出范围如何回应"塞进 System Prompt。
- Socratic 教学 / 引导式提问:用"不要直接给答案,先反问"明确锁定行为。
Agent 中的"提示词作为工具描述"
- Tool 描述 + 参数 schema:让模型知道"有什么工具 / 怎么调用 / 何时调用"。在 LangChain / OpenAI Function Calling / Anthropic Tools 这一类 Agent 框架里,提示词工程的核心战场就是"写好工具描述"。
多模态(Vision / Audio)
- 图像描述 / VQA / OCR:在 Prompt 里明确"按什么顺序描述 / 关注什么 / 忽略什么"。
- 图像生成(DALL·E / Midjourney / Stable Diffusion 的 negative prompt / 风格限定):本质同样是提示词工程。
2.3 低价值场景(提示词作用有限)
- 精确数值计算 / 大数四则运算:无论怎么调 prompt 都救不了,得调工具/代码。
- 强事实性 + 时效性:超过训练截止的事实,提示词只能"让它别瞎编",不可能变出真答案——需要检索/工具。
- 强领域专业决策(医学诊断、法律判决):提示词能稳定输出形态,但不能让模型变专业;需要微调/RAG/人工复核。
经验法则:涉及"形式 + 内容模板化"的任务,提示词工程的收益最大;涉及"事实正确性 + 时效 + 数值精度"的任务,提示词工程收效有限,得靠 RAG + 工具调用 + 后处理校验。
3. 提示词应用实例
下面给出一组真实可用的提示词样例,先看"烂提示词"再给出"工程化版本",目的是直观感受提示词工程的实际产出力度。
3.1 实例一:把自然语言变成结构化 JSON
烂提示词:
帮我抽取这段合同里的关键信息输出(典型情况): 一段看着像 JSON 但用反引号包起来、字段名飘忽、中英混杂、有时还"忘记"某些字段的文字。
工程化版本:
# 角色
你是一个"合同字段抽取器",从给定的合同片段中抽取结构化字段。
# 任务
从下方 <contract> 包裹的合同文本中,按 schema 抽取字段。
# Schema(必须严格遵守)
{
"parties": [ {"name": string, "role": "甲方"|"乙方", "id_no": string|null} ],
"effective_date": string|null, // ISO8601 日期,例 "2026-01-15"
"term_months": integer|null, // 合同期限(月)
"amount_rmb": number|null, // 合同金额(人民币元)
"termination_clause_present": boolean
}
# 规则
1. 找不到的字段返回 null,**不要编造**。
2. 字段值**只**从合同文本里取,不允许推断。
3. 输出格式:**纯 JSON,不带任何解释、不带 markdown 反引号、不带前后缀**。
4. 如果文本太短或不像合同,返回 {"error": "non_contract"}。
# Example(展示期望格式)
contract: "甲方张三(身份证 110101199001011234)与乙方北京某科技公司于 2026 年 1 月 15 日签订服务协议,期限 12 个月,金额 30 万元。"
output: {"parties":[{"name":"张三","role":"甲方","id_no":"110101199001011234"},{"name":"北京某科技公司","role":"乙方","id_no":null}],"effective_date":"2026-01-15","term_months":12,"amount_rmb":300000.0,"termination_clause_present":false}
# 待处理
<contract>
{{CONTRACT_TEXT}}
</contract>为什么有效:
- 明确了角色(避免模型自动"友善地"加旁白)。
- 给定了严格 schema + 字段类型,JSON 解析器能直接吃。
- 设了否定规则(不要编造、不要 markdown 包壳、不带解释)。
- 给了完整的 one-shot 样例,把"期望格式"演示到位。
- 把待处理文本用
<contract>包裹,和正文做了视觉隔离。
3.2 实例二:让模型"先想再答",降低推理错误
烂提示词:
一个房间里 3 只猫,又进来 2 只,然后 1 只出去。现在几只?输出(典型情况): 有时答 4(对),有时答 5(误把"又"当成"再加 1")。
工程化版本(Chain-of-Thought):
一个房间里 3 只猫,又进来 2 只,然后 1 只出去。现在几只?
要求:
1. 先逐步推理(列出每一步的输入与当前总数)。
2. 再给出最终答案,用一行 "Answer: <number>" 输出。为什么有效: 显式要求"先列步骤再给答案",让自回归生成有"算草纸"可以参考。CoT 对算术、逻辑推理、多步工具调用效果显著。
3.3 实例三:客服 / 角色扮演 + 边界控制
System Prompt 工程化版本:
# 角色
你是"灯塔商店"的客服助理"小塔",用简体中文回答顾客问题。
# 行为规则
1. 只回答与"订单、支付、物流、退换货、店内活动"相关的问题。
2. 对于范围外的问题,礼貌拒绝,模板:"抱歉,这个问题不在我的职责范围内,您可以联系人工客服: 400-xxx-xxxx"。
3. 任何情况下**不**编造订单号、价格、物流状态;若信息不足,反问用户。
4. 回答长度 ≤ 80 字,不输出 markdown 标题。
5. 不要主动推销;若用户问有没有折扣,如实说"目前没有针对此商品的折扣"。
# 工具
当用户问"我的订单在哪里"时,先调用工具 get_order_status(order_id);
当工具返回结果后,基于真实数据回答;**不**在工具未返回前编造状态。为什么有效:
- 角色设定 + 5 条显式规则(行为禁区)。
- 模板化的"拒绝话术",让模型风格稳定。
- 把"何时调哪个工具"作为提示词的一部分(Agent 化提示词)。
3.4 实例四:长文档问答 + 引文规范(适合 RAG)
烂提示词:
根据下面文档回答用户的问题。
{{DOCS}}
问题: ...输出(典型情况): 答案貌似有道理,但其实来自模型自己的"常识",文档证据没真正用上。
工程化版本:
# 任务
基于 <docs> 中的资料,回答用户 <question>。
# 严格要求
1. 答案的**每一句事实**都必须在 <docs> 中能直接找到对应原文。
2. 引用必须用 [N] 形式标注在句末,N 对应 <docs> 编号。
3. 如果 <docs> 中没有任何内容能回答 <question>,回答:"文档中没有相关信息。"
4. 不要使用 <docs> 之外的常识。
# 输出格式
(1 句直接回答)
[1]
(可选:补充 1-2 句背景)
[2]
# 输入
<docs>
{{RETRIEVED_DOCS}}
</docs>
<question>
{{USER_QUESTION}}
</question>为什么有效: 这是 RAG 应用的"标准答案模板"——强制让模型基于检索内容作答,并强制标注引用,大幅降低幻觉。
3.5 实例五:Few-shot 风格锁定
任务:把外网用户评论转成"客服回复"。
把下方评论改写成一句"客服回复"。
风格要求:
- 中文,30 字以内,礼貌、不啰嗦。
- 句末用"祝您购物愉快~"。
示例:
输入: "your shipment took forever, not happy"
输出: "非常抱歉给您带来困扰,我们会立即核实物流情况,祝您购物愉快~"
输入: "包裝破損了,內容物還好"
輸出: "您好,包裝破損是我們的疏忽,請聯繫客服安排補發,祝您購物愉快~"
待处理:
输入: "{{USER_COMMENT}}"
输出:为什么有效: 1-2 个高质量样例,胜过 200 字"风格说明"。Few-shot 是让 LLM 稳定风格/格式最直接的工具。
4. 提示词优化(已抽取到独立文章)
第 4 节原本覆盖了"最小优化闭环 + 评测集设计 + 12 条优化原则 + 8 项反模式",因为该部分内容较重且自成体系,已抽取到独立文章:
📘 提示词优化 —— 六组"烂 prompt vs 优化后 prompt"实战对比(含糊指令、否定式、缺 schema、缺 CoT、多任务、上下文无序) + 12 条优化原则 + 8 项反模式 + 日课实践。
读完本文后,建议把那篇作为"提示词优化的随身手册"长期对照迭代。如果你正在做一个真实的 LLM 应用,这篇独立文章是最容易复利的那一篇。
5. 进一步阅读
论文 / 资料
- Chain-of-Thought Prompting Elicits Reasoning in Large Language Models(Wei et al., 2022)——思维链的奠基工作。
- ReAct: Synergizing Reasoning and Acting in Language Models(Yao et al., 2022)——Reason + Act 在 Agent 上的结合。
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(Lewis et al., 2020)——RAG 经典论文。
- Constitutional AI: Harmlessness from AI Feedback(Bai et al., 2022)——Anthropic 提出的"基于原则的反馈"。
- The Prompt Report(Schulhoff et al., 2024)——对提示词技术做了系统性分类的综述。
官方指南(高质量)
- OpenAI Prompt Engineering Guide(官方文档)——覆盖六大策略与多类任务样例。
- Anthropic Claude Prompt Engineering Overview——很多 Anthropic 在生产中的工程化经验。
- Google Gemini Prompting Guide——多模态场景的提示词工程。
- LlamaIndex / LangChain 官方文档——RAG、Agent 的提示词最佳实践。
本仓库相关
- 提示词优化——本文第 4 节已抽取的独立文章,六组"烂 vs 好"对比 + 12 条原则 + 8 项反模式。
- LLM 介绍——提示词工程的"被作用对象"。
- LLM 工作原理——理解 next-token prediction,有助于理解"为什么这样的 prompt 能起效"。
- LLM 训练与对齐——提示词工程是"不改模型参数"这条路;对侧是微调。
- docker安装ollama并使用本地模型——把上面所有方法跑在本地。
一句话总结:提示词工程不是"调文案",而是 LLM 落地最便宜、最快、可量化迭代的那把工程化锤子——把模糊需求拆成可观测的失败模式,用结构化指令 + 样例 + 评测集把模型行为逼向业务目标,先做提示词工程,再考虑 RAG / Agent / 微调。
