AI脑洞板
完整教案
自学课件
第 28 课 · 共 28/51 课

完整语音助手 听、想、说的协作

课时
待定
器材
ESP32-S3 触摸屏板 + USB 线
前置知识
无
配套代码
见项目 demo 目录

一、先做一件事:让它"等"你说话

烧录 demo01_ai_voice(要联网、要密钥)。上电后屏幕顶部出现青绿色状态条,旁边写着"准备就绪 / 按键开始说话"。

先别急着按。做三件事:

  1. 盯着那条状态条,记住它的颜色和文字;
  2. 看看屏幕上有两张卡片:"我说"(空白)和**"助手回答"**(空白);
  3. 然后按住 BOOT 键说一句话(比如"今天天气怎么样"),松开。

看:状态条会依次变色——红(正在录音)→ 黄(正在识别)→ 橙(正在思考)→ 回到青绿(准备就绪)。"我说"卡片出现你说的字,"助手回答"卡片出现它回答的话。

为什么说它"会等"?因为它待机时什么都不干,就等你按。这就是一台真 AI 设备的样子。


二、状态机:一块板子穿五件"马甲"

现在,把整台助手看成一个穿马甲的后台小剧组:板子是舞台,演员每次上场只演一个角色,演完就退场换下一场。这叫状态机(State Machine)。

这块板子一共五件马甲:

状态(马甲)状态条它在干什么谁能让它"让位"我看到的
待机 READY青绿 · 准备就绪 / "按键开始说话"安静等你,什么都不做按下 BOOT → 变"录音"两张卡片都是空
录音 RECORDING红 · 正在录音 + 进度条(3 秒填满)麦克风采 16kHz/16bit/单声道 PCM,存内存松开 BOOT 或录满 3 秒 → 变"识别"卡片还是空,进度条在涨
识别 RECOGNIZING黄 · 正在识别 / "请稍候"把 PCM 转 base64 寄给百度,换回文字收到文字 → 变"思考";失败 → 变"错误""我说"出现你说的字
思考 THINKING橙 · 正在思考 / "请稍候"把文字 + system 提示词寄给火山豆包,换回答收到回答 → 悄悄变回"待机";失败 → 变"错误""助手回答"出现 AI 回答
错误 ERROR红 · 发生错误亮出红字,停住等你按 BOOT → 回到"待机"下方出现红字

⚠️ 比喻的边界:状态机不是"心情"、不是"人格"——板子不会"高兴了才干活"。它必须也只能处于一个状态,换状态是被事件触发的(按键、计时、云端回信),不是它自己决定的。而且状态有限且有数——就这五件,你数得清。最关键的一点:它每一刻只穿一件马甲,绝不会"一边待机一边又在思考"。

状态机五件马甲:待机/录音/识别/思考/错误,每刻只穿一件、被事件触发换装


三、一次完整对话:环形链路图

把五件马甲串起来,就是一条环形数据流:

待机 —— 按下 ——> 录音 —— 松开/录满3秒 ——> 识别 —— 成功 ——> 思考 —— 成功 ——> 回到待机
                                                       |失败                    |失败
                                                       +------> 错误 ——按BOOT——> 回到待机

(彩色箭头版见教案.md 第四节;你只要能顺着箭头说一遍就算懂了。)

看懂的标准:能指着每一环说出——它现在在干嘛、寄给谁、收到什么才换下一件、失败了往哪走。

一次完整对话的环形链路:待机→录音→识别→思考→回待机,失败→错误→按 BOOT 回待机


四、一句话讲清:两段"寄包裹"

这台助手做两趟"寄包裹":

第一趟(识别):你说话 → 板子把声音数字(PCM)包成 base64 → 寄给百度 → 百度猜出文字 → "我说"卡片亮出来。

第二趟(思考):板子把文字 + 一段 system 提示词 → 寄给火山豆包 → 豆包按提示词的口吻回答 → "助手回答"卡片亮出来。

system 提示词就一行(程序里写的),意思是:"你是一个运行在 ESP32-S3 上的语音助手,用简洁的中文回答,不超过 50 个字。"这一句指挥了大模型干两件事:

提示词里的指令它"指挥"了什么没写会怎样
用中文(Simplified Chinese)规定输出语言可能答英文
限 50 字(limit to 50 characters)规定回答长度可能长篇大论

