mcpField
R
realtime

realtime

github.com/elevenlabsAgent 工作流516915 次安装今天更新
代码仓库

关于 realtime

这项 ElevenLabs Realtime 技能指导开发者配置 ElevenAgents 实时语音模式,或将基于 OpenAI Realtime SDK 的浏览器应用迁移到 ElevenLabs API。内容涵盖模型选择、限制检查、配置验证和迁移注意事项。

主要功能

  1. 01配置 ElevenAgents 实时语音模式
  2. 02比较 Mini 与 Max 模型适用条件
  3. 03检查合规与数据驻留限制
  4. 04发布并验证 Agent 配置
  5. 05迁移浏览器实时语音应用

适用场景

  1. 01为 ElevenAgents Agent 启用 Realtime 模型
  2. 02评估模型与工作区限制是否匹配
  3. 03将 OpenAI Realtime 浏览器应用改接 ElevenLabs

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elevenlabs/skills --skill realtime

安装后在 Claude Code 中输入/realtime确认已加载。

附带文件references/browser-audio.mdreferences/session-config.md

详细介绍

ElevenLabs Realtime

Realtime 模型是 ElevenLabs 专为低延迟语音对话打造的模型。有两种使用方式:

  • ElevenAgents Agent(Agent ID、控制面板,或带有 agent_configs/ 的 elevenlabs agents 项目):将 Agent 的 Voice mode 设置为 Realtime,并使用 conversation_config.realtime_model,ElevenLabs 会管理其 LLM、TTS 模型和 ASR 设置。请参阅在 Realtime 模型上运行 Agent。
  • 基于 OpenAI Realtime SDK 构建的浏览器应用:保留 SDK,并将其指向兼容 OpenAI 的 ElevenLabs Realtime API:wss://api.elevenlabs.io/v1/convai/realtime。请参阅将应用从 OpenAI Realtime 迁移。

如果用户是从零开始,且无法确定他们想要哪种方式,请先询问。Agent 提供托管的系统提示词、工具、知识库、widget 和电话功能;Realtime API 则适合已经使用 OpenAI 实时事件的代码,是更快捷的选择。对于语音模式以外的 Agent 功能(提示词、工具、工作流、widget),请使用 agents 技能。

Models

ModelModel IDOptimized for
Eleven Realtime v1 Minieleven_realtime_v1_mini延迟和成本最低。默认选项。
Eleven Realtime v1 Maxeleven_realtime_v1_max响应前会进行推理,适用于复杂指令和多步工具调用。成本较高。

从 Mini 开始。如果任务涉及较长或复杂的指令、多步工具调用,而 Mini 的响应不够理想,或者要迁移的应用使用了更大型的 OpenAI 模型来处理推理密集型任务,请选择 Max。Agent 还会受到合规性和数据驻留要求的限制;请参阅选择模型。

在 Realtime 模型上运行 Agent

每个语音 Agent 都有 Voice mode。在 Custom 模式下,Agent 的 LLM、TTS 模型和 ASR 设置分别单独选择。在 Realtime 模式下,Agent 使用 Realtime 模型运行,由 ElevenLabs 管理这些设置。此模式由一个字段控制:conversation_config.realtime_model 设置为模型 ID 时表示 Realtime,设置为 null 时表示 Custom。

系统提示词、第一条消息、语音、语言、温度、工具、知识库和对话流程设置(轮次积极程度、超时、中断)在两种模式下的工作方式相同。

开始之前
  • 以下步骤会调用 ElevenLabs API。CLI 和 SDK 会从环境中读取 ELEVENLABS_API_KEY;如果尚未设置,请使用 setup-api-key 技能。绝不要要求用户在对话中粘贴密钥。
  • Realtime 模型正在逐步开放。如果 API 因 Realtime models are not available for this workspace. 而拒绝 realtime_model,说明该工作区尚未获得访问权限。请停止操作并告知用户;修改配置无法解决此问题。
步骤 1:检查 Agent 是否能使用 Realtime

对于现有 Agent,先获取其配置(elevenlabs agents pull --agent <agent-id>,或在 SDK 中调用 agents.get)。将 Agent 保持在 Custom 模式;如果符合以下任一情况,请向用户说明原因:

