跳转至

从零运行真实语音 Agent

本页从一个干净的 macOS 开发环境开始,不假设你了解 Agora 或 Qwen。完成后,浏览器 麦克风通过 Agora 进入 Muxiva Graph,由 Qwen 生成实时回复,再通过 Agora 播放出来。

只有 App ID 还不能运行

必须先准备 2 个 Agora RTC Token、百炼 API Key 和 Workspace ID。没有全部配置时, muxiva serve 会启动失败。请先逐项完成语音凭据配置清单

你真正需要准备的东西

Agora 需要一个账号、App ID 和两个临时 RTC Token。Qwen 不需要下载 SDK, 只需要阿里云百炼 API Key 与 Workspace ID。Muxiva 会自动下载并校验 Agora macOS SDK、在隔离 Python 环境中安装 Qwen WebSocket 依赖,并为 Demo 2 安装锁定的 Pi TypeScript Agent 包。

0. 当前支持范围

  • 一键安装路径已在 Apple Silicon macOS 上验证;Agora macOS SDK 固定为 4.6.2
  • Demo 2 要求 Node.js 22.19 或更高版本,用于受管理的 TypeScript Host 和 Pi。
  • Qwen Node 当前使用阿里云百炼华北 2(北京)端点,API Key 和 Workspace 必须来自同一区域。
  • Windows/其他平台目前需要从 Agora SDK 官方页面 手动下载,并把解压目录传给 setup.sh

1. 安装 Muxiva 与官方 Node

先准备 Git、Rust、Python 3、Node.js 22.19+、CMake 3.20+ 与 Xcode Command Line Tools,然后运行:

git clone https://github.com/PiyotaHu/muxiva.git
cd Muxiva
cargo install --locked --path crates/muxiva-cli
./examples/voice-agent/setup.sh

最后一条命令会:

  1. Agora 官方 macOS SDK 仓库 对应的官方 CDN 下载 RTC Basic 所需 XCFramework;
  2. 对每个压缩包执行 SHA-256 校验;
  3. 创建 examples/voice-agent/.muxiva/venv 并安装 websocket-client
  4. 拉取独立的 Pi 编码 Agent 仓库锁定版本,在禁用 Lifecycle Script 的前提下安装 npm 依赖,并执行适配器、Agent 与文件权限测试;
  5. 创建 Agent 默认编码工作区;
  6. 编译 agora.audio_sourceagora.audio_sinkagora.data_sourceagora.data_sink 四个 C++ Node;它们共享一个 RTC Engine 和 Bot UID。

出现以下三行才代表安装完成:

[MUXIVA][READY] Native, Python, and TypeScript Agent Node Packs are installed.
[MUXIVA][AGORA] sdk=.../build/vendor/agora-macos-4.6.2
[MUXIVA][QWEN]  python=.../.muxiva/venv/bin/python (no Qwen SDK download required)
[MUXIVA][AGENT] repository=https://github.com/PiyotaHu/muxiva-pi-agent.git ref=v0.2.1 commit=...
[MUXIVA][AGENT] workspace=.../.muxiva/workspaces/pi-agent permissions=list,read,search,create,replace,web-search

如果你已经手动下载 SDK,也可以运行:

./examples/voice-agent/setup.sh /你的/Agora-SDK-解压目录

2. 申请 Agora App ID 与 Token

如果这是第一次申请,请直接按Agora App ID、Certificate、Token Builder 每个输入框的逐项指南 操作。下面只是完成标准的摘要。

  1. 打开 Agora Console 并注册或登录。
  2. 进入 Projects,点击 Create New,认证方式选择 Secured mode: APP ID + Token
  3. 复制项目的 App ID
  4. 选一个 Channel 名称,例如 muxiva-demo。后面所有 Token 必须使用完全相同的名称。
  5. 按 Agora 官方的账号与临时 Token 指南 打开项目安全配置或 Agora Token Builder, 为同一个 Channel 生成两个短期 RTC Token:
Studio 字段 UID 第一次运行建议角色 用途
Browser UID / Token 1001 Publisher 浏览器采集麦克风并播放音频
Muxiva Bot UID / Token 2001 Publisher 同一个 C++ RTC Engine 接收麦克风并发布助手音频

