资讯动态

be-more-agent源码深度剖析:状态机、多线程TTS队列与流式对话架构是如何运转的

发布时间:2026/10/15 10:34:25 来源:尧图企业网站定制
【免费下载链接】be-more-agentLocal AI Agent running on Raspberry Pi项目地址https://gitcode.com/gh_mirrors/be/be-more-agent点击查看免费下载be-more-agent 是一个运行在树莓派上的100% 本地AI Agent 项目用 Ollama 大模型当大脑、Whisper 做语音识别、Piper 做语音合成被唤醒词叫醒后就能和你语音对话。这篇文章深入剖析它的三大核心设计——状态机、多线程 TTS 队列与流式对话架构解释为什么它的脸能实时变化、声音从不打架。项目概览be-more-agent 是什么一句话概括be-more-agent 把树莓派变成一台完全自治的对话式 AI 助手——监听唤醒词、听懂语音、用本地 LLM 思考、再用低延迟神经语音回答屏幕上还有配套的表情动画。全本地、零云依赖OllamaLLM Whisper.cpp语音识别不产生 API 费用离线唤醒基于 OpenWakeWord 的自定义模型无需任何密钥反应式表情7 种状态各有独立的 PNG 帧序列存放于 faces/ 目录高度可定制换掉脸和音效素材一步就能打造自己的角色。核心逻辑全部集中在 agent.py 一个脚本里模型与硬件参数在 config.json 中配置依赖清单见 requirements.txtsounddevice、openwakeword、ollama 等。启动时系统先进入 warmup 状态用一次ollama.generate预热模型keep_alive-1避免首次响应卡顿同时播放问候音效——屏幕上就是这张像素风的 Loading... 画面be-more-agent 本地AI助手开机预热加载画面状态机让助手有表情的 7 个状态整个程序的心脏是一个极简的BotStates类agent.py枚举了 7 个状态状态含义对应表情动画WARMUP开机加载模型像素 loading 屏IDLE空闲等待唤醒闭眼直嘴LISTENING正在录音睁眼微笑THINKINGLLM 思考中托腮微笑SPEAKING语音合成中睁眼咧嘴ERROR出错裂开脸CAPTURING摄像头拍照大眼睛瞳孔关键在于状态切换函数set_state()agent.py。对话逻辑跑在后台线程里而 Tkinter 只允许主线程操作 UI所以所有界面更新都通过self.master.after(0, _update)投递回主线程——这是保证状态机线程安全的核心。同时状态切换会重置帧索引让每个新状态都从第一帧开始播放。帧播放由update_animation()驱动agent.py普通状态每 500ms 顺序推进一帧而SPEAKING状态改为每 50ms 随机跳帧模拟说话时的嘴巴抖动。be-more-agent 本地AI助手空闲状态表情帧be-more-agent 本地AI助手聆听状态表情帧整体主循环safe_main_execution()agent.py是一条串行的流水线检测唤醒 → 录音 → 转写 → 对话 → 回到等待。流水线的每个分支都配上对应的set_state()调用保证表情、音效和逻辑永不脱节。唤醒词与语音输入助手如何听见你 detect_wake_word_or_ptt()agent.py支持两种触发方式唤醒词默认OpenWakeWord 的.onnx模型按 1280 采样点16kHz连续打分分数超过WAKE_WORD_THRESHOLD0.5即触发PTT 降级没有唤醒词模型时按回车即可手动触发Push-To-Talk。两个工程细节值得新手借鉴硬件友好的重采样choose_input_samplerate()先探测麦克风支持的采样率若输入不是 16kHz就用最近邻抽点代替 scipy 高精度重采样来喂给唤醒模型——这是在树莓派上避免 ALSA 缓冲区溢出的关键自适应 VAD 断句record_voice_adaptive()agent.py不录固定时长而是按能量实时判断——持续静音 1.5 秒自动停录最长 30 秒封顶。录音结束后保存为 WAV并从 sounds/ack_sounds/ 随机播放一个我听到了音效再交给whisper-cli子进程做离线转写agent.py。多线程TTS队列声音为什么从不打架 这是全文最经典的一段设计。队列本体只有几行agent.pyself.tts_queue [] self.tts_queue_lock threading.Lock() self.tts_active threading.Event()生产者对话线程逐句入队消费者是专职的_tts_worker()线程agent.py在tts_queue_lock保护下从队头取一句话取到就置位tts_active事件调用speak()播完再清除事件队列空时休眠 50ms 轮询。单生产者单消费者场景下比重量级队列更轻。speak()agent.py用subprocess.Popen启动 Piper把文本写入其 stdin再从 stdout 按 4096 字节一块读取原始 PCM通过sd.RawOutputStream写声卡设备不支持 22050Hz 时自动重采样到本机原生采样率。子进程句柄保存在self.current_audio_process中随时可以被终止。打断机制是另一个亮点用户按一下空格键handle_speaking_interrupt()agent.py会立刻做四件事——置位interrupted标志、停掉思考音效循环、在锁保护下清空 TTS 队列、杀掉正在播放的音频进程然后直接回到IDLE。整个过程只需几毫秒实现随时插话。主对话流在wait_for_tts()agent.py里轮询队列与tts_active事件确保上一句完全播完才进入下一轮监听回答之间自然衔接、绝不抢话。be-more-agent 本地AI助手说话状态表情帧流式对话架构逐句切分 增量入队对话的核心是chat_and_respond()agent.py关键一行是ollama.chat(..., streamTrue)——模型流式产出 token代码在同一个循环里并行完成三件事上屏_stream_to_text()把每个 chunk 实时插入文本框用户能看着回答被打出来逐句切分内容累积进sentence_buffer一旦出现句末标点.!?或换行且包含有效文字整句立刻压入 TTS 队列agent.py状态切换首个有效 chunk 一到就切到SPEAKING同时终止思考音效循环。be-more-agent 本地AI助手思考状态表情帧逐句切分 增量入队是低延迟的关键不等全文生成完第一句生成完就开始播报第二句还在想第一句已经在说——思考、朗读、上屏三者完全重叠这在树莓派上尤为珍贵。工具路由也发生在流式循环里System Prompt 约定模型在用户要求物理动作时输出 JSON。循环一旦检测到{或action:字样即进入动作模式——停止 TTS、攒齐完整 JSON交给execute_action_and_get_result()agent.py。内置 3 个工具get_time、search_webDuckDuckGo 搜索、capture_image。工具结果不会直接念出来而是让模型非流式地总结成一句话再说话用户永远不会听到一长串搜索原文。be-more-agent 本地AI助手摄像头抓拍状态表情帧比如问你看到什么它会先进CAPTURING状态用rpicam-still拍照再切到视觉模型moondream重新进入对话流程处理图像上下文若任何环节失败就进入ERROR状态露出这张裂开的脸be-more-agent 本地AI助手错误状态裂脸表情帧记忆设计则是两层permanent_memory系统提示session_memory本轮会话退出时只把最近 10 轮写入磁盘agent.py说一声 forget everything 即可立即清空。架构要点总结 模块实现核心要点状态机BotStatesset_state()7 状态主线程更新 UI驱动表情与状态栏唤醒OpenWakeWord PTT 降级最近邻重采样省 CPU自适应静音断句TTS 队列列表 Lock worker 线程单消费者串行播报可打断、可强杀进程流式对话ollama streamTrue 句缓冲遇标点即入队思考与朗读完全重叠工具路由JSON 流式监测 动作分发器3 个内置工具结果先总结再播报记忆双层记忆 近 10 轮落盘forget everything 即时重置整个 be-more-agent 不到 1000 行 agent.py却靠状态机、多线程 TTS 队列、流式对话三件套在树莓派这样算力有限的设备上做出了流畅的语音对话体验。如果你想给自己搭一个本地语音助手它是非常值得逐行研读的开源范本——换上自己的 faces/ 与 sounds/ 素材就能拥有全新角色。赞分享【免费下载链接】be-more-agentLocal AI Agent running on Raspberry Pi项目地址https://gitcode.com/gh_mirrors/be/be-more-agent点击查看免费下载相关推荐Java线程start流程深度剖析从源码到生命周期状态转移YCBlogs线程知识系列Java线程start流程深度剖析从源码到生命周期状态转移YCBlogs线程知识系列 本篇是 YCBlogs 技术博客笔记中「06.线程知识」系列的核心篇教程技术博客文档be-more-agent语音识别深度解析whisper.cpp如何实现树莓派上的离线语音转文字be more agent语音识别深度解析whisper.cpp如何实现树莓派上的离线语音转文字 be more agent 是一个运行在树莓派RaspbeCC Switch 保存供应商后 Codex 的 /model 菜单看不到模型分层定位 自查清单快速排查CC Switch 保存供应商后 Codex 的 /model 菜单看不到模型分层定位 自查清单快速排查 你在 CC Switch 里保存并启用了第三方供AI 应用开发者工具桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