第 5 章 Prompt Engineering——与大模型高效沟通

4 阅读10分钟

第 5 章 Prompt Engineering——与大模型高效沟通

"同样的模型,不同的 Prompt,效果可能天差地别。"

上一章我们学会了如何调用大模型 API。但调用只是开始,怎么写 Prompt 才能得到好结果,这才是关键技能。

Prompt Engineering(提示工程)不是玄学,而是一套可学习、可复用的方法论。本章我们将系统学习:

  • 基础技巧:Zero-shot、Few-shot、角色设定
  • 进阶技巧:思维链(CoT)、ReAct、自我反思
  • 结构化输出:让模型按你的格式返回
  • 工程化实践:Prompt 版本管理、A/B 测试

5.1 Prompt 是什么?为什么写法不同效果差异这么大?

5.1.1 Prompt 的本质

Prompt 是你发给大模型的指令和上下文。模型根据 Prompt 来理解你的意图,并生成相应的回复。

同样的任务,不同的 Prompt,结果可能完全不同:

不好的 Prompt

分析这段代码

好的 Prompt

你是一位资深的 Java 架构师,拥有 10 年代码审查经验。

请分析下面的代码,重点关注:
1. 潜在的性能问题
2. 线程安全隐患
3. 资源泄漏风险

对于每个发现的问题,请说明:
- 问题所在行号
- 具体问题描述
- 修复建议代码

代码:
[代码贴在这里]

后者给出的结果会详细得多、有用得多。

5.1.2 为什么 Prompt 这么重要

大模型没有真正的"理解"能力,它只是在根据概率预测最可能的下一个词。Prompt 的作用是给模型提供足够的上下文和约束,引导它生成你想要的内容。

对后端开发者的类比

Prompt 就像SQL 查询语句——

  • 写得好:精准命中索引,毫秒级返回结果
  • 写得差:全表扫描,几秒都出不来结果
  • 同样的数据库(模型),不同的查询(Prompt),性能天差地别

5.2 基础技巧:Zero-shot、Few-shot、角色扮演

5.2.1 Zero-shot(零样本)

直接描述任务,不给示例。适合简单、明确的任务。

将以下中文翻译成英文:
你好,世界

优点:简单直接,无需准备示例 缺点:复杂任务可能效果不佳

5.2.2 Few-shot(少样本)

给 1-5 个示例,让模型"照猫画虎"。

请将情感分类为正面、负面或中性。

示例 1:
文本:这家餐厅的食物太棒了!
情感:正面

示例 2:
文本:等了一个小时,服务态度很差
情感:负面

示例 3:
文本:今天天气晴朗
情感:中性

待分类:
文本:物流很快,但包装有点破损
情感:

模型会输出:负面(或 混合,取决于你的示例设计)

Few-shot 的关键

  • 示例要覆盖各种情况
  • 示例格式要统一
  • 示例质量要高(错误的示例会教坏模型)

5.2.3 角色扮演(Role-playing)

给模型设定一个角色,让它以该角色的视角和能力来回答。

你是一位经验丰富的 MySQL DBA,擅长数据库性能优化。

用户问:我的查询很慢,怎么优化?

请先询问必要的上下文信息(表结构、数据量、查询语句),
然后再给出优化建议。

角色设定的作用

  • 激活模型在特定领域的知识
  • 约束回答的风格和深度
  • 提高回答的专业性和一致性

📌 插图 5-1:基础 Prompt 技巧对比

Zero-shot(零样本):
用户 ──► "翻译:你好" ──► 模型 ──► "Hello"

Few-shot(少样本):
用户 ──► "示例1...示例2...示例3...待分类:..." ──► 模型 ──► 结果
        ↑
    提供示例,让模型学习模式

角色扮演:
用户 ──► "你是一位专家...用户问题:..." ──► 模型 ──► 专业回答
        ↑
    设定角色,激活领域知识

5.3 进阶技巧:思维链(CoT)、ReAct、自我反思

5.3.1 思维链(Chain-of-Thought, CoT)

对于需要推理的任务,让模型一步步思考,而不是直接给答案。

不用 CoT

问题:一个农场有鸡和兔,头共 35 个,脚共 94 只。鸡兔各几只?
答案:

