Vai alla navigazione

Integra il tuo modello

Collega un agente al tuo LLM o fornisci il tuo server.

LLM personalizzato ti consente di collegare le tue conversazioni al tuo LLM tramite un endpoint esterno. ElevenLabs supporta anche gli LLM integrati nativamente

Gli LLM personalizzati ti consentono di usare la tua chiave API OpenAI o di eseguire un server LLM completamente personalizzato.

Un LLM personalizzato non può essere usato con un modello Realtime.

Panoramica

Per impostazione predefinita, utilizziamo le nostre credenziali interne per modelli popolari come OpenAI. Per usare un server LLM personalizzato, deve essere compatibile con una delle seguenti strutture di richiesta/risposta compatibili con OpenAI:

La Responses API è il nuovo formato API di OpenAI, che supporta funzionalità aggiuntive. Entrambi i formati API sono pienamente supportati per l’integrazione di LLM personalizzati.

Le guide seguenti coprono entrambi i casi d’uso:

  1. Usa la tua chiave OpenAI: usa la tua chiave API OpenAI con la nostra piattaforma.
  2. Server LLM personalizzato: fornisci e collega la tua implementazione di server LLM.

Imparerai a:

  • Archiviare la tua chiave API OpenAI in ElevenLabs
  • Fornire un server che replica l’endpoint Chat Completions o Responses di OpenAI
  • Indirizzare ElevenLabs al tuo endpoint personalizzato
  • Passare parametri aggiuntivi al tuo LLM secondo necessità

Riepilogo del ragionamento

Il tuo endpoint deve restituire il ragionamento separatamente dalla risposta finale. ElevenLabs non genera il ragionamento dalla risposta finale.

Per richiedere il ragionamento da un endpoint supportato, attiva Riepilogo del ragionamento nelle impostazioni LLM dell’agente oppure imposta enable_reasoning_summary tramite l’API.

Restituisci il ragionamento

Usa il formato corrispondente al tuo endpoint:

Trasmetti il ragionamento in streaming nel campo reasoning o reasoning_content di ogni delta di risposta.

Per gli endpoint compatibili con Gemini, ElevenLabs richiede i pensieri con google.thinking_config.include_thoughts e legge il contenuto contrassegnato con extra_content.google.thought.

Consulta Riepilogo del ragionamento per informazioni su archiviazione, distribuzione e limitazioni.

Usa la tua chiave OpenAI

Per integrare una chiave OpenAI personalizzata, aggiorna le impostazioni dell’agente nella dashboard ElevenLabs affinché puntino al tuo server LLM personalizzato e crea un secret contenente OPENAI_API_KEY:

1

Nelle impostazioni dell’agente nella dashboard ElevenLabs, seleziona “LLM personalizzato” dal menu a discesa “LLM” sulla destra.

Aggiungi secret

2

Fai clic sul campo sotto “LLM” e scorri verso il basso per selezionare “LLM personalizzato”.

3

Inserisci l’URL del server e l’ID del modello del tuo server LLM personalizzato.

Inserisci URL

4

Fai clic sul menu a discesa sotto “API key” e seleziona “Crea nuovo secret”. Assegna alla chiave il nome OPENAI_API_KEY, inseriscila nel campo “value” e fai clic su “Aggiungi secret”.

5

Fai clic sul pulsante “x” per chiudere la finestra modale LLM e fai clic su “Pubblica” per salvare le modifiche.

Server LLM personalizzato

Per usare un server LLM personalizzato, configura un endpoint server compatibile nello stile di OpenAI. Puoi implementare la Chat Completions API (/v1/chat/completions) oppure la Responses API (/v1/responses).

Entrambi gli endpoint devono restituire risposte in formato SSE (Server-Sent Events) con Content-Type: text/event-stream.

La Chat Completions API usa l’endpoint /v1/chat/completions.

Ogni chunk deve essere formattato come data: {json}\n\n e lo stream deve terminare con data: [DONE]\n\n.

Ecco un esempio di implementazione del server:

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)

Esegui questo codice o il codice del tuo server.

Configurare un URL pubblico per il server

