Show HN: BillAI Bass,一款基于Strands Agents的AI驱动版大嘴比利巴斯
摘要
本项目提供了一个指南和开源方案,教你如何利用Strands Agents和Amazon Nova 2 Sonic,在树莓派5上把大嘴比利巴斯变身成实时语音助手。
查看缓存全文
缓存时间: 2026/07/13 19:55
morganwilliscloud/billai-bass 来源: https://github.com/morganwilliscloud/billai-bass
🐟 BillAI Bass 构建指南
基于 Strands Agents 双向流式传输 + Amazon Nova 2 Sonic 驱动
https://github.com/user-attachments/assets/02e84cd4-72e2-4b01-8b80-c83e910037e6
将一条大嘴比利·巴斯鱼变成实时语音助手:你说话,鱼会回应——头部转动,嘴巴随着自己的声音同步对口型,尾巴摆动加强语气。这条鱼在树莓派 5 上运行 Strands Agents (https://strandsagents.com) 的双向流式传输代理 (BidiAgent),通过 Amazon Bedrock 实时流式传输音频至 Amazon Nova 2 Sonic 并接收反馈。无需机器人经验,无需焊接经验。本指南的作者此前从未插过树莓派,但一个周末就让鱼开口说话了。
灵感来源于优秀的 billy-b-assistant (https://github.com/Thokoop/billy-b-assistant) 项目,并在 Strands 上重建。
本仓库内容
| 文件 | 用途 |
|---|---|
README.md | 本指南——从这开始,自上而下逐步操作 |
billy.py | 最终可运行的 Python 代码——会说话的鱼 |
motors.py | 独立的电机测试程序——运行 billy.py 之前先运行此程序验证接线 |
asoundrc.example | ALSA 配置文件,用于将 USB 麦克风和扬声器设为默认设备 |
requirements-frozen.txt | 已知可用的树莓派构建中使用的精确依赖版本——运行 pip install -r 即可保证设置成功 |
iot-identity/ | 可选生产级凭证:CloudFormation 模板 + 使用 X.509 证书认证(替代访问密钥)的指南 |
如何与 AI 助手配合使用本指南
将本 README 粘贴到 Claude(或其他 AI 助手)中,然后说: “我正在构建这个。请一步一步引导我——在给出下一步之前,等我确认当前步骤。”
这正是本项目的构建方式,也是最佳的构建方式。如果遇到困难,请参阅下方 与 AI 助手一起构建 部分中发送的内容。
🤝 与 AI 助手一起构建本项目
本项目是在 Claude Code 的帮助下 创建的,你也可以使用任何 AI 助手来帮助你完成构建。
将整个指南粘贴给你的 AI,然后说:“我正在构建这个。请一步一步引导我——在给出下一步之前,等我确认当前步骤。”
你的 AI 会按照你的节奏进行构建,调试你遇到的错误信息,并在你的硬件与本指南略有不同时进行调整。
在此构建过程中,AI 擅长的事情:
- 粘贴你的确切错误信息——一行长的 Python 回溯通常只有一行有意义,AI 会找到它。
- 发送照片——不确定哪个是电机?分不清引脚?拍张照片问它。(在 Mac 上的 Claude Code 中:将图片文件拖入终端,或者说“看下 ~/Downloads/IMG_1234.jpg“。)
- 说“我对 X 一无所知“——AI 会退后一步进行解释。没有愚蠢的问题。
- 在不确定切割/焊接任何东西之前先问清楚。 如果你遇到本指南未涵盖的问题,那不是你的错。这很可能是指南的疏漏。AI 加上你的错误信息会帮你度过难关。
🛒 购物清单
如果你拿到了套件:表中物品你已全部拥有。 从头开始构建:这是原始亚马逊订单(2026年1月价格,总计约240美元)。
| 物品 | 用途 | 大约价格 |
|---|---|---|
| 大嘴比利·巴斯鱼(当前 “Gemmy” 版本) | 这条鱼。现代版本有2个电机,本指南假设如此 | $30 |
| 树莓派 5,8GB | 大脑。4GB 也可以工作 | $80 |
| 27W USB-C PD 电源适配器(官方 Pi 或 RasTech GaN) | 不要用手机充电器代替——如果没有合适的电源,Pi 会限制 USB 端口功率 | $15 |
| 官方树莓派 5 主动散热器 | 散热片 + 风扇。Pi 没有散热器会过热 | $10 |
| microSD 卡,64GB(例如 Transcend USD340,任何知名品牌) | Pi 的硬盘 | $12 |
| USB 迷你扬声器(例如 HONKYOB) | Billy 的声音 | $15 |
| USB 鹅颈迷你麦克风(例如 CGS-M1) | Billy 的耳朵 | $13 |
| MX1508 双 H 桥电机驱动板,5 个装(例如 Aideepen,标注为 “L298N 替代品”) | 让 Pi 安全驱动电机。你需要 1 个;备用的用来宽容错误 | $9 |
| 杜邦跳线套件,120 根,公母混合(例如 ELEGOO) | 连接驱动板到 Pi。你会用到大约 6 根母对母 | $7 |
| 电烙铁套件,60W 可调,带烙铁头 + 焊锡 | 总共 10 个焊点。最便宜的套件即可 | $20 |
| 斜口钳(例如 KATA 2 件套) | 剪线和剥线 | $9 |
| JST XH 连接器套件 | 可选——方便整洁地接线,但不用它也能完成构建 | $9 |
另外需要,但不在套件中的物品:
- 一台个人电脑(Mac/Windows/Linux)来烧录 SD 卡——⚠️ 公司笔记本电脑通常会阻止 USB 存储设备;请使用家用电脑
- 一种将 microSD 插入那台电脑的方法(大多数卡附带 SD 适配器)
- 一个 AWS 账户(个人账户,不是你的雇主账户),并配有支付方式——你将在下面的先决条件中创建一个受限的、仅限鱼使用的 IAM 用户
- 胶带(最好是电工胶带,透明胶布也行),一把小十字螺丝刀
- 你的电脑和 Pi 都能加入的家庭 WiFi
✅ 先决条件(在构建日之前完成)
1. AWS / Amazon Bedrock 设置(最小权限——正确操作)
💸 还没有 AWS 账户?免费套餐足以覆盖本项目。 新 AWS 账户可获得 $100 积分(通过活动可高达 $200),并且 Amazon Bedrock 在免费计划中可用于 Nova 的使用,积分会抵扣。语音聊天很便宜——每次几分钟对话大约一分钱,所以积分可以购买大约 100+ 小时的鱼聊时间。
免费计划的两个注意事项:
- 全新账户有时会将 Bedrock 调用配额设为零(尚无支付记录)。如果模型访问已授予,但每次调用都失败并返回
ValidationException: Operation not allowed,那就是配额问题——提交一个(免费的)AWS 支持工单,要求增加 Nova Sonic 按需配额,或者升级到付费计划(剩余积分会结转)。 - 免费计划账户在 6 个月后自动关闭(或积分用尽时)。对于演示鱼来说没问题;如果 Billy 要成为永久住户,请在截止日期前升级到付费——未使用的积分在升级后仍有效。
你的 AWS 密钥将作为明文文件存放在一条鱼体内的 Pi 上。鱼会被演示、借出、留在桌子上;SD 卡可能会弹出。因此密钥必须只能做一件事:与 Nova Sonic 通信。如果泄露,最坏的情况是有人用你的钱和鱼聊天——而不是有人在你的账户里挖矿。
步骤 1 — 启用模型访问:
- 在 AWS 控制台中,将区域切换至 us-east-1(弗吉尼亚北部)——Nova Sonic 位于该区域。
- 前往 Amazon Bedrock → Model access,请求访问 Nova 2 Sonic (
amazon.nova-2-sonic-v1:0)。通常即时生效。(不是 v1——原始 Nova Sonic 将于 2026 年 9 月终止支持。)
步骤 2 — 创建一个专用的 IAM 用户:
- 控制台 → IAM → Users → Create user。将其命名为类似
billy-bass的名称。 - 不要勾选 “Provide user access to the AWS Management Console”——这个用户是一条机器鱼;它永远不会登录任何东西。
- 在权限屏幕上,选择 “Attach policies directly”,但不要选择任何 AWS 托管策略(不要选
AmazonBedrockFullAccess——这授予的权限远超鱼所需)。只需点击继续,创建一个零权限的用户。
步骤 3 — 附加一个仅允许 Nova Sonic 的策略:
- 打开新用户 → Permissions → Add permissions → Create inline policy → JSON 标签页。
- 粘贴:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BillyTalksToNovaSonicOnly",
"Effect": "Allow",
"Action": "bedrock:InvokeModelWithBidirectionalStream",
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-2-sonic-v1:0"
}
]
}
- 将其命名为
billy-nova-sonic-only,然后保存。
这只是一个区域的一个模型上的一个操作。没有 S3,没有 EC2,没有其他 Bedrock 模型,无法查看或更改你账户中的任何其他内容。(如果你以后给 Billy 添加需要接触 AWS 的工具——比如读取 DynamoDB 表——到那时再将那个特定权限添加到此策略中,而不是现在授予宽泛的访问权限。)
步骤 4 — 创建访问密钥:
- 用户 → Security credentials → Create access key → 选择 “Application running outside AWS”。
- 将访问密钥 ID + 密钥保存在安全的地方——密钥仅显示一次。稍后会在 Pi 上使用(§1.6)。
步骤 5 — 可选但明智:设置计费警报。 控制台 → Billing → Budgets → 创建一个每月 $10 的预算并设置电子邮件警报。随意的 Nova Sonic 聊天只需要几分钱;设置警报是为了防止卡在一直监听状态的鱼(或泄露的密钥)让你措手不及。如果密钥泄露或套件鱼丢失:IAM → 用户 billy-bass → Security credentials → 停用访问密钥。一键点击,鱼变砖,账户安全。
2. 了解两个粘贴陷阱(你肯定会遇到)
当你通过 SSH 将代码粘贴到终端/nano 时,两件事经常出错:
- 多余缩进:每一行粘贴的代码前面都会多出空格。ALSA 配置可以容忍;Python 会报错(
IndentationError: unexpected indent出现在第 1 行就是典型症状)。修复:sed -i 's/^ //' yourfile.py,或者小心地重新粘贴到 nano 中。 - 字符丢失/变形:缺少逗号,或者引号变成了“智能引号”。能救你的习惯:创建任何 Python 文件后,先运行
bash python -m py_compile yourfile.py && echo OK,然后再实际运行。如果没有显示 OK,将错误粘贴给 Claude。
第 1 部分 — 大脑(树莓派,还没有鱼)
策略说明: 我们先在裸 Pi 上完成整个语音助手的工作,然后才打开鱼。软件问题和硬件问题如果无法相互干扰,调试起来就容易得多。
1.1 烧录 SD 卡
在你的个人电脑上:
- 从 raspberrypi.com/software (https://raspberrypi.com/software) 下载 Raspberry Pi Imager,插入 microSD 卡。
- 选择:设备 = Raspberry Pi 5 · 操作系统 = Raspberry Pi OS Lite (64-bit) · 存储 = 你的卡。
- ⚠️ 操作系统版本很重要:你需要一个带有 Python 3.12+ 的镜像(Nova Sonic 要求)。目前基于 “Trixie” 的 Raspberry Pi OS 自带 3.13 ✅。旧的 “Bookworm” 镜像自带 3.11 ❌。
- “Lite” = 无桌面。正确——你永远不会连接显示器。
- ⚠️ 仔细选择 “Lite”。 在操作系统列表中,展开 “Raspberry Pi OS (other)”,然后选择 Raspberry Pi OS Lite (64-bit)——不要选择列表顶部的常规 “Raspberry Pi OS (64-bit)”,那是桌面版。桌面版附带一个 Wayfire 面板,会在每次登录时积极地重写
~/.asoundrc,反复破坏你的音频配置且无明显原因。Lite 版没有 GUI 也没有面板。已经错误安装了桌面版? 无需重新烧录即可修复——sudo systemctl set-default multi-user.target && sudo systemctl disable lightdm.service && sudo reboot可使桌面版像 Lite 版一样启动。但一开始就用 Lite 版更干净。 - 当询问操作系统自定义设置时,选择是——这是神奇的一步:
- 主机名:
billy - 用户名 + 密码:选择一个并记住它们
- WiFi:你的网络名称 + 密码,完全正确(输错一个字母 = 之后神秘消失)
- 服务标签页:启用 SSH(密码认证)
- 主机名:
- 写入,等待,弹出。(“Raspberry Pi Connect” 提示:跳过——如果你以后要在别处演示,一条命令即可添加远程访问。)
1.2 首次启动
- 将 microSD 卡插入 Pi 底部的插槽。插上 USB-C 电源——没有电源按钮;插入即开机。
- 等待 2–3 分钟(首次启动会调整分区大小并连接 WiFi)。
- 从你的电脑终端:
ssh [email protected]
在指纹提示处输入 yes(小写),然后输入你的密码(输入密码时光标不会移动——正常)。
常见问题:
- 指纹提示后立即出现
Connection reset→ Pi 仍在完成首次启动设置。等待 1–2 分钟,重试。(如果之后提示REMOTE HOST IDENTIFICATION HAS CHANGED:运行ssh-keygen -R billy.local然后重试——Pi 在设置过程中重新生成了密钥,这是预期的。) - 找不到
billy.local→ 等待更长时间;然后检查路由器的设备列表,寻找 “billy” 并通过其 IP 地址 SSH。持续找不到通常 = WiFi 密码输入错误 → 重新烧录。 - 当天完成后:运行
sudo shutdown now,等待大约 20 秒,然后拔掉电源。不要直接拔电源。
1.3 系统包
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y python3-dev portaudio19-dev swig git
(portaudio19-dev → 为 Python 提供麦克风/扬声器访问。swig → 稍后构建 GPIO 库时需要;现在安装可以避免一个令人困惑的错误。)
1.4 音频设备
将 USB 麦克风和 USB 扬声器插入 Pi,然后:
arecord -l # 列出麦克风——记下你的声卡名称,例如 "Device"
aplay -l # 列出扬声器——记下你的,例如 "UACDemoV10"(忽略两个 vc4hdmi 条目)
⚠️ 使用声卡名称,绝不要用编号——编号在重启后会改变(原始构建就因此吃过亏)。
现在将你的 USB 设备设为系统默认。使用 nano 创建配置文件(heredoc + SSH 粘贴 = 痛苦;nano 是你的朋友):
nano ~/.asoundrc
粘贴,将 YOUR 替换为你的两个声卡名称:
pcm.!default {
type asym
playback.pcm "plug:hw:UACDemoV10"
capture.pcm "plug:hw:Device"
}
ctl.!default {
type hw
card UACDemoV10
}
保存(Ctrl+O,回车)并退出(Ctrl+X)。然后验证文件确实存在——cat ~/.asoundrc 应该会回显内容。(在原始构建中这个文件静默地保存失败,导致几天后出现令人费解的崩溃。不要相信任何东西;cat 一切。)
往返测试——录制 3 秒自己的声音,然后回放:
arecord -d 3 -f S16_LE -r 16000 test.wav && aplay test.wav
听到自己了吗?最困难的 Pi 特有难题现在解决了。(16000 Hz 是有意为之——那是 Nova Sonic 的采样率。)
1.5 Python 环境 + Strands
python3 -m venv ~/billy/.venv
source ~/billy/.venv/bin/activate
pip install "strands-agents[bidi,bidi-io]" gpiozero lgpio
注意:
- 提示符中出现
(.venv)= 虚拟环境已激活。在每个新的 SSH 会话中都必须重新运行source那行——如果 Python 突然找不到 strands,这就是原因。 - 如果
lgpio构建失败并提到swig:你跳过了第 1.3 步的 swig 安装。sudo apt install -y swig,然后重试。 - 锁定你的版本:这个构建使用了 Strands 的实验性 bidi API 并继承了一个私有类。运行
pip freeze | grep strands并记下版本号。如果未来的升级导致问题,你可以回退到该版本。
1.6 AWS 凭证——放在文件中,而非导出变量
使用你在先决条件中创建的专用 billy-bass IAM 用户的密钥(那个只能调用 Nova Sonic 的用户)——绝不要使用你的个人/根 AWS 密钥。
环境变量会在每次注销时消失(这在构建过程中曾导致崩溃),所以永久保存:
mkdir -p ~/.aws
nano ~/.aws/credentials
[default]
aws_access_key_id = YOUR_KEY_ID
aws_secret_access_key = YOUR_SECRET
nano ~/.aws/config
[default]
region = us-east-1
chmod 600 ~/.aws/credentials
1.7 第一次对话 🎉
nano ~/billy/billy.py:
import asyncio
from strands.experimental.bidi import BidiAgent, BidiAudioIO
from strands.experimental.bidi.models import BidiNovaSonicModel
model = BidiNovaSonicModel(
model_id="amazon.nova-2-sonic-v1:0",
provider_config={
"audio": {
"input_rate": 16000,
"output_rate": 16000,
"voice": "matthew",
"channels": 1,
"format": "pcm",
}
},
)
agent = BidiAgent(
model=model,
system_prompt=(
"You are Billy, a wisecracking animatronic singing bass mounted on a "
"wooden plaque. Keep responses short, punchy, and conversational."
),
)
audio_io = BidiAudioIO()
asyncio.run(agent.run(inputs=[audio_io.input()], outputs=[audio_io.output()]))
python -m py_compile ~/billy/billy.py && echo OK
python ~/billy/billy.py
等待几秒钟,然后直接说话。你应该能进行语音对话。 按 Ctrl+C 停止。
常见问题:
- 一大串 `ALSA l
相似文章
@svpino: 一步一步的视频教程,从零开始构建语音代理。我使用 Claude Code 来做这个,因为手写代码……
一个逐步视频教程,使用 Claude Code 和 AssemblyAI 的新 Voice Agent API 从零开始构建语音代理。
通过持久化流在Jetson上部署本地AI服务
一位开发者记录了在NVIDIA Jetson Orin Nano上使用Kokoro-82M和持久化流构建自托管文本转语音应用的过程,实现了可靠的本地AI推理和可共享的音频输出。
我构建了一个完全沉浸式的AI代理,具备原生时间感知和群聊理解能力,全部采用单通道逻辑。
作者构建了一个名为KawaiiBaka的完全自主AI代理,它在Discord群聊中运行,采用单通道认知循环,具备原生时间感知能力,并能在Windows机器上实际执行Python代码。该系统使用Mistral API作为大语言模型,并通过本地图像生成管道创建上下文感知的自拍照。
语音代理,通俗解释:STT+TTS 与 4 个可在浏览器中对话的演示代理 + 使用 RAG 和工具构建你自己的
一份使用语音转文字和文字转语音技术揭秘语音代理的指南,包含四个基于浏览器的演示代理以及使用RAG和工具的构建说明。
构建了一个JARVIS风格的助手:具备唤醒词、视觉模式、本地语音克隆和LLM生成的系统命令
一位开发者构建了一个名为CYBER的JARVIS风格个人助手,具备唤醒词激活、通过XTTS v2的本地语音克隆、视觉模式以及LLM生成的系统命令,全部在本地运行,无需云端依赖。