realtime

Par elevenlabs · skills

Utilisez les modèles ElevenLabs Realtime (`eleven_realtime_v1_mini`, `eleven_realtime_v1_max`), les modèles à faible latence conçus pour la conversation vocale. À utiliser lorsque l'utilisateur souhaite créer un agent ElevenAgents sur un modèle Realtime ou basculer le mode Voice d'un agent existant vers Realtime, définir `conversation_config.realtime_model`, choisir entre Realtime Mini et Max, ou déboguer un agent Realtime qui refuse de se publier ou de transférer. À utiliser également lors de la migration d'une application vocale construite sur l'API et le SDK Realtime d'OpenAI (`@openai/agents-realtime`, `gpt-realtime`) vers l'API ElevenLabs Realtime compatible OpenAI, y compris la génération de `client_secrets`, le transport WebSocket et l'audio après avoir quitté WebRTC (fermetures avec 4001/4003, absence d'audio). Non applicable pour le choix du modèle LLM ou TTS d'un agent en mode Custom, pour Scribe realtime speech-to-text, ni pour la migration d'appels texte via Chat Completions ou Responses API.

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

ElevenLabs Realtime

Les modèles Realtime sont des modèles ElevenLabs conçus pour la conversation vocale à faible latence. Il y a deux façons de les utiliser :

  • Un agent ElevenAgents (un ID d'agent, le dashboard, ou un projet elevenlabs agents avec agent_configs/) : réglez le Voice mode de l'agent sur Realtime avec conversation_config.realtime_model, et ElevenLabs gère son LLM, son modèle TTS et ses paramètres ASR. Voir Run an agent on a Realtime model.
  • Une application web construite sur le Realtime SDK d'OpenAI : conservez le SDK et pointez-le vers l'API ElevenLabs Realtime compatible OpenAI, wss://api.elevenlabs.io/v1/convai/realtime. Voir Migrate an app from OpenAI Realtime.

Quand l'utilisateur démarre de zéro et qu'il n'est pas clair ce qu'il souhaite, demandez. Un agent fournit un system prompt géré, des outils, une base de connaissances, un widget et la téléphonie ; l'API Realtime est le chemin le plus rapide pour du code qui parle déjà les événements realtime d'OpenAI. Pour les fonctionnalités d'agent au-delà du voice mode (prompt, outils, workflows, widget), utilisez la skill agents.

Models

Model Model ID Optimized for
Eleven Realtime v1 Mini eleven_realtime_v1_mini Latence et coût les plus bas. C'est le modèle par défaut.
Eleven Realtime v1 Max eleven_realtime_v1_max Raisonne avant de répondre, pour les instructions complexes et l'utilisation d'outils multi-étapes. Coûte plus cher.

Commencez avec Mini. Choisissez Max quand le travail implique des instructions longues ou complexes ou des appels d'outils multi-étapes et que les réponses de Mini ne sont pas assez bonnes, ou quand une application en migration provenait d'un modèle OpenAI plus grand pour un travail lourd en raisonnement. Les agents ajoutent des contraintes de conformité et de résidence des données au choix ; voir Choose the model.

Run an agent on a Realtime model

Chaque agent vocal a un Voice mode. En mode Custom, le LLM, le modèle TTS et les paramètres ASR de l'agent sont choisis individuellement. En mode Realtime, l'agent s'exécute sur un modèle Realtime et ElevenLabs gère ces paramètres. Le mode est un seul champ : conversation_config.realtime_model défini sur un ID de modèle signifie Realtime, null signifie Custom.

Le system prompt, le premier message, la voix, les langues, la température, les outils, la base de connaissances et les paramètres de flux de conversation (tour eagerness, timeouts, interruptions) fonctionnent de la même façon dans les deux modes.

Before you start

  • Ces étapes appellent l'API ElevenLabs. Le CLI et les SDKs lisent ELEVENLABS_API_KEY depuis l'environnement ; si elle n'est pas définie, utilisez la skill setup-api-key. Ne demandez jamais à l'utilisateur de coller la clé dans la conversation.
  • Les modèles Realtime se déploient progressivement. Si l'API rejette realtime_model avec Realtime models are not available for this workspace., l'espace de travail n'a pas encore accès. Arrêtez-vous et informez l'utilisateur ; aucun changement de configuration ne le résout.

Step 1: Check the agent can use Realtime

Pour un agent existant, récupérez d'abord sa configuration (elevenlabs agents pull --agent <agent-id>, ou agents.get dans le SDK). Gardez l'agent en mode Custom, et expliquez à l'utilisateur pourquoi, si l'un de ces cas s'applique :

Blocker Where to look
LLM personnalisé ou Amazon Bedrock conversation_config.agent.prompt.llm est custom-llm ou un modèle Bedrock
Créé via un autre produit ElevenLabs, tel que Speech Engine Demandez à l'utilisateur en cas de doute ; seuls les agents ElevenAgents peuvent utiliser un modèle Realtime
Nécessite un LLM ou un modèle TTS spécifique Demandez à l'utilisateur si le agent.prompt.llm ou tts.model_id actuel est une exigence
Les nœuds de workflow remplacent un managed setting ou agent.prompt.max_tokens Remplacements sur les nœuds sous le workflow de l'agent
Transferts vers ou depuis des agents en mode Custom Outils transfer_to_agent et nœuds de workflow agent_transfer sur cet agent et sur tout agent qui transfère vers celui-ci
Agent texte uniquement conversation_config.conversation.text_only est true ; les modèles Realtime sont conçus pour la voix

Un remplacement de workflow peut être supprimé et un partenaire de transfert peut aussi basculer vers Realtime, mais seulement avec l'accord de l'utilisateur : les deux changent la façon dont d'autres parties de leur configuration se comportent.

Step 2: Choose the model

Commencez avec eleven_realtime_v1_mini. Choisissez eleven_realtime_v1_max quand l'agent suit des instructions longues ou complexes ou repose sur des appels d'outils multi-étapes et que Mini n'est pas assez bon, ou quand l'agent doit se conformer au Mode de rétention zéro ou à HIPAA. Ensuite, vérifiez la disponibilité :

Environment eleven_realtime_v1_mini eleven_realtime_v1_max
US Available Available
EU data residency Available Available
India data residency Available Not available
Singapore data residency Available Not available
Zero Retention Mode and HIPAA Not available Available in the US and EU

Le Mode de rétention zéro s'applique qu'il soit appliqué sur l'espace de travail ou activé sur l'agent. Demandez à l'utilisateur quand la résidence des données ou les paramètres de conformité de l'espace de travail ne sont pas clairs à partir du projet. Si aucun modèle n'est disponible pour l'environnement de l'agent, gardez-le en mode Custom.

Max nécessite aussi agent.prompt.max_tokens d'au moins 1024, ou -1 pour pas de limite.

Step 3: Set the model

Sur un agent existant, changez uniquement realtime_model ; laissez le reste de la configuration inchangé.

Avec le CLI, tirez l'agent, réglez le champ dans son fichier sous agent_configs/, et poussez :

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

Avec les SDKs :

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",
  },
});

