Skip to content

Prompt 工程

本笔记介绍如何有效地编写 Prompt,以获得更好的 LLM 输出。从零开始,循序渐进地学习 Prompt 工程技术。


什么是 Prompt?

Prompt(提示词) 是你给大语言模型(LLM)的输入指令,告诉模型你想要什么。

┌─────────────────────────────────────────────────────┐
│                    Prompt 工作原理                   │
├─────────────────────────────────────────────────────┤
│                                                     │
│   用户 ──Prompt──→  LLM  ──输出──→  用户期望的结果  │
│                                                     │
│   Prompt 越好 → 输出质量越高                          │
│                                                     │
└─────────────────────────────────────────────────────┘

为什么 Prompt 很重要?

不好的 Prompt好的 Prompt
"帮我写代码""用 Python 写一个计算器,包含加减乘除功能"
结果模糊结果精准
需要多次修改一次到位

Prompt 基本结构

一个完整的 Prompt 通常包含以下部分:

┌────────────────────────────────────────────────────┐
│  System Prompt (系统指令)                          │
│  - 定义角色:你是谁                                 │
│  - 设置行为:如何回答                               │
│  - 指定格式:输出什么样子                           │
└────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────┐
│  User Prompt (用户输入)                            │
│  - 任务描述:做什么                                 │
│  - 具体问题:具体是什么                             │
│  - 上下文:有什么背景信息                           │
└────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────┐
│  Examples (示例) ← 可选                             │
│  - 展示输入→输出的对应关系                         │
│  - 帮助模型理解你的期望                             │
└────────────────────────────────────────────────────┘

代码示例

python
# 完整的 Prompt 结构
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        # System Prompt
        {"role": "system", "content": """
你是一位资深Python工程师。
回答时:
- 代码要有注释
- 遵循PEP 8规范
- 输出格式用代码块包裹
        """},
        # User Prompt
        {"role": "user", "content": """
写一个函数计算斐波那契数列第n项。

要求:
- 使用递归方式
- 包含类型注解
        """}
    ]
)

第一步:Zero-shot(零样本)

最简单的 Prompt 方式,直接提问,不需要任何示例

什么时候用?

  • 任务简单明确
  • 模型直接能理解
  • 不需要特定格式

示例

python
# 翻译
"将 'Hello' 翻译成中文"

# 总结
"用一句话总结:今天天气很好,适合出门散步"

# 分类
"判断以下内容是正面还是负面:这个产品很好用"

优点

  • 简单直接
  • 消耗 token 少
  • 响应速度快

缺点

  • 格式控制能力弱
  • 复杂任务效果有限

第二步:Few-shot(少样本)

通过提供少量示例来引导模型理解任务。

什么时候用?

  • 需要特定输出格式
  • 需要特定术语解释
  • 模型直接理解有困难

概念对比

方式说明示例数量
Zero-shot直接提问,无示例0 个
One-shot提供 1 个示例1 个
Few-shot提供 2-5 个示例2-5 个

基础示例

python
# 情感分析任务
prompt = """
请判断以下文本的情感类型(积极/消极/中立)。

示例:
输入:"今天天气真好,阳光明媚!"
情感:积极

输入:"这个产品太差了,完全不能用"
情感:消极

输入:"明天可能会下雨"
情感:中立

请分析:
输入:"刚看完这部电影,太精彩了!"
情感:"""

格式化输出

python
# 提取信息任务
prompt = """
请按以下格式提取信息:

示例:
输入:张三,男,1990年出生,软件工程师
输出:{"姓名": "张三", "性别": "男", "出生年": 1990, "职业": "工程师"}

请提取:
输入:李四,女,1985年生,医生
输出:"""

示例设计原则

┌─────────────────────────────────────────────────────────┐
│              设计好示例的 5 个要点                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  1. 数量:2-5 个足够,过多浪费 token                     │
│                                                         │
│  2. 多样性:覆盖不同情况                                  │
│     ✅ 好例子:正面、负面、中立各几个                      │
│     ❌ 坏例子:全是正面的例子                             │
│                                                         │
│  3. 格式一致:示例格式与期望格式相同                      │
│                                                         │
│  4. 标签平衡:正负样本比例适中                            │
│                                                         │
│  5. 相关性:示例与目标任务相似                            │
│                                                         │
└─────────────────────────────────────────────────────────┘

进阶:好示例 vs 坏示例

python
# ❌ 坏示例:过于相似,学不到东西
bad_examples = """
"很好用" → 正面
"很棒" → 正面
"不错" → 正面
"""

# ✅ 好示例:覆盖不同情况
good_examples = """
"这个APP功能很全面" → 正面
"性价比很高,推荐购买" → 正面
"经常闪退,体验很差" → 负面
"等了半小时还没收到货" → 负面
"界面设计不错,但收费太贵" → ?(混合情感)
"""

第三步:CoT(思维链)

Chain of Thought - 引导模型一步步思考,显著提升推理能力。

什么时候用?

  • 数学计算
  • 逻辑推理
  • 需要多步骤的问题

