GooseBusters
给 GooseBusters 一个电话号码和一项任务。它会提出方案,请你批准,然后拨打电话,最后汇报结果,并附上通话中的原话作为佐证。命令行和 Tauri 桌面应用提供同一套工作流。
基于 GDK 构建:使用 goose-agent 和提供商组件,不依赖完整的 goose 应用。
巧妙之处
一通电话并不是一串模型响应和工具调用。语音和 webhook 会在其他工作进行的同时到达。电话那头的人一旦说了新的内容,之前的建议就可能立刻过时。
GooseBusters 用自定义状态机操作来表达这一点:规划、审批、拨号、通话事件、监督和最终提取。传入的语音可以抢占监督者的当前轮次。应用在执行某个动作之前,会先检查它是否仍然有效。
模型只是工作流的一部分,并不掌管工作流的生命周期。审批、通话记录以及作用在记录上的效果,都由应用代码控制。
工作方式
- 规划轮次生成语音智能体的指令和需要收集的字段。
- 用户批准、中止,或给出反馈以修订方案。
- 通过 Telnyx 通话连接到 OpenAI 语音后端。通话期间,监督者处理事件并跟踪进度。
- 挂断后,提取步骤会在转录文本中核对所需字段和对方的佐证原话。通话记录以 YAML 格式保存。
监督者 每一轮都会根据应用记录的快照重建状态机:
let snapshot = record.snapshot();
let turn = call_cancel.child_token();
pipeline.handle.set_turn_token(turn.clone());
let machine = StateMachine::new(build_steps(pipeline), turn.clone());
let emit = Emitter::new(tx.clone(), turn.clone());
它调用 machine.step,把返回的效果应用到自己的记录上,并发出界面事件。命令行和桌面应用以不同方式渲染这些事件,而不必各自实现一套智能体工作流。把
操作
和监督者对照着读,就能看到应用在哪里掌控执行。
自己运行
这是一个端到端的原型。真实通话需要 Rust、Telnyx 和 OpenAI 账号,以及一个可公开访问的 webhook 端点。仓库中记录了 Cloudflare tunnel 的设置方法,以及各个语音后端所需的凭据。
git clone https://github.com/DOsinga/goose-busters.git
cd goose-busters
启动桌面应用之前,先完成账号和 webhook 设置:
cargo run -p goosebusters
请使用你有权拨打的号码和联系人。通话会把音频和转录文本发送到外部服务,并可能产生费用。拨打真实电话之前,请先阅读仓库中的 负责任使用说明。