💻 源码
# Few-shot CoT 演示项目 — 完整说明(老师 / 学生通用)

> 项目路径:`06_代码/Day_02/fewshot_cot_demo/`  
> 讲课话术版:[`课堂讲解指南.md`](课堂讲解指南.md)  
> 数学陷阱题对比:[`../cot_demo/`](../cot_demo/)

---

## 零、30 秒定位:我要找的东西在哪?

**最容易迷路的三件事,直接看这张表:**

| 你想找什么 | 打开哪个文件 | 变量 / 位置 |
|---|---|---|
| **今天要演示的主题目**(小明 70 岁那道) | `question.py` | `MAIN_QUESTION.question`(约第 24 行) |
| **Few-shot 示例题**(苹果题、小红弟弟题) | `examples.py` | `FEW_SHOT_EXAMPLES` 列表(约第 25 行) |
| **三种模式的提示词指令** | `prompts.py` | `SYSTEM_DIRECT` / `SYSTEM_ZERO_SHOT_COT` / `SYSTEM_FEW_SHOT_COT` |
| **程序入口(运行演示)** | `main.py` | 双击 `run.bat` 或 `python main.py` |
| **三种模式怎么拼 messages** | `demo.py` | `run_direct` / `run_zero_shot_cot` / `run_few_shot_cot` |
| **真正调用大模型的地方** | `llm_client.py` | `call_llm()` |
| **API Key、模型名** | `config.py` | `API_KEY`、`MODEL_NAME` |

**一句话记忆:**

- 主题目 → `question.py`
- 示例题 → `examples.py`
- 提示词 → `prompts.py`
- 跑起来 → `main.py`

---

## 一、这个项目是做什么的?

用**同一道年龄推理题**,分别以三种提示词策略去问百炼 `qwen-plus`,对比:

| 模式 | 代码函数 | 有没有示例 | 课堂一句话 |
|---|---|---|---|
| A · 无 CoT | `demo.run_direct()` | 无 | 直接要答案 |
| B · 零样本 CoT | `demo.run_zero_shot_cot()` | 无 | 加一句「请一步一步思考」 |
| C · 少样本 CoT | `demo.run_few_shot_cot()` | **有 1~2 个推理示例** | 先示范怎么推理,再答新题 |

**本项目和 `cot_demo` 的分工:**

| 项目 | 题目文件 | 讲什么 |
|---|---|---|
| `cot_demo` | `questions.py`(3 道数学题) | 建立直觉:复杂题无 CoT 易错 |
| `fewshot_cot_demo`(本项目) | `question.py` + `examples.py` | 深入 Few-shot CoT:示例怎么设计 |

---

## 二、题目全文(不用翻代码也能讲)

### 2.1 主题目(程序运行时会问模型的那道题)

> **当小明 6 岁时,他的妹妹年龄是他的一半。他的哥哥比小明大 4 岁。现在小明 70 岁了,请问他的妹妹和哥哥年龄加起来是多少?**

| 项目 | 内容 |
|---|---|
| 正确答案 | **141 岁** |
| 标准过程 | 妹妹比小明小 3 岁 → 67;哥哥大 4 岁 → 74;67+74=141 |
| 常见误区 | 把「妹妹当时是一半」当成「妹妹现在也是 70 的一半 = 35」 |
| 代码位置 | `question.py` → `MAIN_QUESTION` |

### 2.2 Few-shot 示例题(只在模式 C 里出现)

**示例 1 · 苹果加法(教写法格式)**

> 小明有 3 个苹果,又买了 2 个,他现在一共有几个苹果?  
> 标准答案:5 个(先列条件 → 列关系 → 计算)

**示例 2 · 小红弟弟(教年龄差不变,预热主题目易错点)**

> 当小红 8 岁时,她的弟弟年龄是她的一半。现在小红 20 岁了,请问弟弟现在几岁?  
> 标准答案:16 岁(8 岁时弟弟 4 岁,年龄差 4 岁不变)

| 项目 | 内容 |
|---|---|
| 代码位置 | `examples.py` → `FEW_SHOT_EXAMPLES[0]` 和 `[1]` |
| 控制用几个示例 | 运行 `python main.py --shots 1` 只用示例 1;默认 `--shots 2` 两个都用 |

### 2.3 和课程笔记的对应关系

