Hoppa till navigering

Integrera din egen modell

Anslut en agent till din egen LLM eller kör din egen server.

Med Custom LLM kan du ansluta dina konversationer till din egen LLM via en extern slutpunkt. ElevenLabs stöder även inbyggt integrerade LLM:er

Anpassade LLM:er låter dig använda din egen OpenAI API-nyckel eller köra en helt anpassad LLM-server.

Översikt

Som standard använder vi våra egna interna autentiseringsuppgifter för populära modeller som OpenAI. För att använda en anpassad LLM-server måste den följa någon av följande OpenAI-kompatibla strukturer för begäran och svar:

Responses API är OpenAI:s nyare API-format som stöder ytterligare funktioner. Båda API-formaten stöds fullt ut för integrering av anpassade LLM:er.

Följande guider täcker båda användningsfallen:

  1. Använd din egen OpenAI-nyckel: Använd din egen OpenAI API-nyckel med vår plattform.
  2. Anpassad LLM-server: Kör och anslut din egen LLM-serverimplementering.

Du får lära dig att:

  • Lagra din OpenAI API-nyckel i ElevenLabs
  • Köra en server som efterliknar OpenAI:s slutpunkt för Chat Completions eller Responses
  • Styra ElevenLabs till din anpassade slutpunkt
  • Skicka extra parametrar till din LLM vid behov

Sammanfattning av resonemang

Din slutpunkt måste returnera resonemang separat från det slutliga svaret. ElevenLabs genererar inte resonemang från det slutliga svaret.

För att begära resonemang från en slutpunkt som stöds aktiverar du Sammanfattning av resonemang i agentens LLM-inställningar eller anger enable_reasoning_summary via API:et.

Returnera resonemang

Använd det format som matchar din slutpunkt:

Streama resonemang i fältet reasoning eller reasoning_content i varje svarsdelta.

För Gemini-kompatibla slutpunkter begär ElevenLabs tankar med google.thinking_config.include_thoughts och läser innehåll markerat med extra_content.google.thought.

Se Sammanfattning av resonemang för lagring, leverans och begränsningar.

Använd din egen OpenAI-nyckel

För att integrera en anpassad OpenAI-nyckel uppdaterar du agentinställningarna i ElevenLabs-kontrollpanelen så att de pekar på din anpassade LLM-server och skapar en hemlighet som innehåller din OPENAI_API_KEY:

1

I agentinställningarna i ElevenLabs-kontrollpanelen väljer du “Custom LLM” i rullgardinsmenyn “LLM” till höger.

Lägg till hemlighet

2

Klicka på fältet under “LLM” och skrolla ner för att välja “Custom LLM”.

3

Ange server-URL:en och modell-ID:t för din anpassade LLM-server.

Ange URL

4

Klicka på rullgardinsmenyn under “API key” och välj “Create new secret”. Ge nyckeln namnet OPENAI_API_KEY, lägg till nyckeln i fältet “value” och klicka på “Add secret”.

5

Klicka på “x” för att stänga LLM-modalen och klicka på “Publish” för att spara ändringarna.

Anpassad LLM-server

För att använda en anpassad LLM-server konfigurerar du en kompatibel serverslutpunkt enligt OpenAI:s stil. Du kan implementera antingen Chat Completions API (/v1/chat/completions) eller Responses API (/v1/responses).

Båda slutpunkterna måste returnera svar i SSE-format (Server-Sent Events) med Content-Type: text/event-stream.

Chat Completions API använder slutpunkten /v1/chat/completions.

Varje del måste formateras som data: {json}\n\n och strömmen måste avslutas med data: [DONE]\n\n.

Här är ett exempel på en serverimplementering:

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)

Kör den här koden eller din egen serverkod.

Konfigurera en offentlig URL för din server

För att göra din server tillgänglig skapar du en offentlig URL med ett tunnelverktyg som ngrok:

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

Konfigurera ElevenLabs CustomLLM

Uppdatera sedan agentinställningarna i ElevenLabs-kontrollpanelen så att de pekar på din anpassade LLM-server.

Styr din server-URL till ngrok-slutpunkten och ange “Limit token usage” till 5000.

Du kan nu börja interagera med din agent via din egen LLM-server.

Optimera för LLM:er med långsam bearbetning

Om din anpassade LLM har långa bearbetningstider (kanske på grund av agentbaserat resonemang eller krav på förbearbetning) kan du förbättra samtalsflödet genom att implementera buffertord i dina streamade svar. Den här tekniken hjälper till att bevara naturlig talprosodi medan din LLM genererar det fullständiga svaret.

Buffertord

När din LLM behöver mer tid för att bearbeta hela svaret returnerar du ett första svar som avslutas med "... " (ellips följt av ett mellanslag). Då kan Text to Speech-systemet behålla ett naturligt flöde samtidigt som konversationen känns dynamisk. Detta skapar naturliga pauser som flyter väl in i efterföljande innehåll som LLM:en kan resonera längre kring. Det extra mellanslaget är avgörande för att säkerställa att efterföljande innehåll inte läggs till efter ”…”, vilket kan leda till ljudförvrängningar.

Implementering

Så här ändrar du din anpassade LLM-server för att implementera buffertord:

@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")

Integrering av systemverktyg

Din anpassade LLM kan utlösa systemverktyg för att styra samtalsflöde och tillstånd. De här verktygen inkluderas automatiskt i parametern tools i dina begäranden om chat completion när de är konfigurerade i din agent.

Så fungerar systemverktyg

  1. LLM-beslut: Din anpassade LLM avgör när dessa verktyg ska anropas utifrån konversationens sammanhang
  2. Verktygssvar: LLM:en svarar med funktionsanrop i OpenAI:s standardformat
  3. Bearbetning i backend: ElevenLabs bearbetar verktygsanropen och uppdaterar konversationens tillstånd

