用Claude Code搭建多设备声源定位器
作者借助Claude Code开发Beep Locator,通过Python网页服务连接多台设备,尝试定位房间中的间歇蜂鸣声。设备声音校准效果不佳后,他加入手动粗定位模式,并用拍手模式辅助测试。
AI 深度解读
房间里有个东西隔一阵就响一下,翻箱倒柜又找不到。Simon Willison 让 Claude Code 做了一个网页应用,把手机、平板和笔记本变成分布在房间里的麦克风,最终把声源缩小到约 40 厘米的范围,找出了一台需要换电池的老旧一氧化碳探测器。
这个故事值得程序员读的地方,是作者怎样给编程代理接上真实环境:采集声音、回传记录、在线修改程序,再用现场实验验证。能跑代码之后,AI 还需要一条看得见结果的反馈通道。
多台设备听见同一声响,为什么还不能直接定位
作者做的应用叫 Beep Locator。主界面由 Python Web 服务器提供,其他设备扫描二维码或打开 URL,通过浏览器申请麦克风权限,再经 WebSockets 连接服务器。作者用了两台 iPad、一部手机、一台 MacBook Pro 和一台 Surface Ultra。
目标听起来简单:同一个声音到达不同设备的时间不同,结合设备位置,就能估算声源在哪里。但这些设备各自录音,片段未必处在同一条时间线上。把几个检测时间直接相减,算出来的可能是设备之间的偏差。
Claude 在早期研究中找到了 2007 年的论文 BeepBeep: A High-Accuracy Acoustic-Based System for Ranging and Localization Using COTS Devices。论文提出,用普通设备已有的扬声器、麦克风和通信能力,通过双向感知、自录音和采样计数实现声学测距。这里的 COTS 指现成商用设备,不需要专门购买定位硬件。
这给项目提供了技术方向,但论文研究的是设备间测距与定位,不能直接当成这次浏览器实现的精度证明。
Beep Locator 的实际流程是:每个监听端保留最近 60 秒音频,并由 detector.js 使用快速傅里叶变换(FFT)和高通滤波识别疑似蜂鸣。一旦某台设备上报事件,服务器就选择与自己往返时间最短的设备,播放一声短促的啁啾声。
随后,各监听端上传从疑似蜂鸣前约 0.6 秒,到啁啾声后约 0.8 秒的录音。啁啾声为各段录音提供对齐依据,这是定位之前的重要一步。原文没有展开时钟偏差、声音传播时间等因素具体如何处理,不能把这段描述当成完整算法。
设备自身的位置也是难题。作者原本希望它们互相播放声音,自动确定二维坐标,但实际效果不够好,于是增加了 Rough mode:先在地图上手动拖出大致位置,再根据声音修正。
自动校准遇到困难时,允许人提供粗略位置,项目才更容易继续推进。
拍手、回放和人工确认,怎样让结果可信
作者没有等神秘蜂鸣再次出现才验证定位。他增加了拍手检测,在房间不同位置拍手,检查地图上的标记是否对应实际位置。拍手用菱形表示,蜂鸣用 X 表示,所有标记再加上 HH:MM:SS 时间戳,方便把现场动作与记录对应起来。
这是一种很适合原型阶段的验证方式:制造一个位置已知、可以重复的输入,观察系统是否给出合理输出。不过,原文没有提供拍手测试的次数、位置误差分布或失败率,它增加的是作者对系统的信心。
接下来是确认目标。日志可以按监听设备依次回放同一事件的录音,并明确显示当前声音来自哪台设备。回放时暂停麦克风录制,避免播放的声音又被当成新事件。
听到目标蜂鸣后,作者点击「This is the mystery beep」。系统据此记住频率,继续寻找相似声音、测量蜂鸣间隔,并汇总多次定位结果。

