内容
<div align="center">
<img src=".github/assets/hotato-banner.svg" alt="hotato" width="442" style="max-width:100%;height:auto;">
<p>
<a href="https://pypi.org/project/hotato/"><img src="https://img.shields.io/pypi/v/hotato?style=flat-square&color=c23c07&label=pypi" alt="PyPI version"></a>
<a href="https://pypistats.org/packages/hotato"><img src="https://img.shields.io/pypi/dm/hotato?style=flat-square&color=c23c07&label=downloads" alt="Downloads per month"></a>
<a href="https://pypi.org/project/hotato/"><img src="https://img.shields.io/pypi/pyversions/hotato?style=flat-square&color=6f5d44" alt="Python versions"></a>
<a href="https://github.com/attenlabs/hotato/actions/workflows/tests.yml"><img src="https://github.com/attenlabs/hotato/actions/workflows/tests.yml/badge.svg?branch=main" alt="CI status"></a>
<a href="https://github.com/attenlabs/hotato/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/hotato?style=flat-square&color=6f5d44" alt="MIT license"></a></p>
<!-- Add a stars badge (shields.io github/stars/attenlabs/hotato) here once the repo reaches ~25 stars; below that it advertises the low number. -->
# 热土豆
**本地优先的AI智能体测试和可观察性**
你的评估结果是绿色的。你的智能体仍然会发送它无法看到的错误:打断对话、长时间沉默、它本该运行的工具。hotato会在你的机器上捕获这些错误,并控制持续集成(CI),确保它们得到修复。
<img src="docs/assets/hotato-demo-cast.svg" alt="uvx hotato start --demo catches a 2.66s talk-over and returns exit 1" width="680" style="max-width:100%;height:auto;">
**[hotato.dev](https://hotato.dev)**
</div>
免费、开源、确定性:相同的调用每次运行都会得到相同的评分,因此您可以基于此阻止构建。您的跟踪信息和提示信息永远不会离开您的机器,并且在您扩展时没有按席位或事件计费。
**几秒钟内捕获您的第一个错误。只需一个命令,无需帐户:**
```console
$ uvx hotato start --demo
对话失败:智能体未产生输出;测量的对话超时时间为 2.66 秒。
对话超时 2.66s 智能体在呼叫者持有话筒时继续说话
```
该记录通过了所有文本评估。时间评估未通过。hotato 将该问题作为 CI 契约固定,字节对字节重现,以便修复的错误始终保持修复。它会衡量时间、对话内容和策略,而不是意图。
## 循环
将生产故障转化为可移植的测试,用候选版本进行测试,并为每个版本提供证据。五个步骤,每个步骤一个命令,所有操作都在本地进行。
| | | |
| :-- | :-- | :-- |
| **观察** | 跟踪、令牌、成本和延迟,来自您已经发出的 OTel 跨度 | `hotato observe report traces/` |
| **捕获** | 确定性评分发现文本评估遗漏的内容:时间、对话内容、策略 | `hotato investigate call.wav` |
| **固定** | 您的标签将捕获的内容转化为可移植的、基于内容的契约 | `hotato investigate label STATE#1 --expect yield` |
| **测试** | 模拟、压力测试和驱动候选版本针对您固定的所有内容 | `hotato gauntlet` |
| **证明** | 将所有证据通道组合成一个失败关闭的、基于内容的证明,在 CI 中 | `hotato prove --contracts contracts/` |
确定性。字节可复制。免费,MIT 许可。适用于智能体原生 > MCP 服务器。每个判决都带有其证据,跨五个维度(结果、策略、对话、语音、可靠性),并且生产环节会反馈到下一个循环:`hotato production export-regression` 将实时会话转换回测试。
整个循环,命令逐一介绍:[`docs/LIFECYCLE.md`](docs/LIFECYCLE.md)。
## 为什么它与众不同
与托管平台相同的循环。 它无法提供的三个功能。
| | hotato | 托管平台 |
| :-- | :-- | :-- |
| 观察、捕获、固定、测试、证明 | 是 | 是 |
| 扩展时的价格 | 免费、MIT、无限制 | 按席位和事件计费 |
| 判决 | 字节对字节可复制,控制构建 | 模型-评委通道每次运行结果不同 |
| 您的跟踪信息和提示信息 | 留在您的机器上 | 存放在他们的服务器上 |
| 在 CI 中运行,离线运行 | 是 | 需要他们的服务 |
完整比较:[`docs/COMPARE.md`](docs/COMPARE.md)
## 从一次失败的调用到证明
一次录音。固定的故障成为一个门槛,只有当智能体停止失败该调用时,该门槛才会变绿,并且您拥有的每个门槛都会组合成一个收据,其标题准确说明了它所确定的内容:
```console
$ hotato investigate ./call.wav
最可能的故障:[1] 智能体打断呼叫者 2.66 秒
下一步:hotato investigate label '.hotato/investigate-state.json#1' --expect yield
$ hotato investigate label '.hotato/investigate-state.json#1' --expect yield
创建 hotato 契约:call-8s-yield
$ hotato prove --contracts contracts/
捕获证据:FAIL
通道失败或回归;查看表格。
contracts fail contracts=1 passed=0 failed=1
content_id: sha256:c907143d711a84ae...
```
`hotato prove` 将您拥有的所有通道(契约、套件、之前/之后的电池、压力测试套件)组合成一个失败关闭的、基于内容的收据:只有当所有通道都通过时,才算通过,并且“无法确定”永远不会显示为绿色。标题是证据支持的**声明范围**,而不仅仅是声明:契约本身重新衡量存储的证据(**捕获证据**),套件确定**测试套件**已运行,并且在您绑定候选身份(`--candidate-config-hash`、`--provider`)之前,候选修订版仅在 **候选修订版**中达到。
## 快速入门
```bash
# 1. 在两个捆绑调用中捕获故障(无需帐户;退出 0)
uvx hotato start --demo
# 2. 评估您自己的录音(或转录本:--transcript t.json)
hotato investigate ./call.wav
# 3. 将捕获的时刻固定为回归契约
hotato investigate label '.hotato/investigate-state.json#1' --expect yield
# 4. 将所有门控组合成一个证明,限定其范围
hotato prove --contracts contracts/
```
通过 `pipx install hotato` 保留它,通过 `uvx --from "hotato[mcp]" hotato-mcp` 在 MCP 上驱动它,或在 [`docs/GETTING-STARTED.md`](docs/GETTING-STARTED.md) 中遵循该路径。
## 将其连接到 CI
步骤的退出代码 **是** 判决:`0` 通过,`1` 失败,`2` 拒绝。
```yaml
# .github/workflows/voice-qa.yml
on: [pull_request]
jobs:
hotato:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: attenlabs/hotato@v1.15.1
with:
contracts: contracts/
hotato-version: 1.15.1
```
复制粘贴工作流与提交 SHA 固定:[`docs/CI.md`](docs/CI.md)。
## 将您现有的内容输入到系统中
每个入口都提供相同的离线评分和相同的 `0` / `1` / `2` 退出契约。
```bash
hotato pull --stack vapi --limit 10 # 您的堆栈的录制调用
hotato trace ingest --otel traces.jsonl # 您已经记录的 OTel 跨度
hotato simulate demo.scenario.json --out ./sim # 脚本化夹具,无需生产音频
```
详细信息:[`docs/CONNECT.md`](docs/CONNECT.md) · [`docs/TRACE.md`](docs/TRACE.md) · [`docs/SIMULATE.md`](docs/SIMULATE.md)
## 将您的智能体指向它
将 Claude Code、Cursor 或任何编码智能体指向此仓库:它读取 [`AGENTS.md`](AGENTS.md) 并离线运行整个循环,无需密钥。MCP 服务器通过本地标准输入/输出公开记分器以及读取/验证/提出工具([`docs/MCP.md`](docs/MCP.md))。
## 没有任何内容离开您的机器
hotato 在调用它的机器上离线运行。核心是仅限标准库的 Python:无需帐户,无需密钥,无需网络调用。您的跟踪信息、提示信息和音频保留在本地,并且本地裁判通道是可选的,质量受控,独立于确定性核心。
## 规格
| 属性 | 值 |
| :-- | :-- |
| 足迹 | ~10 MiB 已安装,0 运行时依赖项(仅标准库) |
| 再现性 | 字节对字节,基于内容的契约 |
| 退出契约 | `0` 通过 · `1` 失败 · `2` 拒绝 |
| 发布完整性 | OIDC 受信任的发布 + 构建源证明 |
| 运行时 | 离线,与生产数据路径分离 |
<details>
<summary><b>自己验证测量结果</b></summary>
```bash
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`)。
</details>
## 贡献
问题和拉取请求欢迎:[`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SECURITY.md`](SECURITY.md) · [`CHANGELOG`](CHANGELOG.md) · [`docs/`](docs/)
## 许可证
MIT ([`LICENSE`](LICENSE))
<div align="center"><sub>知道何时传递。</sub></div>
mcp-name: io.github.attenlabs/hotato