阻碍查看位置
自定义 LLM 或 Amazon Bedrockconversation_config.agent.prompt.llm 为 custom-llm 或 Bedrock 模型
通过其他 ElevenLabs 产品创建,例如 Speech Engine如不确定,请询问用户;只有 ElevenAgents Agent 才能使用 Realtime 模型
需要特定的 LLM 或 TTS 模型询问用户当前的 agent.prompt.llm 或 tts.model_id 是否为必需项
工作流节点覆盖了托管设置或 agent.prompt.max_tokensAgent 的 workflow 下的节点覆盖项
与 Custom 模式的 Agent 相互转接此 Agent 以及任何转接到此 Agent 的 Agent 上的 transfer_to_agent 工具和 agent_transfer 工作流节点
纯文本 Agentconversation_config.conversation.text_only 为 true;Realtime 模型专为语音打造

可以移除工作流覆盖项,也可以将转接对象切换为 Realtime,但必须征得用户同意:这两项操作都会改变其设置中其他部分的行为。

步骤 2:选择模型

从 eleven_realtime_v1_mini 开始。如果 Agent 需要遵循冗长或复杂的指令、依赖多步工具调用且 Mini 的效果不够好,或者 Agent 必须符合 Zero Retention Mode 或 HIPAA 要求,则选择 eleven_realtime_v1_max。然后检查可用性:

环境eleven_realtime_v1_minieleven_realtime_v1_max
US可用可用
EU 数据驻留可用可用
India 数据驻留可用不可用
Singapore 数据驻留可用不可用
Zero Retention Mode 和 HIPAA不可用在 US 和 EU 可用

无论 Zero Retention Mode 是在工作区强制启用,还是在 Agent 上启用,均适用。如果项目中无法明确工作区的数据驻留或合规设置,请询问用户。如果 Agent 所处环境无法使用这两种模型,则将其保持在 Custom 模式。

Max 还要求 agent.prompt.max_tokens 至少为 1024,或设为 -1 表示不限制。

步骤 3:设置模型

对于现有 Agent,只更改 realtime_model;其余配置保持不变。

使用 CLI 拉取 Agent,在 agent_configs/ 下的文件中设置该字段,然后推送:

elevenlabs agents pull --agent <agent-id>
{
  "conversation_config": {
    "realtime_model": "eleven_realtime_v1_mini"
  }
}
elevenlabs agents push --agent <agent-id>

使用 SDK:

from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs()

elevenlabs.conversational_ai.agents.update(
    agent_id="<agent-id>",
    conversation_config={
        "realtime_model": "eleven_realtime_v1_mini",
    },
)
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

await elevenlabs.conversationalAi.agents.update("<agent-id>", {
  conversationConfig: {
    realtimeModel: "eleven_realtime_v1_mini",
  },
});

对于新 Agent,将 realtime_model(TypeScript 中为 realtimeModel)放入传递给 agents.create 的 conversation_config 中,与提示词、第一条消息和语音一并设置。不要为其选择 LLM 或 TTS 模型;Realtime Agent 会忽略这些模型。

若要关闭 Realtime,请将 realtime_model 设为 null(Python 中为 None)。Agent 将恢复使用其中存储的 LLM、TTS 模型和 ASR 设置。

由系统管理的设置

设置了 Realtime 模型时,Agent 会忽略 conversation_config 中这些字段的已存储值。Agent 切换到 Custom 后会重新使用这些值,因此不要清除它们,也不要为了调整 Realtime Agent 而修改它们:

设置字段
LLMagent.prompt.llm
推理力度agent.prompt.reasoning_effort
思考预算agent.prompt.thinking_budget
并行工具调用agent.prompt.enable_parallel_tool_calls
级联超时agent.prompt.cascade_timeout_seconds
TTS 模型tts.model_id
表现力模式tts.expressive_mode
ASR 提供方asr.provider

agent.prompt.max_tokens 仍然生效。温度设置也仍然生效,但控制面板会在 Realtime 模式下隐藏该设置,因此请通过 CLI 或 API 修改。如果 Realtime 模型出错或未能及时响应,Agent 会回退到备用 LLM(LLM 级联);等待时长由 Realtime 模型设置决定。

步骤 4:发布并验证

