分类: 未分类

  • CleanLearn 小程序 AI 对话修复实录:从语音识别不了到全链路跑通

    项目简介

    CleanLearn 是一个英语学习微信小程序,前端使用 Taro 3.6 + React + Zustand,后端是 Python FastAPI + MariaDB,部署在一台腾讯云服务器上。核心功能包括单词学习、真题模拟和 AI 对话(口语陪练)。

    这篇文章记录一次完整的线上问题排查与迭代过程:从用户反馈”AI 语音识别不了”,到对话页合并、数据库密码更换,再到部署监控,最终全部链路跑通。

    问题一:AI 语音识别不了

    现象:口语模式录音后,小程序提示”语音识别失败”。

    排查过程:先用 curl 直接测后端 /api/stt 接口,发现返回 500/400 而不是正常转写结果;进一步发现服务器的健康检查也会超时——说明整个 API 被卡住了。最终定位到两个根因:

    • 服务器无法访问 HuggingFace(网络不通),而 faster-whisper 每次启动或首次请求都要去下载模型,导致模型从未加载成功;
    • 旧版 stt_router.py 在事件循环里同步加载模型和转写,一次请求就把整个 API 冻住。

    修复

    • 从 hf-mirror.com 下载 faster-whisper tiny 模型到服务器本地(/opt/english-api/models/faster-whisper-tiny),彻底绕开外网依赖;
    • 重写 STT 路由:模型加载与转录都放进 asyncio.to_thread,事件循环不再被阻塞,失败时返回明确的 503;
    • 前端录音格式从 mp3 改为 wav,后端用 Python 内置 wave 模块解码,不再依赖 PyAV/ffmpeg。

    修复后实测:TTS 生成的英文语音能被正确转写,接口从”卡死超时”变成 1~5 秒返回结果。

    问题二:长文本 AI 朗读中断

    现象:AI 回复一长,朗读只读开头就停了。

    根因:文本在三个地方被硬截断到 200 字符——聊天页调用 speakslice(0, 200)speech.ts 里再次截断、后端 TTS 也 text[:200]。超过 200 字符的回复只朗读开头,看起来就像”中断”。

    修复

    • 前端新增 splitTextForTTS:按句子边界把长文本切成 ≤500 字符的分段,队列式逐段播放,单段失败自动跳过;
    • 聊天页改为传完整文本,不再截断;
    • 后端 TTS 上限提高到 500 字符,edge-tts 全量合成。

    验证:480 字符的文本返回 183KB 音频(原来只有 17KB),朗读完整连贯。

    问题三:AI 对话页合并

    需求:把”打字对话”和”口语录音”两个页面合并成一个,像微信一样点击语音按钮切换输入模式,按住说话、松开发送。

    实现

    • 底部 Tab 从 4 个(对话/口语/场景/记录)合并为 3 个(对话/场景/记录);
    • 输入栏左侧 麦克风/键盘 图标一键切换文字与语音模式;
    • 语音模式按住大麦克风录音(WAV、16kHz、单声道、最长 60 秒),松开自动 STT 转写并发送;
    • AI 回复自动朗读常开,配合分句播放。

    期间用户多次调整需求(”只删提示条,不删功能”),最终版本:删除冗余提示条、顶部状态栏按真题模拟页的间距预留安全区、场景提示条保留。

    数据库密码更换的教训

    为了安全把 english_app 的数据库密码换掉,过程中踩了一个坑:用 skip-grant-tables 模式改密码时,脚本里的 kill %1 在非交互 shell 中无效,导致临时实例没被清理、MariaDB 服务停在 failed 状态,数据库接口全部 500。

    正确处理:先 systemctl stop mariadb,用 --skip-grant-tables 启动临时实例执行 ALTER USER,然后杀掉临时进程systemctl start mariadb 正常启动,最后重启应用加载新配置。改完密码记得同步所有配置文件(生产 + 开发副本),并验证新旧密码的登录结果。

    部署与监控

    • 后端部署路径注意:生产代码在 /opt/english-api/routers/,不是 /opt/english-api/server/
    • 服务用 systemd 管理,改完代码清 __pycache__ 再重启;
    • 建立了持续监控:每轮检查 health / STT / TTS / chat 四个接口,STT 用真实语音样本验证转写结果;
    • 前端用 Taro watch + 微信开发者工具实时预览,确认无误后再通过 CLI 上传新版本。

    收获与后续

    这次迭代最大的收获是:线上问题要先用最小复现(curl 直测接口)定位,再顺着调用链逐层排查;AI 相关服务一定要考虑”外网不可用”的降级方案(本地模型、明确报错而不是挂死)。

    后续计划:为服务器配置 HTTPS 证书(当前真机访问会被微信拦截 http),以及完善 WordPress 博客的部署。

  • 世界,您好!

    欢迎使用 WordPress。这是您的第一篇文章。编辑或删除它,然后开始写作吧!