> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# LiveKit-Integration

Dieser Leitfaden zeigt, wie Sie ElevenLabs Speech Engine als Sprachschicht für einen LiveKit-Raum verwenden. Ein LiveKit-Agents-Worker tritt dem Raum als Teilnehmer bei, abonniert die Audiospur des Benutzers, öffnet einen WebSocket zu Speech Engine und veröffentlicht die synthetisierten Audiodaten von Speech Engine als eigene Spur zurück im Raum.

## Architektur

Speech Engine akzeptiert zwei Arten von WebSocket-Verbindungen:

* Den **Brain-WebSocket**, mit dem sich die ElevenLabs API verbindet. Ihr Server führt diesen mit dem Speech Engine SDK (`engine.serve()` / `engine.attach()`) aus und erhält Transkripte, auf die er reagieren kann.
* Den **Konversations-WebSocket**, mit dem sich Clients verbinden. Browser verbinden sich über ein WebRTC-Token; Nicht-Browser-Clients (wie ein LiveKit-Agents-Worker) verbinden sich über eine signierte URL und streamen rohe PCM-Audiodaten in beide Richtungen.

Der LiveKit-Worker verwendet die zweite Verbindung. Er fungiert im Namen der Teilnehmer im LiveKit-Raum als „Client“ von Speech Engine.

```mermaid
sequenceDiagram
    participant Browser
    participant LK as LiveKit Room
    participant Worker as Agents Worker
    participant EL as ElevenLabs (conversation WS)
    participant Brain as Brain Server

    Browser->>LK: Join room (LiveKit token)
    Worker->>LK: Join room (dispatched)
    Worker->>EL: Open conversation WebSocket (signed URL)

    loop Conversation
        Browser->>LK: Microphone audio (Opus)
        LK->>Worker: Decoded PCM frames
        Worker->>EL: user_audio_chunk (base64 PCM)
        EL->>Brain: user_transcript
        Brain-->>EL: agent_response (streamed)
        EL->>Worker: audio (base64 PCM)
        Worker->>LK: Publish PCM frames
        LK->>Browser: Audio (Opus)
    end
```

Der Brain-Server bleibt gegenüber dem [Speech Engine Quickstart](/docs/de/eleven-api/guides/cookbooks/speech-engine) unverändert – der LiveKit-Worker ersetzt den Browser als Audioquelle, die LLM-Logik bleibt jedoch gleich.

## Wann Sie dieses Muster verwenden sollten

Nutzen Sie die LiveKit-Bridge, wenn der Raum selbst Teil der Erfahrung ist:

* Sitzungen mit mehreren Teilnehmern, in denen Benutzer gemeinsam mit dem Agenten sprechen
* Bestehende LiveKit-Deployments, bei denen ein Wechsel des Transports Clients beeinträchtigen würde
* Sprachagenten, die einen Raum mit Bildschirmfreigabe, Video oder Textchat teilen
* Über SIP an LiveKit weitergeleitete Anrufe, die einen KI-Agenten in der Leitung benötigen