步骤 1 中的规则会在发布 Agent 时检查,而不是在保存草稿时检查:违反规则的草稿仍可保存,但发布会失败,并指出需要更改的设置。

  1. 拉取 Agent,并确认 conversation_config.realtime_model 中保存的是所选模型。如果推送、更新或用户在控制面板中的发布失败,请对照下方的错误说明。
  2. 找出所有会转接到此 Agent 的 Agent,并确认它们也处于 Realtime 模式。Custom 模式的 Agent 转接到 Realtime Agent 的问题,只有在该 Agent 下次发布时才会被发现;在此之前,转接会在对话中途被拒绝,呼叫者会留在当前 Agent。
  3. 让用户进行一次测试对话。
错误
错误原因和解决方法
Realtime models are not available for this workspace.此工作区尚未获得访问权限。无需更改配置。
Transfers between default and Realtime model modes are not supported.不支持转接到或转接自 Custom 模式的 Agent(“default”表示 Custom)。将两个 Agent 设为相同模式。
错误中提及 Realtime 模型根据 Agent 的合规性或数据驻留设置,该模型不可用。请参阅步骤 2。
发布失败,错误中提及某项设置这是步骤 1 中的某项阻碍因素,或 Max 的令牌限制。更改该设置,或让 Agent 保持在 Custom 模式。
定价

Realtime Agent 按 ElevenAgents 标准分钟费率计费,此外还会按 Realtime 模型的费率对输入、缓存输入和输出令牌计费;Max 的每令牌费用高于 Mini。请引导用户前往 https://elevenlabs.io/pricing,而不要直接引用费率。

将应用从 OpenAI Realtime 迁移

ElevenLabs Realtime 使用与 OpenAI GA Realtime API 相同的线路协议:通过 WebSocket 传输相同的客户端和服务端事件。基于 OpenAI Realtime SDK 构建的应用会继续使用该 SDK;迁移需要更改凭据的生成方式、传输连接的 URL,以及模型、语音和会话配置。

唯一的结构性变化是:ElevenLabs Realtime 仅支持 WebSocket。在浏览器中,RealtimeSession 默认使用 WebRTC,由它负责连接麦克风和扬声器。切换到 WebSocket 传输后,应用必须自行采集和播放音频。

本文适用于由浏览器发起实时连接的应用。不适用于由服务端发起连接,并通过自己的协议(例如定制 WebSocket 中继或电话桥接)向客户端传输音频的应用。从服务端连接 ElevenLabs Realtime 应该可行,但本指南没有相关步骤。请告知用户这一点,并建议他们在 https://github.com/elevenlabs/skills 提交 issue 或 pull request,描述其设置,而不要猜测服务端迁移方式。

第 0 步:盘点应用

编辑前,找出应用中所有涉及 OpenAI Realtime 的位置:

grep -rnE "api\.openai\.com/v1/realtime|client_secrets|realtime/sessions|@openai/agents-realtime|@openai/agents/realtime|gpt-realtime|gpt-4o(-mini)?-realtime|OpenAIRealtimeWebRTC|OpenAIRealtimeWebSocket|RealtimeSession|OPENAI_API_KEY" --include='*.{ts,tsx,js,jsx,mjs,py}' .

对找到的内容进行分类,因为每一部分的迁移方式都不同:

  • 凭据生成:调用 /v1/realtime/client_secrets(GA)或 /v1/realtime/sessions(beta)的服务端路由。在第 1 步迁移。
  • 浏览器会话:RealtimeSession、OpenAIRealtimeWebRTC、OpenAIRealtimeWebSocket,或手动实现的 WebSocket/RTCPeerConnection。在第 2 至第 4 步迁移。
  • 服务端实时连接:由 Node 或 Python 进程自行建立实时套接字,例如通过自己的 WebSocket 协议向客户端传输音频的中继、电话桥接、openai Python 的 client.realtime.connect(),或在 Node 中使用完整 API 密钥运行的 RealtimeSession。本文不涉及此类情况;请参阅上述适用范围。如果应用也有浏览器会话,只在用户同意后迁移该部分。
  • 语音对话以外的功能:函数工具、交接、护栏、MCP 服务、图像输入、SIP。ElevenLabs 仅记录了语音对话流程。保留这部分代码,告知用户这些功能尚未经过与 ElevenLabs 的兼容性验证,并让用户进行测试。

