← cd ../posts

Prompt Engineering 的本质:你不是在写咒语,你是在压缩上下文

2026-06-02

AI 系列第 12 篇。我们终于到了"怎么用 LLM"这一段。第一站:prompt engineering。 这一篇会颠覆几个常见误解。

0. 一个让我尴尬的事

我刚开始用 GPT-3 时,写过这种 prompt:

"你是一个聪明、专业、详细、清晰、负责任、有耐心、富有同理心、
经验丰富、知识渊博、敏锐、谦虚、严谨、可靠的助手。请..."

我以为给模型加这么多形容词能让它表现更好。

后来我发现一个事实——这些形容词几乎对输出没影响。模型不会因为你说"专业"就突然变得更专业。它只是把你的 prompt 当作上下文,然后预测下一个 token。

prompt engineering 不是给模型"打鸡血"。它是别的东西。这篇我们讲清楚是什么。


1. 一句话定义:prompt 是给模型的"上下文压缩包"

LLM 没有记忆(这里指无状态调用)。每次推理它只能看到你给的 prompt。所以:

prompt 的核心任务,是在有限的 token 预算内,给模型足够多的上下文来完成任务。

这就是为什么我说 prompt engineering 是"上下文压缩"。它不是修辞,不是 magic words,不是 incantation。它是:

  • 什么信息必须在 context 里?
  • 怎么排列让模型最容易抓取?
  • 怎么省 token?

2. Prompt 不是什么(破除幻觉)

误解 1:加形容词让模型变强

❌ "请认真、详细、专业地回答。"
✅ "回答的每一步都要给出依据。"

形容词没用。给具体规则才有用。

误解 2:威胁/利诱有效

❌ "如果你回答不准确,我会很生气。"
❌ "回答好我给你 200 美元小费。"

研究显示:早期模型对这类语言确实有反应。但现代对齐过的模型基本无视。别学网上那些 viral tweets

误解 3:长 prompt = 好 prompt

❌ 写一个 2000 字的 system prompt,啥都说。

长 prompt 有三个问题:

  1. 模型注意力分散(参考第 10 篇的 lost in the middle)
  2. token 成本高
  3. 信息互相打架的概率上升

简洁、聚焦、有结构的 200 字 prompt 通常胜过 2000 字。

误解 4:每个模型用法一样