模型可能直接猜一个答案,容易错。

使用 CoT

问题:一个农场有鸡和兔,头共 35 个,脚共 94 只。鸡兔各几只?

请一步步思考:
1. 设鸡有 x 只,兔有 y 只
2. 根据头的数量:x + y = 35
3. 根据脚的数量:2x + 4y = 94
4. ...

答案:

模型会展示推理过程,最终答案更准确。

自动 CoT:在 Prompt 末尾加一句"Let's think step by step",就能触发模型的推理模式。

5.3.2 ReAct(Reasoning + Acting)

ReAct 是 CoT 的扩展,把推理行动结合起来。模型不仅思考,还可以决定调用工具。

你是一位智能助手,可以使用以下工具:
- search(query): 搜索信息
- calculator(expression): 计算表达式

请按以下格式回答:
Thought: 你的思考过程
Action: 工具名称(参数)
Observation: 工具返回的结果
...(重复 Thought-Action-Observation 直到得出结论)
Thought: 最终结论
Answer: 最终答案

用户问题:2024年诺贝尔奖物理学奖得主是谁?他/她出生在哪个国家?

模型可能的执行过程:

Thought: 我需要搜索 2024 年诺贝尔物理学奖得主的信息
Action: search("2024 Nobel Prize Physics winner")
Observation: 2024年诺贝尔物理学奖授予约翰·霍普菲尔德和杰弗里·辛顿...
Thought: 现在我需要查询杰弗里·辛顿的出生地
Action: search("Geoffrey Hinton birthplace")
Observation: 杰弗里·辛顿出生于英国伦敦...
Thought: 我已经获得了所有需要的信息
Answer: 2024年诺贝尔物理学奖得主之一是杰弗里·辛顿,他出生于英国。

5.3.3 自我反思(Self-Reflection)

让模型检查自己的回答,发现并修正错误。

请回答以下问题,然后检查你的答案:

问题:Python 中列表和元组有什么区别?

回答:[模型生成初始回答]

检查:
1. 我的回答是否准确?
2. 是否有遗漏的重要区别?
3. 举例是否恰当?

修正后的回答:

自我反思能显著提高回答质量,特别适合事实性问题和代码审查。


5.4 System Prompt 的作用:给模型定角色、规则和输出格式

5.4.1 System Prompt 的最佳实践

System Prompt 是对话的全局设定,应该包含:

  1. 角色定义:你是谁,有什么专业背景
  2. 任务描述:你的主要职责是什么
  3. 约束条件:什么能做,什么不能做
  4. 输出格式:回复应该遵循什么格式
system_prompt = """你是一位专业的技术文档撰写助手。

【角色】
- 你拥有 10 年技术写作经验
- 擅长将复杂技术概念转化为易懂的中文文档

【任务】
- 根据提供的技术信息,撰写清晰的用户文档
- 确保文档结构完整,包含:概述、步骤、示例、注意事项

【约束】
- 使用中文撰写
- 避免使用过于专业的术语,必要时提供解释
- 不要编造信息,不确定的内容标注"[待确认]"

【输出格式】
## 概述
...

## 操作步骤
1. ...
2. ...

## 示例

...


## 注意事项
- ...
"""

5.4.2 System Prompt vs User Prompt 的分工

内容放在哪里原因
全局角色设定System影响整个对话
固定的格式要求System每次回复都要遵循
具体任务描述User每次任务不同
需要处理的数据User动态变化

5.5 结构化输出:让模型返回 JSON / Markdown / 固定模板

5.5.1 为什么要结构化输出

非结构化文本难以解析,结构化输出可以直接用于程序处理。

5.5.2 JSON 输出

system_prompt = """你是一个信息提取助手。

请从用户输入中提取以下信息,并以 JSON 格式返回:
{
    "name": "姓名",
    "date": "日期(YYYY-MM-DD格式)",
    "amount": "金额(数字)",
    "items": ["物品1", "物品2"]
}

只返回 JSON,不要其他内容。"""

user_prompt = "张三在 2024 年 3 月 15 日购买了笔记本电脑和鼠标,共花费 5999 元。"