OPENAI_API_KEY 通常也用于其他 OpenAI 调用。只有在没有其他用途时才将其移除。

第 1 步:从 ElevenLabs 签发客户端密钥

浏览器不会接触 ElevenLabs API 密钥。服务端路由会签发一个短期有效的客户端密钥,并且只返回它的 value。

内容OpenAIElevenLabs
URLPOST https://api.openai.com/v1/realtime/client_secretsPOST https://api.elevenlabs.io/v1/convai/realtime/client_secrets
Auth headerAuthorization: Bearer $OPENAI_API_KEYxi-api-key: $ELEVENLABS_API_KEY
session.modelgpt-realtime,……eleven_realtime_v1_mini 或 eleven_realtime_v1_max
响应{ value, expires_at, session }结构相同

请求正文保持 GA 结构 { session, expires_after }。此处发送的 session 配置是该凭证的权威初始 session。model 字符串会直接选择 Agent 行为;这里没有 agent_id。

使用 ElevenLabs SDK 签发(npm install @elevenlabs/elevenlabs-js 或 pip install elevenlabs),SDK 会代你发送 xi-api-key 标头:

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

const clientSecret =
  await elevenlabs.conversationalAi.realtime.createClientSecret({
    session: {
      type: "realtime",
      model: "eleven_realtime_v1_mini",
      instructions:
        "You are a helpful, friendly voice assistant. Keep replies concise.",
      outputModalities: ["audio"],
      audio: {
        input: {
          format: { type: "audio/pcm", rate: 24000 },
          turnDetection: { type: "semantic_vad", eagerness: "medium" },
        },
        output: {
          format: { type: "audio/pcm" },
          voice: "brian",
        },
      },
    },
    expiresAfter: { anchor: "created_at", seconds: 600 },
  });
import os

from elevenlabs import (
    CreateClientSecretRequest,
    ExpiresAfter,
    OpenAiAudioConfigInput,
    OpenAiAudioInputConfigInput,
    OpenAiAudioInputFormat,
    OpenAiAudioOutputConfigInput,
    OpenAiAudioOutputFormat,
    OpenAiSessionConfigInput,
    OpenAiTurnDetection,
)
from elevenlabs.client import ElevenLabs

elevenlabs = ElevenLabs(api_key=os.environ["ELEVENLABS_API_KEY"])

client_secret = elevenlabs.conversational_ai.realtime.create_client_secret(
    request=CreateClientSecretRequest(
        session=OpenAiSessionConfigInput(
            type="realtime",
            model="eleven_realtime_v1_mini",
            instructions="You are a helpful, friendly voice assistant. Keep replies concise.",
            output_modalities=["audio"],
            audio=OpenAiAudioConfigInput(
                input=OpenAiAudioInputConfigInput(
                    format=OpenAiAudioInputFormat(type="audio/pcm", rate=24000),
                    turn_detection=OpenAiTurnDetection(type="semantic_vad", eagerness="medium"),
                ),
                output=OpenAiAudioOutputConfigInput(
                    format=OpenAiAudioOutputFormat(type="audio/pcm"),
                    voice="brian",
                ),
            ),
        ),
        expires_after=ExpiresAfter(anchor="created_at", seconds=600),
    ),
)

只将 clientSecret.value(Python 中为 client_secret.value)返回给浏览器。

保留路由现有的框架、路径和响应约定;只更改上游调用。如果应用通过 beta /v1/realtime/sessions 端点签发密钥,其前端会读取 client_secret.value。你可以更新前端,让它读取顶层的 value;也可以让路由返回 { client_secret: { value } },这样前端就无需改动。

第 2 步:将 session 配置转换为 GA 结构

发送 GA session 结构。基于 OpenAI beta API 编写的应用使用扁平字段(modalities、voice、input_audio_format、turn_detection 等),需要将其转换;而且 ElevenLabs 会直接拒绝已弃用的 modalities 字段。这对于签发请求正文和任何手动编写的 session.update 尤其重要:SDK 的 config 选项会为你将已弃用的驼峰命名字段转换为 GA 线路格式,不过将它们也改为 GA 格式可以消除弃用警告。

