Eigenes Modell integrieren

Verbinden Sie einen Agenten mit Ihrem eigenen LLM oder hosten Sie einen 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

Mit benutzerdefinierten LLMs können Sie Ihren eigenen OpenAI-API-Schlüssel verwenden oder einen vollständig benutzerdefinierten LLM-Server betreiben.

Überblick

Standardmäßig verwenden wir unsere eigenen internen Anmeldedaten für beliebte Modelle wie OpenAI. Um einen benutzerdefinierten LLM-Server zu verwenden, muss dieser 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 benutzerdefinierter LLMs unterstützt.

Die folgenden Anleitungen behandeln beide Anwendungsfälle:

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

Sie erfahren, wie Sie:

  • Ihren OpenAI-API-Schlüssel in ElevenLabs speichern
  • einen Server hosten, der den Chat Completions- oder Responses-Endpunkt von OpenAI nachbildet
  • ElevenLabs auf Ihren benutzerdefinierten Endpunkt verweisen
  • bei Bedarf zusätzliche Parameter an Ihr LLM übergeben

Zusammenfassung der Begründung

Ihr Endpunkt muss die Begründung getrennt von der endgültigen Antwort zurückgeben. ElevenLabs generiert die Begründung nicht aus der endgültigen Antwort.

Um eine Begründung von einem unterstützten Endpunkt anzufordern, aktivieren Sie Zusammenfassung der Begründung in den LLM-Einstellungen des Agenten oder setzen Sie enable_reasoning_summary über die API.

Begründung zurückgeben

Verwenden Sie das Format, das zu Ihrem Endpunkt passt:

Streamen Sie die Begründung 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 Markierung extra_content.google.thought.

Weitere Informationen zu Speicherung, Bereitstellung und Einschränkungen finden Sie unter Zusammenfassung der Begründung.

Eigenen OpenAI-Schlüssel verwenden

Um einen benutzerdefinierten OpenAI-Schlüssel zu integrieren, aktualisieren Sie die Einstellungen Ihres Agenten im ElevenLabs-Dashboard, sodass sie auf Ihren benutzerdefinierten 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 benutzerdefinierten 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 Schlüssel OPENAI_API_KEY, fügen Sie ihn im Feld „value“ hinzu und klicken Sie auf „Add secret“.

5

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

Benutzerdefinierter LLM-Server

Um einen benutzerdefinierten LLM-Server einzubinden, richten Sie einen kompatiblen Server-Endpunkt 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

Um Ihren Server zugänglich zu machen, erstellen Sie mit einem Tunneling-Tool wie ngrok eine öffentliche URL:

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

ElevenLabs CustomLLM konfigurieren

Aktualisieren Sie als Nächstes die Einstellungen Ihres Agenten im ElevenLabs-Dashboard, sodass sie auf Ihren benutzerdefinierten LLM-Server verweisen.

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

Sie können jetzt mit Ihrem Agenten über Ihren eigenen LLM-Server interagieren.

Optimierung für LLMs mit langsamer Verarbeitung

Wenn Ihr benutzerdefiniertes LLM langsame Verarbeitungszeiten hat (etwa aufgrund von agentischem Reasoning oder Vorverarbeitungsanforderungen), können Sie den Gesprächsfluss verbessern, indem Sie Pufferwörter in Ihren Streaming-Antworten verwenden. Diese Technik sorgt für eine natürliche Sprachprosodie, 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 und das Gespräch dynamisch halten. 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 Standardformat von OpenAI.
  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 geeignete 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 Einverständnis zu einem natürlichen Abschluss gekommen ist.
  • Der Nutzer ausdrücklich mitteilt, dass er das Gespräch beenden möchte.

Parameter:

  • reason (String, erforderlich): Der Grund für das Beenden des Anrufs.
  • message (String, optional): Eine Abschiedsnachricht, die vor dem Beenden des Anrufs an den Nutzer 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 in Ihren Agenteneinstellungen als Systemtool. Das LLM erhält detaillierte Anweisungen dazu, wann es diese Funktion aufrufen 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 in einer anderen Sprache als der aktuellen 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 zur Spracherkennung hinzu. Der Agent passt Stimme und Antworten automatisch an erkannte Sprachen an.

Mehr erfahren: Tool zur Spracherkennung

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

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

  • Die Anfrage des Nutzers Spezialwissen oder andere Agentenfähigkeiten erfordert.
  • Der aktuelle Agent die Anfrage nicht ausreichend bearbeiten kann.
  • Der Gesprächsverlauf auf den Bedarf eines anderen Agententyps hinweist.

Parameter:

  • reason (String, optional): Der Grund für die Weiterleitung an einen Agenten.
  • agent_number (Ganzzahl, erforderlich): Nullbasierte Nummer des Agenten, an den weitergeleitet werden soll (basierend auf den konfigurierten Weiterleitungsregeln).

Format des Funktionsaufrufs:

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

Implementierung: Definieren Sie Weiterleitungsregeln, die Bedingungen bestimmten Agenten-IDs zuordnen. Konfigurieren Sie, an welche Agenten der aktuelle Agent weiterleiten kann. Agenten werden in der Weiterleitungskonfiguration über nullbasierte Nummern referenziert.

Mehr erfahren: Tool zur Agentenweiterleitung

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 ihre Leistungsgrenzen stößt.
  • Eskalationsprotokolle ausgelöst werden.

Parameter:

  • reason (String, optional): Der Grund für die Weiterleitung.
  • transfer_number (String, erforderlich): Die Telefonnummer, an die weitergeleitet werden soll (muss mit den konfigurierten Nummern übereinstimmen).
  • client_message (String, erforderlich): Nachricht, die dem Kunden während des Wartens auf die Weiterleitung 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 Weiterleitungsnummern und Bedingungen. Definieren Sie Nachrichten für den Kunden und den menschlichen Mitarbeitenden, der den Anruf übernimmt. Funktioniert mit Twilio und SIP-Trunking.

Mehr erfahren: Tool zur Weiterleitung an Menschen

Zweck: Dem Agenten erlauben, zu pausieren und auf Nutzereingaben zu warten, ohne zu sprechen.

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

  • Der Nutzer mitteilt, dass er einen Moment braucht (“Give me a second”, “Let me think”).
  • Der Nutzer eine Pause im Gesprächsverlauf anfordert.
  • Der Agent erkennt, dass der Nutzer Zeit braucht, um Informationen zu verarbeiten.

Parameter:

  • reason (String, optional): Freitextgrund, der erklärt, warum die Pause erforderlich ist.

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 wieder 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 Standardformat von OpenAI 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 für 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, um die zusätzlichen Parameter zu verarbeiten:

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"
}
}