提示学习与思维链:API 调用、few-shot 与 CoT 实战
T AGENT 开发纪实 · EP37 · 动手学大模型系列 ②
"提示工程是设计和优化输入的提示,以有效引导生成式大模型生成符合预期输出的技术和实践"。本期用真实 API 把零样本、少样本、思维链三件套跑了一遍,回答一个关键问题:这些技术在 2026 年的模型上还值多少?
本章规模
1 章
本机可跑
✅
API 调用次数
19 次
跑通技术
6 项
💡 本节要点:动手学大模型系列 ②:ch2 提示学习与思维链——PDF 讲义(76 页)+ README + Notebook 三件套,用 token-plan 的 Qwen API 全部实跑;本期结论:few-shot 管格式、CoT 管解释、零样本的基线已经很高
起点问题
四个问题:提示工程到底是干什么的?
- Q1 · 为什么需要提示学习? · 大模型微调的计算代价随参数膨胀难以承受,提示学习用"对齐"思想让下游任务模式贴近预训练模式——不碰权重,只碰输入。
- Q2 · 提示(Prompt)是什么? · 通俗自然语言、文本化 API、结构化信息、任务描述、带样例的提问、提示链、甚至模型自己学出来的连续提示向量——7 种形态。
- Q3 · 提示工程由什么组成? · 四件套:指令(Instruction)、上下文(Context)、输入数据(Input Data)、输出指示(Output Indicator)。
- Q4 · 有哪些技术路线? · 面向新任务:零样本 / 少样本;引入推理:思维链 CoT / 思维树 ToT;进阶:RAG / ReAct / Reflexion——本期把前三层全部实跑。
核心矛盾: 教程是 GPT-3 时代写的("一句咒语把准确率从 17.7% 拉到 78.7%"),我们手里是 2026 年的 Qwen——时代的差距决定了这些技巧今天"为什么有效"和"在哪儿有效"已经变了
💡 本节要点:起点问题:提示学习 = 不碰权重只碰输入;提示 = 7 种形态;提示工程 = 指令/上下文/输入/输出四件套;路线 = 零样本 → 少样本 → CoT → RAG/ReAct/Reflexion
设计决策
怎么跑:教程用 dashscope,我们换 OpenAI 兼容端点
- 🔑 · 接口替换 · 教程示例用阿里云 dashscope SDK(
dashscope.Generation.call(model='qwen-turbo'));本机环境已有 token-plan 的 OpenAI 兼容端点(https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1),一行代码不用改语义,只换请求格式。 - 🧭 · 模型选择 · 主模型
qwen3.7-plus(强、稳、零样本直接答基本都对),对照模型qwen3.6-flash(快、便宜、更能暴露"弱模型才踩的坑")。 - 🪜 · 实验设计 · 每个技术点都做对照:零样本 vs 少样本、直接答 vs 逐步思考、正确标签 vs 反转标签、多次采样投票——用真实输出回答"它到底改变了什么"。
- 🌐 · 网络策略 · token-plan 是国内直连端点,不需要开 Clash 代理——教程里"OpenAI 需要科学手段"的障碍在国产端点上不存在。
为什么不用 dashscope SDK? 教程代码依赖
dashscope包 +qwen-turbo模型名;token-plan 端点按 OpenAI 格式走,且模型名要现查(qwen-plus直接 404,真实型号是qwen3.7-plus)——这是本期踩的第一个坑,也是"教程代码不能照抄"的第一课
💡 本节要点:设计决策:dashscope SDK → OpenAI 兼容端点(token-plan,国内直连免代理);主模型 qwen3.7-plus + 对照 qwen3.6-flash;全程对照实验设计
核心代码 1 · API 调用
第一课:让模型开口说话
import os, json, urllib.request
BASE = os.environ["OPENAI_BASE_URL"] # token-plan OpenAI 兼容端点
KEY = os.environ["OPENAI_API_KEY"]
body = json.dumps({
"model": "qwen3.7-plus",
"messages": [{"role": "user", "content": "用萝卜、土豆、茄子做饭,给我个菜谱。"}],
"temperature": 0.7, "max_tokens": 800,
}).encode("utf-8")
req = urllib.request.Request(BASE + "/chat/completions", data=body,
headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"})
print(json.load(urllib.request.urlopen(req))["choices"][0]["message"]["content"])
真实输出(节选): "用萝卜、土豆、茄子这三种食材,最经典且最下饭的做法莫过于『家常酱焖三鲜』…… 灵魂酱汁:生抽 2 勺、老抽半勺、蚝油 1 勺、黄豆酱 1 大勺、白糖半勺……"
一次调用 800 tokens 上限,返回完整菜谱(食材、步骤、小贴士全齐)。API 调用的本质:
model + messages + 采样参数 → 文本,剩下全是工程问题(重试、超时、流式、token 计费)。
💡 本节要点:核心代码 1:OpenAI 兼容调用的最小骨架——BASE/KEY 走环境变量,messages 传对话,temperature 控制随机性;教程的 dashscope 写法语义等价,格式不同
核心代码 2 · 零样本 vs 少样本
翻译看不出差距,格式一眼看穿
实验 A · 机器翻译(README 原题)
| 方式 | 提示 | 真实输出 |
|---|---|---|
| 零样本 | Translate English to French: cheese => |
fromage ✅ |
| 少样本 | 3 个示例(sea otter => loutre de mer 等)+ cheese => |
fromage ✅ |
| 实验 B · 方面级情感分析(README 原题) |
| 方式 | 提示要点 | 真实输出 |
|---|---|---|
| 零样本 | "Given a review, extract the aspect term(s) and determine their sentiment polarity." | Aspect term: performance / Sentiment polarity: Positive(语义对,格式自由) |
| 少样本 | 同上 + 3 组 Review/Label: [[aspect, polarity]] 示例 |
[[performance, positive]](逐字符贴合格式) |
| > 关键观察:翻译任务零样本和少样本输出一模一样——2026 年模型的零样本基线已经把这种简单任务吃透了。但情感分析暴露了真正的差别:零样本返回自由格式,少样本返回指定格式。few-shot 的第一价值不是"教会任务",是"锁定格式"。 | ||
> 💡 本节要点:核心代码 2:零样本 vs 少样本——翻译无差距(模型已会);方面级情感分析见真章:少样本把输出从自由文本锁成 [[aspect, polarity]] 结构;few-shot 第一价值 = 格式约束 |
核心代码 3 · 思维链 CoT
咒语不灵了,但"步骤感"值钱
实验 C · 16 个球问题(讲义原题,GPT-3 时代 17.7% → 78.7%)
- 直接答:Q: A juggler can juggle 16 balls... A: The answer (arabic numeral) is → 4 ✅(直接答对)
- 逐步思考:... A: Let's think step by step. → 完整推理链,同样得 4
实验 D · Jewel 杂志问题(带干扰项:"邻居买了 1000 份报纸")
- 直接答 → 20 ✅
- 逐步思考 → 五步推理:成本 30 → 售价 5.00 → 收入 50 → 利润 20,并且主动标注"报纸是干扰信息,与利润无关"
诚实的结论:2026 年的 qwen3.7-plus(连 qwen3.6-flash 都能)零样本直接答就把这些"经典陷阱题"全做对了——GPT-3 时代那句魔法咒语的戏剧性效果,在现代模型上不复现。但 CoT 的价值没有消失,它换了个地方:直接答只给你一个数字,CoT 给你一条可审计、可干预、抗干扰的推理路径。
💡 本节要点:核心代码 3:CoT——16 球/Jewel 直接答全对(时代变了,咒语不灵);但 CoT 输出完整推理链、主动识别干扰项;CoT 的价值从"对错"迁移到"可解释 + 可干预"
核心代码 4 · 进阶三件套
JSON 结构化、自主检查、自洽性投票
实验 E · 少样本结构化输出(JSON)——给 3 组"评论 → {"方面": "积极/消极"}"示例,问第 4 条:
真实输出:{"座椅空间": "积极", "机组服务": "积极", "飞机餐": "消极", "机舱温度": "消极"}
严格 JSON、字段自拟、情感判定正确——输出结构被少样本完全锁死,这是"让 LLM 输出可被代码消费"的标准姿势。
实验 F · 自主检查指令(9.9 vs 9.11)——"版本号陷阱":直接答 → 9.9 更大(qwen3.7-plus 没踩坑,讲义里 GPT-4 踩了);加"请仔细分析并检查" → 输出四位对齐分析(十分位 9 > 1)+ 分数验证 + "常见误区"警告。检查指令是廉价保险。
实验 G · 自洽性(temperature=0.7 采样 5 次 + 投票)——16 球问题 5 次推理路径措辞各异,5/5 全部得 4;对难一点的题(GSM8K 级),多次采样投票能对冲单次运气。
三件套对应三个工程痛点:JSON = 让输出能进 pipeline;检查指令 = 让模型"交卷前复查";自洽性 = 用多次采样对冲随机性。它们都不改模型,只改"怎么问"。
💡 本节要点:核心代码 4:进阶三件套——少样本锁 JSON 结构(可编程消费);检查指令防低级错误(9.9 vs 9.11 对齐位值);自洽性 5/5 一致(投票对冲采样随机性)
理解型踩坑 ① · 教程代码不能照抄
dashscope SDK → OpenAI 兼容端点:接口换血
教程 README 的代码是 dashscope.Generation.call(model='qwen-turbo'):要装 dashscope 包、用 qwen-turbo 模型名、响应结构是 resp.output——整套跟本机环境不匹配。
替换三件事: ① SDK:dashscope → urllib/OpenAI SDK;② 模型名:qwen-turbo/qwen-plus → qwen3.7-plus(直接查 /models 接口,别猜——我第一版写 qwen-plus 就 404);③ 响应解析:resp.output['text'] → choices[0].message.content。
通用原则: 教程的"语义"(问什么问题)可以照抄,教程的"胶水代码"(用什么 SDK 调)必须按本机环境重写。这是后续每一章都会遇到的模式。
💡 本节要点:踩坑 1:教程代码的"语义可抄、胶水必重写"——dashscope → OpenAI 兼容三件套(SDK/模型名/响应解析);模型名现查 /models,猜名字必 404
理解型踩坑 ② · 魔法咒语失效
"让我们一步一步思考"在 2026 年不灵了——这本身是个重要发现
讲义里最戏剧性的数字:MultiArith 数据集上,一句 "Let's think step by step." 把 GPT-3 从 17.7% 拉到 78.7%。我复刻实验,qwen3.7-plus 和 qwen3.6-flash 直接答全对。
为什么? 2023 年以来模型在指令遵循和数学推理上被 SFT/RLHF 补强了——"分步思考"这类模式已经内化进权重,不再需要提示词触发。提示工程的边际收益随模型变强而递减,但没说没用:它从"决定对错"退化为"决定风格/格式/可解释性"。
对学习的启示: 读老教程(GPT-3/3.5 时代)时,别被"XX 技巧提升 XX%"的对照表吓到——那些数字是在旧模型上测的。正确姿势是拿现代模型复跑一遍,看差距在哪、还剩多少。
💡 本节要点:踩坑 2:CoT 魔法咒语在现代模型上不复现(直接答已对);提示工程的边际收益随模型变强递减,价值从"对错"转向"格式/可解释";读老教程的对照数字要复跑验证
理解型踩坑 ③ · 示例决定规律,答案正确与否反而不重要
反转标签实验:模型严格跟随示例,哪怕示例是错的
讲义原话:"提示中的输入输出配对比以前想象的要重要得多,示例答案的正确与否反而相对没有那么重要。" 我用 4 组中文情感二分类示例实测:
| 示例标签 | 测试词"人山人海"的真实输出 |
|---|---|
| 正确(一见钟情→1、非常好看→0…) | 1 |
| 全部反转(一见钟情→0、非常好看→1…) | 0 |
| 输出完全跟随示例模式。更妙的是,模型两次都自行归纳出了示例背后的"规则"——它把任务理解成"判断是否四字成语"(成语→1 / 成语→0),而不是"判断情感"。这就是讲义说的:标签空间和输入分布要精心设计,模型会从示例里"学"出它以为的规律。 | |
| > 💡 本节要点:踩坑 3:少样本的规律由示例决定——标签反转,输出跟着反转;模型还会自行总结示例的"隐藏规则"(把情感分类学成成语判断);配对比答案正确性更重要(讲义论断实测复现) |
验证数据 · 实验汇总
一份 Qwen 的账:19 次调用,6 项技术全部跑通
| 实验 | 模型 | 结果 |
|---|---|---|
| 基础调用(菜谱) | qwen3.7-plus | ✅ 完整菜谱 |
| 零样本翻译 en2fr | qwen3.7-plus | ✅ fromage |
| 少样本翻译 en2fr | qwen3.7-plus | ✅ fromage(与零样本相同) |
| 零样本方面级情感 | qwen3.7-plus | ✅ 语义对,自由格式 |
| 少样本方面级情感 | qwen3.7-plus | ✅ 严格 [[performance, positive]] |
| 16 球问题直接答 | qwen3.7-plus / flash | ✅ 4 / 4 |
| 16 球问题 CoT | qwen3.7-plus / flash | ✅ 4,完整推理链 |
| Jewel 杂志(带干扰项) | qwen3.7-plus | ✅ 20,主动识别干扰信息 |
| 向日葵种子多步运算 | qwen3.7-plus | ✅ 90 |
| 9.9 vs 9.11 直接/检查 | qwen3.7-plus / flash | ✅ 9.9 更大(未踩版本号陷阱) |
| JSON 结构化输出 | qwen3.7-plus | ✅ 严格 JSON |
| 正确标签 few-shot | qwen3.7-plus | ✅ 1(跟随示例) |
| 反转标签 few-shot | qwen3.7-plus | ✅ 0(跟随反转示例) |
| 自洽性 5 次采样 | qwen3.7-plus t=0.7 | ✅ 5/5 一致 |
| > 注:口径——19 次调用含 2 次超时重试(token-plan 端点偶发慢);全部结果存 /tmp/ch2_results.json 可复现。 | ||
| > 💡 本节要点:验证:14 组实验 19 次调用全跑通——零样本基线高、few-shot 锁格式、CoT 给解释、JSON/检查/投票三件套解决工程痛点;数据可复现 |
总结
提示工程 = 不碰权重,只碰输入
—— 零样本是默认基线,2026 年已经很强;少样本锁定输出格式与模式;CoT 提供可审计的推理路径
三大技术
—— 格式(JSON/结构)、检查(复查指令)、投票(多次采样)——不改模型,只改"怎么问"
三个工程杠杆
—— 教程语义可抄、胶水代码必重写;老教程的对照数字要复跑验证;示例决定规律,配对比答案重要
三条踩坑教训
理解了"怎么问",下一步就是"怎么改":微调与部署——BERT 分类 + Gradio 一键上线
- 📐 · EP36 · 开篇 · 11 章地图 + 设备评估 + 六阶段路线图 ✅
- 💬 · EP37 · 提示学习 · ch2:API、few-shot、CoT 实战——本期 ✅
- 🛠️ · EP38 · 微调部署 · 预告:ch1 微调与部署——BERT 分类 + Gradio 一键上线
本期证据:ch2 README + 76 页 PDF 讲义 + notebook 全读 · token-plan Qwen API 14 组真实实验(19 次调用)· 真实输入输出全部收录于本文
💡 本节要点:总结:零样本是基线、少样本锁格式、CoT 给解释;三杠杆(JSON/检查/投票);三教训(胶水必重写、旧数字要复跑、示例定规律);下期 EP38:ch1 BERT 微调 + Gradio 部署