Wenn Sie nur eine Browser-zu-Speech-Engine-Sprachschleife ohne weitere Teilnehmer benötigen, ist der WebRTC-Client im [Speech Engine Quickstart](/docs/de/eleven-api/guides/cookbooks/speech-engine#client-setup) einfacher – Speech Engine kommuniziert direkt per WebRTC mit dem Browser, ein LiveKit-Raum ist nicht erforderlich.

## Voraussetzungen

* Ein LiveKit-Projekt ([LiveKit Cloud](https://cloud.livekit.io/) oder ein selbst gehosteter Server). Der Worker benötigt `LIVEKIT_URL`, `LIVEKIT_API_KEY` und `LIVEKIT_API_SECRET`.
* Eine ElevenLabs Speech Engine. Folgen Sie dem [Speech Engine Quickstart](/docs/de/eleven-api/guides/cookbooks/speech-engine), um eine zu erstellen und den Brain-Server auszuführen.
* Python 3.9+ oder Node.js 18+.

> **Note**
>
> Der Node-Bridge-Worker verwendet
> [`@livekit/rtc-node`](https://www.npmjs.com/package/@livekit/rtc-node), das sich derzeit in
> der Developer Preview befindet. Für Produktions-Deployments sollten Sie den Python-Worker verwenden.

## Audioformate für Speech Engine konfigurieren

LiveKits `AudioStream` passt eingehende Opus-Spuren an jede von Ihnen angeforderte PCM-Abtastrate an. So können Sie sie direkt auf Speech Engine abstimmen. Aktualisieren Sie Speech Engine, um 16-kHz-PCM für ASR-Eingaben zu akzeptieren und 24-kHz-PCM für TTS-Ausgaben zu erzeugen.

**`configure_engine.py`**

```python title="configure_engine.py"
import asyncio
import os
from elevenlabs import AsyncElevenLabs

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


async def update_engine():
    await elevenlabs.speech_engine.update(
        speech_engine_id="seng_8k3m9xr4hjnfg983brhmhkd98n6",
        asr={"user_input_audio_format": "pcm_16000"},
        tts={"agent_output_audio_format": "pcm_24000"},
    )


asyncio.run(update_engine())
```

**`configure-engine.mts`**

```typescript title="configure-engine.mts"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import "dotenv/config";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

await elevenlabs.speechEngine.update("seng_8k3m9xr4hjnfg983brhmhkd98n6", {
  asr: { userInputAudioFormat: "pcm_16000" },
  tts: { agentOutputAudioFormat: "pcm_24000" },
});
```

Speech-Engine-PCM ist durchgehend vorzeichenbehaftetes 16-Bit-Little-Endian. Weitere unterstützte Abtastraten finden Sie in der [Referenz zu Audioformaten](#audio-format-reference).

## Bridge-Worker erstellen

Der Worker ist ein lang laufender Prozess, der sich mit Ihrem LiveKit-Server verbindet, auf Aufträge wartet, zugewiesenen Räumen beitritt und Audiodaten zwischen dem Raum und Speech Engine überträgt.

#### Abhängigkeiten installieren

**`Python`**

```bash title="Python"
pip install "livekit-agents" "livekit-api" "elevenlabs" "aiohttp" "python-dotenv"
```

**`Node`**

```bash title="Node"
npm install @livekit/agents @livekit/rtc-node @elevenlabs/elevenlabs-js ws dotenv
```

#### Eine signierte Speech-Engine-URL erstellen

Der Worker fordert eine kurzlebige signierte URL für den Speech-Engine-Konversations-WebSocket an. Die signierte URL enthält die Engine-ID und eine einmalige Signatur. Dadurch kann der Worker den WebSocket öffnen, ohne Ihren API-Schlüssel preiszugeben.

**`bridge.py`**

```python title="bridge.py"
from elevenlabs import AsyncElevenLabs

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

async def signed_url() -> str:
    response = await elevenlabs.conversational_ai.conversations.get_signed_url(
        agent_id=os.environ["SPEECH_ENGINE_ID"],
    )
    return response.signed_url
```

**`bridge.mts`**

```typescript title="bridge.mts"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function signedUrl(): Promise<string> {
  const response = await elevenlabs.conversationalAi.conversations.getSignedUrl({
    agentId: process.env.SPEECH_ENGINE_ID!,
  });
  return response.signedUrl;
}
```

#### Worker-Einstiegspunkt definieren

Jedes Mal, wenn der Worker in einen Raum weitergeleitet wird, wird sein Einstiegspunkt ausgeführt. Der Einstiegspunkt verbindet sich mit dem Raum, öffnet einen Speech-Engine-Konversations-WebSocket und startet zwei Audio-Bridges: eine für Anrufer-Audio zu Speech Engine und eine für zurückkommendes synthetisiertes Audio.

**`bridge.py`**

```python title="bridge.py" maxLines=0
import asyncio
import base64
import json
import os

import aiohttp
from dotenv import load_dotenv
from elevenlabs import AsyncElevenLabs
from livekit import agents, rtc
from livekit.agents import JobContext, WorkerOptions, cli

load_dotenv()

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

USER_INPUT_RATE = 16000
AGENT_OUTPUT_RATE = 24000


async def signed_url() -> str:
    response = await elevenlabs.conversational_ai.conversations.get_signed_url(
        agent_id=SPEECH_ENGINE_ID,
    )
    return response.signed_url


async def entrypoint(ctx: JobContext):
    el_ws_ready: asyncio.Future[aiohttp.ClientWebSocketResponse] = (
        asyncio.get_running_loop().create_future()
    )

    async def pump_user_audio(track: rtc.Track):
        el_ws = await el_ws_ready
        stream = rtc.AudioStream(
            track, sample_rate=USER_INPUT_RATE, num_channels=1,
        )
        async for event in stream:
            payload = base64.b64encode(bytes(event.frame.data)).decode()
            await el_ws.send_str(json.dumps({"user_audio_chunk": payload}))

    # Register the subscriber BEFORE ctx.connect() so we don't miss tracks
    # that get auto-subscribed during the connection handshake.
    @ctx.room.on("track_subscribed")
    def on_track_subscribed(track, publication, participant):
        if track.kind != rtc.TrackKind.KIND_AUDIO:
            return
        if participant.identity == ctx.room.local_participant.identity:
            return
        asyncio.create_task(pump_user_audio(track))

    await ctx.connect()

    # Publish a track for the agent's synthesized audio.
    source = rtc.AudioSource(sample_rate=AGENT_OUTPUT_RATE, num_channels=1)
    track = rtc.LocalAudioTrack.create_audio_track("elevenlabs-agent", source)
    await ctx.room.local_participant.publish_track(
        track,
        rtc.TrackPublishOptions(source=rtc.TrackSource.SOURCE_MICROPHONE),
    )

    # Open the Speech Engine conversation WebSocket.
    http = aiohttp.ClientSession()
    el_ws = await http.ws_connect(await signed_url())
    await el_ws.send_str(json.dumps({"type": "conversation_initiation_client_data"}))
    el_ws_ready.set_result(el_ws)

    async def el_to_room():
        async for msg in el_ws:
            if msg.type != aiohttp.WSMsgType.TEXT:
                continue
            event = json.loads(msg.data)
            etype = event.get("type")
            if etype == "audio":
                pcm = base64.b64decode(event["audio_event"]["audio_base_64"])
                samples_per_channel = len(pcm) // 2
                frame = rtc.AudioFrame(
                    pcm, AGENT_OUTPUT_RATE, 1, samples_per_channel,
                )
                await source.capture_frame(frame)
            elif etype == "interruption":
                source.clear_queue()
            elif etype == "ping":
                event_id = event.get("ping_event", {}).get("event_id")
                await el_ws.send_str(json.dumps({
                    "type": "pong", "event_id": event_id,
                }))

    pump_task = asyncio.create_task(el_to_room())

    async def cleanup():
        pump_task.cancel()
        await el_ws.close()
        await http.close()

    ctx.add_shutdown_callback(cleanup)


if __name__ == "__main__":
    cli.run_app(WorkerOptions(
        entrypoint_fnc=entrypoint,
        agent_name="elevenlabs-bridge",
    ))
```

**`bridge.mts`**

```typescript title="bridge.mts" maxLines=0
import {
  type JobContext,
  WorkerOptions,
  cli,
  defineAgent,
} from "@livekit/agents";
import {
  AudioFrame,
  AudioSource,
  AudioStream,
  LocalAudioTrack,
  RoomEvent,
  TrackKind,
  TrackPublishOptions,
  TrackSource,
} from "@livekit/rtc-node";
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import WebSocket from "ws";
import { fileURLToPath } from "node:url";
import "dotenv/config";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});
const SPEECH_ENGINE_ID = process.env.SPEECH_ENGINE_ID!;

const USER_INPUT_RATE = 16000;
const AGENT_OUTPUT_RATE = 24000;

async function signedUrl(): Promise<string> {
  const response = await elevenlabs.conversationalAi.conversations.getSignedUrl({
    agentId: SPEECH_ENGINE_ID,
  });
  return response.signedUrl;
}

export default defineAgent({
  entry: async (ctx: JobContext) => {
    let resolveElReady: (ws: WebSocket) => void;
    const elReady = new Promise<WebSocket>((resolve) => {
      resolveElReady = resolve;
    });

    // Register the subscriber BEFORE ctx.connect() so we don't miss
    // tracks that get auto-subscribed during the connection handshake.
    ctx.room.on(RoomEvent.TrackSubscribed, (track, _pub, participant) => {
      if (track.kind !== TrackKind.KIND_AUDIO) return;
      if (participant.identity === ctx.room.localParticipant?.identity) return;

      (async () => {
        const ws = await elReady;
        const stream = new AudioStream(track, {
          sampleRate: USER_INPUT_RATE,
          numChannels: 1,
        });
        for await (const frame of stream) {
          const payload = Buffer.from(
            frame.data.buffer,
            frame.data.byteOffset,
            frame.data.byteLength,
          ).toString("base64");
          ws.send(JSON.stringify({ user_audio_chunk: payload }));
        }
      })();
    });

    await ctx.connect();

    const source = new AudioSource(AGENT_OUTPUT_RATE, 1);
    const track = LocalAudioTrack.createAudioTrack("elevenlabs-agent", source);
    const publishOptions = new TrackPublishOptions();
    publishOptions.source = TrackSource.SOURCE_MICROPHONE;
    await ctx.room.localParticipant!.publishTrack(track, publishOptions);

    const ws = new WebSocket(await signedUrl());
    await new Promise<void>((resolve, reject) => {
      ws.once("open", () => resolve());
      ws.once("error", reject);
    });
    ws.send(JSON.stringify({ type: "conversation_initiation_client_data" }));
    resolveElReady!(ws);

    // Serialize captureFrame calls — concurrent captures throw
    // InvalidState in the rtc-node native layer.
    let captureChain: Promise<unknown> = Promise.resolve();

    ws.on("message", (raw) => {
      const event = JSON.parse(raw.toString());
      if (event.type === "audio") {
        const pcm = Buffer.from(event.audio_event.audio_base_64, "base64");
        const samples = new Int16Array(
          pcm.buffer, pcm.byteOffset, pcm.byteLength / 2,
        );
        const frame = new AudioFrame(
          samples, AGENT_OUTPUT_RATE, 1, samples.length,
        );
        captureChain = captureChain
          .then(() => source.captureFrame(frame))
          .catch((err) => console.warn("captureFrame:", err.message));
      } else if (event.type === "interruption") {
        source.clearQueue();
      } else if (event.type === "ping") {
        ws.send(JSON.stringify({
          type: "pong", event_id: event.ping_event?.event_id,
        }));
      }
    });

    ctx.addShutdownCallback(async () => {
      ws.close();
    });
  },
});

cli.runApp(new WorkerOptions({
  agent: fileURLToPath(import.meta.url),
  agentName: "elevenlabs-bridge",
}));
```

Der Worker filtert im `track_subscribed`-Handler sein eigenes veröffentlichtes Audio heraus, indem er es mit der Identität des lokalen Teilnehmers vergleicht. Ohne diese Prüfung würde der Worker versuchen, sein eigenes synthetisiertes Audio zurück an Speech Engine zu senden.

Zwei Details zur Reihenfolge sind für die korrekte Funktion wichtig:

* **Zeitpunkt des Listeners**: `TrackSubscribed` wird vor `ctx.connect()` registriert. LiveKit abonniert vorhandene Spuren während des Verbindungs-Handshakes automatisch. Ein später registrierter Listener kann das Ereignis verpassen. Die Audioübertragung wartet auf ein `Future` / `Promise` für den Speech-Engine-WebSocket, sodass sie sich sofort anmelden und Audio weiterleiten kann, sobald die Verbindung geöffnet ist.
* **Nur TypeScript – Serialisierung der Aufnahme**: `AudioSource.captureFrame` von `@livekit/rtc-node` löst bei gleichzeitigen Aufrufen `InvalidState` aus. Der TypeScript-Handler serialisiert Aufnahmen mit einer Promise-Kette. Die einzelne Python-Schleife `async for el_to_room` läuft von Natur aus sequenziell und benötigt dies nicht.

#### Worker starten

**`Python`**

```bash title="Python"
python bridge.py dev
```

**`Node`**

```bash title="Node"
npx tsx bridge.mts dev
```

`dev` aktiviert Hot Reload und farbige Logs. Verwenden Sie in der Produktion `start` für JSON-Logs und ein kontrolliertes Herunterfahren.

Der Worker verbindet sich mit Ihrem LiveKit-Server und wartet auf Auftragszuweisungen. Er tritt keinen Räumen bei, bis er weitergeleitet wird.

## Worker an einen Raum weiterleiten

Da der Worker einen `agent_name` hat, verwendet er eine explizite Weiterleitung – er tritt Räumen nur bei, wenn Ihr Backend ihn dazu auffordert. Das einfachste Muster besteht darin, einen `RoomAgentDispatch` in das LiveKit-Zugriffstoken aufzunehmen, das der Browser für die Verbindung verwendet.

**`token_server.py`**

```python title="token_server.py"
import os

from dotenv import load_dotenv
from flask import Flask, jsonify, request
from livekit.api import AccessToken, RoomAgentDispatch, VideoGrants

load_dotenv()

app = Flask(**name**)

@app.route("/api/livekit-token")
def get_token():
room_name = request.args.get("room", "demo-room")
identity = request.args.get("identity", "web-user")

    token = (
        AccessToken(
            os.environ["LIVEKIT_API_KEY"],
            os.environ["LIVEKIT_API_SECRET"],
        )
        .with_identity(identity)
        .with_grants(VideoGrants(room_join=True, room=room_name))
        .with_room_config(
            room_configuration={
                "agents": [RoomAgentDispatch(agent_name="elevenlabs-bridge")],
            },
        )
    )

    return jsonify(token=token.to_jwt(), url=os.environ["LIVEKIT_URL"])

if **name** == "**main**":
app.run(port=3002)

```

**`token-server.mts`**

```typescript title="token-server.mts"
import express from "express";
import { AccessToken } from "livekit-server-sdk";
import "dotenv/config";

const app = express();

app.get("/api/livekit-token", async (req, res) => {
  const room = (req.query.room as string) ?? "demo-room";
  const identity = (req.query.identity as string) ?? "web-user";

  const token = new AccessToken(
    process.env.LIVEKIT_API_KEY!,
    process.env.LIVEKIT_API_SECRET!,
    { identity },
  );
  token.addGrant({ roomJoin: true, room });
  token.roomConfig = {
    agents: [{ agentName: "elevenlabs-bridge" }],
  };

  res.json({
    token: await token.toJwt(),
    url: process.env.LIVEKIT_URL,
  });
});

app.listen(3002, () => {
  console.log("Token server listening on port 3002");
});
```

Wenn ein Browser dieses Token verwendet, um einen Raum zu erstellen oder ihm beizutreten, leitet LiveKit den Bridge-Worker automatisch in denselben Raum weiter.

## Verbindung über den Browser herstellen

Der Browser benötigt nur den Standard-LiveKit-Client – er interagiert nicht direkt mit Speech Engine.

**`App.tsx`**

```typescript title="App.tsx"
import { Room, RoomEvent, Track } from "livekit-client";
import { useCallback, useState } from "react";

export default function App() {
  const [room] = useState(() => new Room());

  const join = useCallback(async () => {
    const response = await fetch("/api/livekit-token");
    const { token, url } = await response.json();

    room.on(RoomEvent.TrackSubscribed, (track) => {
      if (track.kind === Track.Kind.Audio) {
        document.body.appendChild(track.attach());
      }
    });

    await room.connect(url, token);
    await room.localParticipant.setMicrophoneEnabled(true);
  }, [room]);

  return <button onClick={join}>Start conversation</button>;
}
```

Wenn auf die Schaltfläche geklickt wird, ruft der Browser ein LiveKit-Token ab, tritt dem Raum mit aktiviertem Mikrofon bei und beginnt, die Audiospur des Agenten zu empfangen. Der Worker wird weitergeleitet, öffnet seine Speech-Engine-Sitzung und überträgt Audio in beide Richtungen.

## Referenz für Audioformate

Speech Engine unterstützt die folgenden Audioformate. Konfigurieren Sie diese in der Engine über `asr.user_input_audio_format` und `tts.agent_output_audio_format`.

| Format      | Abtastrate | Kodierung                | Hinweise                                                          |
| ----------- | ---------- | ------------------------ | ----------------------------------------------------------------- |
| `pcm_8000`  | 8 kHz      | Signiertes 16-Bit-LE-PCM | Nur ASR-Eingabe.                                                  |
| `pcm_16000` | 16 kHz     | Signiertes 16-Bit-LE-PCM | Empfohlen für LiveKit-Benutzereingaben.                           |
| `pcm_22050` | 22,05 kHz  | Signiertes 16-Bit-LE-PCM |                                                                   |
| `pcm_24000` | 24 kHz     | Signiertes 16-Bit-LE-PCM | Empfohlen für LiveKit-Agent-Ausgaben.                             |
| `pcm_44100` | 44,1 kHz   | Signiertes 16-Bit-LE-PCM | TTS-Ausgabe erfordert den Tarif Independent Publisher oder höher. |
| `pcm_48000` | 48 kHz     | Signiertes 16-Bit-LE-PCM | Nur ASR-Eingabe.                                                  |
| `ulaw_8000` | 8 kHz      | μ-law                    | Wird von Twilio Media Streams verwendet.                          |

`AudioStream` und `AudioSource` in LiveKit übernehmen das Resampling für Sie — Sie können von `AudioStream` jede Abtastrate anfordern, und das SDK konvertiert sie aus dem zugrunde liegenden Opus-Track mit 48 kHz.

## Hinweise für den Produktionseinsatz

* **Explizite Zuweisung**: Setzen Sie auf `WorkerOptions` immer `agent_name` / `agentName`. Bei der automatischen Zuweisung wird der Worker für jeden Raum gestartet, der in Ihrem LiveKit-Projekt erstellt wird. Das ist selten erwünscht.
* **Authentifizierung des Brain-Servers**: Legen Sie ein gemeinsames Secret für die Speech Engine fest und prüfen Sie es in Ihrem Brain-Server, damit nur die Speech Engine Ihren Endpunkt erreichen kann:
  ```python
  await elevenlabs.speech_engine.update(
      speech_engine_id="seng_8k3m9xr4hjnfg983brhmhkd98n6",
      speech_engine={"request_headers": {"x-api-key": os.environ["SHARED_SECRET"]}},
  )
  ```
  Der Brain-Server prüft dann `request.headers["x-api-key"]`, bevor er das WebSocket-Upgrade akzeptiert.
* **Token-Server**: Erstellen Sie LiveKit- und Speech-Engine-Tokens serverseitig. Geben Sie `LIVEKIT_API_SECRET` oder `ELEVENLABS_API_KEY` niemals im Browser preis.
* **Saubere Event Loop-Nutzung**: Halten Sie CPU-intensive Aufgaben vom Event Loop des Workers fern. `AudioSource.capture_frame` und die Iteration von `AudioStream` sind zeitkritisch. Lange synchrone Aufrufe verzögern oder verwerfen Unterbrechungsereignisse. Verwenden Sie für blockierende Aufgaben `asyncio.to_thread()` (Python) oder `worker_threads` (Node).
* **Herunterfahren**: Registrieren Sie `ctx.add_shutdown_callback` / `ctx.addShutdownCallback`, um den ElevenLabs-WebSocket sauber zu schließen. Standardmäßig wird der Raum (und der Job) beendet, wenn der letzte Teilnehmer, der kein Agent ist, den Raum verlässt.

## Nächste Schritte

#### [Speech Engine-Schnellstart](/docs/de/eleven-api/guides/cookbooks/speech-engine)

Erstellen Sie den Brain-Server, der auf Transkripte reagiert.

#### [Pipecat-Integration](/docs/de/eleven-api/guides/how-to/speech-engine/pipecat-integration)

Nutzen Sie Pipecat als LLM-Pipeline hinter der Speech Engine.

#### [Python-SDK-Referenz](/docs/de/eleven-api/resources/libraries/speech-engine/python-sdk-reference)

Klassen, Methoden und Ereignisse für das Speech Engine Python SDK.

#### [JavaScript-SDK-Referenz](/docs/de/eleven-api/resources/libraries/speech-engine/javascript-sdk-reference)

Klassen, Methoden und Ereignisse für das Speech Engine JavaScript SDK.