CoT vs 普通回答

┌─────────────────────────────────────────────────────────────┐
│                     普通推理 vs 思维链                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  普通推理:                                                   │
│  ┌─────────────────────────────────────────────────────┐  │
│  │ Q: 50 - 20 + 35 = ?                                 │  │
│  │ A: 65                                               │  │
│  └─────────────────────────────────────────────────────┘  │
│                                                             │
│  思维链 (CoT):                                              │
│  ┌─────────────────────────────────────────────────────┐  │
│  │ Q: 50 - 20 + 35 = ?                                 │  │
│  │ A: 第一步: 50 - 20 = 30                             │  │
│  │      第二步: 30 + 35 = 65                           │  │
│  │      最终答案: 65                                   │  │
│  └─────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Zero-shot CoT(最简单)

只需在问题后加一句话:

python
# 只需添加 "让我们一步步思考"
prompt = """
问题:小明有 15 个苹果,送给朋友 8 个,又买了 12 个,现在有多少个?

让我们一步步思考:
"""

# 或者英文版本
# "Let's think step by step."

Few-shot CoT(更稳定)

通过示例展示完整推理过程:

python
prompt = """
请按以下格式解答数学问题:

示例:
问题:书店有 45 本书,卖出 12 本,又进货 20 本,问现在有多少本?
解题:
  步骤1:原有 45 本
  步骤2:卖出后:45 - 12 = 33 本
  步骤3:进货后:33 + 20 = 53 本
答案:53 本

现在请解答:
问题:停车场有 100 辆车,开走 35 辆,又开来 28 辆,现在有多少辆?
解题:
"""

CoT 适用场景

场景效果原因
数学推理⭐⭐⭐⭐⭐需要多步计算
逻辑推理⭐⭐⭐⭐⭐复杂逻辑链条
代码调试⭐⭐⭐⭐追踪执行流程
常识问题⭐⭐⭐逐步验证假设
简单任务增加不必要复杂性

进阶技术

1. Self-Consistency(自一致性)

多次推理,投票选最佳答案,适用于高准确率要求的场景。

┌─────────────────────────────────────────────────────────────┐
│                   Self-Consistency 工作流程                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│     问题 ──→ 推理路径1 ──→ 答案A                            │
│      │                                                       │
│      ├──→ 推理路径2 ──→ 答案B                              │
│      │                                                       │
│      ├──→ 推理路径3 ──→ 答案A  ←── 投票                    │
│      │                                                       │
│      └──→ 推理路径4 ──→ 答案C                              │
│                                                             │
│              最终答案: A(出现最多)                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
def self_consistency(question: str, n_paths: int = 5) -> str:
    """自一致性:多次推理 + 投票"""
    answers = []

    for _ in range(n_paths):
        response = client.chat.completions.create(
            model="gpt-4",
            messages=[{"role": "user", "content": f"{question}\n\n请一步步思考。"}]
        )
        # 提取答案
        answer = extract_answer(response.choices[0].message.content)
        answers.append(answer)

    # 投票
    from collections import Counter
    return Counter(answers).most_common(1)[0][0]

何时使用:答案唯一、成本允许、准确率至关重要 何时不用:成本敏感、实时性要求高、答案开放


2. Tree of Thoughts(思维树)

探索多个推理分支,评估后选择最优路径。适用于开放式问题。

                    问题

            ┌─────────┼─────────┐
            ▼         ▼         ▼
         思路 A     思路 B     思路 C
           │         │         │
      ┌────┴────┐    │    ┌────┴────┐
      ▼         ▼    ▼    ▼         ▼
    A1 评估    A2 继续  B1 回溯   C1 继续
      │                    │         │
      ▼                    ▼         ▼
    最优   继续探索       放弃     继续探索
python
prompt = """
请用思维树的方式分析:如何在 3 个月内提升编程技能?

思维树结构:
第1层 - 主要路径:
  1. 理论学习
     - 看教程视频
     - 读技术书籍
  2. 实践项目
     - 做小项目
     - 参与开源
  3. 社区交流
     - 技术博客
     - 线下聚会

请选择一个分支深入分析,给出具体计划。
"""

何时使用:没有标准答案、需要探索多种可能、需要权衡取舍 何时不用:有明确正确答案、时间有限、需要快速决策


3. ReAct(推理+行动)

结合推理与工具使用,适用于需要外部信息的任务。

python
prompt = """
你是一个智能助手,能够使用工具解决问题。

任务:查一下今天北京的空气质量,并判断是否适合户外运动。

请按以下格式回答:
思考:我需要做什么
行动:调用什么工具
观察:工具返回什么结果
思考:根据结果得出什么结论
答案:最终回答
"""

何时使用:需要搜索、API调用、数据库查询、多轮信息收集 何时不用:纯推理任务、不需要外部信息


4. Prompt Chaining(提示链)

将复杂任务分解为多个步骤,串联执行。

     输入


    Step 1: 提取信息


    Step 2: 分类判断


    Step 3: 生成回复


     最终输出