Mer information om systemverktyg finns i vår guide

Tillgängliga systemverktyg

Syfte: Avsluta automatiskt konversationer när rätt villkor är uppfyllda.

Villkor för utlösning: LLM:en ska anropa verktyget när:

  • Huvuduppgiften har slutförts och användaren är nöjd
  • Konversationen har nått en naturlig avslutning med ömsesidig överenskommelse
  • Användaren uttryckligen säger att hen vill avsluta konversationen

Parametrar:

  • reason (sträng, obligatorisk): Orsaken till att samtalet avslutas
  • message (sträng, valfri): Ett avskedsmeddelande som skickas till användaren innan samtalet avslutas

Format för funktionsanrop:

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

Implementering: Konfigurera som ett systemverktyg i agentinställningarna. LLM:en får detaljerade instruktioner om när den ska anropa denna funktion.

Läs mer: Verktyget Avsluta samtal

Syfte: Växla automatiskt till användarens identifierade språk under konversationer.

Villkor för utlösning: LLM:en ska anropa verktyget när:

  • Användaren talar ett annat språk än det aktuella konversationsspråket
  • Användaren uttryckligen ber om att byta språk
  • Konversationen behöver stöd för flera språk

Parametrar:

  • reason (sträng, obligatorisk): Orsaken till språkbytet
  • language (sträng, obligatorisk): Språkkoden att byta till (måste finnas i listan över språk som stöds)

Format för funktionsanrop:

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

Implementering: Konfigurera språk som stöds i agentinställningarna och lägg till systemverktyget för språkidentifiering. Agenten växlar automatiskt röst och svar för att matcha identifierade språk.

Läs mer: Verktyget Språkidentifiering

Syfte: Överför konversationer mellan specialiserade AI-agenter utifrån användarens behov.

Villkor för utlösning: LLM:en ska anropa verktyget när:

  • Användarens begäran kräver specialkunskap eller andra agentfunktioner
  • Den aktuella agenten inte kan hantera frågan tillräckligt väl
  • Samtalsflödet visar att en annan typ av agent behövs

Parametrar:

  • reason (sträng, valfri): Orsaken till agentöverföringen
  • agent_number (heltal, obligatorisk): Det nollindexerade numret för agenten att överföra till (baserat på konfigurerade överföringsregler)

Format för funktionsanrop:

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

Implementering: Definiera överföringsregler som kopplar villkor till specifika agent-ID:n. Konfigurera vilka agenter den aktuella agenten kan överföra till. Agenter refereras med nollindexerade nummer i överföringskonfigurationen.

Läs mer: Verktyget Agentöverföring

Syfte: Överlämna smidigt konversationer till mänskliga handläggare när AI-hjälp inte räcker till.

Villkor för utlösning: LLM:en ska anropa verktyget när:

  • Komplexa problem kräver mänskligt omdöme
  • Användaren uttryckligen begär mänsklig hjälp
  • AI:n når gränsen för sin kapacitet för den specifika begäran
  • Eskaleringsprotokoll utlöses

Parametrar:

  • reason (sträng, valfri): Orsaken till överföringen
  • transfer_number (sträng, obligatorisk): Telefonnummer att överföra till (måste matcha konfigurerade nummer)
  • client_message (sträng, obligatorisk): Meddelande som läses upp för kunden medan överföringen väntar
  • agent_message (sträng, obligatorisk): Meddelande till den mänskliga handläggare som tar emot samtalet

Format för funktionsanrop:

{
"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.\"}"
}
}

Implementering: Konfigurera telefonnummer och villkor för överföring. Definiera meddelanden för både kunden och den mänskliga handläggaren som tar emot samtalet. Fungerar med både Twilio och SIP-trunking.

Läs mer: Verktyget Överför till människa

Syfte: Låter agenten pausa och vänta på användarindata utan att tala.

Villkor för utlösning: LLM:en ska anropa verktyget när:

  • Användaren signalerar att hen behöver en stund (“Ge mig en sekund”, “Låt mig tänka”)
  • Användaren begär en paus i samtalsflödet
  • Agenten upptäcker att användaren behöver tid för att bearbeta information

Parametrar:

  • reason (sträng, valfri): Fritt formulerad orsak som förklarar varför pausen behövs

Format för funktionsanrop:

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

Implementering: Ingen ytterligare konfiguration behövs. Verktyget signalerar bara att agenten ska vara tyst tills användaren talar igen.

Läs mer: Verktyget Hoppa över tur

Parametrar:

  • reason (sträng, obligatorisk): Anledningen till att röstbrevlåda identifierades (t.ex. ”automatiskt hälsningsmeddelande identifierat”, ”inget mänskligt svar”)

Format för funktionsanrop:

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

Läs mer: Verktyget Röstmeddelandeidentifiering

Exempelbegäran med systemverktyg

När systemverktyg är konfigurerade får din anpassade LLM begäranden som innehåller verktygen i OpenAI:s standardformat:

{
"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": []
}
}
}
]
}

Din anpassade LLM måste stödja funktionsanrop för att använda systemverktyg. Kontrollera att modellen kan generera korrekta svar på funktionsanrop i OpenAI-format.

Ytterligare funktioner

Du kan skicka ytterligare parametrar till din anpassade LLM-implementering.

1

Definiera de extra parametrarna

Skapa ett objekt som innehåller dina anpassade parametrar:

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

Uppdatera LLM-implementeringen

Ändra din anpassade LLM-kod för att hantera de ytterligare parametrarna:

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)

Exempelbegäran

Med den här anpassade meddelandeinställningen får din LLM begäranden i följande 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"
}
}