Pour un nouvel agent, mettez realtime_model (realtimeModel en TypeScript) dans le conversation_config passé à agents.create, à côté du prompt, du premier message et de la voix. Ne sélectionnez pas de LLM ou de modèle TTS pour lui ; un agent Realtime les ignore.

Pour désactiver Realtime, réglez realtime_model sur null (None en Python). L'agent revient aux paramètres LLM, TTS et ASR stockés sur lui.

Managed settings

Pendant qu'un modèle Realtime est défini, l'agent ignore les valeurs stockées de ces champs dans conversation_config. Elles reviendront en usage quand l'agent basculera vers Custom, donc ne les effacez pas, et ne les éditez pas pour affiner un agent Realtime :

Setting Field
LLM agent.prompt.llm
Reasoning effort agent.prompt.reasoning_effort
Thinking budget agent.prompt.thinking_budget
Parallel tool calls agent.prompt.enable_parallel_tool_calls
Cascade timeout agent.prompt.cascade_timeout_seconds
TTS model tts.model_id
Expressive mode tts.expressive_mode
ASR provider asr.provider

agent.prompt.max_tokens continue de s'appliquer. La température aussi, mais le dashboard la masque en mode Realtime, donc changez-la via le CLI ou l'API. Si le modèle Realtime erreur ou ne répond pas à temps, l'agent bascule sur ses LLMs de secours (LLM cascading) ; le modèle Realtime définit combien de temps il attend.

Step 4: Publish and verify

Les règles de l'étape 1 sont vérifiées quand l'agent est publié, pas quand un brouillon est sauvegardé : un brouillon qui en viole une se sauvegarde, puis la publication échoue avec une erreur nommant le paramètre à changer.

  1. Récupérez l'agent et confirmez que conversation_config.realtime_model contient le modèle choisi. Si la poussée, la mise à jour, ou la publication par l'utilisateur dans le dashboard échouent, comparez l'erreur ci-dessous.
  2. Trouvez tous les agents qui transfèrent vers celui-ci et confirmez qu'ils sont aussi en mode Realtime. Un transfert d'un agent en mode Custom vers un agent Realtime n'est détecté que quand cet agent est publié à nouveau ; jusqu'alors le transfert est rejeté au milieu de la conversation et l'appelant reste avec l'agent actuel.
  3. Faites tenir à l'utilisateur une conversation de test.

Errors

