attenlabs/hotato
GitHub: attenlabs/hotato
hotato 是一款本地运行的语音 agent 通话取证与回归防护工具,帮助开发者定位语音交互中的问题并通过 CI 检查防止其再次发布。
Stars: 1 | Forks: 0
## 它能发现什么
- **打断 → 说到做到的差距(Say-do gaps)**:呼叫者打断以取消;agent 说“已取消”,但预订工具仍然触发了:这是一个在呼叫者取消后依然触发操作的 bug。(时间点来自音频;工具触发检查会读取你的调用工具日志:hotato 会获取 Vapi/OTel traces。)
- **延迟尖峰**:800ms 到 5s 的不可预测性导致用户挂断电话。
- **死寂(Dead air)**:破坏对话流的长时间沉默。
- **抢话(Talk-over)**:agent 在呼叫者说话时抢话;从不退让。
## 快速开始
### Vapi
```
pip install hotato
export VAPI_API_KEY=...
hotato vapi health --last 7d --output report.html
```
打开 `report.html`。查看你的语音稳定性得分(Voice Stability Score)以及每一个关键事件。
### Retell
```
export RETELL_API_KEY=...
hotato retell health --call-id CALL_ID
```
`--call-id` 是必填且可重复的:Retell 没有经验证的 list-recent-calls endpoint,因此 hotato 绝不会随意猜测一个。`hotato bland health`、`hotato synthflow health` 和 `hotato millis health` 遵循 Vapi 的结构;这些技术栈导出的是混合单声道,因此它们的报告会包含测量置信度单声道观察块。
### 本地音频
```
hotato autopsy ./call.wav
```
在 `hotato-output/` 目录下生成一份详尽且独立的 HTML 事件报告;在浏览器中打开它。
## 从发现 bug 到预防 bug
`autopsy` 用于发现 bug。`scan` 用于跟踪整个调用文件夹的趋势。当你准备好后,将事件锁定到你的 CI 中,确保它们不再被发布:`hotato pin` 将单个事件转换为可移植的失败检查,而 `hotato prove` 则是 CI 检查,它会重新运行所有存储的证据并在闭环中失败。每个判定都包含跨越五个维度(结果、策略、对话、语音、可靠性)的证据。
[阅读更多 →](docs/CI.md)
用于持续使用:按计划运行 `hotato vapi health`,并打开 `hotato console --production-db DB` 以在本地检查存储的运行记录。
## 将其接入 CI
该步骤的退出代码(exit code)**即**判定结果:`0` 通过,`1` 失败,`2` 拒绝。
```
# .github/workflows/voice-qa.yml
on: [pull_request]
jobs:
hotato:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: attenlabs/hotato@v1.17.0
with:
contracts: contracts/
hotato-version: 1.17.0
```
带有 commit-SHA 锁定的可直接复制粘贴的工作流:[`docs/CI.md`](docs/CI.md)。
## 将你的 agent 指向它
将 Claude Code、Cursor 或任何编程 agent 指向此仓库:它会读取 [`AGENTS.md`](AGENTS.md) 并离线端到端地运行循环,无需密钥。MCP server 通过本地 stdio 暴露评分器以及读取/验证/提议工具:`uvx --from "hotato[mcp]" hotato-mcp` ([`docs/MCP.md`](docs/MCP.md))。
## 任何数据都不会离开你的机器
hotato 完全离线运行,就在调用它的那台机器上。其核心是仅使用标准库(stdlib-only)的 Python:无需账户、无需密钥、自身也不进行任何网络调用。你的 traces、prompts 和音频都将保留在本地,并且本地评审器通道(local-judge lane)是可选的且受质量控制的,与确定性核心相互独立。
## 深入了解
整个循环,逐条命令解析:[`docs/LIFECYCLE.md`](docs/LIFECYCLE.md)。
从初次接触到 CI 拦截:[`docs/GETTING-STARTED.md`](docs/GETTING-STARTED.md)。
把现有的东西喂给它:[`docs/CONNECT.md`](docs/CONNECT.md) · [`docs/TRACE.md`](docs/TRACE.md) · [`docs/SIMULATE.md`](docs/SIMULATE.md)。
每个判定基于什么:[`docs/EVIDENCE-CONTRACT.md`](docs/EVIDENCE-CONTRACT.md)。
与托管型替代方案的对比:[`docs/COMPARE.md`](docs/COMPARE.md)。
深度工具集 —— 捕获、模拟、负载、基准测试、修复阶梯、集群控制平面 —— 位于 `hotato lab` 之下(`hotato lab --help`)。
公开命令是持久稳定的;`hotato lab` 演进得更快;1.17 版本之前的所有顶级拼写依然保持原样正常工作。
## 规格
| 属性 | 值 |
| :-- | :-- |
| 占用空间 | 安装后约 10 MiB,0 运行时依赖(仅使用标准库) |
| 可复现性 | 逐字节,内容寻址检查 |
| 退出代码 | `0` 通过 · `1` 失败 · `2` 拒绝 |
| 发布完整性 | OIDC Trusted Publishing + build-provenance 证明 |
| 运行时 | 离线,脱离生产数据路径 |
亲自验证测量结果
```
PYTHONPATH=src python3 -m hotato.benchmark \
--scenarios corpus/real/scenarios --audio corpus/real/audio
```
在 13 段录制的 AMI Meeting Corpus 音频片段中,测量到的呼叫者发音起点与人类词语对齐标签之间的中位数误差为 **20 ms**。来源:[`corpus/real/README.md`](corpus/real) · 方法:[`METHODOLOGY.md`](METHODOLOGY.md)。
只有当两个声音通过不同的声道传输时,时间点才是可测量的;单声道或混合导出会被标记为 **NOT SCORABLE** 并被拒绝(`hotato trust --stereo call.wav`)。完整的四级证据策略(每次判定基于什么,针对不同输入)详见 [`docs/EVIDENCE-CONTRACT.md`](docs/EVIDENCE-CONTRACT.md)。
## 许可证
MIT ([`LICENSE`](LICENSE))
知道何时该把它传递下去。
mcp-name: io.github.attenlabs/hotato
标签:AI智能体, 回归测试, 性能监控, 用户代理, 语音Agent, 逆向工具