5.5.3 Markdown 表格输出

请对比以下三种数据库,并以 Markdown 表格形式输出:

对比维度:性能、一致性、扩展性、适用场景

数据库:MySQL、PostgreSQL、MongoDB

5.5.4 固定模板输出

请按以下模板生成代码审查报告:

## 审查概览
- 审查文件:{文件名}
- 问题总数:{数量}
- 风险等级:{高/中/低}

## 详细问题
### 问题 1:[类型] - [严重程度]
- 位置:{行号}
- 描述:{问题描述}
- 建议:{修复建议}

## 总结建议
{总结}

5.6 Prompt 的版本管理与工程化实践

5.6.1 为什么需要版本管理

Prompt 也是代码,需要:

  • 版本控制(Git)
  • 变更记录
  • A/B 测试
  • 回滚机制

5.6.2 Prompt 管理方案

方案 1:代码中的常量

# prompts.py
class Prompts:
    CODE_REVIEW = """你是一位代码审查专家..."""
    TRANSLATION = """你是一位专业翻译..."""

方案 2:配置文件

# prompts.yaml
code_review:
  version: "1.2.0"
  system: "你是一位代码审查专家..."
  temperature: 0.2

translation:
  version: "2.0.0"
  system: "你是一位专业翻译..."
  temperature: 0.5

方案 3:数据库 + 管理后台

适合大型团队,支持:

  • 在线编辑 Prompt
  • 版本历史
  • 灰度发布
  • 效果监控

5.6.3 Prompt A/B 测试

import random

def get_prompt_version(experiment_id: str) -> str:
    """根据实验 ID 决定使用哪个版本的 Prompt"""
    if experiment_id in experiment_group_a:
        return "v1"  # 对照组
    else:
        return "v2"  # 实验组

# 记录结果用于分析
log_experiment_result(experiment_id, prompt_version, user_satisfaction_score)

5.7 常见 Prompt 反模式与避坑指南

5.7.1 常见错误

反模式示例问题修正
过于模糊"分析一下"模型不知道分析什么明确分析维度和输出格式
要求矛盾"详细但简洁"模型无所适从明确优先级或分步骤
示例错误给错误的 Few-shot 示例模型学到错误模式确保示例质量
过度约束限制太多导致无法回答模型放弃或胡编平衡约束和灵活性
忽略边界没处理"我不知道"的情况模型可能幻觉明确允许拒绝回答

5.7.2 Prompt 优化检查清单

  • 角色是否明确?
  • 任务描述是否清晰?
  • 输出格式是否定义?
  • 约束条件是否合理?
  • 是否提供了足够的上下文?
  • 是否处理了边界情况?
  • 示例是否覆盖各种场景?

本章小结

Prompt Engineering 是与大模型高效沟通的核心技能:

  1. 基础技巧:Zero-shot 简单直接,Few-shot 提供示例,角色扮演激活领域知识

  2. 进阶技巧:CoT 让模型一步步推理,ReAct 结合推理和行动,自我反思提高准确性

  3. System Prompt:定义全局角色、任务、约束、格式,是 Prompt 工程的基石

  4. 结构化输出:JSON/Markdown/模板,让模型输出可直接用于程序处理

  5. 工程化:Prompt 需要版本管理、A/B 测试、灰度发布,像管理代码一样管理 Prompt

  6. 避坑:避免模糊、矛盾、错误示例、过度约束,使用检查清单确保 Prompt 质量


思考题

  1. 你正在开发一个 SQL 生成助手,用户用自然语言描述查询需求。设计一个 Prompt,让模型生成正确、安全的 SQL。

  2. 假设你的客服机器人之前用简单的 Prompt,现在想升级到 Few-shot + CoT。如何设计实验来验证新 Prompt 的效果?

  3. 你的团队有 5 个不同的 Prompt,分别用于代码审查、文档生成、测试用例生成、Bug 分析、性能优化建议。设计一个 Prompt 管理方案,支持版本控制和 A/B 测试。


下一章预告:Prompt 写好了,但怎么管理对话历史?怎么处理长文本超出上下文窗口?第 6 章,上下文工程——让你的大模型应用能处理复杂的多轮对话和长文档。