Error Cause and fix
Realtime models are not available for this workspace. L'espace de travail n'a pas encore accès. Rien à fixer dans la configuration.
Transfers between default and Realtime model modes are not supported. Un transfert vers ou depuis un agent en mode Custom (« default » signifie Custom). Mettez les deux agents dans le même mode.
Une erreur nommant le modèle Realtime Le modèle n'est pas disponible sous les paramètres de conformité ou de résidence des données de l'agent. Voir étape 2.
La publication échoue en nommant un paramètre L'un des blockers de l'étape 1 ou la limite de tokens de Max. Changez ce paramètre, ou gardez l'agent en Custom.

Pricing

Un agent Realtime est facturé au tarif standard par minute d'ElevenAgents plus ses jetons d'entrée, d'entrée en cache et de sortie aux tarifs du modèle Realtime ; Max coûte plus cher par token que Mini. Pointez l'utilisateur vers https://elevenlabs.io/pricing plutôt que de citer les tarifs.

Migrate an app from OpenAI Realtime

ElevenLabs Realtime parle le même protocole filaire que l'API Realtime GA d'OpenAI : les mêmes événements client et serveur sur WebSocket. Une application construite sur le Realtime SDK d'OpenAI garde ce SDK ; la migration change où les credentials sont créés, l'URL à laquelle le transport se connecte, et la configuration du modèle, de la voix et de la session.

Le seul changement structurel : ElevenLabs Realtime est WebSocket uniquement. Dans un navigateur, RealtimeSession utilise par défaut WebRTC, qui câble le microphone et le haut-parleur pour vous. Après basculage au transport WebSocket, l'application doit capturer et lire l'audio elle-même.

Ceci couvre les applications où le navigateur ouvre la connexion realtime. Cela ne couvre pas les applications où un serveur ouvre la connexion et diffuse l'audio à ses clients sur son propre protocole, comme un relais WebSocket personnalisé ou un pont téléphonique. La connexion à ElevenLabs Realtime depuis un serveur devrait fonctionner, mais cette skill n'a pas d'étapes pour cela. Dites-le à l'utilisateur, et suggérez-lui d'ouvrir un problème ou une pull request à https://github.com/elevenlabs/skills décrivant leur configuration, plutôt que de deviner la migration côté serveur.

Step 0: Inventory the app

Trouvez chaque place où l'application touche OpenAI Realtime avant d'éditer quoi que ce soit :

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}' .

Classez ce que vous trouvez, car chaque partie se migre différemment :

  • Credential minting : une route serveur qui appelle /v1/realtime/client_secrets (GA) ou /v1/realtime/sessions (beta). Migrez à l'étape 1.
  • Browser session : RealtimeSession, OpenAIRealtimeWebRTC, OpenAIRealtimeWebSocket, ou un WebSocket/RTCPeerConnection fait à la main. Migrez aux étapes 2 à 4.
  • Server-side realtime connections : un processus Node ou Python qui ouvre lui-même le socket realtime, par exemple un relais qui diffuse l'audio aux clients sur son propre protocole WebSocket, un pont téléphonique, openai Python's client.realtime.connect(), ou un RealtimeSession fonctionnant dans Node avec une clé API complète. Non couvert ; voir la portée ci-dessus. Si l'application a aussi une session navigateur, migrez uniquement cette partie, et seulement avec l'accord de l'utilisateur.
  • Fonctionnalités au-delà d'une conversation vocale : function tools, handoffs, guardrails, serveurs MCP, image input, SIP. ElevenLabs documente uniquement le flux de conversation vocale. Laissez ce code en place, listez-le pour l'utilisateur comme non vérifié par rapport à ElevenLabs, et faites-le tester.

OPENAI_API_KEY sert souvent aussi d'autres appels OpenAI. Ne le supprimez que si rien d'autre ne l'utilise.

Step 1: Mint the client secret from ElevenLabs

Le navigateur ne voit jamais la clé API ElevenLabs. Une route serveur crée un client secret à courte durée de vie et retourne uniquement sa value.

What OpenAI ElevenLabs
URL POST https://api.openai.com/v1/realtime/client_secrets POST https://api.elevenlabs.io/v1/convai/realtime/client_secrets
Auth header Authorization: Bearer $OPENAI_API_KEY xi-api-key: $ELEVENLABS_API_KEY
session.model gpt-realtime, … eleven_realtime_v1_mini ou eleven_realtime_v1_max
Response { value, expires_at, session } Même structure

Le corps de la requête garde la structure GA, { session, expires_after }. La configuration de session envoyée ici est la session initiale autorisée pour cette credential. La chaîne model sélectionne directement le comportement de l'agent ; il n'y a pas d'agent_id.

Créez avec le SDK ElevenLabs (npm install @elevenlabs/elevenlabs-js ou pip install elevenlabs), qui envoie l'en-tête xi-api-key pour vous :

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),
    ),
)

