写 Prompt 这件事,很容易让人觉得是”试出来的”。但做了足够多的项目之后,你会发现好的 Prompt 和好的代码一样,有可复用的结构模式,也有几种看似合理但实际上效果很差的反模式。
模式一:角色 + 约束 + 示例
这是最基础也最实用的模式。核心结构是:
- 告诉模型它是谁(角色)
- 告诉模型什么该做、什么不该做(约束)
- 给一到两个期望输出的例子(Few-shot)
很多人只写了第一步就觉得”够了”。但角色只设了方向,没有边界。真正让输出稳定的是约束和示例。
一个典型的例子:
你是一位资深的技术文档工程师。
- 使用中文回答
- 段落之间用空行分隔
- 不要使用表情符号
- 不要给出主观评价
- 参考以下示例格式:
[示例输入]:解释 WebSocket
[示例输出]:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议……
约束越具体,输出越可控。
模式二:思维链(Chain of Thought)
当任务涉及推理——比如数学题、逻辑判断、多步决策——直接让模型给答案往往不可靠。但如果你在 Prompt 里加一句”请一步一步思考”,模型的准确率会显著提升。
原理并不神秘:思维链本质上是让模型把中间推理步骤显式地写出来,而不是在”脑子里”一步到位。每一步的输出成为下一步的输入上下文,相当于给模型增加了”工作记忆”。
更进一步,你可以自己设计推理步骤的模板:
请按以下步骤分析:
1. 识别问题的核心变量
2. 列出已知条件
3. 推导中间结论
4. 给出最终答案
结构化的思维链比”请一步一步思考”更稳定,因为你定义了推理的框架,模型只需要填充内容。
模式三:输出格式锁定
当你需要模型返回结构化数据——比如 JSON、Markdown 表格、特定格式的列表——最有效的做法不是”请用 JSON 格式返回”,而是直接给出 JSON Schema 或示例结构。
请以下面的 JSON 格式返回结果:
{
"summary": "一句话摘要",
"key_points": ["要点1", "要点2"],
"confidence": 0.85
}
同时在约束里加一条:“不要在 JSON 之外输出任何内容。”
为什么?因为模型有时候会在 JSON 前后加上解释性文字,导致你的 JSON parser 直接报错。这一个约束可以省掉很多下游处理的麻烦。
模式四:分而治之
复杂任务不要试图用一个 Prompt 搞定。把它拆成多个步骤,每一步用一个专注的 Prompt,前一步的输出作为后一步的输入。
比如”把一篇英文论文翻译成中文技术博客”这个任务,如果直接丢一个 Prompt,质量通常很差。但拆成三步就好得多:
- 第一步:提取论文的核心观点、方法、结论
- 第二步:把提取的内容翻译成中文,保留专业术语
- 第三步:按技术博客的风格重新组织结构,加引导段和总结段
每一步的 Prompt 都很简单,但组合起来的效果远超单个复杂 Prompt。
反模式一:过度客气
“请你尽可能好地帮我……如果可以的话……” 这类客气话不仅浪费 token,还会让模型的输出变得犹豫和冗余。模型不需要礼貌,它需要清晰的指令。
直接说”翻译以下文本为中文”比”能否请你帮我把这段文字翻译成中文呢”效果更好。
反模式二:负面指令堆叠
“不要太长、不要太短、不要太正式、不要太随意、不要使用复杂词汇、不要太简单……”
大量的”不要”会让模型的行为空间变得非常模糊。它不知道你到底想要什么。更好的做法是用正面描述定义你想要的风格:
语气:像朋友聊天一样自然
长度:200-300 字
词汇:日常用语,必要时保留英文术语
告诉模型”要什么”永远比告诉它”不要什么”更有效。
反模式三:上下文过载
把整个文档库、所有历史对话、全部背景资料一股脑塞进上下文,然后期望模型自己找到重要的部分。
模型的注意力并不是均匀分布在所有 token 上的。上下文越长,模型对中间部分内容的关注度越低(这就是”Lost in the Middle”问题)。
更好的做法:只给模型当前任务需要的最少上下文。如果不确定哪些是必要的,用检索(RAG)来动态选取,而不是全量输入。
最后
Prompt Engineering 不是一次性的工作。它更像是一个持续迭代的过程:写 Prompt → 观察输出 → 分析失败 case → 调整约束和示例 → 再观察。
好的 Prompt 是”调出来的”,但前提是你知道往哪个方向调。掌握这些模式和反模式,至少能让你少走一半弯路。