Voice Agent文档
EnglishGitHub ↗
从聆听到回应,自然衔接每一轮对话。

一场对话。
就在你的工作空间。

一款 Python 语音助手,配备实时终端面板和浏览器界面。从麦克风输入到语音回应,随时查看每一轮对话的进展。

Voice Agent 中文界面,使用模拟数据运行
正在运行的浏览器预览界面。对话内容和延迟数据均为模拟数据。
01 / 聆听

识别说话时机。

本地 VAD 将语音与背景中的静音区分开来。

02 / 回应

逐句播报回应。

异步处理流程将回应中的句子转成语音。

03 / 打断

让对话自然继续。

通过终端或浏览器停止当前播报。

使用文档

安装

需要 Python 3.11+ 和 uv。预览模式无需 API 密钥或麦克风,即可体验界面。

终端
git clone https://github.com/natelindev/voice-agent.git
cd voice-agent
uv sync --locked
uv run voice-agent --demo --web
预览使用模拟数据。 对话、音量和延迟指标都是示例数据,不会调用语音或模型 API。

实时 API 模式

为操作系统安装 PortAudio,允许启动程序的终端访问麦克风,并配置 OpenAI API 密钥。在 Ubuntu/Debian 上,通过软件包管理器安装 libportaudio2。在 macOS 上,使用下方命令。

终端
brew install portaudio
cp .env.example .env
# Edit .env and set OPENAI_API_KEY
uv run voice-agent --web

请勿公开 .env。API 模式会发送语音片段进行转写,发送文本和对话上下文生成回应,再发送回应文本合成语音。API 用量由服务提供商计费。

使用文档

选择运行模式

模式语音处理回应生成
API本地 Silero VAD;Whisper API 转写;OpenAI PCM 语音合成OpenAI 流式聊天补全
Mac 语音 + Codex本地 whisper.cpp 转写;macOS say通过网络调用已登录的 Codex CLI
预览模拟音频和对话轮次固定的示例对话

配置 OPENAI_API_KEY 后,默认使用 API 模式。未配置密钥时,CLI 默认使用 Mac 语音后端,除非指定 --demo。--local 明确选择 Mac 语音,优先级高于 --demo。

Mac 语音的准备工作

此后端需要 macOS、say、已登录的 codex 可执行程序、whisper.cpp 的 whisper-server 或 whisper-cli,以及位于下方路径的 OpenSuperWhisper 模型。它面向 Apple Silicon 设备。

预期的模型路径
~/Library/Application Support/ru.starmel.OpenSuperWhisper/whisper-models/ggml-large-v3-turbo.bin

程序会先尝试连接 127.0.0.1:8178 上的 whisper 服务;如果模型存在,则尝试启动该服务,失败时回退到 whisper-cli。默认 macOS 音色为 Samantha。

终端
uv run voice-agent --local --web
本地语音不代表离线回应。 Codex 使用网络服务,并依赖自身的身份验证、套餐限制和权限。此后端不需要 OpenAI 开发者 API 密钥,但并非完全离线的助手。
使用文档

说话、聆听与打断

标准输出为 TTY 时会显示终端面板。可选的浏览器界面位于 http://127.0.0.1:8000,展示处理状态、音量、对话记录和每轮指标。音频采集和播放由主机上的 Python 进程完成,而非浏览器。

控制方式操作
Space / 打断停止助手当前的回应。
M / 静音切换麦克风采集状态。
R / 清空重置对话记录。
Ctrl+C停止进程。

使用扬声器或耳机

扬声器模式会在助手播报期间及结束后的 500 毫秒回声消退期内暂停麦克风输入。回声过滤会拒绝识别到的扬声器漏音。通过扬声器播放时,请使用手动打断。

终端
uv run voice-agent --web --headphones

耳机模式允许在播报期间通过麦克风语音触发打断。请使用耳机,避免助手听到自己的声音。

理解延迟指标

每轮指标记录转写耗时、回应生成时间、首个语音片段时间和整体回应时间。实际延迟取决于硬件、网络、语音长度和后端。预览数值为模拟数据;本项目尚未确立有保证的延迟基准。

使用文档

处理流程与音频规范

异步事件中心连接音频采集、VAD、转写、生成、播放和两个界面。音频回调在 sounddevice 的线程中执行,处理流程使用 asyncio。

单轮流程
Microphone → Silero VAD → utterance PCM
  → ASR → user text → response sentences
  → speech synthesis → speaker playback

EventHub → terminal dashboard + WebSocket companion
阶段当前 API 实现
采集 / VAD16 kHz 单声道 float32 输入,每块 512 个采样点;语音片段为 int16 PCM。
转写使用 whisper-1 处理语音片段。
生成使用 gpt-4o-mini,支持流式聊天和句子拆分。
语音合成使用 gpt-4o-mini-tts、coral 音色和流式 PCM。
打断发出取消信号并停止播放,以协作方式取消正在进行的工作。

模型、采样格式、本地服务地址和 Mac 音色目前在源代码中定义,不能通过环境变量切换。本地 Codex 后端会等待命令输出,再将回应拆分成句子。

使用文档

命令行

选项行为
--web / -w启动本地 HTTP 和 WebSocket 浏览器界面。
--port / -p浏览器界面端口,默认为 8000。
--no-open启动浏览器界面,但不自动打开浏览器。
--headless / --no-tui关闭终端面板。
--local / -l选择 Mac 语音 + Codex 后端。
--demo使用模拟预览;设置 --local 时会忽略此选项。
--headphones允许在助手播报期间通过语音打断。
--verbose / -v启用调试日志。
--help显示命令行帮助。
终端
uv run voice-agent --demo --web --no-open --port 8010
uv run voice-agent --web --headless
uv run voice-agent --help

浏览器界面绑定到 127.0.0.1,没有内置身份验证,面向本地使用。调试日志可能包含对话文本,分享前请进行脱敏。

使用文档

故障排查

预览正常,但实时模式无法运行

检查 PortAudio、麦克风权限、输入和输出设备,以及所选后端的准备要求。预览模式会绕过麦克风、转写和语音合成。

程序意外选择了 Mac 模式

未配置 API 密钥时,默认选择 Mac 后端。在环境变量或项目的 .env 中设置 OPENAI_API_KEY,或使用 --demo 进入预览。

本地转写没有内容

检查预期的模型路径、whisper.cpp 可执行程序,以及端口 8178 是否提供兼容的推理接口。缺少工具或模型文件会导致本地实时语音识别不可用。

助手听到了自己的声音

使用默认扬声器模式并手动打断,或在启用 --headphones 前戴上耳机。

浏览器显示未连接

保持 Python 进程运行,检查配置的端口,并刷新浏览器界面。浏览器依赖与本地后端的 WebSocket 连接。

尚未验证音频或模型

单元测试和预览检查无法替代使用真实服务进行的麦克风到扬声器测试。在依赖延迟或打断表现之前,请在目标硬件上测量一次真实对话。

使用文档

开发与贡献

测试使用模拟的服务边界,覆盖音频转换、VAD、取消、本地后端、事件、终端面板和 WebSocket 行为。

终端
uv sync --locked
uv run pytest tests/ -q
uv build
uv run voice-agent --demo --web --no-open

请参阅贡献指南。修改处理流程时,请保持采样率规范和协作取消机制。