BillAI Bass: 使用 Strands Agents 與 Amazon Nova 2 Sonic 打造 AI 驅動的語音助手
BillAI Bass: 使用 Strands Agents 與 Amazon Nova 2 Sonic 打造 AI 驅動的語音助手
BillAI Bass 是一個 AI 驅動的仿生機器人專案,它將 Big Mouth Billy Bass 轉換為即時語音助手。透過整合 Raspberry Pi 5、Strands Agents 的雙向串流 (BidiAgent) 以及 Amazon Bedrock 上的 Amazon Nova 2 Sonic,這條魚可以進行低延遲的語音對話,並伴隨著同步的嘴部動作、頭部轉動與尾部擺動。
技術架構
該專案利用雙向串流架構來最小化延遲,並將物理動作與音訊輸出同步。
核心組件
- Brain: Raspberry Pi 5 (建議使用 8GB 版本) 執行 Raspberry Pi OS Lite (64-bit)。
- AI Model: 透過 Amazon Bedrock 使用 Amazon Nova 2 Sonic,負責處理語音對語音的處理。
- Orchestration: Strands Agents 的
BidiAgent管理 Pi 與雲端模型之間的雙向音訊串流。 - Hardware Interface: 使用 MX1508 雙 H 橋馬達驅動器,將 Pi 的 3.3V GPIO 訊號轉換為驅動魚類馬達所需的 5V 電流。
- Audio I/O: USB mini speaker 與 USB gooseneck microphone。
唇形同步與動畫邏輯
由於 AI 模型串流音訊的速度快於播放速度,該專案並非根據數據到達的時間來觸發動畫,而是實作了一個自定義的音訊輸出類別 (BillyBody),用於即時測量作用於 speaker 的音訊位元組的音量大小。
- Mouth Movement: 由平滑後的音量等級驅動;當音訊超過特定閾值 (
MOUTH_OPEN) 時,會啟動嘴部馬達。 - Head Position: 當音訊正在播放時,頭部會升起,並在一段靜音時間 (
SILENCE閾值) 後落下。 - Tail Flapping: 由音量峰值 (
EMPHASIS閾值) 或特定的對話事件(如回應的開始或完成)觸發。
硬體實作
馬達配置
該專案是針對現代的 "Gemmy" 版本 Billy Bass 設計的,該版本使用兩個馬達:一個用於嘴部,另一個共享馬達則根據旋轉方向同時控制頭部與尾部。
接線與電源
一個關鍵要求是使用 27W USB-C PD 電源供應器。標準的手機充電器通常會導致 Raspberry Pi 限制 USB 埠的供電,這可能導致馬達驅動器或音訊裝置的不穩定。
焊接與組裝
MX1508 驅動板需要焊接 10 個焊點,將 Pi 的 GPIO pins 連接到馬達輸出。指南強調進行 "tug test"(拉力測試)與 "bridge check"(橋接檢查),以確保連接穩固且沒有短路,特別是在正負電源軌之間。
雲端整合與安全性
最小權限 IAM 設定
為了防止與在實體裝置上儲存 AWS keys 相關的安全風險,該專案採用了嚴格限制範圍的 IAM user。該政策僅限於在 us-east-1 區域對特定模型資源 (amazon.nova-2-sonic-v1:0) 執行單一動作 (bedrock:InvokeModelWithBidirectionalStream)。
生產級身分識別
對於大規模部署,該專案提供了一個使用 AWS IoT Core 的可選路徑。這會將長期存取的 access keys 替換為 X.509 憑證。裝置會使用這些憑證向 IoT credentials endpoint 請求臨時的 IAM credentials,確保 SD 卡上不會留存任何永久性的秘密資訊。
社群洞察與反對觀點
雖然該專案展示了高度的整合能力,但 Hacker News 上的社群討論提出了幾項技術考量:
- Local vs. Cloud: 一些使用者建議將 Amazon Bedrock 替換為本地對話模型(例如 Gemma),以消除訂閱費用並減少對網路連接的依賴。
- Hardware Tools: 資深開發者指出使用斜口鉗來剝線是並非最佳做法,並建議使用正確的線剝皮鉗以獲得更乾淨的連接。
- Interaction Models: 有人建議實作本地 "thought"(思考)生成,即由一個小型模型在背景生成回應,並將其儲存為音訊檔案,以便在物理觸發(例如戳一下魚)時播放。
常見故障排除
| 症狀 | 主要原因 | 解決方案 |
|---|---|---|
IndentationError |
SSH paste 導致前導空格 | 使用 sed -i 's/^ //' file.py |
| Weak mouth movement | 馬達方向不對稱 | 在 Pi header 上交換兩個嘴部通道的插頭 |
Audio Invalid sample rate |
~/.asoundrc 配置錯誤 |
使用 arecord -l 與 aplay -l 驗證卡片名稱 |
| Head stays up | 回應結束事件未觸發 | 將頭部狀態基於音訊靜音閾值而非模型事件來設定 |