Retournez uniquement clientSecret.value (client_secret.value en Python) au navigateur.

Conservez le framework, le chemin et le contrat de réponse existants de la route ; seul l'appel en amont change. Si l'application a créé avec l'endpoint beta /v1/realtime/sessions, son frontend lit client_secret.value. Soit mettez à jour le frontend pour lire le value de niveau supérieur, soit faites la route retourner { client_secret: { value } } pour que le frontend reste inchangé.

Step 2: Convert the session config to the GA shape

Envoyez la structure de session GA. Les applications écrites contre l'API beta d'OpenAI utilisent des champs plats (modalities, voice, input_audio_format, turn_detection, …) qui doivent être convertis, et ElevenLabs rejette purement et simplement le champ déprécié modalities. Cela importe surtout pour le corps de la requête de mint et tout session.update fait à la main : l'option config du SDK convertit les champs camelCase dépréciés à la structure filaire GA pour vous, bien que le déplacer à la forme GA aussi supprime les avertissements de dépréciation.

Lisez Session config mapping pour la table complète des champs beta-to-GA, la gestion des voix, et la forme camelCase que l'option config du SDK utilise.

Step 3: Point the browser session at ElevenLabs

Remplacez le transport par OpenAIRealtimeWebSocket visé sur l'URL ElevenLabs, réglez le modèle sur la session, et passez le value créé comme clé 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 });

Conservez le nom RealtimeAgent existant de l'application, les instructions et les gestionnaires d'événements. Supprimez les options WebRTC uniquement (audioElement, mediaStream, changePeerConnection) et tout paramètre transport: "webrtc" ; ils n'ont pas d'équivalent WebSocket.

Step 4: Wire up audio (when the app was on WebRTC)

Si l'application utilisait auparavant WebRTC (un OpenAIRealtimeWebRTC explicite, transport: "webrtc", ou pas de transport du tout dans un navigateur), elle doit maintenant :

  1. Capturer l'audio du microphone en PCM16 à 24 kHz et le diffuser avec session.sendAudio(...).
  2. Lire les chunks PCM16 depuis l'événement audio de la session.
  3. Arrêter la lecture sur audio_interrupted. Sans cela, l'assistant continue à parler par-dessus l'utilisateur après une interruption, car l'audio déjà mis en buffer continue à jouer.
  4. Libérer le microphone et fermer la session au démontage.

Lisez Browser audio over WebSocket pour une implémentation qui fonctionne avec wavtools, l'assistant qu'OpenAI utilise dans ses propres exemples WebSocket, et ses pièges.

Les applications déjà sur OpenAIRealtimeWebSocket ont ce câblage ; vérifiez que le taux d'échantillonnage est 24 kHz et conservez-le.

Step 5: Verify

  1. Trouvez où le serveur charge OPENAI_API_KEY (.env, .env.local, secrets de déploiement) et demandez à l'utilisateur de stocker ELEVENLABS_API_KEY là. Ne demandez pas la clé dans la conversation et ne l'écrivez pas vous-même dans un fichier. Ajoutez un ELEVENLABS_API_KEY= vide à .env.example si le projet en a un.

  2. Une fois que l'utilisateur confirme que la clé est en place, exécutez l'application, démarrez une conversation et parlez.

  3. Confirmez que l'événement de transport session.created rapporte le modèle eleven_realtime_* et la voix choisie :

    session.on("transport_event", (event) => {
      if (event.type === "session.created") console.log(event);
    });
  4. Interrompez l'assistant au milieu d'une phrase et confirmez que la lecture s'arrête.

  5. Dites à l'utilisateur quelles fonctionnalités de l'étape 0 restent non vérifiées (outils, handoffs, guardrails, …).

Troubleshooting

Symptom Cause and fix
WebSocket ferme avec le code 4003 Realtime n'est pas activé pour cet espace de travail ElevenLabs. Contactez ElevenLabs ; le code ne peut pas le fixer.
WebSocket ferme avec le code 4001 Client secret rejeté : expiré, ou pas le value créé passé comme apiKey à session.connect().
Mint retourne 401 Toujours envoyer Authorization: Bearer ; ElevenLabs utilise l'en-tête xi-api-key.
Mint ou session.update est rejeté Champs en forme beta comme modalities. Convertissez avec le mapping.
Se connecte, mais pas d'audio de part et d'autre L'application était sur WebRTC et l'audio n'est pas encore câblé. Voir étape 4.
L'audio est du bruit, chipmunk-rapide, ou ralenti Mésappariement du taux d'échantillonnage ou du buffer. Capturez et jouez à 24 kHz ; voir les pièges dans la référence audio.
L'assistant parle par-dessus l'utilisateur après une interruption La lecture n'est pas arrêtée sur audio_interrupted.

References

Skills similaires