Per rendere accessibile il tuo server, crea un URL pubblico usando uno strumento di tunneling come ngrok:

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

Configurare CustomLLM di ElevenLabs

Ora aggiorna le impostazioni dell’agente nella dashboard ElevenLabs affinché puntino al tuo server LLM personalizzato.

Indirizza l’URL del server all’endpoint ngrok e imposta “Limita l’uso dei token” su 5000.

Ora puoi iniziare a interagire con il tuo agente usando il tuo server LLM.

Ottimizzazione per LLM con elaborazione lenta

Se il tuo LLM personalizzato ha tempi di elaborazione lunghi (forse a causa del ragionamento agentico o di requisiti di pre-elaborazione), puoi migliorare il flusso conversazionale implementando le parole di riempimento nelle risposte in streaming. Questa tecnica aiuta a mantenere una prosodia naturale mentre l’LLM genera la risposta completa.

Parole di riempimento

Quando il tuo LLM ha bisogno di più tempo per elaborare la risposta completa, restituisci una risposta iniziale che termini con "... " (puntini di sospensione seguiti da uno spazio). In questo modo, il sistema Text to Speech può mantenere un flusso naturale e la conversazione resta dinamica. Questo crea pause naturali che si collegano bene ai contenuti successivi, su cui l’LLM può ragionare più a lungo. Lo spazio aggiuntivo è fondamentale per evitare che il contenuto successivo venga aggiunto a ”…”, causando possibili distorsioni audio.

Implementazione

Ecco come modificare il server del tuo LLM personalizzato per implementare le parole di riempimento:

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

Integrazione degli strumenti di sistema

Il tuo LLM personalizzato può attivare gli strumenti di sistema per controllare il flusso e lo stato della conversazione. Quando sono configurati nel tuo agente, questi strumenti vengono inclusi automaticamente nel parametro tools delle richieste di completamento della chat.

Come funzionano gli strumenti di sistema

  1. Decisione dell’LLM: il tuo LLM decide quando chiamare questi strumenti in base al contesto della conversazione
  2. Risposta dello strumento: l’LLM risponde con chiamate di funzione nel formato OpenAI standard
  3. Elaborazione backend: ElevenLabs elabora le chiamate degli strumenti e aggiorna lo stato della conversazione

Per maggiori informazioni sugli strumenti di sistema, consulta la nostra guida

Strumenti di sistema disponibili

Scopo: terminare automaticamente le conversazioni quando vengono soddisfatte le condizioni appropriate.

Condizioni di attivazione: l’LLM deve chiamare questo strumento quando:

  • L’attività principale è stata completata e l’utente è soddisfatto
  • La conversazione ha raggiunto una conclusione naturale con accordo reciproco
  • L’utente indica esplicitamente di voler terminare la conversazione

Parametri:

  • reason (stringa, obbligatorio): il motivo per terminare la chiamata
  • message (stringa, facoltativo): un messaggio di saluto da inviare all’utente prima di terminare la chiamata

Formato della chiamata di funzione:

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

Implementazione: configura lo strumento di sistema nelle impostazioni dell’agente. L’LLM riceverà istruzioni dettagliate su quando chiamare questa funzione.

Scopri di più: Strumento Termina chiamata

Scopo: passare automaticamente alla lingua rilevata dell’utente durante le conversazioni.

Condizioni di attivazione: l’LLM deve chiamare questo strumento quando:

  • L’utente parla una lingua diversa da quella della conversazione corrente
  • L’utente richiede esplicitamente di cambiare lingua
  • La conversazione richiede il supporto multilingue

Parametri:

  • reason (stringa, obbligatorio): il motivo del cambio di lingua
  • language (stringa, obbligatorio): il codice della lingua a cui passare (deve essere nell’elenco delle lingue supportate)

Formato della chiamata di funzione:

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

Implementazione: configura le lingue supportate nelle impostazioni dell’agente e aggiungi lo strumento di sistema per il rilevamento della lingua. L’agente cambierà automaticamente voce e risposte in base alle lingue rilevate.

Scopri di più: Strumento di rilevamento della lingua

Scopo: trasferire le conversazioni tra agenti IA specializzati in base alle esigenze dell’utente.

