Zur Navigation springen

Eigenes Modell integrieren

Verbinden Sie einen Agent mit Ihrem eigenen LLM oder hosten Sie Ihren eigenen Server.

Mit Custom LLM können Sie Ihre Gespräche über einen externen Endpunkt mit Ihrem eigenen LLM verbinden. ElevenLabs unterstützt auch nativ integrierte LLMs

Custom LLMs ermöglichen es Ihnen, Ihren eigenen OpenAI-API-Key zu verwenden oder einen vollständig eigenen LLM-Server zu betreiben.

Ein Custom LLM kann nicht mit einem Realtime-Modell verwendet werden.

Überblick

Standardmäßig verwenden wir für beliebte Modelle wie OpenAI unsere eigenen internen Zugangsdaten. Um einen Custom-LLM-Server zu verwenden, muss er einer der folgenden OpenAI-kompatiblen Anfrage-/Antwortstrukturen entsprechen:

Die Responses API ist das neuere API-Format von OpenAI und unterstützt zusätzliche Funktionen. Beide API-Formate werden vollständig für die Integration von Custom LLMs unterstützt.

Die folgenden Anleitungen behandeln beide Anwendungsfälle:

  1. Eigenen OpenAI-Key verwenden: Verwenden Sie Ihren eigenen OpenAI-API-Key mit unserer Plattform.
  2. Custom-LLM-Server: Hosten und verbinden Sie Ihre eigene LLM-Serverimplementierung.

Sie erfahren, wie Sie:

  • Ihren OpenAI-API-Key in ElevenLabs speichern
  • Einen Server hosten, der den Endpunkt Chat Completions oder Responses von OpenAI nachbildet
  • ElevenLabs auf Ihren Custom-Endpunkt verweisen
  • Bei Bedarf zusätzliche Parameter an Ihr LLM übergeben

Zusammenfassung der Schlussfolgerungen

Ihr Endpunkt muss Schlussfolgerungen getrennt von der endgültigen Antwort zurückgeben. ElevenLabs generiert keine Schlussfolgerungen aus der endgültigen Antwort.

Um Schlussfolgerungen von einem unterstützten Endpunkt anzufordern, aktivieren Sie Reasoning summary in den LLM-Einstellungen des Agents oder setzen Sie enable_reasoning_summary über die API.

Schlussfolgerungen zurückgeben

Verwenden Sie das Format, das zu Ihrem Endpunkt passt:

Streamen Sie Schlussfolgerungen im Feld reasoning oder reasoning_content jedes Antwort-Deltas.

Für Gemini-kompatible Endpunkte fordert ElevenLabs Gedanken mit google.thinking_config.include_thoughts an und liest Inhalte mit der Kennzeichnung extra_content.google.thought.

Informationen zu Speicherung, Bereitstellung und Einschränkungen finden Sie unter Reasoning summary.

Eigenen OpenAI-Key verwenden

Um einen eigenen OpenAI-Key zu integrieren, aktualisieren Sie die Einstellungen Ihres Agents im ElevenLabs-Dashboard, sodass sie auf Ihren Custom-LLM-Server verweisen, und erstellen Sie ein Secret mit Ihrem OPENAI_API_KEY:

1

Wählen Sie in den Agent-Einstellungen im ElevenLabs-Dashboard rechts im Dropdown-Menü „LLM“ die Option „Custom LLM“.

Secret hinzufügen

2

Klicken Sie auf das Feld unter „LLM“ und scrollen Sie nach unten, um „Custom LLM“ auszuwählen.

3

Geben Sie die Server-URL und die Modell-ID Ihres Custom-LLM-Servers ein.

URL eingeben

4

Klicken Sie auf das Dropdown-Menü unter „API key“ und wählen Sie „Create new secret“. Benennen Sie den Key OPENAI_API_KEY, fügen Sie den Key in das Feld „value“ ein und klicken Sie auf „Add secret“.

5

Klicken Sie auf die Schaltfläche „x“, um das LLM-Modal zu schließen, und auf „Publish“, um Ihre Änderungen zu speichern.

Custom-LLM-Server

