Vai alla navigazione

Integra il tuo modello

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

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

Con gli LLM personalizzati puoi usare la tua chiave API OpenAI o eseguire un server LLM completamente personalizzato.

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 di OpenAI:

La Responses API è il formato API più recente di OpenAI e supporta funzionalità aggiuntive. Entrambi i formati API sono completamente supportati per l’integrazione di LLM personalizzati.

Le guide seguenti illustrano 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 replichi 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.

Restituire il ragionamento

Usa il formato corrispondente al tuo endpoint:

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

Per gli endpoint compatibili con Gemini, ElevenLabs richiede i pensieri con google.thinking_config.include_thoughts e legge i contenuti contrassegnati con extra_content.google.thought.

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

Usare la tua chiave OpenAI

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

1

Nelle impostazioni del tuo agente nella dashboard di ElevenLabs, seleziona “Custom LLM” dal menu a discesa “LLM” sulla destra.

Aggiungi segreto

2

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

3

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

Inserisci l'URL

4

Fai clic sul menu a discesa sotto “API key” e seleziona “Create new secret”. Assegna alla chiave il nome OPENAI_API_KEY, aggiungila al campo “value” e fai clic su “Add secret”.

5

Fai clic sul pulsante “x” per chiudere la finestra LLM e fai clic su “Publish” 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’implementazione di esempio 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 oppure 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 ElevenLabs CustomLLM

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

Indirizza l’URL del server all’endpoint ngrok e imposta “Limit token usage” su 5000.

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

Ottimizzare per LLM con elaborazione lenta

Se il tuo LLM personalizzato ha tempi di elaborazione lenti, magari a causa di requisiti di ragionamento agentico o pre-elaborazione, puoi migliorare il flusso conversazionale implementando le parole di attesa nelle risposte in streaming. Questa tecnica aiuta a mantenere una prosodia naturale mentre il tuo LLM genera la risposta completa.

Parole di attesa

Quando il tuo LLM necessita di più tempo per elaborare la risposta completa, restituisci una risposta iniziale che termini con "... " (puntini di sospensione seguiti da uno spazio). Questo permette al sistema Text to Speech di mantenere un flusso naturale e una conversazione dinamica. In questo modo crei 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 tuo server LLM personalizzato per implementare le parole di attesa:

@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 tue richieste di completamento chat.

Come funzionano gli strumenti di sistema

  1. Decisione dell’LLM: il tuo LLM personalizzato 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: termina automaticamente le conversazioni quando si verificano 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 della fine della 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 come strumento di sistema nelle impostazioni dell’agente. L’LLM riceverà istruzioni dettagliate su quando chiamare questa funzione.

Scopri di più: Strumento Termina chiamata

Scopo: passa 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
  • Per la conversazione è necessario 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 incluso 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 Rilevamento della lingua

Scopo: trasferisce 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 capacità di un agente diverse
  • L’agente corrente non riesce a 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 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 di agenti specifici. Configura gli agenti a cui l’agente corrente può trasferire la conversazione. Gli agenti sono indicati tramite numeri con indice zero nella configurazione del trasferimento.

Scopri di più: Strumento Trasferimento dell’agente

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

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

  • Si verificano problemi complessi che richiedono giudizio umano
  • L’utente richiede esplicitamente assistenza umana
  • L’IA raggiunge i limiti delle proprie 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, che 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 messaggi sia per il cliente sia per l’operatore umano ricevente. Funziona sia con Twilio sia con SIP trunking.

Scopri di più: Strumento Trasferimento a un operatore umano

Scopo: consente 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 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 il function calling 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 messaggio personalizzato, 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"
}
}