# 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. 布置本文件第九节实验作业