Condizioni di attivazione: l’LLM deve chiamare questo strumento quando:

  • La richiesta dell’utente richiede conoscenze specialistiche o funzionalità di un agente diverso
  • L’agente corrente non è in grado di gestire adeguatamente la richiesta
  • Il flusso della conversazione indica la necessità di un tipo di agente diverso

Parametri:

  • reason (stringa, facoltativo): il motivo del trasferimento dell’agente
  • agent_number (intero, obbligatorio): numero con indice a partire da zero dell’agente a cui trasferire la conversazione (in base alle regole di trasferimento configurate)

Formato della chiamata di funzione:

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

Implementazione: definisci regole di trasferimento che associno le condizioni a ID agente specifici. Configura gli agenti a cui l’agente corrente può trasferire la conversazione. Nella configurazione di trasferimento, gli agenti sono indicati da numeri con indice a partire da zero.

Scopri di più: Strumento di trasferimento dell’agente

Scopo: passare senza interruzioni le conversazioni a operatori umani quando l’assistenza IA non è sufficiente.

Condizioni di attivazione: l’LLM deve chiamare questo strumento quando:

  • Ci sono problemi complessi che richiedono il giudizio umano
  • L’utente richiede esplicitamente assistenza umana
  • L’IA raggiunge i limiti delle sue capacità per la richiesta specifica
  • Vengono attivati i protocolli di escalation

Parametri:

  • reason (stringa, facoltativo): il motivo del trasferimento
  • transfer_number (stringa, obbligatorio): il numero di telefono a cui trasferire la chiamata (deve corrispondere ai numeri configurati)
  • client_message (stringa, obbligatorio): messaggio letto al cliente durante l’attesa del trasferimento
  • agent_message (stringa, obbligatorio): messaggio per l’operatore umano che riceve la chiamata

Formato della chiamata di funzione:

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

Implementazione: configura i numeri di telefono e le condizioni di trasferimento. Definisci i messaggi sia per il cliente sia per l’operatore umano che riceve la chiamata. Funziona sia con Twilio sia con SIP trunking.

Scopri di più: Strumento di trasferimento a un operatore

Scopo: consentire all’agente di fare una pausa e attendere l’input dell’utente senza parlare.

Condizioni di attivazione: l’LLM deve chiamare questo strumento quando:

  • L’utente indica di aver bisogno di un momento (“Dammi un secondo”, “Fammi pensare”)
  • L’utente richiede una pausa nel flusso della conversazione
  • L’agente rileva che l’utente ha bisogno di tempo per elaborare le informazioni

Parametri:

  • reason (stringa, facoltativo): motivo in formato libero che spiega perché è necessaria la pausa

Formato della chiamata di funzione:

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

Implementazione: non è necessaria alcuna configurazione aggiuntiva. Lo strumento segnala semplicemente all’agente di rimanere in silenzio finché l’utente non parla di nuovo.

Scopri di più: Strumento Salta turno

Parametri:

  • reason (stringa, obbligatorio): il motivo del rilevamento della segreteria telefonica (ad esempio, “rilevato messaggio di benvenuto automatico”, “nessuna risposta umana”)

Formato della chiamata di funzione:

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

Scopri di più: Strumento di rilevamento della segreteria telefonica

Esempio di richiesta con strumenti di sistema

Quando gli strumenti di sistema sono configurati, il tuo LLM personalizzato riceverà richieste che includono gli strumenti nel formato OpenAI standard:

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

Il tuo LLM personalizzato deve supportare la chiamata di funzioni per usare gli strumenti di sistema. Assicurati che il modello possa generare risposte di chiamata di funzione corrette nel formato OpenAI.

Funzionalità aggiuntive

Puoi passare parametri aggiuntivi alla tua implementazione LLM personalizzata.

1

Definisci i parametri aggiuntivi

Crea un oggetto contenente i tuoi parametri personalizzati:

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

Aggiorna l'implementazione LLM

Modifica il codice del tuo LLM personalizzato per gestire i parametri aggiuntivi:

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)

Esempio di richiesta

Con questa configurazione di messaggi personalizzata, il tuo LLM riceverà richieste in questo formato:

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