主题目与 `02_笔记/Day02/04_Day02_完整笔记.md` **第八节「课堂重点题」** 完全一致,讲课可直接引用笔记 + 本项目代码对照。

---

## 三、目录结构(每个文件干什么)

```
fewshot_cot_demo/
├── main.py           # 【入口】组织 A/B/C 三种模式演示,打印对比小结
├── demo.py           # 【核心】三种模式组装 messages 并调用模型
├── question.py       # 【主题目】MAIN_QUESTION — 小明/妹妹/哥哥年龄题
├── examples.py       # 【示例题】FEW_SHOT_EXAMPLES — Few-shot CoT 的示范题
├── prompts.py        # 【提示词】三种模式的 system / user 模板
├── llm_client.py     # 【API】唯一联网层,调用 dashscope.Generation.call
├── config.py         # 【配置】DASHSCOPE_API_KEY、模型名、温度
├── display.py        # 【展示】终端打印介绍、概念说明
├── run.bat           # 双击运行(默认 2 个示例)
├── requirements.txt  # 依赖:dashscope
├── README.md         # 快速上手
└── docs/
    ├── 项目说明.md       # 本文件:找题目、懂结构、会改实验
    └── 课堂讲解指南.md   # 老师讲课话术、板书、FAQ
```

---

## 四、三种模式分别发了什么给模型?

### 模式 A:无 CoT

```text
system: 「只输出一行最终答案,禁止写推理过程」
user:   【主题目原文,来自 question.py】
```

### 模式 B:零样本 CoT

```text
system: 「必须先写推理过程,按第一步/第二步组织…」
user:   【主题目原文】+ 「请一步一步思考,并把每一步推理过程写出来。」
```

### 模式 C:少样本 CoT(重点)

```text
system:    「请模仿示例的推理格式…遇到年龄题要先算年龄差…」
user:      【示例 1 的问题】          ← examples.py
assistant: 【示例 1 的完整推理过程】   ← examples.py
user:      【示例 2 的问题】          ← examples.py(--shots 2 时)
assistant: 【示例 2 的完整推理过程】   ← examples.py(--shots 2 时)
user:      【主题目原文】              ← question.py
```

**课堂要强调:** 模式 C 比模式 B 多了中间的 `user + assistant` 示例对话轮次;示例的 `assistant` 里必须写推理过程,不能只写最终数字。

对应代码:`demo.py` 里的 `run_few_shot_cot()`。

---

## 五、程序运行流程(老师演示时按这个顺序讲)

```
第 0 步  打开终端,进入项目目录
         cd 06_代码\Day_02\fewshot_cot_demo

第 1 步  main.py 启动 → 检查 DASHSCOPE_API_KEY

第 2 步  从 question.py 读取 MAIN_QUESTION(主题目)
         从 examples.py 读取 FEW_SHOT_EXAMPLES(示例题)

第 3 步  模式 A:prompts.py(SYSTEM_DIRECT) + 主题目 → API → 打印
第 4 步  模式 B:prompts.py(SYSTEM_ZERO_SHOT_COT) + 主题目 → API → 打印
第 5 步  模式 C:prompts.py + 示例对话 + 主题目 → API → 打印

第 6 步  对比三种模式的「最终答案 / 是否正确 / 有没有分步推理」
```

**跑 1 次完整演示 = 3 次 API 调用**(A、B、C 各 1 次)。

---

## 六、怎么运行?

### 前置条件

1. Python 3.8+
2. `pip install -r requirements.txt`
3. Windows 系统环境变量已配置 `DASHSCOPE_API_KEY`(配置后需重新打开终端)

### 命令

```powershell
cd 06_代码\Day_02\fewshot_cot_demo

python main.py              # 默认:主题目 + 2 个 Few-shot 示例
python main.py --shots 1    # 只用 1 个示例(做对比实验)
python main.py --shots 2    # 用 2 个示例(与默认相同)
```

或双击 `run.bat`。

---

## 七、实测结果参考(qwen-plus,供课堂预期)

以下为真实 API 调用结果,不同账号/时间措辞可能略有差异,但对比关系稳定:

| 模式 | 典型最终答案 | 有无分步推理 | 教学价值 |
|---|---|---|---|
| A · 无 CoT | **136**(错误) | 无 | 说明直接要答案会跳步 |
| B · 零样本 CoT | **141**(正确) | 有(6 步左右) | 说明「请一步一步思考」能触发思维链 |
| C · 少样本 CoT | **141**(正确) | 有(格式贴近示例) | 说明示例能稳定推理写法 |

