Files
doodle-mini/docs/AI生成题目方案.md
2026-06-25 12:46:43 +08:00

171 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 生成题目方案(对话式出题)
> 文档状态:方案讨论 / 待评审
> 创建日期:2026-06-16
> 背景:当前小程序与同类应用差异不明显,用户画像不够精准。探索引入 AI 能力——用户用自然语言描述需求,AI 将其翻译为对预置「技能(绘制方法)」的调用,并完成出题与绘制。
---
## 一、战略层面:先想清楚「为什么要做」
本方案在技术上完全可行,但要避免 AI 沦为「为差异化而加的功能」,而非「解决真实痛点的功能」。立项前需先回答:
- **用户的真实痛点是什么?** 是「找不到合适的题目」,还是「孩子不爱练」「不知道该练什么」?如果痛点不在出题,AI 出题器再酷也救不了留存。
- **家长真的会打字描述需求吗?** 「我想要培养数感的题目」这类话,家长未必说得出(多数人不知道「数感」是什么)。更真实的诉求往往是「我家娃 5 岁,给我今天该练的」。这意味着 AI 的价值可能不在「自然语言理解」,而在 **「帮不懂教育的家长做决策」**。
- **不用 AI 能否满足 80%?** 如果几个下拉框 + 模板就能满足,AI 的边际价值仅是「输入方式更自然」,通常撑不起差异化。
**结论 / 定位建议:** 把 AI 定位成 **「懂教育的助教」**(帮家长判断该练什么、循序渐进地推荐),而不是 **「自然语言转绘制指令的翻译器」**。前者是真差异,后者只是花哨的表单。
---
## 二、技术层面:经典的 Function Calling / Tool Use 架构
「把需求变成可调用的技能」在工程上的成熟范式叫 **工具调用(tool use / function calling**:已有的「绘制方法」即工具,LLM 负责把人话翻译成「调用哪个工具 + 什么参数」。
### 2.1 整体数据流(小程序云开发)
```
用户输入(自然语言)
→ 小程序前端 (聊天式 UI)
→ 云函数 ai-orchestrator
→ 调用 LLM(带 tools 定义)
├─ 缺参数 → 返回追问("孩子几岁?") ← 多轮
└─ 参数齐全 → 返回结构化调用意图
→ 确认环节(用户点"确认生成")
→ 云函数 / 前端调用内置绘制方法
→ 生成题目数据 + 渲染(canvas/图片)
→ 返回前端展示 / 保存 / 下载
```
### 2.2 关键模块
**1)技能注册表(最核心)**
每个绘制方法描述成一个 tool schema,让 LLM 知道有哪些能力、各需要什么参数:
```json
{
"name": "generate_number_sense",
"description": "生成培养数感的练习题(比大小、数的分解、数数等)",
"parameters": {
"type": "object",
"properties": {
"age": { "type": "integer", "description": "孩子年龄 3-8" },
"sub_type": { "type": "string", "enum": ["比大小", "数的分解", "按数取物"] },
"count": { "type": "integer", "description": "题目数量" },
"number_range": { "type": "string", "enum": ["1-10", "1-20", "1-100"] }
},
"required": ["age", "sub_type", "count"]
}
}
```
**2)LLM 选型(国内合规很重要)**
云函数可发 HTTP 请求,能接任意 LLM。国内备案合规、且支持 OpenAI 兼容 function calling 的可选:**通义千问、豆包(火山方舟)、DeepSeek、文心、混元**。微信云开发本身也有「AI 能力 / 微信对话开放平台」。建议挑一个支持 `tools` 参数的,编排逻辑几乎无需自写。
**3)多轮对话 + 槽位填充(slot filling**
「缺年龄就追问年龄」的逻辑交给 LLM 判断,比手写 if-else 更强。需要做的只是:
- 每轮带上对话历史(存云数据库或前端回传);
- 在 system prompt 里要求:「参数不全时先友好追问,不要瞎猜」。
**4)「决策」与「生成」必须分离 ⚠️(最重要的工程原则)**
让 LLM 决定「生成什么」(结构化参数),但题目实际内容由确定性代码生成:
- ❌ 不要让 LLM 直接吐出 20 道算术题——会算错、会重复、不可控。
- ✅ 让 LLM 输出 `{age:5, sub_type:"比大小", count:20, range:"1-10"}`,再由绘制方法按规则生成 + 渲染。
兼得 AI 的「听得懂人话」与传统代码的「100% 正确可控」。
**5)确认环节**
真正调用绘制方法前,把解析出的参数回显给用户确认(「将生成 20 道 1-10 比大小,确认?」)。既防误解,也是好体验。
### 2.3 小程序云开发的几个坑
| 坑 | 说明 / 对策 |
| -------------- | ------------------------------------------------------------------------------------- |
| **云函数超时** | 默认 20s,LLM 调用可能慢。先做**非流式**(一次返回);想要打字机效果,后期再用 WebSocket 或 HTTP 触发器 + SSE,复杂度高,别一开始就做。 |
| **内容安全(必须)** | 微信强制要求。用户输入和 AI 输出都要过 `security.msgSecCheck`,否则可能被封。合规硬要求,非可选。 |
| **API Key 保护** | LLM 的 key 只能放云函数环境变量,**绝不能进前端**。 |
| **成本与频率** | 每次对话烧 token。加缓存(相同需求复用)、限频,防刷。 |
| **冷启动延迟** | 云函数冷启动 + LLM 延迟叠加,首次可能 3-5sUI 要有 loading 反馈。 |
---
## 三、要不要把绘制方法搬到服务端?
**短答:不需要把「绘制」搬到服务端。但要先把现有方法拆成两层——「出题数据」和「画图」——只有前者可能值得上服务端,后者留在小程序里。**
### 3.1 把「绘制方法」拆成三层
```
① 意图理解层 用户人话 → 结构化参数 ← 必须在服务端(云函数 + LLM)
② 出题数据层 参数 → 题目数据(JSON) ← 可服务端、可客户端
③ 渲染绘制层 题目数据 → canvas 画出来 ← 留在小程序前端
```
现有「绘制方法」大概率是 ②③ 混在一起(一个函数既算题目又调 `wx.canvas` 画图)。做 AI **真正要做的不是「搬到服务端」,而是「把 ② 和 ③ 解耦」**
### 3.2 为什么渲染层(③)不该搬服务端
- 小程序 canvas 是**客户端 API**,云函数(Node 环境)里没有 DOM、没有原生 canvas;要画图得引 `node-canvas` 之类,又重又易踩坑,得不偿失。
- 渲染留前端:性能好、可交互(手写、橡皮擦等)、省服务器成本。
→ ③ **保持现状,一行都不用动**
### 3.3 ② 出题数据层:搬不搬都行
**方案 A — 什么都不搬(最快上线,推荐起步)**
云函数只做 ①,返回结构化参数给前端:
```js
// 云函数返回
{ skill: "number_sense", age: 5, sub_type: "比大小", count: 20, range: "1-10" }
```
前端拿到参数,调已有的出题 + 绘制方法,照常跑。AI 是「加在前面的一层翻译」,老代码完全复用。
**方案 B — 把出题逻辑(②)搬服务端**
云函数直接算好题目数据返回:
```js
{ problems: [ {left:7, right:3, op:">"}, {left:2, right:8, op:"<"}, ... ] }
```
前端只负责画。
什么时候才值得选 B
- 出题逻辑要**保密/防作弊**(题库、难度算法不想暴露前端);
- **多端复用**(以后有 H5、APP,出题逻辑只维护一份);
- 出题需要**服务端资源**(查数据库题库、调别的接口)。
以上都没有,**先选 A**。
### 3.4 关键动作
唯一的关键动作:**确保出题逻辑是个「纯数据函数」(输入参数、输出 JSON、不碰 canvas)**。做到这点,搬不搬服务端都是后话,随时可切。
---
## 四、最小可行起步(MVP
别一上来做全套对话系统,先做最小闭环验证:
1. **单个技能**:只挑「数感题目」一个绘制方法接进来。
2. **单轮或两轮对话**:用户说需求 → AI 解析参数(缺了追问一次)→ 确认 → 生成。
3. **跑通链路**:「人话 → 结构化参数 → 已有绘制方法」。
跑通后回答关键问题:**家长真的会用自然语言输入吗?还是更想点几下就出题?** 用真实数据决定是否继续往「对话式」投入,而非凭感觉。
---
## 五、待办 / 下一步
- [ ] 盘点现有「绘制方法」清单及调用方式,判断 ②③ 缠绕程度。
- [ ] 确定 LLM 供应商(合规 + 支持 function calling)。
- [ ] 抽离一个出题逻辑为纯数据函数(以「数感题目」为试点)。
- [ ] 搭建 `ai-orchestrator` 云函数骨架 + 技能注册表。
- [ ] 接入内容安全 `msgSecCheck`
- [ ] MVP 灰度,观察家长真实输入行为与转化数据。