不要暴露 App Certificate

App Certificate 只用于服务端生成 Token。不要把它填进 Studio、网页或提交到 Git。 临时 Token 适合本地体验;生产环境必须部署自己的 Token Server。

3. 申请 Qwen 凭据

如果不熟悉百炼地域与业务空间,请直接按百炼 API Key 与 Workspace ID 逐项指南 操作。Key 与 Workspace ID 必须是华北 2(北京)同一业务空间的一对值。

  1. 打开阿里云百炼控制台,选择 华北 2(北京)并开通服务。
  2. 按官方获取 API Key指南创建 Key, 创建成功后立即保存明文。
  3. 按官方首次调用 Qwen 指南找到同一 Workspace 的 Workspace ID

这里没有“Qwen SDK 下载”步骤。Muxiva 的 Python Node 直接使用官方 WebSocket/HTTP 协议。Realtime 图默认使用 qwen-audio-3.0-realtime-flash;级联图在 Qwen ASR 与 Qwen TTS 之间使用由 qwen-flash 驱动的 Pi 编码 Agent。它可以在 受限工作区真实读取、搜索、创建和修改文件,也能复用相同百炼凭据按需联网搜索并返回 来源;通用接入方法见 Agent 集成 SOP

4. 选择 Studio 或 Headless 启动方式

先从示例创建本地凭据文件并填一次。它被 Git 忽略,之后 CLI 和 Studio 都会自动读取:

cp examples/voice-agent/.env.example examples/voice-agent/.env
# 编辑 examples/voice-agent/.env,填入第 2、3 节取得的值
muxiva doctor --voice

doctor 应显示 Agora Node Pack 为 mode=agora-native,并显示 Qwen Python 与 Pi TypeScript Agent 已就绪。出现 MISSING 表示 .env 仍缺必填值,不是可以跳过的提示。

macOS 本地开发直接运行以下命令,默认打开 Studio;Windows Git Bash 使用相同命令, PowerShell 可执行 muxiva studio examples/voice-agent/graph.json

./examples/voice-agent/run.sh

在 Studio 中选择模板、点击 Run,并通过 ◎ Observe 调试 Node 与 Edge。 在 Linux、Docker、SSH,或者需要验收前后端分离链路时,终端 A 显式启动 Headless Runtime:

./examples/voice-agent/run.sh --headless

终端 B 只启动网页静态文件:

cd examples/voice-agent
npm run voice-room

打开 http://127.0.0.1:4173,Backend URL 使用 Runtime 打印的 http://127.0.0.1:8080,点击 Test connection,再开始通话。网页和 Runtime 是两个 独立进程;网页关闭不会停止 Graph,Graph 停止也不会由网页静态服务器接管。

run.sh 在 macOS/Windows Shell 默认 Studio、Linux 默认 Headless;--studio--headless 可显式覆盖。无 GUI Linux、SSH、公网和 Docker 的完整命令见 Headless Runtime 与独立网页。项目 Voice Room 始终独立于 Studio; 完整浏览器通话使用 Headless 模式提供的 Client API。

Realtime 跑通后,再切换 Pi Agent Full-Duplex Cascade(Demo 2),观察 Qwen Server VAD + Streaming ASR → 有状态 TypeScript Agent 与 Tool Call → Speech Formatter → 可取消 Qwen TTS。聊天框保留 Agent 原始 Markdown,TTS 只接收不含强调符号、裸 URL、 代码块和表格的自然播报文本。 可以询问当前时间或今天的天气,强制触发真实 Tool Call。助手播放时重新开口: Voice Room 应立即显示打断状态,旧文字停止增长、旧语音停止播放,新一句转写和回答随后 进入同一会话。会话会持续运行,直到点击 End session

当前 graph.json 是 Demo 2,默认使用 vad_threshold: 0.45。需要适配麦克风或房间时,可在 Studio 画布选择 qwen-vad-asr,修改 Configuration 中的数值,然后点击 ValidateSave graph。数值越低越灵敏,越高越能过滤低能量声音。

运行日志与链路定位

run.sh 会同时把终端输出保存到 examples/voice-agent/.muxiva/runtime.log。遇到“已经 连接但没有回复”时,按下面的顺序找第一个没有增长的指标:

Headless 模式先以终端和 runtime.log 定位;本地设计时可另开 Studio 使用 ◎ Observe 检查同一份 Graph。指标含义、阈值与日志过滤命令见可观测性与堵点定位

  1. Voice Room 显示浏览器已加入、麦克风已发布;
  2. 说话时 MIC LEVEL 增长;连续五秒没有语音能量时页面会直接提示检查输入设备;
  3. 日志出现 [MUXIVA][AGORA][participant.joined] uid=1001
  4. 日志出现 [MUXIVA][AGORA][audio.received],Studio 的 agora-input 增长;在 Observe 点击 agora-audio-sourceinput.audio_peak_pcm16 说话时必须明显大于 0;
  5. Demo 1 的 Qwen Realtime Node 先打印 Server VAD 的 speech_started / speech_stopped, 随后出现 ASR 和 response.created;Demo 2 则检查 transcript-to-agentagent-to-speech-formatterspeech-formatter-to-tts
  6. tts-audioaudio-to-room 增长,浏览器听到回复。

第一个没有出现的步骤,就是故障所在层。凭据值不会写入日志。

Voice Room 从 Agora RTC 数据流接收消息,而不是读取 Studio NotificationBus;页面会把每轮对话 显示成聊天记录:用户 ASR 在右侧,Agent 流式回复在左侧。 Qwen 增量 ASR 使用 text + stash 作为实时预览,并在 conversation.item.input_audio_transcription.completed 到达后固定最终文本。Agora Bot 只消费远端 PCM,不在运行机器的扬声器播放用户声音;助手音频以 10 ms PCM 包匀速发布。

独立页面只通过 Headless Runtime 的 /api/v1/client/session 获取浏览器 RTC 启动配置。 该服务没有 Studio 的 Graph 或 Runtime 管理接口;生产网页应进一步替换为业务 Token Service。

5. 常见错误

现象 原因与处理
Agora SDK directory does not exist 路径不是解压目录;macOS 直接重新运行无参数 setup.sh
AgoraRtcKit.xcframework not found 手动下载了错误平台或不完整包;使用一键下载命令
qwen-python ready=false 没运行 setup.sh,或项目虚拟环境损坏;重新运行安装
pi-typescript-agent ready=false 安装 Node.js 22.19+,再运行 setup.sh 安装锁定的 Pi 包
installed Agora Node Packs are older 先停止正在运行的 Studio,执行一次 ./examples/voice-agent/setup.sh,再重新启动;run.sh 会拒绝加载过期 Native 代码,不再静默使用旧产物
Qwen 返回鉴权/模型错误 API Key、Workspace ID、模型必须属于华北 2(北京)同一 Workspace
Agora 加入 Channel 失败 App ID、Channel、UID 必须与生成该 Token 时完全一致,Token 也不能过期
页面没有麦克风 浏览器未授权;在浏览器站点权限中允许本地 Studio 使用麦克风
有 RTC Frame 但完全没反应 先看 Voice Room MIC LEVEL,再看 Observe 的 input.audio_peak_pcm16;始终接近 0 表示发布的是静音或选错输入设备
顶部没有 ◎ Observe 查看启动日志 [MUXIVA][CLI];源码开发必须使用当前仓库 target/.../muxiva,重新运行 setup.sh 会自动构建并选择它
清晰听到自己的声音 更新 Muxiva 并重新运行 setup.sh 编译 Agora Node Pack;Bot 日志必须显示 local_remote_playback=silenced-after-mix
有文字但没有语音 查找 [MUXIVA][AGORA][audio.published];没有该日志说明 Qwen 未产生音频,有日志则检查浏览器是否订阅 Bot 音轨
页面没有用户 ASR 查找 Qwen input_audio_transcription.completed;新版页面显示 text + stash 实时预览和最终 transcript

6. 工程验收

不使用凭据时,可以验证代码、Node 边界与动态 ABI:

./scripts/check-provider-boundaries.sh
./scripts/check-voice-node-packs.sh

它们不会伪装成真实通话。完整验收标准是:真实加入 Agora Channel、真实麦克风输入、 Qwen 返回字幕和语音,并且在播放期间成功插话打断。