课堂可让学生重点看:**同一道题、同一个模型,只改提示词,答案从错变对。**

---

## 八、老师怎么给同学讲(15 分钟版路线)

### 课前准备(2 分钟)

1. 打开 `question.py`,投屏 `MAIN_QUESTION`,先把主题目念一遍
2. 打开 `examples.py`,指出示例 1、示例 2 分别教什么
3. 打开 `prompts.py`,快速扫一眼三种 `SYSTEM_*` 的差异

### 课中演示(10 分钟)

| 顺序 | 做什么 | 指着哪里讲 |
|---|---|---|
| 1 | 让学生先心算主题目 | `question.py` 或笔记第八节 |
| 2 | 运行 `python main.py` | 终端输出 |
| 3 | 先看模式 A 答错 | 对照 `prompts.py` 的 `SYSTEM_DIRECT` |
| 4 | 再看模式 B 答对 | 对照 `USER_ZERO_SHOT_COT_TEMPLATE` 里的「请一步一步思考」 |
| 5 | 最后看模式 C | 对照 `demo.py` 里怎么插入示例,再看 `examples.py` |
| 6 | 跑 `--shots 1` 对比 | 讨论示例质量 vs 数量 |

### 收束(3 分钟)

用三句话总结:

1. **CoT** = 先写步骤再给答案(草稿纸)
2. **Zero-shot CoT** = 只说「请一步一步想」,不给例题
3. **Few-shot CoT** = 例题里带完整推理,让模型模仿写法

更详细话术见 [`课堂讲解指南.md`](课堂讲解指南.md)。

---

## 九、学生改实验指南

| 想改什么 | 改哪个文件 | 改完怎么验证 |
|---|---|---|
| 换一道主题目 | `question.py` → `MAIN_QUESTION` | `python main.py` |
| 增删改 Few-shot 示例 | `examples.py` → `FEW_SHOT_EXAMPLES` | `python main.py --shots 1` |
| 调整「请一步一步思考」等指令 | `prompts.py` | `python main.py` |
| 换模型 | `config.py` → `MODEL_NAME` | `python main.py` |

**推荐实验:**

1. 删掉 `examples.py` 里的示例 2,只留示例 1,对比模式 C 是否仍答对
2. 把 `prompts.py` 里 `SYSTEM_FEW_SHOT_COT` 中「要先算年龄差」那句删掉,再对比 `--shots 1` 和 `--shots 2`
3. 自己写一个「找零」或「买卖数量」的 Few-shot CoT 示例替换示例 1

---

## 十、常见问题

**Q:题目到底在哪?怎么一眼找到?**  
A:主题目在 `question.py` 的 `MAIN_QUESTION`;示例题在 `examples.py` 的 `FEW_SHOT_EXAMPLES`。运行 `main.py` 时终端也会打印题目全文。

**Q:为什么终端里题目出现了好几次?**  
A:开头打印的是「题目说明」;模式 A/B/C 各调用一次 API,但问的是同一道主题目;模式 C 还会额外带上示例题(来自 `examples.py`)。

**Q:模式和文件的对应关系?**  
A:`prompts.py` 决定「怎么说」;`question.py` / `examples.py` 决定「说什么」;`demo.py` 负责拼在一起。

**Q:和 `cot_demo` 先讲哪个?**  
A:建议先 `cot_demo`(9.9 vs 9.10,直觉强),再本项目(Few-shot 示例设计)。

**Q:运行报错「未读取到 DASHSCOPE_API_KEY」?**  
A:在 Windows 系统环境变量中配置后,**重新打开终端**再运行。

---

## 十一、建议阅读顺序

**学生:**

1. 读本文件「零、30 秒定位」→ 知道题目在哪
2. 运行 `python main.py` 看终端对比
3. 打开 `question.py`、`examples.py` 对照终端输出
4. 读 `prompts.py` → `demo.py` → `llm_client.py`

**老师:**

1. 读 [`课堂讲解指南.md`](课堂讲解指南.md) 第四节「课堂导入」
2. 课前打开 `question.py` + `examples.py` 备课
3. 课中按本文件第八节路线演示
4. 布置本文件第九节实验作业