截图中的目标频率是 3345 Hz,已有 3 次人工确认;地图上的一个估计标注来自 2 次听测,范围约 41 厘米。作者最后报告的结果是约 40 厘米,并在对应箱堆里找到了探测器。这些数字描述的是这次现场使用,不能当成产品的通用精度指标。
有些界面细节也说明系统保留了不确定性。日志可能提示到达时间在物理上不成立,原因可能是回声或检测到了不同声音。响度面板给出「约增加 6 dB,距离大致减半」的提示,但室内遮挡和反射会影响这个粗略关系。
作者还加入了重新摆放设备的流程:点击「Reposition the devices」,移动后点击「Repositioned」,重新进入 Rough mode,旧会话仍可只读查看。地图也能建议额外监听设备的位置,截图中预计可让定位范围改善约 12%。这个百分比是应用的估计,原文没有给出独立验证。
Claude 的「耳朵」,其实是一条可以反复调试的工具链
作者先在 iPhone 上通过 Claude Code Cloud 开始项目,使用 Opus 5.5 的 Extra thinking effort 模式。他的第一步是让 Claude 在空 GitHub 仓库里写 problem.md,描述问题、设备组成、Python Web 应用、WebAudio 和 WebSockets,以及自动确定设备位置的可能性。
研究方向看起来可行后,他才要求实现,并特别提出:监听端必须能自动运行新下发的代码。这样设备摆好以后,就不用每次修改都逐台操作。
第一轮完成了大部分系统,但还没有实际运行验证。作者把仓库克隆到笔记本上,在 Fable 5.2 发布后改用它继续实验,让本地 Claude Code 启动服务器、查看运行情况并实时修改软件。
这里最关键的工程安排,是监听端的 installModule() 方法。管理服务器可以经 WebSocket 触发它,让客户端执行新 JavaScript。一些设备在页面刷新后会重新请求麦克风权限,通过热替换模块更新逻辑,就能减少反复授权带来的中断。
编程代理能持续改进系统,靠的是它既能修改程序,也能检查修改后的现场结果。
按作者的描述,Claude 当时没有原生音频输入,但可以运行 JavaScript 和 Python 分析麦克风采集的数据,查询音频日志,再调整采集与处理逻辑。因此,「给 Claude 耳朵」指的是接入一套可编程的感知工具链。
作者还提到 Martin Woodward 的类似做法:通过 USB-C 更新 GitHub Universe Badge 设备,再用摄像头拍摄屏幕,让编程代理判断更新是否生效。声音和画面不同,解决的都是同一个问题:把程序运行后的外部结果交还给代理。
我的判断
这次实践最有价值的部分,是作者不断把模糊问题改造成可检查的步骤。自动确定设备位置不好用,就补人工粗定位;无法判断录音是不是目标,就加回放和确认;目标声音出现得太慢,就用拍手测试。它展示了一种有效的调试思路。
但约 40 厘米的结果只有一个家庭场景支撑。原文没有交代房间尺寸、设备组合变化、重复实验误差,也没有与只看响度、拿手机逐处排查等做法比较。它能证明这次找到了东西,不能证明多设备声学定位通常更省时间,也不能据此判断 Opus 5.5 与 Fable 5.2 谁更擅长这类任务。
installModule() 也有明确前提:作者控制服务器和监听设备,可以接受管理端下发代码。如果迁移到多人使用的产品里,这个能力就需要认证、权限边界和代码来源约束。
对国内前端和全栈开发者来说,最值得借鉴的是反馈设计。浏览器能采集,服务器能协调,代理能分析日志,人能确认关键事件,几者连起来,才有持续调试的空间。
能拿来做什么
- 做浏览器采集原型时,可以借鉴「滚动缓冲加事件截取」:先保留近期数据,检测到事件后再提取前后片段,方便回查触发前发生了什么。
- 用 AI 开发依赖现场输入的程序时,先准备可重复的测试信号。作者用拍手验证定位,你也应让代理有办法检查输入和结果是否对应。
- 给多设备网页工具增加明确的时间戳、设备身份和事件回放,让人能够确认检测结果,再把确认用于后续处理。
- 需要频繁修改监听逻辑时,可以借鉴免刷新更新的思路,同时为运行中的服务器保留可查询日志,让代理能依据结果继续修改。