请阅读Session 配置映射,了解完整的 beta 到 GA 字段对照表、语音处理方式,以及 SDK 的 config 选项使用的驼峰命名形式。

第 3 步:将浏览器 session 指向 ElevenLabs

将传输方式替换为指向 ElevenLabs URL 的 OpenAIRealtimeWebSocket,在 session 上设置模型,并将签发的 value 作为 API 密钥传入:

import {
  OpenAIRealtimeWebSocket,
  RealtimeAgent,
  RealtimeSession,
} from "@openai/agents-realtime";

const { value: clientSecret } = await fetch("/api/token").then((res) =>
  res.json(),
);

const agent = new RealtimeAgent({
  name: "Assistant",
  instructions:
    "You are a helpful, friendly voice assistant. Keep replies concise.",
});

const transport = new OpenAIRealtimeWebSocket({
  url: "wss://api.elevenlabs.io/v1/convai/realtime",
});

const session = new RealtimeSession(agent, {
  transport,
  model: "eleven_realtime_v1_mini",
  config: {
    outputModalities: ["audio"],
    audio: { output: { voice: "brian" } },
  },
});

await session.connect({ apiKey: clientSecret });

保留应用现有的 RealtimeAgent 名称、指令和事件处理程序。移除仅适用于 WebRTC 的选项(audioElement、mediaStream、changePeerConnection)以及任何 transport: "webrtc" 设置;WebSocket 没有对应选项。

第 4 步:接入音频(适用于原先使用 WebRTC 的应用)

如果应用之前使用 WebRTC(显式指定了 OpenAIRealtimeWebRTC、transport: "webrtc",或在浏览器中未指定传输方式),现在必须:

  1. 以 24 kHz 采集 PCM16 麦克风音频,并通过 session.sendAudio(...) 流式发送。
  2. 播放 session 的 audio 事件中的 PCM16 音频块。
  3. 在 audio_interrupted 时停止播放。否则,用户插话后助手仍会继续说话,因为已缓冲的音频还会继续播放。
  4. 在拆卸时释放麦克风并关闭 session。

请阅读通过 WebSocket 传输浏览器音频,查看一个可运行的实现。它使用了 wavtools,这是 OpenAI 在其 WebSocket 示例中使用的辅助工具;文中还介绍了相关注意事项。

已经使用 OpenAIRealtimeWebSocket 的应用已完成这些接线;请检查采样率是否为 24 kHz,并保持不变。

第 5 步:验证
  1. 找出服务从哪里加载 OPENAI_API_KEY(.env、.env.local、部署密钥),并请用户将 ELEVENLABS_API_KEY 存放在那里。不要在对话中索要密钥,也不要自行将其写入文件。如果项目有 .env.example,请添加空的 ELEVENLABS_API_KEY=。

  2. 用户确认密钥已就位后,运行应用、开始对话并进行语音交流。

  3. 确认 session.created 传输事件报告了 eleven_realtime_* 模型和所选语音:

    session.on("transport_event", (event) => {
      if (event.type === "session.created") console.log(event);
    });
    
  4. 在助手说到一半时打断它,并确认播放已停止。

  5. 告知用户第 0 步中的哪些功能仍未验证(工具、交接、防护措施等)。

故障排除
症状原因和修复
WebSocket 以代码 4003 关闭此 ElevenLabs 工作区未启用 Realtime。请联系 ElevenLabs;代码无法解决此问题。
WebSocket 以代码 4001 关闭客户端密钥被拒绝:密钥已过期,或不是传递给 session.connect() 的已生成 value(作为 apiKey)。
Mint 返回 401仍在发送 Authorization: Bearer;ElevenLabs 使用 xi-api-key 标头。
Mint 或 session.update 被拒绝使用了 Beta 格式的字段,例如 modalities。请根据映射进行转换。
已连接,但双方都没有音频应用使用的是 WebRTC,且音频尚未接入。请参阅第 4 步。
音频是噪声、像花栗鼠一样快,或速度变慢采样率或缓冲区不匹配。请以 24 kHz 采集和播放;音频参考中列出了相关注意事项。
助手在被打断后仍盖过用户说话收到 audio_interrupted 时未停止播放。

参考资料

评论

支持 Markdown