python
def process_customer_message(user_input: str) -> str:
    """处理客户消息的提示链"""

    # Step 1: 提取关键信息
    info_prompt = f"从以下文本提取:实体、日期、问题类型\n{user_input}"
    info = call_llm(info_prompt)

    # Step 2: 分类
    class_prompt = f"判断以下属于哪类:投诉/咨询/建议\n{info}"
    category = call_llm(class_prompt)

    # Step 3: 生成回复
    reply_prompt = f"生成{category}类回复\n信息:{info}"
    return call_llm(reply_prompt)

何时使用:子任务相互依赖、每步需要上一步结果、需要验证中间结果 何时不用:任务简单独立、单次调用足够


实用技巧

1. 角色扮演

让模型扮演特定角色,获得更专业的回答:

python
system_prompt = """
你是一位[角色]。

角色设定:
- 身份:资深Python工程师,10年经验
- 风格:代码遵循PEP 8,详细注释
- 特点:善于用简单例子解释复杂概念

请用Python实现以下功能。
"""

2. 格式化输出

明确指定输出格式:

python
prompt = """
分析以下文本情绪,按JSON格式输出:

输入:这个产品真的很棒!

输出格式:
{
    "情绪": "positive/negative/neutral",
    "分数": 0.0-1.0,
    "理由": "简短解释"
}

请严格按格式输出,不要添加其他内容。
"""

3. 设置约束

明确限制输出:

python
prompt = """
写一个产品介绍。

约束:
1. 不超过 100 字
2. 不使用最高级词汇(最好、第一)
3. 必须包含价格信息
4. 语气客观专业

产品:无线蓝牙耳机
"""

4. 任务分解

复杂任务分解成简单步骤:

python
# ❌ 一次完成太复杂
bad = "分析这家公司并给出完整投资建议"

# ✅ 分步骤完成
good = """
请按以下步骤分析:
1. 介绍公司主营业务
2. 分析近三年财务数据
3. 对比行业竞争对手
4. 给出投资建议
"""

场景选择指南

快速决策表

任务类型推荐技术原因
简单问答、翻译Zero-shot直接明确
格式要求、特定术语Few-shot示例示范
数学计算、逻辑推理CoT分步思考
高准确率要求Self-Consistency多路径投票
创意方案、规划ToT探索分支
需要搜索、查询ReAct工具调用
多步骤复杂任务Prompt Chaining分解执行

组合使用

组合适用场景效果
Few-shot + CoT复杂格式+推理⭐⭐⭐⭐⭐
Few-shot + ReAct带搜索的信息提取⭐⭐⭐⭐⭐
CoT + Self-Consistency高要求推理⭐⭐⭐⭐⭐
ToT + Self-Consistency开放性问题最优解⭐⭐⭐⭐

技术对比总结

技术复杂度成本适用场景
Zero-shot简单任务
Few-shot⭐⭐需要格式/风格
CoT⭐⭐推理任务
Self-Consistency⭐⭐⭐高准确率
ToT⭐⭐⭐开放问题
ReAct⭐⭐⭐需要工具
Prompt Chaining⭐⭐⭐多步骤任务

学习路径建议

初学者路线:
1. 先掌握 Zero-shot → 最基础
2. 然后学会 Few-shot → 大部分场景够用
3. 再学习 CoT → 处理复杂推理
4. 最后了解进阶技术 → 按需使用

调试与优化

1. 迭代改进

python
def optimize_prompt(prompt: str, feedback: str) -> str:
    """根据反馈优化 Prompt"""
    return f"""
当前 Prompt:
{prompt}

用户反馈:
{feedback}

请分析问题并提出改进后的 Prompt。
"""

2. 版本管理

python
class PromptManager:
    """管理不同版本的 Prompt"""

    def __init__(self):
        self.versions = {}

    def save(self, name: str, prompt: str):
        self.versions[name] = prompt

    def compare(self, v1: str, v2: str):
        return self.versions.get(v1), self.versions.get(v2)

最佳实践清单

基础原则

  • [ ] 明确任务:知道要什么
  • [ ] 结构清晰:分段落、有层次
  • [ ] 提供上下文:让模型理解背景
  • [ ] 给出示例:减少歧义
  • [ ] 指定格式:JSON、Markdown 等
  • [ ] 设置约束:长度、风格限制
  • [ ] 测试迭代:不断优化

进阶技巧

  • [ ] 复杂推理 → 用 CoT 引导分步思考
  • [ ] 格式要求 → 用 Few-shot 提供示例
  • [ ] 高准确率 → 用 Self-Consistency 投票
  • [ ] 开放问题 → 用 ToT 探索分支
  • [ ] 多步骤任务 → 用 Prompt Chaining 分解

参考资源

资源链接
OpenAI Prompt Engineering官方指南
Anthropic Best Practices官方指南

掌握 Prompt 工程是构建 Agent 的基础。继续学习 5.MCP 了解如何让 Agent 使用工具。

基于 MIT 许可发布