3.2 高级 Prompt 技术
掌握基础原则后,用高级技术解决复杂推理任务:思维链、思维树、自洽性、结构化模板与 A/B 测试。
学习时长:2-3 周
学习时长:3-4 周
掌握高级 Prompt 技术可以解锁 LLM 的复杂推理能力,实现从简单问答到多步骤规划的质的飞跃。
3.2.1 Few-shot vs Zero-shot Learning
核心概念:
- Zero-shot:不提供任何示例,直接让模型完成任务
- Few-shot:提供 1-5 个示例,引导模型学习模式
- Many-shot:提供数十到上百个示例(超长上下文模型)
效果对比:
| 方法 | Token 消耗 | 准确率 | 适用场景 |
|---|---|---|---|
| Zero-shot | 低 | 60-70% | 通用任务,模型已有能力 |
| Few-shot (1-3 例) | 中 | 75-85% | 格式化输出,特定领域 |
| Few-shot (5-10 例) | 高 | 85-95% | 复杂推理,边界情况多 |
| 微调 | - | 95%+ | 垂直领域,批量任务 |
示例 1:情感分析任务
❌ Zero-shot(效果一般):
python
prompt = """
判断以下评论的情感:正面/负面/中性
评论:"这个产品还可以吧,没有想象中好。"
情感:
"""
# 输出可能不稳定:有时是"中性",有时是"负面"✅ Few-shot(效果优秀):
python
prompt = """
判断以下评论的情感:正面/负面/中性
示例 1:
评论:"非常满意,质量超出预期!"
情感:正面
示例 2:
评论:"垃圾产品,用了一天就坏了。"
情感:负面
示例 3:
评论:"还行吧,价格便宜但功能一般。"
情感:中性
现在判断:
评论:"这个产品还可以吧,没有想象中好。"
情感:
"""
# 输出稳定:中性示例 2:复杂数据提取(Few-shot 威力)
python
from openai import OpenAI
client = OpenAI(api_key="your-api-key")
# Few-shot 示例
few_shot_examples = """
示例 1:
文本:"小明在2023年5月12日购买了一台iPhone 14 Pro,花费8999元。"
JSON:{"buyer": "小明", "date": "2023-05-12", "product": "iPhone 14 Pro", "price": 8999}
示例 2:
文本:"去年双十一,李华买了个戴森吹风机,打折后2300块。"
JSON:{"buyer": "李华", "date": "2022-11-11", "product": "戴森吹风机", "price": 2300}
示例 3:
文本:"王芳昨天订了一套化妆品,总共1580。"
JSON:{"buyer": "王芳", "date": null, "product": "化妆品", "price": 1580}
"""
user_text = "张伟上周三在京东买了一个小米电视,4500元包邮。"
prompt = f"""
从文本中提取购买信息,输出 JSON 格式。如果信息不存在则填 null。
{few_shot_examples}
现在提取:
文本:"{user_text}"
JSON:
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
import json
result = json.loads(response.choices[0].message.content)
print(result)
# 输出:{"buyer": "张伟", "date": null, "product": "小米电视", "price": 4500}Few-shot 最佳实践:
- ✅ 示例质量 > 数量:3个高质量示例 > 10个低质量示例
- ✅ 覆盖边界情况:包含正常、异常、空值等情况
- ✅ 格式严格统一:所有示例保持完全相同的格式
- ✅ 动态示例选择:根据输入相似度选择最相关的示例(Semantic Few-shot)
3.2.2 Chain-of-Thought (CoT) 思维链
CoT 让模型"展示推理过程",显著提升复杂推理任务的准确率(Google 2022 年论文发现提升超 50%)。
核心原理: 在 Prompt 中加入"让我们一步步思考"(Let's think step by step),引导模型输出中间推理步骤。
示例 1:数学应用题
❌ 直接提问(容易出错):
python
prompt = "一个苹果5元,买3个打9折,再用20元优惠券,最后付多少钱?"
# 模型可能直接输出错误答案:-6.5元(计算错误)✅ CoT 提示(准确率提升):
python
prompt = """
一个苹果5元,买3个打9折,再用20元优惠券,最后付多少钱?
让我们一步步计算:
1. 原价:
2. 打折后:
3. 使用优惠券:
4. 最终金额:
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
print(response.choices[0].message.content)输出示例:
让我们一步步计算:
1. 原价:3个苹果 × 5元 = 15元
2. 打折后:15元 × 0.9 = 13.5元
3. 使用优惠券:13.5元 - 20元 = -6.5元
4. 最终金额:0元(优惠券超过商品价格,实际支付0元)
答案:0元示例 2:Few-shot CoT(零样本 → 少样本)
python
prompt = """
判断以下逻辑推理是否正确,给出推理过程。
示例 1:
问题:所有程序员都会写代码,小明是程序员,所以小明会写代码。正确吗?
推理过程:
- 前提1:所有程序员都会写代码(全称命题)
- 前提2:小明是程序员(特称事实)
- 结论:小明会写代码(演绎推理)
- 判断:✅ 正确(三段论,逻辑有效)
示例 2:
问题:有些猫是黑色的,小花是黑色的,所以小花是猫。正确吗?
推理过程:
- 前提1:有些猫是黑色的(存在命题)
- 前提2:小花是黑色的(特称事实)
- 结论:小花是猫(不当归纳)
- 判断:❌ 错误(逆向推理谬误,黑色物体不一定是猫)
现在判断:
问题:所有鸟都会飞,企鹅是鸟,所以企鹅会飞。正确吗?
推理过程:
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
print(response.choices[0].message.content)输出示例:
推理过程:
- 前提1:所有鸟都会飞(全称命题,但这是一个错误前提)
- 前提2:企鹅是鸟(事实正确)
- 结论:企鹅会飞(演绎推理)
- 判断:❌ 错误(虽然逻辑形式有效,但前提错误——企鹅是不会飞的鸟)
这是一个"前提错误"导致的谬误,并非逻辑推理过程的问题。CoT 变体技术:
| 技术 | 说明 | 适用场景 |
|---|---|---|
| Zero-shot CoT | 只加"Let's think step by step" | 通用推理任务 |
| Few-shot CoT | 提供带推理过程的示例 | 复杂逻辑、领域知识 |
| Least-to-Most | 从简单子问题逐步推导 | 多步骤问题分解 |
| Self-Ask | 模型自己提出子问题并回答 | 需要背景知识的推理 |
3.2.3 Self-Consistency(自洽性)
通过多次采样不同推理路径,投票选出最一致的答案,提升可靠性。
核心步骤:
- 用 CoT 生成多个答案(temperature > 0.7)
- 提取每个答案的最终结果
- 投票选出出现频率最高的答案
代码实现:
python
from collections import Counter
def self_consistency(prompt, model="gpt-4o", num_samples=5):
"""
使用 Self-Consistency 提升推理准确性
"""
answers = []
# 1. 生成多个推理路径
for i in range(num_samples):
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=0.8, # 增加多样性
max_tokens=500
)
full_answer = response.choices[0].message.content
# 2. 提取最终答案(假设在最后一行)
final_answer = full_answer.strip().split('\n')[-1]
answers.append(final_answer)
print(f"路径 {i+1}:{final_answer}")
# 3. 投票选出最常见答案
vote_result = Counter(answers)
best_answer = vote_result.most_common(1)[0]
print(f"\n投票结果:{dict(vote_result)}")
print(f"最终答案:{best_answer[0]} (出现 {best_answer[1]} 次)")
return best_answer[0]
# 测试
prompt = """
一个水池有两个进水管和一个出水管。
- 甲管单独注满需要 6 小时
- 乙管单独注满需要 8 小时
- 丙管单独排空需要 12 小时
如果三管同时打开,需要多少小时注满水池?
请一步步计算,最后一行只输出最终答案(格式:"答案:X小时")
"""
result = self_consistency(prompt, num_samples=5)输出示例:
路径 1:答案:4.8小时
路径 2:答案:4.8小时
路径 3:答案:4.8小时
路径 4:答案:5小时
路径 5:答案:4.8小时
投票结果:{'答案:4.8小时': 4, '答案:5小时': 1}
最终答案:答案:4.8小时 (出现 4 次)适用场景:
- ✅ 数学推理、逻辑题
- ✅ 医疗诊断、法律分析(高风险场景)
- ✅ 代码生成(选择最常见的实现方式)
- ❌ 创意写作、翻译(不需要一致性)
3.2.4 Tree of Thoughts (ToT) 树状思维
ToT 将推理过程建模为搜索树,在每个节点评估"思考质量",选择最优路径继续探索。
架构对比:
Chain-of-Thought: 思考1 → 思考2 → 思考3 → 答案
(线性单路径)
Tree of Thoughts: 思考1A ──→ 思考2A ──→ 答案A ✓
↗ ↘
问题 思考2B ──→ 答案B ✗
↘ ↗
思考1B ──→ 思考2C ──→ 答案C ✓
(树状多路径,评估后剪枝)简化实现(Python + OpenAI):
python
def evaluate_thought(thought, problem):
"""评估某个思考步骤的质量(1-10分)"""
prompt = f"""
问题:{problem}
当前思考步骤:{thought}
评估这个思考步骤是否有助于解决问题,打分 1-10(10分最优)。
只输出数字分数。
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0,
max_tokens=10
)
return int(response.choices[0].message.content.strip())
def tree_of_thoughts(problem, depth=2, branches=3):
"""
Tree of Thoughts 简化实现
Args:
problem: 要解决的问题
depth: 搜索深度(思考层级)
branches: 每层生成的分支数
"""
print(f"问题:{problem}\n")
# 第一层:生成多个初始思考
thoughts = []
for i in range(branches):
prompt = f"{problem}\n\n生成一个可能的解题思路(第{i+1}种方案):"
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.8,
max_tokens=200
)
thought = response.choices[0].message.content
score = evaluate_thought(thought, problem)
thoughts.append({"content": thought, "score": score})
print(f"思路 {i+1}(评分 {score}):{thought[:100]}...")
# 选择得分最高的思路
best_thought = max(thoughts, key=lambda x: x["score"])
print(f"\n✅ 选择最优思路(评分 {best_thought['score']}):")
print(best_thought["content"])
# 基于最优思路生成最终答案
final_prompt = f"""
问题:{problem}
选定的解题思路:
{best_thought["content"]}
基于此思路,给出完整的解决方案:
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": final_prompt}],
temperature=0.3
)
print(f"\n最终答案:\n{response.choices[0].message.content}")
return response.choices[0].message.content
# 测试
problem = """
有5个海盗抢到了100颗宝石,他们按以下规则分配:
1. 抽签决定5个人的顺序(1-5号)
2. 由1号提出分配方案,所有人投票(包括1号自己)
3. 如果超过半数同意,按方案分配;否则1号被扔下海,由2号提出方案
4. 每个海盗都绝对理性,优先保命,其次多得宝石,最后喜欢看别人被扔下海
问:1号海盗应该提出什么方案才能既保命又利益最大化?
"""
tree_of_thoughts(problem, depth=2, branches=3)ToT 适用场景:
- ✅ 策略游戏(如象棋、围棋下一步走法)
- ✅ 创意设计(多个方案对比)
- ✅ 复杂决策(需要评估多个可能性)
- ❌ 简单事实查询(过度复杂)
3.2.5 结构化 Prompt 模板设计
生产环境中,Prompt 应该是可维护、可测试、可复用的代码资产。
推荐模板结构:
python
from typing import Dict, List
from jinja2 import Template
class PromptTemplate:
"""结构化 Prompt 模板基类"""
def __init__(self, template_string: str):
self.template = Template(template_string)
def render(self, **kwargs) -> str:
return self.template.render(**kwargs)
def validate(self, **kwargs) -> bool:
"""验证必需参数是否存在"""
required_vars = self.template.module.__dict__.get('required_vars', [])
return all(key in kwargs for key in required_vars)
# 定义模板
CODE_REVIEW_TEMPLATE = """
你是一位资深的 {{language}} 开发专家。
请审查以下代码,重点关注:
{% for concern in concerns %}
- {{ concern }}
{% endfor %}
代码:
```{{language}}{{ code }}
输出格式:
1. **严重问题**(会导致程序崩溃或安全漏洞)
2. **性能问题**(影响运行效率)
3. **代码风格**(可读性、可维护性)
4. **改进建议**(具体的优化代码)
评分标准:🔴严重 / 🟡中等 / 🟢轻微
"""
# 使用模板
code_review_prompt = PromptTemplate(CODE_REVIEW_TEMPLATE)
prompt = code_review_prompt.render(
language="Python",
concerns=["SQL注入风险", "异常处理", "性能瓶颈"],
code="""
def get_user(user_id):
query = f"SELECT * FROM users WHERE id = {user_id}"
return db.execute(query)
"""
)
print(prompt)高级模板特性:
python
# 1. 带默认值的模板
SUMMARY_TEMPLATE = """
总结以下{{doc_type | default("文档")}}:
内容:
{{ content }}
要求:
- 长度:{{max_length | default(200)}} 字以内
- 风格:{{style | default("客观中立")}}
- 受众:{{audience | default("普通读者")}}
"""
# 2. 条件逻辑
TRANSLATION_TEMPLATE = """
将以下文本翻译成 {{target_lang}}:
{{ text }}
{% if formality == "formal" %}
注意:使用正式的书面语,避免口语化表达。
{% elif formality == "casual" %}
注意:使用轻松的口语化表达。
{% endif %}
{% if preserve_formatting %}
保持原文的格式(换行、加粗等)。
{% endif %}
"""
# 3. 循环和嵌套
BATCH_TASK_TEMPLATE = """
批量处理以下 {{tasks|length}} 个任务:
{% for task in tasks %}
任务 {{loop.index}}:
- 类型:{{ task.type }}
- 输入:{{ task.input }}
{% if task.priority == "high" %}
- ⚠️ 高优先级
{% endif %}
{% endfor %}
依次输出每个任务的处理结果。
"""Prompt 版本管理(Git + YAML):
yaml
# prompts/v1.0/code_review.yaml
version: "1.0"
name: "code_review"
description: "代码审查 Prompt 模板"
author: "dev-team"
created_at: "2024-01-15"
system_prompt: |
你是一位资深的 {{language}} 开发专家,擅长发现代码漏洞。
user_prompt: |
请审查以下代码:
```{{language}}{{ code }}
重点关注:
{% for concern in concerns %}
- {{ concern }}
{% endfor %}
parameters:
temperature: 0.3
max_tokens: 1000
test_cases:
- input:
language: "Python"
code: "print('hello')"
concerns: ["性能问题"]
expected_keywords: ["没有明显问题", "正常"]加载和使用:
python
import yaml
def load_prompt_template(version: str, name: str):
"""从 YAML 文件加载 Prompt 模板"""
with open(f"prompts/{version}/{name}.yaml") as f:
config = yaml.safe_load(f)
return {
"system": Template(config["system_prompt"]),
"user": Template(config["user_prompt"]),
"params": config["parameters"],
"metadata": {
"version": config["version"],
"author": config["author"]
}
}
# 使用
template = load_prompt_template("v1.0", "code_review")
system_msg = template["system"].render(language="Python")
user_msg = template["user"].render(
language="Python",
code="def add(a, b): return a + b",
concerns=["错误处理", "类型检查"]
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": system_msg},
{"role": "user", "content": user_msg}
],
**template["params"]
)3.2.6 Prompt A/B 测试与迭代优化
生产环境中必须通过数据驱动的方式优化 Prompt。
A/B 测试框架:
python
import random
from datetime import datetime
class PromptABTest:
"""Prompt A/B 测试框架"""
def __init__(self, variants: Dict[str, str], split_ratio: Dict[str, float]):
"""
Args:
variants: {"A": prompt_a, "B": prompt_b, "C": prompt_c}
split_ratio: {"A": 0.5, "B": 0.3, "C": 0.2}
"""
self.variants = variants
self.split_ratio = split_ratio
self.results = {k: [] for k in variants.keys()}
def get_variant(self, user_id: str = None) -> tuple[str, str]:
"""
根据流量分配返回变体
Returns:
(variant_name, prompt)
"""
if user_id:
# 确保同一用户总是看到相同变体(一致性)
random.seed(hash(user_id))
rand = random.random()
cumulative = 0
for variant_name, ratio in self.split_ratio.items():
cumulative += ratio
if rand < cumulative:
return variant_name, self.variants[variant_name]
def log_result(self, variant: str, success: bool, latency: float, user_rating: int = None):
"""记录实验结果"""
self.results[variant].append({
"timestamp": datetime.now(),
"success": success,
"latency": latency,
"user_rating": user_rating
})
def get_stats(self):
"""计算各变体的统计指标"""
stats = {}
for variant, logs in self.results.items():
if not logs:
continue
success_rate = sum(1 for log in logs if log["success"]) / len(logs)
avg_latency = sum(log["latency"] for log in logs) / len(logs)
ratings = [log["user_rating"] for log in logs if log["user_rating"]]
avg_rating = sum(ratings) / len(ratings) if ratings else None
stats[variant] = {
"样本数": len(logs),
"成功率": f"{success_rate:.2%}",
"平均延迟": f"{avg_latency:.2f}s",
"平均评分": f"{avg_rating:.2f}" if avg_rating else "N/A"
}
return stats
# 使用示例
prompt_a = "用一句话总结:{{text}}"
prompt_b = "用不超过20字总结核心观点:{{text}}"
prompt_c = "提取关键信息并总结(20字内):{{text}}"
ab_test = PromptABTest(
variants={"A": prompt_a, "B": prompt_b, "C": prompt_c},
split_ratio={"A": 0.5, "B": 0.3, "C": 0.2} # 50% / 30% / 20%
)
# 模拟100次请求
for i in range(100):
user_id = f"user_{i % 20}" # 20个不同用户
variant_name, prompt_template = ab_test.get_variant(user_id)
# 调用 LLM
start_time = datetime.now()
response = client.chat.completions.create(
model="gpt-4o-mini", # 使用便宜的模型做测试
messages=[{"role": "user", "content": Template(prompt_template).render(text="测试文本...")}],
temperature=0.7
)
latency = (datetime.now() - start_time).total_seconds()
# 模拟成功率和用户评分
success = len(response.choices[0].message.content) <= 50 # 假设长度<50为成功
user_rating = random.randint(3, 5) if success else random.randint(1, 3)
ab_test.log_result(variant_name, success, latency, user_rating)
# 查看结果
import pandas as pd
stats_df = pd.DataFrame(ab_test.get_stats()).T
print(stats_df)输出示例:
样本数 成功率 平均延迟 平均评分
A 50 76.00% 0.85s 4.12
B 30 86.67% 0.92s 4.45
C 20 90.00% 0.89s 4.65决策标准:
- 成功率最重要:优先选择成功率高的变体
- 平衡延迟与效果:如果成功率相近,选择延迟低的
- 用户评分:主观感受也很重要
- 统计显著性:至少收集 100+ 样本再下结论
3.2.7 学习资源与实战建议
推荐论文:
- Chain-of-Thought Prompting(Google, 2022):https://arxiv.org/abs/2201.11903
- Self-Consistency(Google, 2023):https://arxiv.org/abs/2203.11171
- Tree of Thoughts(Princeton, 2023):https://arxiv.org/abs/2305.10601
开源工具:
- LangChain Prompt Hub:社区共享的 Prompt 模板库
- PromptTools:Prompt 测试和评估框架(https://github.com/hegelai/prompttools)
- Weights & Biases Prompts:Prompt 版本管理和追踪
实战路径:
Week 1:基础技巧
- 实现 10 个 Few-shot 示例(不同任务类型)
- 对比 Zero-shot 和 Few-shot 的效果差异
- 练习编写 CoT Prompt
Week 2-3:高级技术
- 实现 Self-Consistency(至少3个场景)
- 尝试简化版 Tree of Thoughts
- 对比不同技术在同一任务上的表现
Week 4:工程化实践
- 设计 Prompt 模板系统(Jinja2 + YAML)
- 实现一个 A/B 测试框架
- 为真实业务场景优化 Prompt
关键要点:
- ✅ Few-shot 是性价比之王:大多数任务 3-5 个示例足够
- ✅ CoT 对推理任务提升巨大:数学、逻辑、代码生成必用
- ✅ Self-Consistency 适合高风险场景:医疗、金融、法律
- ✅ 模板化 + 版本管理:Prompt 也是代码,需要工程化管理
- ✅ 持续 A/B 测试:数据驱动优化,不要凭感觉