从零构建一个AI驱动的英语单词默写小程序:技术架构全解析
从零构建一个AI驱动的英语单词默写小程序:技术架构全解析
本文记录了一个英语单词默写辅助工具从0到1的完整技术实践,涵盖AI多模态识别、云开发架构、语音合成等核心模块的设计思路与踩坑经验。适合想了解小程序全栈开发、AI能力落地实践的开发者阅读。想体验小程序整体效果wx中搜索英语单词默写AI助手
一、项目背景与痛点
作为一个需要辅导孩子英语默写的家长,我发现了几个典型的痛点:
- 家长发音不标准:很多家长自己的英语发音就不够标准,带孩子读单词反而"教错"
- 批改耗时耗力:逐字对照课本批改,效率极低
- 错词管理混乱:孩子错了哪些词、错了几次,全凭记忆,缺乏系统管理
- 激励机制缺失:孩子默写缺少正向反馈,容易产生抵触情绪
基于这些真实场景,我决定用技术来解决这些问题。整个项目采用微信小程序原生开发 + 微信云开发的全栈方案,无需自建服务器,一个人就能完成前后端开发。
二、整体技术架构
2.1 架构概览
项目采用经典的三层架构:
┌─────────────────────────────────────────────────────────────┐ │ 小程序前端层 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │ │ │ 默写流程 │ │ 拍照批改 │ │ 点读功能 │ │ 用户中心/统计 │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────────┬────────┘ │ │ └─────────────┴──────────┴────────────────┘ │ │ │ │ │ ┌──────────▼──────────┐ │ │ │ 前端工具层 │ │ │ │ (音频/图片/AI/分享) │ │ │ └──────────┬──────────┘ │ └─────────────────────────┼───────────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────────┐ │ 微信云开发层 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 云函数(13个) │ │ │ │ • 用户管理(注册/资料/次数扣减/分享奖励) │ │ │ │ • AI 服务(多模态识别 / 智能批改 / OCR) │ │ │ │ • 语音服务(TTS 合成 / ASR 识别) │ │ │ │ • 数据同步(本地数据云端备份) │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 云数据库(MongoDB 风格) │ │ │ │ • user 集合:用户资料 / 权限 / 统计 / 错题本 │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 云存储 │ │ │ │ • TTS 音频文件 / 临时图片 / 用户头像 │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ┌─────────────────────────▼───────────────────────────────────┐ │ 第三方 AI 服务层 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ 百度 OCR │ │ 腾讯云 │ │ 大模型(混元/GLM) │ │ │ │ 文字识别 │ │ TTS + ASR │ │ 多模态识别 + 批改 │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘2.2 技术选型理由
| 技术 | 选择理由 |
|---|---|
| 微信小程序原生 | 目标用户是家长群体,微信生态触达率最高,无需下载 |
| 微信云开发 | 免运维、免服务器配置,个人开发者一人搞定全栈,云函数自动扩缩容 |
| 百度 OCR | 印刷体识别率高,支持高精度版本,价格亲民 |
| 腾讯云 TTS | 支持多种音色,发音质量接近真人,与云开发同生态 |
| 混元大模型 | 腾讯云内置支持,流式调用避免网关超时,中文语境理解好 |
三、核心功能模块详解
3.1 AI 多模态识别:让"拍照导入单词"成为现实
这是整个项目技术含量最高的模块。传统的 OCR 对手写体识别效果一般,而家长的需求是:孩子课本/作业本上的单词,拍张照就能自动识别出来生成默写列表。
识别流程设计
用户拍照/选图 │ ▼ ┌─────────────────────┐ │ 前端图片预处理 │ ← Canvas 压缩(长边≤1600,quality 0.92) └──────────┬──────────┘ ▼ ┌─────────────────────┐ │ AI 多模态识别 │ ← 调用 GLM-5V-Turbo 识别图片中的英文单词 │ (ai-vision 云函数) │ 支持手写体/印刷体两种模式 └──────────┬──────────┘ │ 识别失败 ▼ ┌─────────────────────┐ │ 百度 OCR 兜底 │ ← 高精度印刷体/手写体识别 + 行列聚类排序 │ (ocr-word-detect) │ 提取题号、过滤低置信度结果 └──────────┬──────────┘ ▼ ┌─────────────────────┐ │ 结果编辑页 │ ← 用户可增删改,确保词表准确 └─────────────────────┘行列聚类算法:解决 OCR 结果乱序问题
OCR 返回的文本坐标是离散的,直接按 y 坐标排序在遇到换行、表格等场景时会错乱。我实现了一个行列聚类算法:
// 核心思路:双向中心包含判断,替代简单的距离阈值functionclusterWords(words){constlines=[];for(constwordofwords){constcenterY=(word.top+word.bottom)/2;letmatched=false;// 判断当前单词属于哪一行:双向中心包含for(constlineoflines){constlineCenterY=(line.minY+line.maxY)/2;// 单词中心是否在当前行范围内,且当前行中心是否在单词范围内constwordInLine=centerY>=line.minY&¢erY<=line.maxY;constlineInWord=lineCenterY>=word.top&&lineCenterY<=word.bottom;if(wordInLine||lineInWord){line.words.push(word);line.minY=Math.min(line.minY,word.top);line.maxY=Math.max(line.maxY,word.bottom);matched=true;break;}}if(!matched){lines.push({words:[word],minY:word.top,maxY:word.bottom});}}// 每行内部按 x 坐标排序returnlines.map(l=>l.words.sort((a,b)=>a.left-b.left));}这个算法相比传统的"距离阈值法",对字体大小差异、行间距不均匀的适配性更好。
大模型流式调用:绕过 15 秒网关超时
微信小程序云函数有 15 秒的 HTTP 网关超时限制,而大模型处理一张图片往往超过这个时间。解决方案是使用streamText进行流式调用:
// 云函数 ai-vision 核心逻辑conststream=awaitai.streamText({model:'hunyuan-v3',messages:[{role:'user',content:[{type:'image',image:base64Image},{type:'text',text:prompt}]}]});// 流式读取,避免整体响应超时letfullText='';forawait(constchunkofstream.textStream){fullText+=chunk;}同时设计了三段兜底策略:GLM 首次调用 → GLM 重试 → Kimi 备份模型,确保识别成功率。
3.2 拍照批改:AI 替代家长逐字核对
这是用户价值最直接的模块。孩子默写完,拍张照片,AI 自动对照原始词表批改。
批改流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 原始词表 │ │ 默写照片 │ │ 用户编辑 │ │ (预期单词) │ + │ (实际书写) │ → │ 确认词表 │ └──────┬──────┘ └─────────────┘ └──────┬──────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ AI 智能批改 (ai-grade 云函数) │ │ • 调用腾讯混元 hy3-preview 模型 │ │ • Prompt 设计:要求 JSON 格式返回每个单词的批改结果 │ │ • 容错设计:考虑 OCR 常见误识(l↔1、o↔0、I↔l) │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 结果页 │ │ • 正确/错误/漏写 三种状态标记 │ │ • 正确率统计 + 星级评分 │ │ • 一键加入错题本 │ └─────────────────────────────────────────────────────────┘Prompt 工程:让大模型输出结构化结果
批改的核心是大模型的 Prompt 设计。我要求模型返回严格的 JSON 格式,便于前端解析:
你是一位严格的英语老师。请对照"预期单词列表"批改"学生默写内容"。 要求: 1. 返回 JSON 数组,每个元素包含:word(单词)、status(correct/wrong/missing)、reason(批改说明) 2. 考虑 OCR 误识的容错:l/1、o/0、I/l 等常见混淆可视为正确 3. 拼写错误但发音相近的标注为 wrong 并说明 4. 漏写的单词标注为 missing 预期单词:[apple, banana, orange, ...] 学生默写(OCR识别结果):[aple, banana, 0range, ...]为了应对模型偶尔返回"不纯粹 JSON"的情况,还加了多层解析兜底:
// JSON 安全解析策略functionsafeParseJSON(text){// 策略1:直接解析try{returnJSON.parse(text);}catch(e){}// 策略2:提取代码块中的 JSONconstcodeBlock=text.match(/```(?:json)?\s*([\s\S]*?)```/);if(codeBlock){try{returnJSON.parse(codeBlock[1]);}catch(e){}}// 策略3:提取方括号包裹的内容constbracket=text.match(/\[[\s\S]*\]/);if(bracket){try{returnJSON.parse(bracket[0]);}catch(e){}}returnnull;}3.3 语音播放系统:让机器"读"单词
TTS 合成 + 本地缓存
调用腾讯云 TTS 合成音频后,将音频文件上传至云存储获取临时 URL,前端播放。为了节省调用成本,实现了音频缓存:
// 音频缓存策略asyncfunctiongetVoiceUrl(word,speed){constcacheKey=`voice_${word}_${speed}`;constcached=wx.getStorageSync(cacheKey);// 缓存有效期 7 天if(cached&&Date.now()-cached.timestamp<7*24*60*60*1000){returncached.url;}// 调用云函数合成const{fileID,tempFileURL}=awaitcallTTSCloudFunction(word,speed);wx.setStorageSync(cacheKey,{url:tempFileURL,timestamp:Date.now()});returntempFileURL;}ASR 语音指令:解放双手
播放页支持语音控制,孩子可以说"下一个"、“暂停”、"重复"等指令控制播放流程:
播放单词 "apple" │ ▼ ┌─────────────────┐ │ 播放间隙监听 │ ← 启动 ASR 识别 │ (约 500ms 窗口) │ └────────┬────────┘ │ 识别到语音 ──→ "下一个" │ ▼ 播放下一个单词3.4 点读功能:离线词库 + 即点即读
针对低龄用户(幼儿园/小学低年级),设计了四个点读模块:
| 模块 | 内容 | 数据来源 |
|---|---|---|
| 音标点读 | 48 个国际音标 | 静态内置 |
| 字母点读 | 26 个英文字母 | 静态内置 |
| 常用单词 | 颜色、动物、水果、数字等主题 | 静态内置词库 |
| 常用短句 | 日常对话短句 | 静态内置 |
这些模块完全离线,无需网络即可使用,降低了使用门槛。
四、数据库设计
采用单集合设计(user),以 OpenID 为主键,兼顾查询效率与开发复杂度:
{_id:"openid_xxx",// 主键openid:"openid_xxx",nickname:"小明妈妈",avatar:"https://...",// 权限体系free_times:5,// 剩余免费次数vip_type:"none",// none / month / yearvip_expire:null,// 分享激励share_count_today:0,share_last_date:"2026-06-11",// 累计统计stats:{total_words:120,correct_words:98,dictation_count:15},// 业务数据wishlist:{prize:"玩具车",target_stars:50,current_stars:32},wishlistHistory:[...],correctionHistory:[...],wrongBook:[// 错题本{word:"apple",wrong_count:3,last_wrong:"2026-06-10"}],wordCollections:[...],// 自定义单词集settings:{voice_speed:1.0,auto_next:true}}设计考量:
- 单集合避免多表关联,云开发环境下更简单
- 原子累加操作(
$inc)处理统计字段,避免并发覆盖 - 分享奖励在服务端做冷却校验,防刷
五、项目目录结构
wordDictation/ ├── miniprogram/ # 小程序前端 │ ├── app.js / app.json / app.wxss │ ├── pages/ # 24 个页面 │ │ ├── index/ # 默写首页 │ │ ├── camera/ # 拍照识别 │ │ ├── result/ # 识别结果编辑 │ │ ├── play/ # 语音播放页 │ │ ├── finish/ # 默写完成 │ │ ├── photo-grade/ # 拍照批改 │ │ ├── tabs/ # 点读入口 │ │ ├── phonics/ # 音标点读 │ │ ├── common-words/ # 常用单词 │ │ ├── my/ # 个人中心 │ │ └── ... │ ├── utils/ # 工具模块 │ │ ├── ai-vision.js # AI 多模态识别 │ │ ├── ai-grade.js # AI 批改调用 │ │ ├── audio-controller.js # 音频播放器封装 │ │ ├── share.js # 分享激励逻辑 │ │ └── ... │ └── config/ # 配置文件 │ ├── cloudfunctions/ # 云函数(13个) │ ├── ai-vision/ # AI 多模态识别 │ ├── ai-grade/ # AI 智能批改 │ ├── ocr-word-detect/ # 百度 OCR │ ├── word-tts-synthesize/ # TTS 语音合成 │ ├── asr-word-detect/ # ASR 语音识别 │ ├── user-info/ # 用户注册查询 │ ├── user-times-deduct/ # 次数扣减 │ ├── user-times-share-reward/ # 分享奖励 │ └── ... │ └── docs/ # 项目文档六、踩坑与经验总结
6.1 云函数 15 秒超时问题
微信小程序云函数的 HTTP 网关超时是 15 秒,而大模型处理图片往往需要 20-30 秒。解决方案:使用streamText流式调用,边接收边处理,避免等待完整响应。
6.2 图片上传尺寸优化
用户可能上传几 MB 的手机原图,直接传给 AI 服务既慢又贵。解决方案:前端用 Canvas 做等比缩放,长边限制 1600px,质量 0.92,通常能压缩到 200KB 以内。
6.3 音频文件堆积
TTS 合成的音频文件会不断累积,长期会占满云存储空间。解决方案:云数据库记录音频元数据,配合定时触发器(clean-audio-daily)清理过期文件。
6.4 分享防刷
分享换次数的激励机制容易被薅羊毛。解决方案:服务端记录最后分享时间戳,设置冷却时间 + 每日上限双重限制。
七、效果数据与迭代方向
当前核心指标
| 指标 | 数据 |
|---|---|
| 页面数量 | 24 个 |
| 云函数 | 13 个 |
| AI 识别准确率 | > 90%(印刷体)/ > 75%(手写体) |
| TTS 缓存命中率 | ~80% |
后续规划
- AI 识别准确率继续提升:引入更多多模态模型做 A/B 对比
- 学习报告:基于错题本生成周期性学习报告,可视化进步曲线
- 班级模式:支持老师创建班级,批量布置默写任务
- 多语言支持:扩展至其他科目(语文生字、数学口算等)
八、结语
这个项目的核心思路是:用 AI 能力降低家长的辅导负担,用游戏化设计提升孩子的学习兴趣。技术栈选择上走"轻量路线"——微信小程序原生 + 云开发,让个人开发者也能独立交付一个完整的产品。
如果你对某个模块的实现细节感兴趣,欢迎在评论区交流,我可以单独展开讲解。
关于作者:一名全栈开发者,也是一名家长。相信技术应该服务于真实的生活场景。这个项目的每一行代码都源自"给自己孩子用"的初心。