Um einen eigenen LLM-Server bereitzustellen, richten Sie einen kompatiblen Serverendpunkt im Stil von OpenAI ein. Sie können entweder die Chat Completions API (/v1/chat/completions) oder die Responses API (/v1/responses) implementieren.

Beide Endpunkte müssen Antworten im SSE-Format (Server-Sent Events) mit Content-Type: text/event-stream zurückgeben.

Die Chat Completions API verwendet den Endpunkt /v1/chat/completions.

Jeder Chunk muss als data: {json}\n\n formatiert sein und der Stream muss mit data: [DONE]\n\n enden.

Hier ist eine beispielhafte Serverimplementierung:

import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional
# Load environment variables from .env file
load_dotenv()
# Retrieve API key from environment
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY not found in environment variables")
app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
class Message(BaseModel):
role: str
content: str
class ChatCompletionRequest(BaseModel):
messages: List[Message]
model: str
temperature: Optional[float] = 0.7
max_tokens: Optional[int] = None
stream: Optional[bool] = False
user_id: Optional[str] = None
@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
oai_request = request.dict(exclude_none=True)
if "user_id" in oai_request:
oai_request["user"] = oai_request.pop("user_id")
chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)
async def event_stream():
try:
async for chunk in chat_completion_coroutine:
# Convert the ChatCompletionChunk to a dictionary before JSON serialization
chunk_dict = chunk.model_dump()
yield f"data: {json.dumps(chunk_dict)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logging.error("An error occurred: %s", str(e))
yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"
return StreamingResponse(event_stream(), media_type="text/event-stream")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8013)

Führen Sie diesen Code oder Ihren eigenen Servercode aus.

Öffentliche URL für Ihren Server einrichten

Damit Ihr Server erreichbar ist, erstellen Sie mit einem Tunneling-Tool wie ngrok eine öffentliche URL:

ngrok http --url=<Your url>.ngrok.app 8013

ElevenLabs CustomLLM konfigurieren

Aktualisieren Sie anschließend die Einstellungen Ihres Agents im ElevenLabs-Dashboard, sodass sie auf Ihren Custom-LLM-Server verweisen.

Verweisen Sie Ihre Server-URL auf den ngrok-Endpunkt und setzen Sie „Limit token usage“ auf 5000.

Sie können nun mit Ihrem Agent über Ihren eigenen LLM-Server interagieren.

Optimierung für LLMs mit langsamer Verarbeitung

Wenn Ihr benutzerdefiniertes LLM lange Verarbeitungszeiten hat (etwa aufgrund agentenbasierter Schlussfolgerungen oder Vorverarbeitungsanforderungen), können Sie den Gesprächsfluss verbessern, indem Sie Pufferwörter in Ihren Streaming-Antworten verwenden. Diese Technik trägt dazu bei, eine natürliche Sprachprosodie beizubehalten, während Ihr LLM die vollständige Antwort generiert.

Pufferwörter

Wenn Ihr LLM mehr Zeit benötigt, um die vollständige Antwort zu verarbeiten, geben Sie eine erste Antwort zurück, die mit "... " endet (Auslassungspunkte gefolgt von einem Leerzeichen). So kann das Text to Speech-System den natürlichen Fluss beibehalten, während sich das Gespräch dynamisch anfühlt. Dadurch entstehen natürliche Pausen, die gut in nachfolgende Inhalte übergehen, über die das LLM länger nachdenken kann. Das zusätzliche Leerzeichen ist entscheidend, damit der nachfolgende Inhalt nicht an die ”…” angehängt wird, was zu Audioverzerrungen führen kann.

Implementierung

So passen Sie Ihren benutzerdefinierten LLM-Server an, um Pufferwörter zu implementieren:

