CopilotKit Agno 集成语音示例音频 sample.wav 配置与生成完全指南
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
本指南围绕 CopilotKit 仓库中 Agno 集成(showcase/integrations/agno)的语音演示(Voice Demo)展开,核心目标是教会你如何正确放置并生成驱动该演示的示例音频文件sample.wav。读完本文,你将掌握该音频文件的目录位置、格式规格(16kHz 单声道、3–5 秒、小于 100KB)、内容要求(必须包含 "What is the weather in Tokyo?" 这句台词),以及 macOS / Linux / Windows 三平台的标准生成命令,并理解该文件在语音转写链路(/transcribe端点、E2E 断言)中的真实作用。
一、这份 README 说明文档的用途:语音演示的"固定台词"音频
在仓库路径 showcase/integrations/agno/public/demo-audio/README.md 下,存放着一份专门解释语音演示音频文件的说明文档。它对应的是 Agno 集成中的Voice Input(语音输入)演示,在 manifest.yaml 中被登记为id: voice,路由为/demos/voice,其功能描述为:
Microphone + sample-audio button → /transcribe endpoint → text injected into the chat composer(麦克风 + 示例音频按钮 →
/transcribe端点 → 文本注入聊天输入框)
该演示页面同时提供两条输入通道(详见 voice-chat.tsx 的注释):
- 麦克风按钮:由
<CopilotChat />在运行时(runtime)通告audioFileTranscriptionEnabled: true时渲染,点击后录音并调用真正的转写端点; - 示例音频按钮(Sample Audio Button):同步将一段预设台词注入聊天输入框,不依赖麦克风权限,也不走
/transcribe往返,是确定性的测试/演示手段。
本 README 说明文档所管理的sample.wav,正是为了让上述"示例音频"路径在不需要麦克风权限的前提下完整复现"语音 → 文本 → Agent 应答"的链路:演示页面会在客户端取用该音频文件,并将其 POST 到转写端点。
二、文件放置位置与命名约定
说明文档明确规定:
- 将一个小体积(小于 100KB)的 WAV 文件放在本目录:
showcase/integrations/agno/public/demo-audio/ - 文件必须命名为
sample.wav
当前仓库中该目录实际已存在 sample.wav,与 README 约定的命名一致。该目录位于 Agno 集成的 Next.jspublic/静态资源目录下,因此客户端可以直接通过 URL 访问并获取该音频文件。
为什么放在public/demo-audio/?从 manifest.yaml 中可以看到,public/目录还包含demo-files/(用于 Multimodal 附件演示),说明public/承担着为各演示提供静态样例资源(音频、文件附件等)的统一职责。sample.wav作为语音演示的客户端样例音频,被归类于此。
三、音频内容要求:一句"固定台词"为什么这么关键
说明文档明确要求音频内容必须是一段朗读"What is the weather in Tokyo?"的语音片段。这个要求并非随意,而是由演示的端到端验证链决定的:
演示页面会向用户展示这句台词:在 voice-chat.tsx 中定义了
const SAMPLE_TEXT = "What is the weather in Tokyo?";,并作为示例音频按钮的 tooltip 提示(见 sample-audio-button.tsx)。用户看到页面后按图索骥,理应能听到同一句话。E2E 测试会断言转写文本包含关键词:在 voice.spec.ts 中,Playwright 测试断言
textarea的值匹配正则/weather|tokyo/i。也就是说,只要转写结果(或示例按钮注入的固定文本)中包含 "weather" 或 "Tokyo",测试即通过。QA 检查清单与测试套件共用同一台词:说明文档指出"bundled QA checklist + E2E spec"都依赖这段台词来断言转写结果。因此,如果音频内容与页面广告的台词不一致,即使音频本身能正常转写,验证流程也无法通过。
四、三平台生成命令:从朗读到 16kHz 单声道 WAV
说明文档为三种主流开发平台分别给出了生成命令。下面逐条展开,并补充参数说明。
macOS:say + ffmpeg 两步转换
say -o sample.aiff "What is the weather in Tokyo?" && ffmpeg -i sample.aiff -ar 16000 -ac 1 sample.wavsay -o sample.aiff:调用 macOS 系统自带文本朗读引擎,将文本合成为 AIFF 格式音频;ffmpeg -i sample.aiff -ar 16000 -ac 1 sample.wav:将 AIFF 转码为 WAV,同时完成两项关键规格转换:-ar 16000:采样率设为 16kHz(转写服务的标准输入采样率);-ac 1:强制单声道。
Linux:espeak-ng 一步直达
espeak-ng -w sample.wav "What is the weather in Tokyo?"espeak-ng是 Linux 上常用的开源文本转语音(TTS)工具,-w参数直接输出 WAV 文件。若系统未安装,可通过发行版包管理器安装(如apt install espeak-ng)。- 注意:espeak-ng 生成的默认 WAV 通常已是 16kHz 单声道,但为保险起见,可以同样通过
ffmpeg校验或强制转换规格(见下文规格自查)。
Windows:PowerShell 系统语音合成
Add-Type -AssemblyName System.Speech $synth = New-Object System.Speech.Synthesis.SpeechSynthesizer $synth.SetOutputToWaveFile("sample.wav") $synth.Speak("What is the weather in Tokyo?") $synth.Dispose()说明文档给出的核心 API 是 .NET 的System.Speech.Synthesis.SpeechSynthesizer配合SetOutputToWaveFile,上述 PowerShell 脚本即为该 API 的完整落地写法。
五、目标规格:为什么是 16kHz 单声道 + 3–5 秒 + <100KB
说明文档给出的最终规格目标:
| 规格项 | 目标值 | 原因分析 |
|---|---|---|
| 采样率 | 16kHz | 语音识别模型的标准输入采样率,与转写服务兼容 |
| 声道 | 单声道(mono) | 语音识别通常只需要单声道,减小体积 |
| 时长 | 3–5 秒 | "What is the weather in Tokyo?" 正常语速朗读的时长区间;过短会截断内容,过长会撑大文件体积 |
| 文件大小 | 小于 100KB | 保证客户端快速获取、转写接口请求体轻量 |
为什么是 <100KB?这与该演示"无需麦克风权限"的定位直接相关:音频需要在客户端被取用并 POST 到转写端点(见说明文档与 route.ts 注释中提到的/transcribe端点)。过大的文件会让该链路变得缓慢甚至不可用,因此 README 明确将 100KB 作为硬性上限。
自查建议:生成后可用ffprobe(ffmpeg 套件自带)验证规格:
ffprobe -v error -show_entries stream=sample_rate,channels -of default=noprint_wrappers=1 sample.wav以及查看文件大小:
ls -la sample.wav若采样率/声道不符或超过 100KB,按需用ffmpeg -i in.wav -ar 16000 -ac 1 out.wav重新转换。
六、源码级佐证:sample.wav 在转写链路中的真实角色
将说明文档与仓库源码对照,可以还原这条完整的链路:
1. 转写端点(服务端)
语音演示使用了一个专门的 CopilotRuntime 路由:showcase/integrations/agno/src/app/api/copilotkit-voice/[[...slug]]/route.ts。该路由的实现目标(见文件头注释)包括:
- 在
/info上通告audioFileTranscriptionEnabled: true,让聊天输入框渲染出麦克风按钮; - 处理
POST /transcribe,调用 OpenAI 支持的TranscriptionServiceOpenAI(来自@copilotkit/voice包); - 当
OPENAI_API_KEY未配置时,返回类型化的 401 错误,而不是 5xx。
其中GuardedOpenAITranscriptionService类(第 33–54 行)封装了密钥守卫逻辑:若未设置OPENAI_API_KEY,transcribeFile会抛出包含 "api key" 子串的错误,该错误会被映射为AUTH_FAILED→ 401。也就是说,要真正跑通"上传 WAV → 转写为文本",必须为部署环境配置OPENAI_API_KEY;否则音频文件即使放置正确,转写也会返回 401。
2. 客户端取用与按钮注入(前端)
- 演示页面 page.tsx 通过
<CopilotKit runtimeUrl="/api/copilotkit-voice" agent="voice-demo" useSingleEndpoint={false} enableInspector={false}>挂载语音专用运行时; - voice-chat.tsx 中的
handleTranscribed通过 DOM 操作(原生 value setter + 触发input事件)将文本注入data-testid="copilot-chat-textarea",这是绕过CopilotChat内部受控状态的 React 兼容做法; - sample-audio-button.tsx 提供
data-testid="voice-sample-audio-button"的按钮,点击后同步调用onTranscribed(sampleText)。其注释明确指出:该按钮是纯粹的测试/演示辅助手段,不涉及麦克风权限、不获取音频、不经过/transcribe往返。
3. E2E 测试验证(端到端)
voice.spec.ts 中的三个测试分别覆盖:
- 页面加载(第 23–44 行):断言标题 "Voice input"、示例音频按钮、聊天输入框可见,并断言麦克风按钮(
copilot-start-transcribe-button)最终出现——该按钮的出现证明运行时通告了audioFileTranscriptionEnabled: true; - 示例按钮注入(第 46–63 行):点击按钮后,textarea 在 1 秒内匹配
/weather|tokyo/i,且无瞬态 "Transcribing…" 状态、无/transcribe往返; - 发送后产生 Agent 响应(第 65–98 行):发送文本后,等待天气卡片(
weather-card)或通用 catchall 卡片(custom-catchall-card[data-tool-name="get_weather"])或 assistant 消息出现,断言"某种 agent 响应面"已呈现。
测试头部注释还说明了设计取舍:麦克风路径(真实的转写)不在 E2E 范围内,因为MediaRecorder在无头环境中难以稳定驱动,真实的转写路径改由qa/目录下的人工 QA 清单覆盖;示例音频按钮路径则保证 Playwright 测试不依赖转写端点健康状态或特定 aimock fixture。这也解释了为什么说明文档要把sample.wav的内容限定为固定台词——它是整个确定性验证体系的一部分。
七、常见问题排查
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
目录中缺少sample.wav或命名不符 | 未放置或命名错误 | 严格命名为sample.wav并放入showcase/integrations/agno/public/demo-audio/ |
| 音频内容不是 "What is the weather in Tokyo?" | 使用了自定义文本 | 按文档生成标准台词,否则 E2E/QA 断言无法通过 |
| 文件超过 100KB | 采样率过高、立体声或时长过长 | 用ffmpeg -ar 16000 -ac 1重编码并缩短时长 |
| 点击麦克风后转写报错/返回 401 | 未配置OPENAI_API_KEY | 在部署环境设置OPENAI_API_KEY,参见 route.ts 的守卫逻辑 |
| E2E 测试无法点击示例按钮 | 本地开发时 web-inspector 覆盖层拦截点击 | 演示页面已显式enableInspector={false}以保持两环境行为一致(见 page.tsx) |
八、小结
showcase/integrations/agno/public/demo-audio/README.md看似只是一段简短的资源放置说明,但在 CopilotKit Agno 集成的语音演示体系中,它承载着"确定性验证"的关键职责:固定的文件名、固定的台词、固定的音频规格,与voice-demo专用运行时(/api/copilotkit-voice)、示例音频按钮组件以及 Playwright E2E 测试共同构成了一条不依赖麦克风权限即可端到端演示语音输入 → 转写 → Agent 应答的稳定链路。按本文提供的三平台命令生成合规的sample.wav,即可让该演示在任何环境中稳定复现。
【免费下载链接】CopilotKitThe Frontend Stack for Agents & Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考