Few-shot 与思维链(CoT)大模型提示技巧实战指南
Few-shot 与思维链(CoT)大模型提示技巧实战指南
别再让AI说“我不会算了”——用几个例子和“一步步想”把它教成解题高手
WEB项目地址:AI智能商品导购系统
安卓APP下载地址:精打细算
你有没有碰到过这种事:问AI一道小学数学题,它信誓旦旦算出个错误答案;让它模仿你喜欢的某位博主的文风,写出来的东西四不像;明明给了它好几个正确答案的例子,下一道题它还是按自己的野路子来……
这些问题的解药,就是Few-shot(少样本学习)和思维链(Chain of Thought, CoT)。这俩词听着像学术黑话,其实特别简单:
- Few-shot:给AI两三个例子,它就能照葫芦画瓢。
- 思维链:让AI把解题过程一步步写出来,而不是直接蹦答案。
今天这篇教程,我会用你最熟悉的“人教人”的方式,把这两个技巧拆开揉碎。学完你就能让AI从“不太聪明的实习生”变成“靠得住的解题搭档”。
① 少样本学习与思维链核心概念解析
先讲个我自己的翻车经历。去年我想让AI帮我分类客户评价(好评/差评/中性),我给它写了很长一段规则:“如果包含‘垃圾’‘差劲’就是差评,如果包含‘很棒’‘推荐’就是好评……”结果它把“没有想象中好,但也不差”这种给判成了差评,还死活不改。
后来我换了个方法:不写规则,直接扔给它三个例子——
例子1:“这手机电池太烂了,一天充三回” → 差评
例子2:“物流快,包装严实,下次还来” → 好评
例子3:“价格还行,就是颜色有色差” → 中性
然后让它分类第四条评论。你猜怎么着?全对。
这就是Few-shot的本质:人类擅长讲规则,AI擅长看例子。你给两三个高质量的“输入→输出”对,它就能自己总结出背后的模式,比你说一百句规则都管用。
再来说思维链(CoT)。我做过一个实验:让AI直接回答“小明有5个苹果,给了小红2个,又从妈妈那拿了3个,现在比原来多了几个?”它直接说“多了1个”(正确答案应该是多了1个?算一下:5-2+3=6,比原来5多了1,没错。但这不是重点)。重点是我让它把过程写出来——
第一步:原来有5个
第二步:给小红2个,剩下3个
第三步:从妈妈那拿3个,变成6个
第四步:6比5多1个,所以多了1个
这时候哪怕最后答案算错了(假设它算错成2),你也能看出它错在哪一步,而不是面对一个莫名其妙的数字。而且让AI写步骤,它的最终正确率会大幅提升——因为推理过程强迫它把问题拆解了。
Few-shot和CoT怎么配合?Few-shot告诉AI“你要模仿这种形式”,CoT告诉AI“你要像这样一步步想”。两个一起用,效果1+1>2。
② 运行环境准备与模型调用配置
动手之前先把锅灶搭好。我会用OpenAI API做演示,但你用Claude、文心、通义千问、DeepSeek都行,接口逻辑大同小异。
你需要三样东西:
- Python 3.8+(没有就去装Anaconda,新手友好)
- 一个API Key(去各自官网注册,一般有免费额度)
- openai库(版本≥1.0.0)
安装命令(复制粘贴就行):
pip install openai
基础调用代码(你的第一个Few-shot测试):
from openai import OpenAI
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.openai.com/v1" # 国内用户改成代理地址
)
response = client.chat.completions.create(
model="gpt-3.5-turbo", # 便宜且够用
messages=[
{"role": "system", "content": "你是一个分类助手"},
{"role": "user", "content": """
请将以下评论分类为【好评】或【差评】。
例子:
评论:"质量太差,用三天就坏了" → 差评
评论:"客服态度好,解决速度快" → 好评
现在分类这条:
评论:"包装破损但产品本身没问题" →
"""}
]
)
print(response.choices[0].message.content)
跑一下,你应该会得到类似“差评”或“中性”的输出。如果它给了“中性”,说明模型自动补了第三个类别——这就是Few-shot的威力:你只给了两类例子,它理解了你意图,但也会灵活处理边界情况。
注意:如果你用的是国内模型(比如文心、通义),可能system和user的字段名略有不同,换成prompt或者直接字符串就行。核心思路不变。
③ 构建高质量 Few-shot 示例库方法
Few-shot 的效果,90%取决于你给的例子好不好。烂例子会把AI带沟里去。
一个好例子的三个标准:
- 覆盖面:把各种可能情况都覆盖到。比如做情感分类,别只给“太好啦”和“太差了”,还得给“还行吧”“一般般”“无感”这种边界样本。
- 一致性:同一类别的例子,格式、粒度、逻辑要统一。别第一个好评写“好吃!”,第二个写“价格实惠、服务热情、味道正宗”——第二个太详细,AI会以为好评必须写长句。
- 干净:例子里的输入不要有歧义,输出不要有笔误。AI会学你的错误。
实操步骤:如何从零构建一个示例库(以“客服回复生成”为例)
任务:用户说一句话,AI生成客服回复,要求:先共情,再给方案,最后留个话头。
步骤1:手写3个黄金例子
输入:“你们快递把我包裹弄丢了”
输出:“非常抱歉给您带来不便(共情)。我们马上联系快递公司查询,如果确认丢失会立即补发或全额退款(方案)。请您提供一下订单号,我们加急处理(留话头)。”
输入:“这软件怎么注册不了”
输出:“很理解您着急使用的心情。请您尝试以下步骤:先检查网络,再确认验证码是否输入正确。如果还不行,请提供您的手机型号,我们帮您排查。”
输入:“上次买的鞋子磨脚,能退吗”
输出:“穿得不舒服真是糟心。可以退的,我们支持7天无理由。您登录订单页面点击‘申请售后’,上传磨脚部位的照片,我们审核后就会安排退货。”
步骤2:检查覆盖度
这三个例子覆盖了“物流问题”“功能问题”“质量问题”。如果你们的客服场景还有“价格咨询”“活动规则”,再加对应的例子。
步骤3:增加一个“负面约束”例子(可选但推荐)
告诉AI什么不能做:
输入:“我要投诉你们”
输出:(禁止说“祝您生活愉快”,禁止推卸责任,禁止超过20个字)→ “收到投诉,我们会认真处理,1个工作日内给您答复。”
示例数量多少合适?
- 简单分类任务:3~5个就够了
- 格式化生成任务:5~8个
- 复杂推理任务:2~3个高质量的例子 + 思维链
记住:宁缺毋滥。给8个平庸的例子,不如给3个精品的例子。
④ 设计逻辑清晰的思维链推导步骤
很多人写CoT,就是简单加一句“请一步步思考”,这有用,但不够。真正的思维链要手把手教AI怎么拆解问题。
一个失败的CoT:
用户:一个水池,进水管5小时注满,出水管8小时排空,同时打开,几小时注满?
AI(直接回复):3.08小时。
你也不知道它对不对,错了也看不出原因。
一个成功的CoT(带步骤模板):
用户:请按以下步骤计算:
步骤1:将进水管每小时注水量设为1/5池
步骤2:将出水管每小时排水量设为1/8池
步骤3:同时打开,净注水速度 = 1/5 - 1/8 = 3/40池/小时
步骤4:注满时间 = 1 ÷ (3/40) = 40/3 ≈ 13.33小时
最后给出答案。
现在计算:进水管4小时注满,出水管6小时排空,同时打开,几小时注满?
这种叫显式步骤模板。你不仅要让AI“一步步想”,还要告诉它每一步该做什么操作。
三种常用的思维链结构:
1. 清单式(适合列举、核查类任务)
请按以下清单分析这份合同:
- [ ] 检查甲方乙方名称是否完整
- [ ] 检查金额大小写是否一致
- [ ] 检查签署日期是否在有效期内
- [ ] 检查违约责任条款是否明确
依次输出每条的检查结果。
2. 计算式(适合数学、逻辑)
先写公式,再代入数字,再计算结果,最后解释。
3. 对比式(适合决策、选择)
列出方案A的优点和缺点
列出方案B的优点和缺点
对比后给出推荐,并说明原因
小技巧:把你的思考草稿直接塞进去
如果你自己会做这道题,就把你脑子里的步骤写出来,塞给AI当示范。AI模仿你步骤的能力,远超你的想象。
⑤ 融合 Few-shot 与 CoT 的完整代码实现
很多人把这两个技巧分开用,其实合在一起才最猛。下面是一个完整可运行的代码,实现一个“数学应用题解答助手”,要求:用例子示范步骤格式 + 强制思维链。
from openai import OpenAI
client = OpenAI(api_key="你的key")
def solve_math_problem(question):
# 构造带Few-shot和CoT的提示词
prompt = f"""
你是一个数学解题助手。请严格按照以下两个例子的格式,先写出推导步骤,再给出答案。
例子1:
问题:小明有8支铅笔,送给小红3支,又买了5支,现在有多少支?
步骤:
1. 原来有8支
2. 送给小红3支,剩下 8 - 3 = 5支
3. 又买了5支,变成 5 + 5 = 10支
答案:10支
例子2:
问题:一个长方形的长是12米,宽是5米,它的面积是多少?
步骤:
1. 长方形面积公式:面积 = 长 × 宽
2. 长=12米,宽=5米
3. 计算:12 × 5 = 60
答案:60平方米
现在请解答以下问题,必须按照上面的格式,先写步骤,再写答案。
问题:{question}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0, # 降低随机性,保证步骤稳定
)
return response.choices[0].message.content
# 测试
print(solve_math_problem("一辆车行驶了3小时,速度是60公里/小时,之后又行驶了2小时,速度是80公里/小时,一共行驶了多少公里?"))
你运行后会看到类似输出:
步骤:
1. 第一段路程:3小时 × 60公里/小时 = 180公里
2. 第二段路程:2小时 × 80公里/小时 = 160公里
3. 总路程:180 + 160 = 340公里
答案:340公里
注意两个关键点:
temperature=0:保证模型不瞎发挥,严格按照例子的格式- 例子里的步骤写法要极度一致:都用“步骤1、步骤2…”,都用“答案:xxx”
如果你想让AI输出结果可以直接被程序解析,可以要求它最后用JSON格式:
答案:{{"steps": ["步骤1", "步骤2"], "final_answer": 340}}
然后你用json.loads()就能拿到结构化数据。
⑥ 典型场景下的提示词效果对比验证
光说不练假把式。我们选三个典型场景,分别用三种提示方式(zero-shot、Few-shot-only、Few-shot+CoT),看看真实效果。
场景1:实体抽取(从用户评论中抽取出“产品名”和“问题”)
输入文本:“苹果14的电池掉电太快了,还不如我旧的小米”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot:“抽取产品和问题” | 产品:苹果14,问题:电池掉电快 | 还行,但漏掉了“小米”的对比信息 |
| Few-shot-only:给3个抽取例子 | 产品:苹果14,对比产品:小米,问题:电池续航差 | 更好,学会了“对比”也能抽 |
| Few-shot+CoT:先写“这句话提到哪些实体?每个实体出了什么问题?” | 分析:句子中提到“苹果14”和“小米”。“苹果14”的问题是“电池掉电快”,“小米”没有明确问题,只是用来对比。输出:{“苹果14”: “电池掉电快”} | 最准,而且没有虚构问题 |
场景2:逻辑推理(三段论)
输入:“所有A都是B。有些B是C。那么有些A是C吗?”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot | 可能得出“是”或“不是”,随机性强 | 不稳 |
| Few-shot-only(给几个类似的三段论例子) | 可能模仿例子的结论,但不知道为什么 | 碰运气 |
| Few-shot+CoT(先画欧拉图或用文字推理) | “不能确定。因为A全部在B中,但B中只有一部分是C,A可能碰巧在非C的那部分B里。” | 正确且解释了原因 |
场景3:代码生成(写个函数判断闰年)
输入:“写Python函数is_leap_year(year)”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot | 可能写出year % 4 == 0,忘了世纪年规则 |
有bug |
| Few-shot-only(给两个正确用例的输入输出) | 代码大概率正确,但不知道它怎么推导的 | 能用,但不好调试 |
| Few-shot+CoT(要求先写出判断规则步骤) | 先写“1.能被400整除的是闰年;2.能被100整除但不能被400的不是;3.能被4整除但不能被100的是”。然后再写代码 | 代码几乎无bug,而且规则清晰 |
结论:Few-shot+CoT在所有场景下都最稳。额外的好处是——你拿到AI的推理步骤,以后出了问题好排查。
⑦ 常见输出偏差分析与调试策略
AI不是神,它会有各种奇奇怪怪的错误。下面是四个最常遇到的偏差,以及对应的调试方法。
偏差1:示例过拟合——AI死板模仿例子里的无关特征
现象:你在Few-shot里所有的例子输出都带感叹号,结果AI给所有输出都加感叹号,哪怕是“您的订单已取消”这种不该有感叹号的地方。
原因:AI以为感叹号是格式要求的一部分。
调试:
- 把例子里的感叹号去掉,或者只在必要的例子中保留
- 在system里明确加一句:“不要模仿例子中的标点符号风格,只模仿逻辑”
偏差2:步骤遗漏——思维链跳步
现象:你让它分四步,它经常合并成三步,导致中间推理错误。
原因:模型为了省tokens,自动压缩步骤。
调试:
- 在提示词里加惩罚:“每缺少一步,答案就无效”
- 用结构化的步骤模板,比如强制它写“步骤1:… 步骤2:… 步骤3:… 步骤4:…”,缺了任何一个就不输出最终答案
偏差3:上下文冲突——Few-shot例子和真实问题矛盾
现象:你给的例子中全是“正面评价→回复要热情”,但真实用户输入是一个投诉,AI依然热情地说“感谢您的反馈!”,显得很假。
原因:AI优先服从例子模式,忽略了真实问题的负面情绪。
调试:
- 在Few-shot中加入负面例子(投诉应该怎么回)
- 或者用动态示例选择(见第⑩节):根据用户问题的情绪,只选择相似情绪的例子
偏差4:幻觉——AI编造步骤中没出现过的事实
现象:让AI根据提供的数据分析,它却在步骤里突然写“根据行业标准,通常…”,引用了你根本没给的数据。
原因:模型的预训练知识干扰了它。
调试:
- 在system里加硬约束:“只允许使用用户输入中明确给出的信息,不要引入外部知识”
- 如果必须用外部知识,单独给一个知识库片段
通用调试流程:
- 把temperature调到0,排除随机性
- 只保留一个Few-shot例子,看AI是否还能正确模仿
- 去掉所有例子,只用CoT,看基础推理能力是否在线
- 逐步加回例子,找到导致偏差的那一个
⑧ 复杂任务中的多步推理优化技巧
当任务本身就需要多个阶段(比如“先摘要→再分类→再生成报告”),你不能指望AI在一个提示词里全做完。那样上下文会爆炸,而且容易出错。
技巧1:分而治之——多轮调用
把大任务拆成小任务,每轮只做一件事,把上一轮的结果传给下一轮。
示例:分析客户反馈邮件并生成回复草稿。
轮次1:调用AI提取邮件关键信息(发件人、情绪、具体问题)
输出:{"sender": "张三", "sentiment": "愤怒", "issue": "重复扣款"}
轮次2:调用AI根据问题类别匹配处理方案(用Few-shot)
输入:问题“重复扣款” → 输出:处理方案“核实交易记录,发起退款”
轮次3:调用AI生成回复邮件(用CoT,先写要点再成文)
输入:情绪愤怒+方案退款 → 输出完整邮件
这样做的好处:
- 每一步都可以单独调试
- 总tokens消耗反而更少(因为不需要在每一步都带着原始长邮件)
- 准确率更高
技巧2:自我纠错——让AI检查自己的推理
在复杂任务后,加一个验证环节。
第一步:AI生成答案A
第二步:提示“请检查你上一步的答案,重点检查第3步的计算。如果有错误,写出正确步骤。”
第三步:AI输出修正后的答案B
实测这种方法能让数学题的准确率提升15~20%。你可以循环多次,但一般两次就够了。
技巧3:引入“占位符”变量
如果你的Few-shot例子中有重复出现的数字或名词,可以用变量代替,强制AI先提取变量再代入。
例子:
问题:{user}买了{count1}件{product},每件{price}元,又退了{count2}件,需要付多少钱?
步骤:
1. 提取变量:count1=?, price=?, count2=?
2. 原价 = count1 × price
3. 退款 = count2 × price
4. 应付 = 原价 - 退款
这种模板能减少AI的错漏。
⑨ 降低 Token 消耗的示例精简方案
Few-shot+CoT虽然效果好,但代价是提示词变长。如果你每天调用成千上万次,tokens费用会肉疼。下面几个方法能帮你省掉60%以上的tokens,同时保持效果。
方案1:示例压缩——删除冗余词
把例子中的自然语言改成缩写或代码风格。
压缩前(90 tokens):
问题:小明有5个苹果,给了小红2个,又买了3个,现在有多少个?
步骤:第一步,原来有5个;第二步,给小红2个,剩下3个;第三步,买3个,变成6个;答案:6个
压缩后(50 tokens):
Q:5苹果-2+3=?
A:5-2=3,3+3=6 →6
AI照样能看懂,尤其对于数学类任务。
方案2:使用“示例哈希”缓存
如果你的用户问的问题有很多重复或相似,可以在本地维护一个示例库,每次只发用户当前问题,不发任何例子,但在system里写“你已学习过以下3个案例:案例A、B、C”。这需要模型支持系统提示且足够聪明。
更保险的做法:先用一个轻量模型(如gpt-3.5-turbo-16k)判断问题和哪个已有示例最像,然后只把那一个示例发过去。这叫动态示例选择,下一节会细讲。
方案3:CoT 压缩——只保留关键步骤
对于已经稳定的任务,可以精简思维链的步骤描述。
完整CoT:
请按照以下步骤:第一步,列出已知条件;第二步,写出公式;第三步,代入数字;第四步,计算;第五步,写答案。
精简CoT:
已知→公式→代入→结果
模型经过几次微调(或者你已经在系统提示里给过完整格式),就能理解这些简称。
方案4:用“指令”代替“例子”
当你发现AI已经学懂了某种模式,可以逐渐把Few-shot替换成简单的指令。比如一开始你用5个例子教会AI什么是“共情式回复”,50轮对话后,你可以直接说“用共情式回复”,不再给例子。
经验法则:同一任务,前10次调用给足例子,之后每10次减少一个例子,直到只保留1个例子甚至0个。
⑩ 进阶应用:动态示例选择与自适应推理
最后这一节给学有余力的朋友。如果你已经熟练掌握了上面的所有技巧,可以再上两个台阶。
进阶1:动态示例选择(DSS)
不是所有例子都适合所有问题。比如用户问的是“退货流程”,你给的例子全是“投诉处理”,效果就不好。
实现思路:
- 预先准备一个大的示例库(比如100条),每条示例附带一个“特征向量”(可以用Embedding模型把用户问题转成向量)
- 每次收到新用户问题,也转成向量
- 在示例库里找向量最相似的K个例子(K=1~3)
- 只把这几个最相关的例子塞进提示词
代码骨架:
import numpy as np
from openai import OpenAI
client = OpenAI()
# 假设你已经有一个示例库
examples = [
{"question": "怎么退货", "answer": "退货流程...", "embedding": [...]},
# ... 更多示例
]
def get_dynamic_few_shot(user_question):
# 获取用户问题的embedding
q_emb = client.embeddings.create(input=user_question, model="text-embedding-3-small").data[0].embedding
# 计算相似度(余弦相似度)
similarities = [cosine_similarity(q_emb, ex["embedding"]) for ex in examples]
top_indices = np.argsort(similarities)[-2:] # 取前2个最相似的
return [examples[i] for i in top_indices]
这样每次Few-shot的例子都是量身定制的,效果更好且例子总数可以很小(2~3个)。
进阶2:自适应推理——根据问题难度调整CoT深度
简单问题用浅层CoT(甚至不用CoT),复杂问题才启用深度CoT。可以省tokens。
实现:
- 第一轮:用一个小模型(或gpt-3.5-turbo)评估问题难度(分简单/中等/困难)
- 如果是简单问题:直接zero-shot回答
- 如果是中等:给2步CoT
- 如果是困难:给5步+多个例子
评估方法(简单粗暴但有效):
def estimate_difficulty(question):
prompt = f"将以下问题的难度分为1(极简单)、2(中等)、3(复杂):{question}"
response = client.chat.completions.create(..., temperature=0)
return int(response.choices[0].message.content)
写在最后
Few-shot和思维链,本质上是你在教AI如何思考,而不是替它思考。你给的每一个例子、每一条步骤,都是在给AI搭建一个思维的脚手架。
新手最容易犯的错是贪多——又想给10个例子,又想写超级详细的步骤,结果提示词长到模型都糊涂了。我的建议是:从最简单的开始。先拿一个你手头真实的任务,给2个例子+3步CoT,跑通了再慢慢加料。
最后送你一个常用模板,可以直接贴在每个提示词的开头:
【模式】Few-shot + Chain-of-Thought
【示例】[此处放2个你的黄金例子]
【要求】1. 必须分步骤输出 2. 每步只做一件事 3. 最后输出答案
【现在请处理】[用户问题]
把这个模板存成文本片段,以后每次调用前粘贴一下。一个月后你会回来感谢我的。
如果遇到具体问题,欢迎按照第⑦节的调试流程自己先折腾一下——说实话,大部分坑我都帮你踩过了。剩下的,就是多练。# Few-shot 与思维链(CoT)大模型提示技巧实战指南
别再让AI说“我不会算了”——用几个例子和“一步步想”把它教成解题高手
你有没有碰到过这种事:问AI一道小学数学题,它信誓旦旦算出个错误答案;让它模仿你喜欢的某位博主的文风,写出来的东西四不像;明明给了它好几个正确答案的例子,下一道题它还是按自己的野路子来……
这些问题的解药,就是Few-shot(少样本学习)和思维链(Chain of Thought, CoT)。这俩词听着像学术黑话,其实特别简单:
- Few-shot:给AI两三个例子,它就能照葫芦画瓢。
- 思维链:让AI把解题过程一步步写出来,而不是直接蹦答案。
今天这篇教程,我会用你最熟悉的“人教人”的方式,把这两个技巧拆开揉碎。学完你就能让AI从“不太聪明的实习生”变成“靠得住的解题搭档”。
① 少样本学习与思维链核心概念解析
先讲个我自己的翻车经历。去年我想让AI帮我分类客户评价(好评/差评/中性),我给它写了很长一段规则:“如果包含‘垃圾’‘差劲’就是差评,如果包含‘很棒’‘推荐’就是好评……”结果它把“没有想象中好,但也不差”这种给判成了差评,还死活不改。
后来我换了个方法:不写规则,直接扔给它三个例子——
例子1:“这手机电池太烂了,一天充三回” → 差评
例子2:“物流快,包装严实,下次还来” → 好评
例子3:“价格还行,就是颜色有色差” → 中性
然后让它分类第四条评论。你猜怎么着?全对。
这就是Few-shot的本质:人类擅长讲规则,AI擅长看例子。你给两三个高质量的“输入→输出”对,它就能自己总结出背后的模式,比你说一百句规则都管用。
再来说思维链(CoT)。我做过一个实验:让AI直接回答“小明有5个苹果,给了小红2个,又从妈妈那拿了3个,现在比原来多了几个?”它直接说“多了1个”(正确答案应该是多了1个?算一下:5-2+3=6,比原来5多了1,没错。但这不是重点)。重点是我让它把过程写出来——
第一步:原来有5个
第二步:给小红2个,剩下3个
第三步:从妈妈那拿3个,变成6个
第四步:6比5多1个,所以多了1个
这时候哪怕最后答案算错了(假设它算错成2),你也能看出它错在哪一步,而不是面对一个莫名其妙的数字。而且让AI写步骤,它的最终正确率会大幅提升——因为推理过程强迫它把问题拆解了。
Few-shot和CoT怎么配合?Few-shot告诉AI“你要模仿这种形式”,CoT告诉AI“你要像这样一步步想”。两个一起用,效果1+1>2。
② 运行环境准备与模型调用配置
动手之前先把锅灶搭好。我会用OpenAI API做演示,但你用Claude、文心、通义千问、DeepSeek都行,接口逻辑大同小异。
你需要三样东西:
- Python 3.8+(没有就去装Anaconda,新手友好)
- 一个API Key(去各自官网注册,一般有免费额度)
- openai库(版本≥1.0.0)
安装命令(复制粘贴就行):
pip install openai
基础调用代码(你的第一个Few-shot测试):
from openai import OpenAI
client = OpenAI(
api_key="sk-你的密钥",
base_url="https://api.openai.com/v1" # 国内用户改成代理地址
)
response = client.chat.completions.create(
model="gpt-3.5-turbo", # 便宜且够用
messages=[
{"role": "system", "content": "你是一个分类助手"},
{"role": "user", "content": """
请将以下评论分类为【好评】或【差评】。
例子:
评论:"质量太差,用三天就坏了" → 差评
评论:"客服态度好,解决速度快" → 好评
现在分类这条:
评论:"包装破损但产品本身没问题" →
"""}
]
)
print(response.choices[0].message.content)
跑一下,你应该会得到类似“差评”或“中性”的输出。如果它给了“中性”,说明模型自动补了第三个类别——这就是Few-shot的威力:你只给了两类例子,它理解了你意图,但也会灵活处理边界情况。
注意:如果你用的是国内模型(比如文心、通义),可能system和user的字段名略有不同,换成prompt或者直接字符串就行。核心思路不变。
③ 构建高质量 Few-shot 示例库方法
Few-shot 的效果,90%取决于你给的例子好不好。烂例子会把AI带沟里去。
一个好例子的三个标准:
- 覆盖面:把各种可能情况都覆盖到。比如做情感分类,别只给“太好啦”和“太差了”,还得给“还行吧”“一般般”“无感”这种边界样本。
- 一致性:同一类别的例子,格式、粒度、逻辑要统一。别第一个好评写“好吃!”,第二个写“价格实惠、服务热情、味道正宗”——第二个太详细,AI会以为好评必须写长句。
- 干净:例子里的输入不要有歧义,输出不要有笔误。AI会学你的错误。
实操步骤:如何从零构建一个示例库(以“客服回复生成”为例)
任务:用户说一句话,AI生成客服回复,要求:先共情,再给方案,最后留个话头。
步骤1:手写3个黄金例子
输入:“你们快递把我包裹弄丢了”
输出:“非常抱歉给您带来不便(共情)。我们马上联系快递公司查询,如果确认丢失会立即补发或全额退款(方案)。请您提供一下订单号,我们加急处理(留话头)。”
输入:“这软件怎么注册不了”
输出:“很理解您着急使用的心情。请您尝试以下步骤:先检查网络,再确认验证码是否输入正确。如果还不行,请提供您的手机型号,我们帮您排查。”
输入:“上次买的鞋子磨脚,能退吗”
输出:“穿得不舒服真是糟心。可以退的,我们支持7天无理由。您登录订单页面点击‘申请售后’,上传磨脚部位的照片,我们审核后就会安排退货。”
步骤2:检查覆盖度
这三个例子覆盖了“物流问题”“功能问题”“质量问题”。如果你们的客服场景还有“价格咨询”“活动规则”,再加对应的例子。
步骤3:增加一个“负面约束”例子(可选但推荐)
告诉AI什么不能做:
输入:“我要投诉你们”
输出:(禁止说“祝您生活愉快”,禁止推卸责任,禁止超过20个字)→ “收到投诉,我们会认真处理,1个工作日内给您答复。”
示例数量多少合适?
- 简单分类任务:3~5个就够了
- 格式化生成任务:5~8个
- 复杂推理任务:2~3个高质量的例子 + 思维链
记住:宁缺毋滥。给8个平庸的例子,不如给3个精品的例子。
④ 设计逻辑清晰的思维链推导步骤
很多人写CoT,就是简单加一句“请一步步思考”,这有用,但不够。真正的思维链要手把手教AI怎么拆解问题。
一个失败的CoT:
用户:一个水池,进水管5小时注满,出水管8小时排空,同时打开,几小时注满?
AI(直接回复):3.08小时。
你也不知道它对不对,错了也看不出原因。
一个成功的CoT(带步骤模板):
用户:请按以下步骤计算:
步骤1:将进水管每小时注水量设为1/5池
步骤2:将出水管每小时排水量设为1/8池
步骤3:同时打开,净注水速度 = 1/5 - 1/8 = 3/40池/小时
步骤4:注满时间 = 1 ÷ (3/40) = 40/3 ≈ 13.33小时
最后给出答案。
现在计算:进水管4小时注满,出水管6小时排空,同时打开,几小时注满?
这种叫显式步骤模板。你不仅要让AI“一步步想”,还要告诉它每一步该做什么操作。
三种常用的思维链结构:
1. 清单式(适合列举、核查类任务)
请按以下清单分析这份合同:
- [ ] 检查甲方乙方名称是否完整
- [ ] 检查金额大小写是否一致
- [ ] 检查签署日期是否在有效期内
- [ ] 检查违约责任条款是否明确
依次输出每条的检查结果。
2. 计算式(适合数学、逻辑)
先写公式,再代入数字,再计算结果,最后解释。
3. 对比式(适合决策、选择)
列出方案A的优点和缺点
列出方案B的优点和缺点
对比后给出推荐,并说明原因
小技巧:把你的思考草稿直接塞进去
如果你自己会做这道题,就把你脑子里的步骤写出来,塞给AI当示范。AI模仿你步骤的能力,远超你的想象。
⑤ 融合 Few-shot 与 CoT 的完整代码实现
很多人把这两个技巧分开用,其实合在一起才最猛。下面是一个完整可运行的代码,实现一个“数学应用题解答助手”,要求:用例子示范步骤格式 + 强制思维链。
from openai import OpenAI
client = OpenAI(api_key="你的key")
def solve_math_problem(question):
# 构造带Few-shot和CoT的提示词
prompt = f"""
你是一个数学解题助手。请严格按照以下两个例子的格式,先写出推导步骤,再给出答案。
例子1:
问题:小明有8支铅笔,送给小红3支,又买了5支,现在有多少支?
步骤:
1. 原来有8支
2. 送给小红3支,剩下 8 - 3 = 5支
3. 又买了5支,变成 5 + 5 = 10支
答案:10支
例子2:
问题:一个长方形的长是12米,宽是5米,它的面积是多少?
步骤:
1. 长方形面积公式:面积 = 长 × 宽
2. 长=12米,宽=5米
3. 计算:12 × 5 = 60
答案:60平方米
现在请解答以下问题,必须按照上面的格式,先写步骤,再写答案。
问题:{question}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0, # 降低随机性,保证步骤稳定
)
return response.choices[0].message.content
# 测试
print(solve_math_problem("一辆车行驶了3小时,速度是60公里/小时,之后又行驶了2小时,速度是80公里/小时,一共行驶了多少公里?"))
你运行后会看到类似输出:
步骤:
1. 第一段路程:3小时 × 60公里/小时 = 180公里
2. 第二段路程:2小时 × 80公里/小时 = 160公里
3. 总路程:180 + 160 = 340公里
答案:340公里
注意两个关键点:
temperature=0:保证模型不瞎发挥,严格按照例子的格式- 例子里的步骤写法要极度一致:都用“步骤1、步骤2…”,都用“答案:xxx”
如果你想让AI输出结果可以直接被程序解析,可以要求它最后用JSON格式:
答案:{{"steps": ["步骤1", "步骤2"], "final_answer": 340}}
然后你用json.loads()就能拿到结构化数据。
⑥ 典型场景下的提示词效果对比验证
光说不练假把式。我们选三个典型场景,分别用三种提示方式(zero-shot、Few-shot-only、Few-shot+CoT),看看真实效果。
场景1:实体抽取(从用户评论中抽取出“产品名”和“问题”)
输入文本:“苹果14的电池掉电太快了,还不如我旧的小米”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot:“抽取产品和问题” | 产品:苹果14,问题:电池掉电快 | 还行,但漏掉了“小米”的对比信息 |
| Few-shot-only:给3个抽取例子 | 产品:苹果14,对比产品:小米,问题:电池续航差 | 更好,学会了“对比”也能抽 |
| Few-shot+CoT:先写“这句话提到哪些实体?每个实体出了什么问题?” | 分析:句子中提到“苹果14”和“小米”。“苹果14”的问题是“电池掉电快”,“小米”没有明确问题,只是用来对比。输出:{“苹果14”: “电池掉电快”} | 最准,而且没有虚构问题 |
场景2:逻辑推理(三段论)
输入:“所有A都是B。有些B是C。那么有些A是C吗?”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot | 可能得出“是”或“不是”,随机性强 | 不稳 |
| Few-shot-only(给几个类似的三段论例子) | 可能模仿例子的结论,但不知道为什么 | 碰运气 |
| Few-shot+CoT(先画欧拉图或用文字推理) | “不能确定。因为A全部在B中,但B中只有一部分是C,A可能碰巧在非C的那部分B里。” | 正确且解释了原因 |
场景3:代码生成(写个函数判断闰年)
输入:“写Python函数is_leap_year(year)”
| 提示方式 | 输出 | 评价 |
|---|---|---|
| Zero-shot | 可能写出year % 4 == 0,忘了世纪年规则 |
有bug |
| Few-shot-only(给两个正确用例的输入输出) | 代码大概率正确,但不知道它怎么推导的 | 能用,但不好调试 |
| Few-shot+CoT(要求先写出判断规则步骤) | 先写“1.能被400整除的是闰年;2.能被100整除但不能被400的不是;3.能被4整除但不能被100的是”。然后再写代码 | 代码几乎无bug,而且规则清晰 |
结论:Few-shot+CoT在所有场景下都最稳。额外的好处是——你拿到AI的推理步骤,以后出了问题好排查。
⑦ 常见输出偏差分析与调试策略
AI不是神,它会有各种奇奇怪怪的错误。下面是四个最常遇到的偏差,以及对应的调试方法。
偏差1:示例过拟合——AI死板模仿例子里的无关特征
现象:你在Few-shot里所有的例子输出都带感叹号,结果AI给所有输出都加感叹号,哪怕是“您的订单已取消”这种不该有感叹号的地方。
原因:AI以为感叹号是格式要求的一部分。
调试:
- 把例子里的感叹号去掉,或者只在必要的例子中保留
- 在system里明确加一句:“不要模仿例子中的标点符号风格,只模仿逻辑”
偏差2:步骤遗漏——思维链跳步
现象:你让它分四步,它经常合并成三步,导致中间推理错误。
原因:模型为了省tokens,自动压缩步骤。
调试:
- 在提示词里加惩罚:“每缺少一步,答案就无效”
- 用结构化的步骤模板,比如强制它写“步骤1:… 步骤2:… 步骤3:… 步骤4:…”,缺了任何一个就不输出最终答案
偏差3:上下文冲突——Few-shot例子和真实问题矛盾
现象:你给的例子中全是“正面评价→回复要热情”,但真实用户输入是一个投诉,AI依然热情地说“感谢您的反馈!”,显得很假。
原因:AI优先服从例子模式,忽略了真实问题的负面情绪。
调试:
- 在Few-shot中加入负面例子(投诉应该怎么回)
- 或者用动态示例选择(见第⑩节):根据用户问题的情绪,只选择相似情绪的例子
偏差4:幻觉——AI编造步骤中没出现过的事实
现象:让AI根据提供的数据分析,它却在步骤里突然写“根据行业标准,通常…”,引用了你根本没给的数据。
原因:模型的预训练知识干扰了它。
调试:
- 在system里加硬约束:“只允许使用用户输入中明确给出的信息,不要引入外部知识”
- 如果必须用外部知识,单独给一个知识库片段
通用调试流程:
- 把temperature调到0,排除随机性
- 只保留一个Few-shot例子,看AI是否还能正确模仿
- 去掉所有例子,只用CoT,看基础推理能力是否在线
- 逐步加回例子,找到导致偏差的那一个
⑧ 复杂任务中的多步推理优化技巧
当任务本身就需要多个阶段(比如“先摘要→再分类→再生成报告”),你不能指望AI在一个提示词里全做完。那样上下文会爆炸,而且容易出错。
技巧1:分而治之——多轮调用
把大任务拆成小任务,每轮只做一件事,把上一轮的结果传给下一轮。
示例:分析客户反馈邮件并生成回复草稿。
轮次1:调用AI提取邮件关键信息(发件人、情绪、具体问题)
输出:{"sender": "张三", "sentiment": "愤怒", "issue": "重复扣款"}
轮次2:调用AI根据问题类别匹配处理方案(用Few-shot)
输入:问题“重复扣款” → 输出:处理方案“核实交易记录,发起退款”
轮次3:调用AI生成回复邮件(用CoT,先写要点再成文)
输入:情绪愤怒+方案退款 → 输出完整邮件
这样做的好处:
- 每一步都可以单独调试
- 总tokens消耗反而更少(因为不需要在每一步都带着原始长邮件)
- 准确率更高
技巧2:自我纠错——让AI检查自己的推理
在复杂任务后,加一个验证环节。
第一步:AI生成答案A
第二步:提示“请检查你上一步的答案,重点检查第3步的计算。如果有错误,写出正确步骤。”
第三步:AI输出修正后的答案B
实测这种方法能让数学题的准确率提升15~20%。你可以循环多次,但一般两次就够了。
技巧3:引入“占位符”变量
如果你的Few-shot例子中有重复出现的数字或名词,可以用变量代替,强制AI先提取变量再代入。
例子:
问题:{user}买了{count1}件{product},每件{price}元,又退了{count2}件,需要付多少钱?
步骤:
1. 提取变量:count1=?, price=?, count2=?
2. 原价 = count1 × price
3. 退款 = count2 × price
4. 应付 = 原价 - 退款
这种模板能减少AI的错漏。
⑨ 降低 Token 消耗的示例精简方案
Few-shot+CoT虽然效果好,但代价是提示词变长。如果你每天调用成千上万次,tokens费用会肉疼。下面几个方法能帮你省掉60%以上的tokens,同时保持效果。
方案1:示例压缩——删除冗余词
把例子中的自然语言改成缩写或代码风格。
压缩前(90 tokens):
问题:小明有5个苹果,给了小红2个,又买了3个,现在有多少个?
步骤:第一步,原来有5个;第二步,给小红2个,剩下3个;第三步,买3个,变成6个;答案:6个
压缩后(50 tokens):
Q:5苹果-2+3=?
A:5-2=3,3+3=6 →6
AI照样能看懂,尤其对于数学类任务。
方案2:使用“示例哈希”缓存
如果你的用户问的问题有很多重复或相似,可以在本地维护一个示例库,每次只发用户当前问题,不发任何例子,但在system里写“你已学习过以下3个案例:案例A、B、C”。这需要模型支持系统提示且足够聪明。
更保险的做法:先用一个轻量模型(如gpt-3.5-turbo-16k)判断问题和哪个已有示例最像,然后只把那一个示例发过去。这叫动态示例选择,下一节会细讲。
方案3:CoT 压缩——只保留关键步骤
对于已经稳定的任务,可以精简思维链的步骤描述。
完整CoT:
请按照以下步骤:第一步,列出已知条件;第二步,写出公式;第三步,代入数字;第四步,计算;第五步,写答案。
精简CoT:
已知→公式→代入→结果
模型经过几次微调(或者你已经在系统提示里给过完整格式),就能理解这些简称。
方案4:用“指令”代替“例子”
当你发现AI已经学懂了某种模式,可以逐渐把Few-shot替换成简单的指令。比如一开始你用5个例子教会AI什么是“共情式回复”,50轮对话后,你可以直接说“用共情式回复”,不再给例子。
经验法则:同一任务,前10次调用给足例子,之后每10次减少一个例子,直到只保留1个例子甚至0个。
⑩ 进阶应用:动态示例选择与自适应推理
最后这一节给学有余力的朋友。如果你已经熟练掌握了上面的所有技巧,可以再上两个台阶。
进阶1:动态示例选择(DSS)
不是所有例子都适合所有问题。比如用户问的是“退货流程”,你给的例子全是“投诉处理”,效果就不好。
实现思路:
- 预先准备一个大的示例库(比如100条),每条示例附带一个“特征向量”(可以用Embedding模型把用户问题转成向量)
- 每次收到新用户问题,也转成向量
- 在示例库里找向量最相似的K个例子(K=1~3)
- 只把这几个最相关的例子塞进提示词
代码骨架:
import numpy as np
from openai import OpenAI
client = OpenAI()
# 假设你已经有一个示例库
examples = [
{"question": "怎么退货", "answer": "退货流程...", "embedding": [...]},
# ... 更多示例
]
def get_dynamic_few_shot(user_question):
# 获取用户问题的embedding
q_emb = client.embeddings.create(input=user_question, model="text-embedding-3-small").data[0].embedding
# 计算相似度(余弦相似度)
similarities = [cosine_similarity(q_emb, ex["embedding"]) for ex in examples]
top_indices = np.argsort(similarities)[-2:] # 取前2个最相似的
return [examples[i] for i in top_indices]
这样每次Few-shot的例子都是量身定制的,效果更好且例子总数可以很小(2~3个)。
进阶2:自适应推理——根据问题难度调整CoT深度
简单问题用浅层CoT(甚至不用CoT),复杂问题才启用深度CoT。可以省tokens。
实现:
- 第一轮:用一个小模型(或gpt-3.5-turbo)评估问题难度(分简单/中等/困难)
- 如果是简单问题:直接zero-shot回答
- 如果是中等:给2步CoT
- 如果是困难:给5步+多个例子
评估方法(简单粗暴但有效):
def estimate_difficulty(question):
prompt = f"将以下问题的难度分为1(极简单)、2(中等)、3(复杂):{question}"
response = client.chat.completions.create(..., temperature=0)
return int(response.choices[0].message.content)
写在最后
Few-shot和思维链,本质上是你在教AI如何思考,而不是替它思考。你给的每一个例子、每一条步骤,都是在给AI搭建一个思维的脚手架。
新手最容易犯的错是贪多——又想给10个例子,又想写超级详细的步骤,结果提示词长到模型都糊涂了。我的建议是:从最简单的开始。先拿一个你手头真实的任务,给2个例子+3步CoT,跑通了再慢慢加料。
最后送你一个常用模板,可以直接贴在每个提示词的开头:
【模式】Few-shot + Chain-of-Thought
【示例】[此处放2个你的黄金例子]
【要求】1. 必须分步骤输出 2. 每步只做一件事 3. 最后输出答案
【现在请处理】[用户问题]
把这个模板存成文本片段,以后每次调用前粘贴一下。一个月后你会回来感谢我的。
如果遇到具体问题,欢迎按照第⑦节的调试流程自己先折腾一下——说实话,大部分坑我都帮你踩过了。剩下的,就是多练。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)