- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
导读:本文以 AAS(agentic-awesome-skills)仓库中社区贡献的
azure-ai-voicelive-ts技能文档为骨架,系统讲解如何使用@azure/ai-voicelive(JavaScript/TypeScript 版)在 Node.js 与浏览器环境中构建基于双向 WebSocket 的实时语音助手。读完本文,你将掌握 SDK 安装与环境配置、Entra ID/API Key 双认证方式、会话(Session)全量配置项、Azure SDK 订阅式事件模型、函数调用(Function Calling)闭环、语义 VAD 转向检测、音频格式选型以及浏览器端采集麦克风音频的完整实战方案。
该技能在仓库中的注册信息位于 data/skills_index.json(条目azure-ai-voicelive-ts,分类cloud,风险等级critical),技能文件本体位于 plugins/agentic-awesome-skills-claude/skills/azure-ai-voicelive-ts/SKILL.md,在agentic-awesome-skills插件中亦有同内容镜像 plugins/agentic-awesome-skills/skills/azure-ai-voicelive-ts/SKILL.md。
一、SDK 概览:面向实时双向语音交互的 TypeScript 客户端
@azure/ai-voicelive是 Azure AI 官方推出的 JavaScript/TypeScript 实时语音 SDK(技能文档标注当前版本为1.0.0-beta.3),其核心定位是:在 Node.js 与浏览器环境中,通过一条双向 WebSocket 连接,让 AI 助手能够"边说边听"——客户端持续向服务端推送麦克风音频流,服务端实时回传文本增量(text delta)、音频增量(audio delta)、用户语音转写结果与函数调用指令,从而实现真正低延迟的自然对话体验。
技能文档明确支持的运行环境为:
- Node.js LTS 版本(20+)
- 现代浏览器(Chrome、Firefox、Safari、Edge),浏览器场景需要配合 Vite、webpack 等打包器使用
从该技能在仓库中的分类(cloud)与风险等级(critical)可以看出,它面向的是生产级语音应用的实时交互链路,涉及音频数据流与凭据管理,使用时应遵循仓库的 SECURITY_GUARDRAILS.md 与 SEC_SKILLS.md 中的安全护栏要求。
二、安装与环境变量配置
2.1 安装依赖
npm install @azure/ai-voicelive @azure/identity # TypeScript 用户额外安装类型声明 npm install @types/node其中@azure/identity用于提供 Microsoft Entra ID 凭据(推荐认证方式),若使用 API Key 方式则依赖@azure/core-auth中的AzureKeyCredential。
2.2 环境变量
AZURE_VOICELIVE_ENDPOINT=https://<resource>.cognitiveservices.azure.com # 可选:不使用 Entra ID 时配置 API Key AZURE_VOICELIVE_API_KEY=<your-api-key> # 可选:日志级别 AZURE_LOG_LEVEL=info说明:
AZURE_VOICELIVE_ENDPOINT为必填项,指向你的 Azure 认知服务(Speech/Cognitive Services)资源地址,代码中可通过process.env.AZURE_VOICELIVE_ENDPOINT!读取;AZURE_VOICELIVE_API_KEY仅在走 API Key 认证时使用;技能文档明确建议优先使用 Entra ID(见下文"最佳实践"第 1 条),避免把密钥硬编码进代码或仓库;AZURE_LOG_LEVEL可取值如info、verbose、debug、warning、error,与@azure/logger的setLogLevel()行为等价,用于排查连接与协议问题。
三、双认证方式:Entra ID 与 API Key
技能文档提供了两种客户端初始化方式。
3.1 Microsoft Entra ID(推荐)
import { DefaultAzureCredential } from "@azure/identity"; import { VoiceLiveClient } from "@azure/ai-voicelive"; const credential = new DefaultAzureCredential(); const endpoint = "https://your-resource.cognitiveservices.azure.com"; const client = new VoiceLiveClient(endpoint, credential);DefaultAzureCredential会按顺序尝试多种 Azure 身份来源(环境变量、Azure CLI 登录态、托管身份等),适用于本地开发与云端部署一致的凭据链,无需硬编码密钥。
3.2 API Key
import { AzureKeyCredential } from "@azure/core-auth"; import { VoiceLiveClient } from "@azure/ai-voicelive"; const endpoint = "https://your-resource.cognitiveservices.azure.com"; const credential = new AzureKeyCredential("your-api-key"); const client = new VoiceLiveClient(endpoint, credential);AzureKeyCredential是 Azure SDK for JS 的通用密钥凭据类型,将 API Key 封装为可注入的凭据对象,便于统一处理鉴权头。
四、客户端层次结构:Client → Session → 操作
技能文档给出了 SDK 的核心对象关系,这是理解整个 API 的关键:
VoiceLiveClient └── VoiceLiveSession (WebSocket connection) ├── updateSession() → 配置会话选项 ├── subscribe() → 事件处理器(Azure SDK 模式) ├── sendAudio() → 流式发送音频输入 ├── addConversationItem() → 追加消息/函数输出 └── sendEvent() → 发送原始协议事件VoiceLiveClient:顶层入口,负责创建会话(startSession(model)),持有 endpoint 与凭据;VoiceLiveSession:一条活跃的 WebSocket 会话,代表一次完整的实时对话链路;所有上行操作(配置、音频、消息、原始事件)与下行事件分发都发生在会话对象上;sendEvent()是底层透传通道,例如手动触发模型回复时发送{ type: "response.create" }。
五、快速开始:一个最小可运行的实时语音会话
技能文档给出了从建连、配置、订阅事件到发送音频的完整最小示例:
import { DefaultAzureCredential } from "@azure/identity"; import { VoiceLiveClient } from "@azure/ai-voicelive"; const credential = new DefaultAzureCredential(); const endpoint = process.env.AZURE_VOICELIVE_ENDPOINT!; // 创建客户端并启动会话(指定实时模型) const client = new VoiceLiveClient(endpoint, credential); const session = await client.startSession("gpt-4o-mini-realtime-preview"); // 配置会话 await session.updateSession({ modalities: ["text", "audio"], instructions: "You are a helpful AI assistant. Respond naturally.", voice: { type: "azure-standard", name: "en-US-AvaNeural", }, turnDetection: { type: "server_vad", threshold: 0.5, prefixPaddingMs: 300, silenceDurationMs: 500, }, inputAudioFormat: "pcm16", outputAudioFormat: "pcm16", }); // 订阅事件 const subscription = session.subscribe({ onResponseAudioDelta: async (event, context) => { // 处理流式音频输出 const audioData = event.delta; playAudioChunk(audioData); }, onResponseTextDelta: async (event, context) => { // 处理流式文本 process.stdout.write(event.delta); }, onInputAudioTranscriptionCompleted: async (event, context) => { console.log("User said:", event.transcript); }, }); // 从麦克风发送音频 function sendAudioChunk(audioBuffer: ArrayBuffer) { session.sendAudio(audioBuffer); }要点拆解:
startSession(model)参数为实时语音模型 ID(如gpt-4o-mini-realtime-preview);updateSession()是"事后可再配置"的幂等操作,可在会话生命周期内随时调整指令、语音、VAD 与工具;- 事件回调统一采用
async (event, context) => {}的 Azure SDK 风格签名,context中携带sessionId、connectionId等上下文信息; session.sendAudio(arrayBuffer)接受ArrayBuffer音频块,实现连续流式上行。
六、会话配置详解:modalities / instructions / voice / VAD / 音频格式 / 工具
技能文档给出了完整可复制的updateSession配置块,逐项说明如下:
await session.updateSession({ // 模态:音频+文本 modalities: ["audio", "text"], // 系统指令 instructions: "You are a customer service representative.", // 语音选择 voice: { type: "azure-standard", // 或 "azure-custom"、"openai" name: "en-US-AvaNeural", }, // 转向检测(VAD) turnDetection: { type: "server_vad", // 或 "azure_semantic_vad" threshold: 0.5, prefixPaddingMs: 300, silenceDurationMs: 500, }, // 音频格式 inputAudioFormat: "pcm16", outputAudioFormat: "pcm16", // 工具(函数调用) tools: [ { type: "function", name: "get_weather", description: "Get current weather", parameters: { type: "object", properties: { location: { type: "string" } }, required: ["location"] } } ], toolChoice: "auto", });参数语义与取值范围:
| 配置项 | 说明 | 典型取值 |
|---|---|---|
modalities | 启用模态,语音助手建议同时包含"text"与"audio" | ["text", "audio"] |
instructions | 系统提示词,决定助手角色与应答风格 | 任意自然语言字符串 |
voice.type | 语音来源类型 | azure-standard、azure-custom、azure-personal、openai |
voice.name | 语音名称(标准语音) | 如en-US-AvaNeural;OpenAI 语音为alloy、echo、shimmer |
voice.endpointId | 自定义语音端点 ID(azure-custom时使用) | 自定义语音端点 |
voice.speakerProfileId | 个人语音克隆 ID(azure-personal时使用) | 个人语音档案 |
turnDetection.type | VAD 策略 | server_vad、azure_semantic_vad、azure_semantic_vad_en、azure_semantic_vad_multilingual |
turnDetection.threshold | VAD 激活阈值(0~1) | 默认约 0.5 |
turnDetection.prefixPaddingMs | 语音起始前的保留缓冲 | 约 300ms |
turnDetection.silenceDurationMs | 判定"说完"的静音时长 | 约 500ms |
inputAudioFormat/outputAudioFormat | 音频编解码格式 | pcm16、pcm16-8000hz、pcm16-16000hz、g711_ulaw、g711_alaw |
tools | 函数定义(OpenAI function 格式的 JSON Schema) | 数组 |
toolChoice | 工具选择策略 | "auto"、"none"或指定函数名 |
说明:
threshold、prefixPaddingMs、silenceDurationMs的数值语义(0~1 阈值、毫秒缓冲)依据技能文档给出的示例值(0.5 / 300 / 500)整理,实际默认值以@azure/ai-voicelive发布包的类型声明为准,建议在集成时以 IDE 补全与官方类型定义复核。
七、事件处理:Azure SDK 订阅模式全事件表
SDK 采用订阅式(subscription-based)事件模型:通过session.subscribe(handlers)注册回调,返回一个可关闭的VoiceLiveSubscription。技能文档完整列出了核心事件,按生命周期归类如下:
const subscription = session.subscribe({ // ---- 连接生命周期 ---- onConnected: async (args, context) => { console.log("Connected:", args.connectionId); }, onDisconnected: async (args, context) => { console.log("Disconnected:", args.code, args.reason); }, onError: async (args, context) => { console.error("Error:", args.error.message); }, // ---- 会话事件 ---- onSessionCreated: async (event, context) => { console.log("Session created:", context.sessionId); }, onSessionUpdated: async (event, context) => { console.log("Session updated"); }, // ---- 音频输入事件(VAD)---- onInputAudioBufferSpeechStarted: async (event, context) => { console.log("Speech started at:", event.audioStartMs); }, onInputAudioBufferSpeechStopped: async (event, context) => { console.log("Speech stopped at:", event.audioEndMs); }, // ---- 转写事件 ---- onConversationItemInputAudioTranscriptionCompleted: async (event, context) => { console.log("User said:", event.transcript); }, onConversationItemInputAudioTranscriptionDelta: async (event, context) => { process.stdout.write(event.delta); }, // ---- 响应事件 ---- onResponseCreated: async (event, context) => { console.log("Response started"); }, onResponseDone: async (event, context) => { console.log("Response complete"); }, // ---- 流式文本 ---- onResponseTextDelta: async (event, context) => { process.stdout.write(event.delta); }, onResponseTextDone: async (event, context) => { console.log("\n--- Text complete ---"); }, // ---- 流式音频 ---- onResponseAudioDelta: async (event, context) => { const audioData = event.delta; playAudioChunk(audioData); }, onResponseAudioDone: async (event, context) => { console.log("Audio complete"); }, // ---- 助手语音转写(模型说了什么)---- onResponseAudioTranscriptDelta: async (event, context) => { process.stdout.write(event.delta); }, // ---- 函数调用 ---- onResponseFunctionCallArgumentsDone: async (event, context) => { if (event.name === "get_weather") { const args = JSON.parse(event.arguments); const result = await getWeather(args.location); await session.addConversationItem({ type: "function_call_output", callId: event.callId, output: JSON.stringify(result), }); await session.sendEvent({ type: "response.create" }); } }, // ---- 全量兜底(调试用)---- onServerEvent: async (event, context) => { console.log("Event:", event.type); }, }); // 用完后关闭订阅 await subscription.close();事件流设计要点:
- VAD 事件:
onInputAudioBufferSpeechStarted/Stopped携带audioStartMs/audioEndMs,可用于 UI 上的"说话中"指示器; - 转写双通道:用户语音转写有"完成"与"增量"两个事件,分别适用于结果展示与实时字幕;
- 文本/音频双流:模型回复同时以文本与音频增量推送,
onResponseAudioDelta收到的是可播放的音频字节(event.delta),onResponseAudioTranscriptDelta提供对应文字; - 函数调用闭环:
onResponseFunctionCallArgumentsDone中解析event.arguments(JSON 字符串),执行真实业务函数后,通过addConversationItem()回填function_call_output,再用sendEvent({ type: "response.create" })触发模型基于结果继续生成回复; - 兜底事件:
onServerEvent可打印所有服务端事件类型,是排查协议问题的利器; - 资源释放:
subscription.close()在会话结束后调用,避免内存泄漏(见最佳实践第 5 条)。
八、函数调用(Function Calling)完整闭环
技能文档单列了函数调用小节,核心是"定义工具 → 处理调用 → 回填结果 → 触发续答"四步循环:
// 第一步:在会话配置中定义工具 await session.updateSession({ modalities: ["audio", "text"], instructions: "Help users with weather information.", tools: [ { type: "function", name: "get_weather", description: "Get current weather for a location", parameters: { type: "object", properties: { location: { type: "string", description: "City and state or country", }, }, required: ["location"], }, }, ], toolChoice: "auto", }); // 第二步:处理函数调用 const subscription = session.subscribe({ onResponseFunctionCallArgumentsDone: async (event, context) => { if (event.name === "get_weather") { const args = JSON.parse(event.arguments); const weatherData = await fetchWeather(args.location); // 第三步:回传函数执行结果 await session.addConversationItem({ type: "function_call_output", callId: event.callId, output: JSON.stringify(weatherData), }); // 第四步:触发新一轮响应生成 await session.sendEvent({ type: "response.create" }); } }, });关键细节:
tools采用 OpenAI 兼容的 JSON Schema 描述函数签名,parameters.properties中每个字段都建议补充description以提升模型参数抽取质量;event.callId必须原样回传,否则服务端无法把结果关联到对应的函数调用;output必须是字符串(通常为JSON.stringify后的结果);toolChoice: "auto"表示由模型自主决定是否调用工具。
九、语音选项与支持模型
9.1 四种语音类型
| 语音类型 | 配置 | 示例 |
|---|---|---|
| Azure 标准语音 | { type: "azure-standard", name: "..." } | "en-US-AvaNeural" |
| Azure 自定义语音 | { type: "azure-custom", name: "...", endpointId: "..." } | 自定义语音端点 |
| Azure 个人语音 | { type: "azure-personal", speakerProfileId: "..." } | 个人语音克隆档案 |
| OpenAI 语音 | { type: "openai", name: "..." } | "alloy"、"echo"、"shimmer" |
其中azure-personal使用speakerProfileId引用已训练的个人语音克隆档案,适用于需要"复刻特定人声"的场景;azure-custom通过endpointId指向自定义神经语音端点。
9.2 支持的实时模型
| 模型 | 描述 | 适用场景 |
|---|---|---|
gpt-4o-realtime-preview | 支持实时音频的 GPT-4o | 高质量对话式 AI |
gpt-4o-mini-realtime-preview | 轻量级 GPT-4o | 快速、经济的交互 |
phi4-mm-realtime | Phi 多模态模型 | 成本敏感型应用 |
模型选择建议:需要最高对话质量选gpt-4o-realtime-preview;追求响应速度与成本平衡选gpt-4o-mini-realtime-preview;成本极度敏感且任务简单可选phi4-mm-realtime。
十、转向检测(Turn Detection)与音频格式选型
10.1 VAD 四种策略
// 服务器 VAD(默认) turnDetection: { type: "server_vad", threshold: 0.5, prefixPaddingMs: 300, silenceDurationMs: 500, } // Azure 语义 VAD(更智能的转向检测) turnDetection: { type: "azure_semantic_vad", } // Azure 语义 VAD(英文优化版) turnDetection: { type: "azure_semantic_vad_en", } // Azure 语义 VAD(多语言版) turnDetection: { type: "azure_semantic_vad_multilingual", }server_vad基于能量阈值与静音时长判定说话结束,参数可调、行为透明;azure_semantic_vad系列则引入语义理解,能区分"停顿思考"与"说完",技能文档的"最佳实践"第 3 条建议语音助手优先采用 Azure 语义 VAD,以获得更自然的对话节奏。
10.2 音频格式对照表
| 格式 | 采样率 | 适用场景 |
|---|---|---|
pcm16 | 24kHz | 默认,高质量 |
pcm16-8000hz | 8kHz | 电话(Telephony) |
pcm16-16000hz | 16kHz | 语音助手 |
g711_ulaw | 8kHz | 电话(美标) |
g711_alaw | 8kHz | 电话(欧标) |
技能文档建议默认使用pcm16(24kHz)以获得最佳音质(最佳实践第 6 条);接入 PSTN/电话网关时,则需按运营商规范切换到 8kHz 的pcm16-8000hz或g711_ulaw/g711_alaw。
十一、关键类型速查
| 类型 | 用途 |
|---|---|
VoiceLiveClient | 用于创建会话的主客户端 |
VoiceLiveSession | 活跃的 WebSocket 会话 |
VoiceLiveSessionHandlers | 事件处理器接口(subscribe 参数类型) |
VoiceLiveSubscription | 活跃的事件订阅对象 |
ConnectionContext | 连接事件上下文(如connectionId) |
SessionContext | 会话事件上下文(如sessionId) |
ServerEventUnion | 所有服务端事件的联合类型 |
ServerEventUnion是 TypeScript 类型层面的"全事件表",配合onServerEvent可以做类型安全的调试分发;VoiceLiveSubscription暴露close()用于释放订阅资源。
十二、错误处理:分层错误类型
SDK 提供了层次化的错误类型,便于精确分流处理:
import { VoiceLiveError, VoiceLiveConnectionError, VoiceLiveAuthenticationError, VoiceLiveProtocolError, } from "@azure/ai-voicelive"; const subscription = session.subscribe({ onError: async (args, context) => { const { error } = args; if (error instanceof VoiceLiveConnectionError) { console.error("Connection error:", error.message); } else if (error instanceof VoiceLiveAuthenticationError) { console.error("Auth error:", error.message); } else if (error instanceof VoiceLiveProtocolError) { console.error("Protocol error:", error.message); } }, onServerError: async (event, context) => { console.error("Server error:", event.error?.message); }, });错误类型语义:
VoiceLiveConnectionError:WebSocket 连接层异常(断连、超时等),通常需要重连策略配合;VoiceLiveAuthenticationError:凭据无效或权限不足,检查 Entra ID 配置与资源访问策略;VoiceLiveProtocolError:客户端与服务端协议交互异常,通常伴随 SDK 版本或模型能力不匹配;onServerError:服务端主动上报的业务错误,event.error中携带消息体。
十三、日志开关
SDK 基于 Azure SDK 统一日志体系,可通过代码或环境变量开启:
import { setLogLevel } from "@azure/logger"; // 开启详情日志 setLogLevel("info"); // 或通过环境变量 // AZURE_LOG_LEVEL=info日志级别包括info、warning、error、verbose等,生产排查 WebSocket 断连或协议异常时建议先开info及以上,必要时上调至verbose。
十四、浏览器端接入:麦克风采集与打包注意
浏览器环境下 SDK 同样可用,但必须配合打包器(Vite、webpack 等),并使用浏览器兼容的凭据:
// 浏览器需要打包器(Vite、webpack 等) import { VoiceLiveClient } from "@azure/ai-voicelive"; import { InteractiveBrowserCredential } from "@azure/identity"; // 使用浏览器兼容凭据 const credential = new InteractiveBrowserCredential({ clientId: "your-client-id", tenantId: "your-tenant-id", }); const client = new VoiceLiveClient(endpoint, credential); // 请求麦克风权限 const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const audioContext = new AudioContext({ sampleRate: 24000 }); // 处理音频并发送到会话 // ...(完整实现见 SDK samples)实现要点:
InteractiveBrowserCredential需要提供应用注册的clientId与tenantId,并通过 OAuth 弹窗完成登录;- 用
navigator.mediaDevices.getUserMedia({ audio: true })获取麦克风流; AudioContext采样率设为 24000,与pcm16输入格式匹配;- 通过
AudioWorklet或ScriptProcessor采集 PCM 数据,调用session.sendAudio()持续上行(技能文档注明完整实现请参考官方 samples)。
十五、最佳实践清单
技能文档给出 6 条可操作的最佳实践,汇总如下:
- 始终使用
DefaultAzureCredential——绝不硬编码 API Key,避免凭据泄露; - 同时设置两种模态——语音助手必须包含
["text", "audio"],才能同时获得流式文本与音频; - 使用 Azure 语义 VAD——比基础 server VAD 拥有更智能的转向检测,对话更自然;
- 处理所有错误类型——连接、认证、协议三类错误分别处理,避免静默失败;
- 清理订阅资源——结束时调用
subscription.close(),防止监听器泄漏; - 选择合适音频格式——默认
pcm16(24kHz)音质最佳,电话场景按需降采样。
十六、适用边界与使用约束
技能文档末尾明确了该技能的适用范围与限制:
- 该技能仅适用于其描述范围内的实时语音工作流(语音助手、实时对话、双向音频 AI 应用)的构建与执行;
- 不应将技能输出视为环境特定验证、测试或专家评审的替代品——部署前必须结合目标环境的实际资源、网络与安全策略进行验证;
- 当输入、权限、安全边界或成功标准缺失时,应停止执行并向用户澄清,而不是擅自假定。
结合仓库的 QUALITY_BAR.md 与 COMMUNITY_GUIDELINES.md,risk: critical类技能(如本技能)在 Agent 工作流中启用时,建议同步开启安全护栏与凭据管理审查,确保密钥、端点信息只通过环境变量注入。
结语
azure-ai-voicelive-ts技能为 TypeScript/JavaScript 开发者提供了一条从零到一构建实时双向语音 AI 应用的完整路径:双认证接入、会话全量配置、订阅式事件模型、函数调用闭环、语义 VAD 与音频格式选型,以及浏览器端麦克风采集方案。将本技能与 AAS 仓库中的安全护栏文档结合使用,即可在 Node.js 或浏览器环境中搭建具备生产级意识(错误分层、资源清理、凭据安全)的实时语音助手原型。进一步扩展时,可参考仓库中同系列的azure-ai-voicelive-dotnet、azure-ai-voicelive-java、azure-ai-voicelive-py技能(见 data/skills_index.json),实现多语言客户端的一致性接入。
- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
相关推荐
基于 AAS 技能库使用 Azure AI VoiceLive Java SDK 构建实时双向语音会话
基于 AAS 技能库使用 Azure AI VoiceLive Java SDK 构建实时双向语音会话 本技术指南以 agentic awesome skill
AI 技能AI 插件人工智能agentic-awesome-skills 实战:使用 azure-ai-voicelive-py 构建双向 WebSocket 实时语音 AI 应用
agentic awesome skills 实战:使用 azure ai voicelive py 构建双向 WebSocket 实时语音 AI 应用 本文以
AI 技能AI 插件人工智能基于 Azure AI Anomaly Detector Java SDK 构建异常检测应用:AAS 技能实战指南
基于 Azure AI Anomaly Detector Java SDK 构建异常检测应用:AAS 技能实战指南 导读 本文围绕 agentic awesom
AI 技能AI 插件人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考