@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
oai_request = request.dict(exclude_none=True)
if "user_id" in oai_request:
oai_request["user"] = oai_request.pop("user_id")
async def event_stream():
try:
# Send initial buffer chunk while processing
initial_chunk = {
"id": "chatcmpl-buffer",
"object": "chat.completion.chunk",
"created": 1234567890,
"model": request.model,
"choices": [{
"delta": {"content": "Let me think about that... "},
"index": 0,
"finish_reason": None
}]
}
yield f"data: {json.dumps(initial_chunk)}\n\n"
# Process the actual LLM response
chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)
async for chunk in chat_completion_coroutine:
chunk_dict = chunk.model_dump()
yield f"data: {json.dumps(chunk_dict)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logging.error("An error occurred: %s", str(e))
yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"
return StreamingResponse(event_stream(), media_type="text/event-stream")

Integration von Systemtools

Ihr benutzerdefiniertes LLM kann Systemtools auslösen, um Gesprächsfluss und -status zu steuern. Diese Tools werden automatisch in den Parameter tools Ihrer Chat-Completion-Anfragen aufgenommen, wenn sie in Ihrem Agenten konfiguriert sind.

Funktionsweise von Systemtools

  1. LLM-Entscheidung: Ihr benutzerdefiniertes LLM entscheidet anhand des Gesprächskontexts, wann diese Tools aufgerufen werden
  2. Tool-Antwort: Das LLM antwortet mit Funktionsaufrufen im Standard-OpenAI-Format
  3. Backend-Verarbeitung: ElevenLabs verarbeitet die Tool-Aufrufe und aktualisiert den Gesprächsstatus

Weitere Informationen zu Systemtools finden Sie in unserem Leitfaden

Verfügbare Systemtools

Zweck: Gespräche automatisch beenden, wenn die entsprechenden Bedingungen erfüllt sind.

Auslösebedingungen: Das LLM sollte dieses Tool aufrufen, wenn:

  • die Hauptaufgabe abgeschlossen ist und der Nutzer zufrieden ist
  • das Gespräch mit beiderseitigem Einvernehmen natürlich zu Ende gegangen ist
  • der Nutzer ausdrücklich angibt, das Gespräch beenden zu wollen

Parameter:

  • reason (String, erforderlich): Der Grund für das Beenden des Anrufs
  • message (String, optional): Eine Abschiedsnachricht, die dem Nutzer vor dem Beenden des Anrufs gesendet wird

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "end_call",
"arguments": "{\"reason\": \"Task completed successfully\", \"message\": \"Thank you for using our service. Have a great day!\"}"
}
}

Implementierung: Konfigurieren Sie das Tool als Systemtool in Ihren Agenteneinstellungen. Das LLM erhält detaillierte Anweisungen dazu, wann diese Funktion aufgerufen werden soll.

Mehr erfahren: Tool zum Beenden von Anrufen

Zweck: Während Gesprächen automatisch zur erkannten Sprache des Nutzers wechseln.

Auslösebedingungen: Das LLM sollte dieses Tool aufrufen, wenn:

  • der Nutzer eine andere Sprache als die aktuelle Gesprächssprache spricht
  • der Nutzer ausdrücklich darum bittet, die Sprache zu wechseln
  • das Gespräch Unterstützung für mehrere Sprachen benötigt

Parameter:

  • reason (String, erforderlich): Der Grund für den Sprachwechsel
  • language (String, erforderlich): Der Sprachcode, zu dem gewechselt werden soll (muss in der Liste der unterstützten Sprachen enthalten sein)

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "language_detection",
"arguments": "{\"reason\": \"User requested Spanish\", \"language\": \"es\"}"
}
}

Implementierung: Konfigurieren Sie unterstützte Sprachen in den Agenteneinstellungen und fügen Sie das Systemtool für die Spracherkennung hinzu. Der Agent wechselt Stimme und Antworten automatisch passend zu den erkannten Sprachen.

Mehr erfahren: Tool zur Spracherkennung

Zweck: Gespräche je nach Nutzerbedarf zwischen spezialisierten KI-Agenten übertragen.

Auslösebedingungen: Das LLM sollte dieses Tool aufrufen, wenn:

  • die Nutzeranfrage Spezialwissen oder andere Agentenfähigkeiten erfordert
  • der aktuelle Agent die Anfrage nicht angemessen bearbeiten kann
  • der Gesprächsverlauf auf den Bedarf eines anderen Agententyps hinweist

