编码 Agent 能写出渲染产品演示影片的代码,却听不到自己做出来的声音对不对。earshot 补的就是这一环:它把音频变成 Agent 可以检索、比对、打分的证据,纯 CPU 运行,不调云端模型,同时给出命令行、Python API 与 MCP 服务器三种接口。本教程按官方 README 六步实操:装好并预热模型、挂到 MCP 客户端、挑音效、定位片段、核对音画、用代码合成声音。命令逐条来自官方仓库 README 与其安装说明,主线不需要任何 API Key。
uv、ffmpeg 与 ffprobe 在 PATH 上、约 1.1 GB 磁盘放模型、一个支持 MCP 的客户端(本教程用 Claude Code 演示)。不需要 GPU,主线不需要 API Key;只有可选的 llm 音频点评才要你自己的 Gemini Key。先弄清:为什么用 MCP 服务器,而不是每条命令都调 CLI
官方 README 把这条限制写得很直白:每条 CLI 调用都是新进程,要先加载模型(约 20 到 40 秒)才能回答;只有 measure、sfx、kit 这三类命令不加载模型。所以官方给的建议是——调用次数多时改用 MCP 服务器(模型常驻),或者写一个 Python 脚本用 from earshot import api 一次加载多次调用。
| 形态 | 模型加载 | 适合场景 |
|---|---|---|
| CLI 单条命令 | 每次新进程重新加载,约 20–40 秒 | 偶尔跑一条、写进 shell 脚本 |
| MCP 服务器 | 头一次调用加载后常驻 | Agent 连续听多个文件(本教程主线) |
| Python API | 脚本内一次加载 | 批处理、接进自己的流水线 |
版本与来源:本教程按本次核对的官方仓库 Leonxlnx/earshot README 撰写,安装走 uv tool install 的 git 形式,README 未在正文写死当前版本号,需要版本号请用 earshot doctor 或 uv tool list 自查,不要照抄第三方文章里的旧命令。项目许可请以仓库 LICENSE 文件为准;两条安装路线(uv 工具 / 克隆源码)不要混用,否则 MCP 命令里的可执行文件路径会指错。
Step 1:用 uv 安装,doctor 预热两个模型
官方主推 uv 一条命令安装。装完立刻跑 doctor --fetch 把两个开放模型提前下好,避免 Agent 调用时卡在下载上。
# 前置:确认 ffmpeg / ffprobe 可用(官方要求二者在 PATH 上)
ffmpeg -version
ffprobe -version
# 安装(MCP 形态,官方 README 原样)
uv tool install "earshot[mcp] @ git+https://github.com/Leonxlnx/earshot"
# 立刻把两个模型下到本地(约 1.1 GB)
earshot doctor --fetch
# 后续升级
uv tool upgrade earshot
# 可选:需要 Gemini 音频点评时才装 llm 扩展
uv tool install "earshot[mcp,llm] @ git+https://github.com/Leonxlnx/earshot"
官方说明下的是两个固定 revision 的 safetensors 权重:文本-音频嵌入模型 CLAP laion/larger_clap_general @ 16c8cc3,以及 AudioSet 标签器 MIT/ast-finetuned-audioset-10-10-0.4593 @ f826b80。缓存位置在克隆安装时是仓库内 .cache/hf,用 uv 工具安装时是 ~/.cache/earshot/hf,可用 EARSHOT_HOME 改。
EARSHOT_OFFLINE=1、HF_HUB_OFFLINE=1、TRANSFORMERS_OFFLINE=1 任一设上即可(三者对 earshot 等价),缺模型会明确报错。磁盘与首轮耗时:两个模型合计约 1.1 GB,其中 CLAP 的 safetensors 单独约 776 MB。官方还说明 0.2.1 之前建的缓存里 CLAP 是 pickle 权重(pytorch_model.bin),仍可从缓存以 weights_only 加载;跑 doctor --fetch 会补下 pinned 的 safetensors 版本。纯 CPU 推理,机器慢时先用 EARSHOT_THREADS 限制线程数(默认 min(4, 核数/2))。
Step 2:挂成 MCP 服务器,让 Agent 连续听
官方给了 uv 安装与克隆安装两种注册写法,区别只在最后那个可执行文件。选你 Step 1 用的那条,别两个都配。
# 方式 A:uv tool install 装的(推荐)
claude mcp add earshot --scope user -e EARSHOT_THREADS=3 -- earshot mcp
# 方式 B:从源码克隆装的,换成虚拟环境里的 python
claude mcp add earshot --scope user -e EARSHOT_THREADS=3 -- /path/to/earshot/.venv/bin/python -m earshot mcp
# Windows 克隆安装时把路径换成 .venv/Scripts/python.exe
# 任意 MCP 客户端的 .mcp.json 等价写法
{
"mcpServers": {
"earshot": {
"command": "/path/to/earshot/.venv/bin/python",
"args": ["-m", "earshot", "mcp"],
"env": { "EARSHOT_THREADS": "3" }
}
}
}
# 机器较慢、客户端超时:启动 Claude Code 时放宽 MCP 超时
MCP_TIMEOUT=60000 claude
# 注册后确认在列表里
claude mcp list
模型在头一次工具调用时加载,之后保持常驻,这正好解决 CLI 每次 20–40 秒的开销。让 Agent 试着问一句「列出 earshot 能做的事」,或者直接给一段音频让它描述,就能确认链路通了。
llm_critique 这个可选工具从环境里读 GEMINI_API_KEY,并特别提醒不要把明文 Key 写进配置文件。主线工具(描述、检索、比对、定位、点评、报表、合成)都不需要 Key。路径与进程:官方要求 .mcp.json 里写完整路径,因为 MCP 客户端不一定继承你 shell 的 PATH;Windows 的 JSON 里每个反斜杠要写成两个。MCP 服务器会常驻并占着模型内存,用完记得在客户端里移除该服务器,别让它一直在后台挂两个模型。
Step 3:从一堆候选音效里挑出对的那一个
典型场景:下载了十个按键音,要挑一个贴合「沉闷的机械键盘敲击」的。先用 rank 按文字描述给候选排序,再对胜出者跑 match 拿判定与 z 分数,用 describe 让工具把某个文件「听」成文字。
# 用自然语言描述给一批候选排序
earshot rank "a single mechanical key press" candidates/*.ogg
# 对选中的文件做匹配判定,--alts 给出容易混淆的干扰项
earshot match key.ogg "a deep thocky mechanical keyboard press" --alts "a clicky blue switch keyboard" "a mouse click"
# 让工具用文字描述某个文件听起来是什么
earshot describe key.ogg
# 每条命令都支持通用输出开关
earshot rank "a single mechanical key press" candidates/*.ogg --json --out rank.json
官方说明 match 返回的是 strong / plausible / weak / no match 这样的判定加一个 z 分数;每条命令都先打印一段大白话摘要,--json 才给完整结果,--out f.json 把结果存盘。错误是一行 stderr(形如 earshot <command>: error: ...)并以退出码 1 结束,方便脚本判断。
判定不是主观听感:z 分数与四档判定来自嵌入模型和标签器的计算,不保证与你的听感一致。选进正式素材前请自己再听一遍,别把 strong 当成免检通过。
Step 4:在长录音里定位「那一声」
拿到一段很长的录音,只想找出其中一次按键声出现在第几秒,用 find 加 --top 拿若干候选时间点。
# 在长录音里找最像「单次机械按键」的 4 个片段
earshot find keys.ogg "a single mechanical key press" --top 4
# 输出是若干 start / end 秒数,可直接喂给 ffmpeg 裁剪
# 例:把 2.40 到 2.75 秒切出来复核
ffmpeg -i keys.ogg -ss 2.40 -to 2.75 -c copy hit.ogg
# 批量脚本里用 --json + --out 拿结构化结果
earshot find keys.ogg "a single mechanical key press" --top 4 --json --out hits.json
官方给的排错建议很实用:若排名靠前的片段听起来不对,换两三种描述措辞再试,别只调 --top 的数字。返回的是时间区间而不是音频文件,剪出来复核这一步要自己做。
--json --out 的结果交给 Agent,它就能自己决定裁哪一段、再对裁出来的片段跑一次 match 复核,形成「粗定位 → 精验证」两步链,比一次性要求它找对更稳。依赖 ffmpeg:earshot 自己需要 ffmpeg / ffprobe 在 PATH 上;上面的裁剪命令也是 ffmpeg。若报找不到解码器或容器格式,先用 ffprobe keys.ogg 确认输入能被读,再排查是不是首轮模型还在加载。
Step 5:影片音画核对,拿到可归档的报表
把做好的发布影片交给 Agent 检查声音与画面是否对得上。critique 给带时间戳的修改建议,sheet 生成一张带标注的 PNG(帧、声音事件、频谱、响度、同步标记),方便能读图的 Agent 直接看。
# 对整段影片做音画点评,输出按时间戳列出待修项
earshot critique film.mp4
# 生成标注图:帧 + 事件标签 + 频谱 + 响度 + 对拍标记
earshot sheet film.mp4 -o sheet.png
# 把一批 forge 产物汇成一个静态试听页
earshot gallery made/ -o page.html
# 可选:调用音频大模型点评(需自己的 GEMINI_API_KEY 且显式同意上传)
earshot llm film.mp4 --yes-upload
# 结构化结果落盘,供 Agent 二次处理
earshot critique film.mp4 --json --out critique.json
critique 输出一串带时间戳的修改建议,sheet.png 里能看到帧与声音事件是否对齐、响度有无突跳。把这两份产物一起交给 Agent,它就能定位到「第几秒该补一个音效」这种可执行结论,而不是泛泛说「音画不够贴」。评分口径要看清:官方说明 critique 的分数是「与一组专业发布影片(7 部)的接近程度」,并非通用的质量分,别把它当成及格线写进验收标准。llm --yes-upload 会把音频送给你自己配置的音频大模型并可能产生费用,且需要显式同意;企业素材请先确认合规再开启,主线 critique / sheet 全在本地。
Step 6:用 forge 以代码合成音效,并审阅报告
官方把 forge 描述成「让 Agent 用代码写声音」:一份物理合成配方(模态谐振器、接触激励、滤波噪声、房间与麦克风),渲染出候选后由内置 critic 按描述匹配、真实度、与参考录音的接近度以及一组无模型测量(1/3 倍频程音色平衡、时频谱包络、咔哒/混叠/削波等瑕疵、起振与尾音)打分,Agent 读评语改配方再跑。
# 列出可用配方与参考集
earshot forge --list
# 按键音:给真实参考录音、搜索预算与变体数
earshot forge keypress --refs path/to/real/keypresses/ --budget 144 --variants 4 --dir made/keypress
# 用内置参考集的 forge 划分跑 whoosh
earshot forge whoosh --refset whoosh_fast --budget 96 --dir made/whoosh
# 用文字目标 + 干扰项 + 自己的参考录音,走 real 模式
earshot forge whoosh --target "a fast crisp air whoosh" --alts "a wind gust" "a sword swing" --refs path/to/real/whooshes/ --mode real --dir made/whoosh
# 拿报告里的参数换随机种子重渲染,验证是否稳定
earshot forge --render keypress --params made/keypress/report.json --seeds 1 2 3 --dir made/again
# 打开 made/keypress/report.md 与 audition.wav 试听对比
--refs 带自己的;或用 --refset 选内置划分。报告里 critic 的评语是「听起来像:软木塞弹出、玻璃叮」这类可执行的文字,配合频谱图与参考录音并排看,比只看一个分数更好改配方。官方自己给的诚实限制:README 写明搜索过程可能只是在讨好自家的打分模型,而声音并没有真的变好。所以定稿请靠耳朵,并对照那些不依赖模型的测量量(音色平衡、包络、 artifacts)。另外 preset 是把各角色对到音乐床与剪辑点上的无模型能力,kit init --preset 里的 preset 是旗标而非独立子命令,别按第三方文章的写法乱拼。
常见问题 FAQ
| 现象 | 原因与处理 |
|---|---|
| 报找不到 ffmpeg / ffprobe | 官方要求二者在 PATH 上,先 ffmpeg -version 验证 |
| 每条 CLI 命令都要等半分钟 | 正常:新进程加载模型约 20–40 秒;改用 MCP 服务器或 Python API 常驻 |
| 客户端连上就超时 | 慢机器用 MCP_TIMEOUT=60000 claude 启动 |
| cloned 安装后 MCP 起不来 | .mcp.json 里要写完整路径,Windows 反斜杠需双写;确认指向 .venv 内的 python |
| 离线环境报模型缺失 | 先在有网时 earshot doctor --fetch,再设 EARSHOT_OFFLINE=1;缺缓存会明确报目录 |
| find 找出的片段不对 | 换两三种描述措辞重试,别只加大 --top |
| critique 分数低但听着没问题 | 分数是相对 7 部参考影片的接近度,并非通用的质量分 |
| forge 分数一路涨、声音没变好 | 官方已注明可能过拟合打分模型,靠耳朵与无模型测量复核 |
做到哪一步算成功
四条验收线:① earshot doctor --fetch 完成且报告里能看到两个模型的 revision 与权重精度;② claude mcp list 里出现 earshot,连续问两个音频问题没有重复加载模型的长等待;③ 用 rank 选出候选、match 给出带 z 分数的判定、find 返回可裁剪的起止秒数;④ critique 产出带时间戳的建议、sheet 生成标注图。做到这些,再按自己的参考录音试一次 forge,并记住定稿靠耳朵而不是分数。
交付前自查:本教程命令来自官方仓库 README 与其安装/CLI 说明;README 未在正文写死版本号,工具清单与旗标请以你安装当天的 earshot doctor 与仓库 README 为准。音频素材注意授权,参考录音不在仓库里;接 llm 扩展会把音频送到第三方并产生费用,企业环境务必先过合规。