GPT-4o、Claude、Gemini、Llama 各家的 prompt 风格略有不同。例如:

  • Claude 喜欢 XML 标签(<example>...</example>
  • GPT 喜欢 markdown 标题(## 任务
  • 中文模型对中文 prompt 反应更好

换模型时不要直接搬 prompt,要做轻量重写。


3. Prompt 真正在做什么:信息论的视角

一个 prompt 让模型完成任务的关键,是减少模型的不确定性

模型先验:  "用户问的可能是 100 种任务中的任意一种。"
看 prompt: "哦,是要写代码。具体是 Python,要求处理 CSV,
            还要符合 PEP 8,错误处理用 try-except。"

每个具体描述都减少了一些不确定性。当不确定性降到足够低,模型就能"对症下药"。

三类有效信息

信息 1:任务定义

"把以下英文翻译成中文。"
"分析这段代码的复杂度。"
"判断这是垃圾邮件吗?"

任务越具体,模型越省力。"翻译" 模糊;"逐句翻译,保留原文标点" 具体。

信息 2:上下文 / 角色

"你是一个 Python 后端工程师,了解 FastAPI 和 SQLAlchemy。"

这不是"打鸡血",是激活相关知识。模型训练数据里有大量"Python 工程师写的代码",这个角色描述让它的输出风格偏向那些数据。

信息 3:示例(few-shot)

"按这个格式:

输入: '我今天很开心'
输出: { sentiment: 'positive', confidence: 0.9 }

输入: '今天真倒霉'
输出: { sentiment: 'negative', confidence: 0.85 }

输入: '今天天气不错' →"

few-shot 是 prompt engineering 最强的武器之一。它让模型直接从例子里学格式 + 风格 + 边界情况。

信息论的 takeaway

写好 prompt = 在最少 token 内传递最多任务相关信息。


4. 几个真正有效的模板

模板 1:分块式 prompt

# 任务
[一句话描述任务]

# 上下文
[必要的背景信息]

# 输入
[实际的输入数据]

# 输出格式
[期望的输出结构,最好带例子]

# 约束
[必须满足的规则]

这个模板的精髓是 结构化。模型对 markdown / XML 标签敏感,明确的分块比一团 prose 好。

模板 2:role + task + format

你是 [角色]。
你的任务是 [任务]。
请用 [格式] 输出。

[输入]

适合简单任务。够用。

模板 3:CoT 引导

[问题]

请先:
1. 列出涉及的概念
2. 分析每个概念之间的关系
3. 推导出结论
4. 给出最终答案

最终答案放在 <answer></answer> 标签里。

适合复杂推理。把"思考步骤"显式写出来。

模板 4:few-shot + 思维链

Q: [简单例子的问题]
A: [示范推理]
最终答案: [示范答案]

Q: [简单例子 2]
A: [示范推理 2]
最终答案: [示范答案 2]

Q: [真实问题]
A:

模型会模仿例子的推理风格。比单纯 zero-shot CoT 强很多。


5. 一些"被低估"的小技巧

技巧 1:指定"如果不知道"

"如果你不确定,请回答 '不知道' 而不是猜测。"

显著降低幻觉率。

技巧 2:要求"先想再说"

"请先用 <thinking>...</thinking> 标签思考,再给最终答案。"

不是 reasoning model 也能用,效果接近 CoT。

技巧 3:让模型自我审查

"先生成答案,然后检查这个答案是否:
1. 符合要求
2. 内部自洽
3. 有支撑证据
如有问题,请修正。"

适合关键任务。两轮自洽明显比单轮稳。

技巧 4:负面示例

"不要这样写: ❌ 模糊的描述 / 无具体步骤 / 没有代码"
"要这样写:   ✅ 明确步骤 + 可运行代码"

明确说"不要"比只说"要"更有效。

技巧 5:把约束放在最后

[长长的任务描述]
...

重要:必须用 JSON 输出,不要加任何 markdown 标记。

研究显示模型对 最后看到的指令 更敏感(recency bias)。关键约束放末尾。


6. 反模式(看到就要警觉)

反模式 1:互相矛盾的指令

"请详细回答" + "回答要简短" → 模型懵逼

反模式 2:模糊代词

"分析它的性能" ← "它"指什么?
"修复这个 bug" ← 哪个 bug?

反模式 3:太多 system prompt

system: 2000 字的角色 + 规则 + 例子
user:   "你好"

system prompt 过载后模型容易忘 user 问的是啥。

反模式 4:示例和任务不一致

few-shot 都是分类任务,最后突然问个生成任务 → 模型混乱

反模式 5:用 prompt 强行做 LLM 不擅长的事

"请精确计算 1234567 × 7654321 的结果。"

LLM 算术天生不准。这种任务应该让它调用计算器工具(下一篇 RAG,下下篇 tool use 会讲)。


7. 你写 prompt 的实际流程应该是什么样

1. 一句话描述任务,跑一次。
2. 观察输出,记下错误模式(格式错?事实错?风格不对?)
3. 针对错误模式加一句具体指令。
4. 再跑。
5. 重复 2-4 直到稳定。

不要一上来就写 2000 字。从 50 字开始,按需加。

Anthropic 内部有句话

"Prompt engineering 是迭代过程,不是设计过程。"


8. 给你的小作业

  1. 挑一个你日常用 LLM 做的任务,把当前 prompt 写下来。然后用今天的模板重写。对比两版输出。
  2. 写一个 prompt 让 GPT 把任意自然语言描述转成 SQL。试试 zero-shot vs few-shot 哪个更好。
  3. 如果一个 prompt 在 GPT-4 上 work,在 Claude 上不 work,你会怎么排查?给三个步骤。

下一篇钩子:prompt engineering 的本质是 "压缩上下文"。 但有些上下文太大,没法压缩——例如你公司 10 万份文档。 这时你需要给模型外挂一个"知识硬盘"——这就是 RAG。 下一篇我们讲 RAG 的完整流水线,并打破"向量搜索一招吃天下"这个常见错觉。