这就是第 26 课的观点:提示词能"指挥"口吻和长度。 把这行改成"一位数学老师",它口吻就变了。


五、改一个条件验证:看它怎么"扛"住意外

状态机强在出错不乱。动手拆一拆:

我改了什么我猜会怎样实际/推论
说话不到 1 秒就松手可能识别出乱码报"录音时间至少一秒"——太短,它宁可不认也不硬猜
按住 BOOT 3 秒不放一直录下去到 3 秒自动停,自动进"正在识别"——有硬上限
拔掉 WiFi 再按 BOOT识别失败报"百度识别连接失败/超时"进错误态——但没网永远救不回
说一句英语可能识别成中文dev_pid=1537 只认中文普通话,英文常变成乱码/空
改提示词让"≤50 字"变"≤10 字"回答更短回答真的短了——提示词能"指挥"长度
一次说一整段书识别可能不全最多只能录 3 秒,太长要分次说

结论:状态机把"意外"变成了"规则"——每个失败都有明确去处,每段录音都有上限,每次识别都有门槛。它永远知道"出错往哪走",所以不会卡死。


六、一个藏在代码里的小聪明:录音时屏幕只画进度条

你发现了吗——录音时屏幕几乎不动,只有进度条在涨。为什么不画整个屏幕?

程序里写了句注释:"录音中只更新进度条这一小块(整屏 fillScreen 太慢会阻塞音频采集)。" 意思是:麦克风每毫秒都在往里灌声音数字,如果一边"画整屏"一边"听声音",画画会抢走太多时间,声音就漏采了(会卡顿、断句)。

所以它只重新画"进度条"这一小块,把时间和 CPU 留给录音。

这告诉你的道理:做真实设备时,"好看"和"干正事"打架,先保干正事。 为了把声音录完整,宁可让画面"朴素"一点。

两趟寄包裹(识别寄百度、思考寄豆包) + 录音时只画进度条的小聪明


七、自己做一遍 + 过关检查

动手实验

  1. 看状态条:按 BOOT 说一句话,全程盯住状态条,把每一次变色和对应的卡片内容填进一张表。
  2. 录太短:按下又马上松开,看红字"录音时间至少一秒"。
  3. 按住 3 秒:不松手,看它自己停、自己进"正在识别"。

过关检查(对着这张表打勾)

  • 我能说出 5 种状态的中文名(待机 / 录音 / 识别 / 思考 / 错误)。
  • 按下 BOOT 进"录音",松开或满 3 秒进"识别",成功进"思考",成功回待机。
  • 识别失败、模型超时,都进"错误",按 BOOT 回到待机。
  • 我能说出 system 提示词"指挥"了大模型哪两件事(语言 + 长度)。
  • 我能解释"为什么录音时只画进度条、不画整屏"。

自己想通一个开放问题

这一课助手回答是显示在屏幕上的。如果要让板子开口把回答念出来,应该接第几课的哪一棒?(提示:第 25 课文字转语音。)


八、创意方向

想做什么描述给 AI 的效果会观察到
换个人设的助手把提示词里的"voice assistant"改成"一位聪明数学老师"换口吻,更容易帮你解题
把回答"念"出来在思考→回待机之间接上第 25 课 textToSpeech回答从屏幕上到你耳朵里——这才是完整的语音助手
加唤醒词待机再拆成"未唤醒/已唤醒",听到"你好小助"才进录音更像真音箱、更省电,代价是多了个状态
会记事的助手把多轮问答存数组,下轮再喂给大模型它就"记得你们刚才聊的"——多轮对话雏形
会认生的助手识别置信度太低时显示"我不太确定"比答错更友好

别忘了保密:密钥(百度/火山的 key)只放你自己配置里,绝不写进课件、截图,也不出现在任何公开分享里。公开仓库只留 config.example.h 模板。

下一课:第 29 课,板子要陪你下五子棋了——第五章 AI 感知与对话收官,第六章游戏开发开始。

第 28 课 · 完整语音助手

第 28 课 · 完整语音助手

按住 BOOT 说一句话,板子会听完、听懂、想一想、再回答你——前后穿五件「马甲」。

28语音助手状态机大模型