Parameter:

  • reason (String, optional): Der Grund für die Agentenübergabe
  • agent_number (Ganzzahl, erforderlich): Nullbasierte Nummer des Agenten, an den übergeben werden soll (basierend auf den konfigurierten Übergaberegeln)

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "transfer_to_agent",
"arguments": "{\"reason\": \"User needs billing support\", \"agent_number\": 0}"
}
}

Implementierung: Definieren Sie Übergaberegeln, die Bedingungen bestimmten Agenten-IDs zuordnen. Konfigurieren Sie, an welche Agenten der aktuelle Agent übergeben kann. Agenten werden in der Übergabekonfiguration über nullbasierte Nummern referenziert.

Mehr erfahren: Tool zur Agentenübergabe

Zweck: Gespräche nahtlos an menschliche Mitarbeitende übergeben, wenn KI-Unterstützung nicht ausreicht.

Auslösebedingungen: Das LLM sollte dieses Tool aufrufen, wenn:

  • komplexe Probleme menschliches Urteilsvermögen erfordern
  • der Nutzer ausdrücklich menschliche Unterstützung anfordert
  • die KI bei der konkreten Anfrage an die Grenzen ihrer Fähigkeiten stößt
  • Eskalationsprotokolle ausgelöst werden

Parameter:

  • reason (String, optional): Der Grund für die Übergabe
  • transfer_number (String, erforderlich): Die Telefonnummer, an die übergeben werden soll (muss mit den konfigurierten Nummern übereinstimmen)
  • client_message (String, erforderlich): Nachricht, die dem Kunden während des Wartens auf die Übergabe vorgelesen wird
  • agent_message (String, erforderlich): Nachricht für den menschlichen Mitarbeitenden, der den Anruf entgegennimmt

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "transfer_to_number",
"arguments": "{\"reason\": \"Complex billing issue\", \"transfer_number\": \"+15551234567\", \"client_message\": \"I'm transferring you to a billing specialist who can help with your account.\", \"agent_message\": \"Customer has a complex billing dispute about order #12345 from last month.\"}"
}
}

Implementierung: Konfigurieren Sie Telefonnummern und Bedingungen für Übergaben. Definieren Sie Nachrichten für Kunden und den übernehmenden menschlichen Mitarbeitenden. Funktioniert sowohl mit Twilio als auch mit SIP-Trunking.

Mehr erfahren: Tool zur Übergabe an Menschen

Zweck: Dem Agenten ermöglichen, zu pausieren und ohne zu sprechen auf Nutzereingaben zu warten.

Auslösebedingungen: Das LLM sollte dieses Tool aufrufen, wenn:

  • der Nutzer angibt, einen Moment zu brauchen (“Geben Sie mir eine Sekunde”, “Lassen Sie mich nachdenken”)
  • der Nutzer eine Pause im Gesprächsverlauf anfordert
  • der Agent erkennt, dass der Nutzer Zeit braucht, um Informationen zu verarbeiten

Parameter:

  • reason (String, optional): Freitext-Grund, der erklärt, warum die Pause benötigt wird

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "skip_turn",
"arguments": "{\"reason\": \"User requested time to think\"}"
}
}

Implementierung: Keine zusätzliche Konfiguration erforderlich. Das Tool signalisiert dem Agenten lediglich, still zu bleiben, bis der Nutzer erneut spricht.

Mehr erfahren: Tool zum Überspringen eines Zugs

Parameter:

  • reason (string, erforderlich): Der Grund für die Erkennung einer Mailbox (z. B. „automatische Begrüßung erkannt“, „keine menschliche Antwort“)

Format des Funktionsaufrufs:

{
"type": "function",
"function": {
"name": "voicemail_detection",
"arguments": "{\"reason\": \"Automated greeting detected with request to leave message\"}"
}
}

Mehr erfahren: Tool zur Mailbox-Erkennung

Beispielanfrage mit Systemtools

Wenn Systemtools konfiguriert sind, erhält Ihr benutzerdefiniertes LLM Anfragen, die die Tools im Standard-OpenAI-Format enthalten:

{
"messages": [
{
"role": "system",
"content": "You are a helpful assistant. You have access to system tools for managing conversations."
},
{
"role": "user",
"content": "I think we're done here, thanks for your help!"
}
],
"model": "your-custom-model",
"temperature": 0.7,
"max_tokens": 1000,
"stream": true,
"tools": [
{
"type": "function",
"function": {
"name": "end_call",
"description": "Call this function to end the current conversation when the main task has been completed...",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for the tool call."
},
"message": {
"type": "string",
"description": "A farewell message to send to the user along right before ending the call."
}
},
"required": ["reason"]
}
}
},
{
"type": "function",
"function": {
"name": "language_detection",
"description": "Change the conversation language when the user expresses a language preference explicitly...",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "The reason for the tool call."
},
"language": {
"type": "string",
"description": "The language to switch to. Must be one of language codes in tool description."
}
},
"required": ["reason", "language"]
}
}
},
{
"type": "function",
"function": {
"name": "skip_turn",
"description": "Skip a turn when the user explicitly indicates they need a moment to think...",
"parameters": {
"type": "object",
"properties": {
"reason": {
"type": "string",
"description": "Optional free-form reason explaining why the pause is needed."
}
},
"required": []
}
}
}
]
}

Ihr benutzerdefiniertes LLM muss Funktionsaufrufe unterstützen, um Systemtools zu verwenden. Stellen Sie sicher, dass Ihr Modell korrekte Antworten auf Funktionsaufrufe im OpenAI-Format generieren kann.

Zusätzliche Funktionen

Sie können zusätzliche Parameter an Ihre benutzerdefinierte LLM-Implementierung übergeben.

1

Zusätzliche Parameter definieren

Erstellen Sie ein Objekt mit Ihren benutzerdefinierten Parametern:

from elevenlabs.conversational_ai.conversation import Conversation, ConversationInitiationData
extra_body_for_convai = {
"UUID": "123e4567-e89b-12d3-a456-426614174000",
"parameter-1": "value-1",
"parameter-2": "value-2",
}
config = ConversationInitiationData(
extra_body=extra_body_for_convai,
)
2

LLM-Implementierung aktualisieren

Passen Sie Ihren benutzerdefinierten LLM-Code an, damit er die zusätzlichen Parameter verarbeitet:

import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from fastapi import Request
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional
# Load environment variables from .env file
load_dotenv()
# Retrieve API key from environment
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY not found in environment variables")
app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
class Message(BaseModel):
role: str
content: str
class ChatCompletionRequest(BaseModel):
messages: List[Message]
model: str
temperature: Optional[float] = 0.7
max_tokens: Optional[int] = None
stream: Optional[bool] = False
user_id: Optional[str] = None
elevenlabs_extra_body: Optional[dict] = None
@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
oai_request = request.dict(exclude_none=True)
print(oai_request)
if "user_id" in oai_request:
oai_request["user"] = oai_request.pop("user_id")
if "elevenlabs_extra_body" in oai_request:
oai_request.pop("elevenlabs_extra_body")
chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)
async def event_stream():
try:
async for chunk in chat_completion_coroutine:
chunk_dict = chunk.model_dump()
yield f"data: {json.dumps(chunk_dict)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logging.error("An error occurred: %s", str(e))
yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"
return StreamingResponse(event_stream(), media_type="text/event-stream")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8013)

Beispielanfrage

Mit dieser benutzerdefinierten Nachrichteneinrichtung erhält Ihr LLM Anfragen in diesem Format:

{
"messages": [
{
"role": "system",
"content": "\n <Redacted>"
},
{
"role": "assistant",
"content": "Hey I'm currently unavailable."
},
{
"role": "user",
"content": "Hey, who are you?"
}
],
"model": "gpt-4o",
"temperature": 0.5,
"max_tokens": 5000,
"stream": true,
"elevenlabs_extra_body": {
"UUID": "123e4567-e89b-12d3-a456-426614174000",
"parameter-1": "value-1",
"parameter-2": "value-2"
}
}