Ir para a navegação

Integre seu próprio modelo

Conecte um agente ao seu próprio LLM ou hospede seu próprio servidor.

O LLM personalizado permite conectar suas conversas ao seu próprio LLM por meio de um endpoint externo. A ElevenLabs também oferece suporte a LLMs integrados nativamente

Os LLMs personalizados permitem que você use sua própria chave de API da OpenAI ou execute um servidor de LLM totalmente personalizado.

Um LLM personalizado não pode ser usado com um modelo em tempo real.

Visão geral

Por padrão, usamos nossas próprias credenciais internas para modelos populares, como OpenAI. Para usar um servidor de LLM personalizado, ele deve seguir uma das seguintes estruturas de solicitação/resposta compatíveis com a OpenAI:

A API Responses é o formato de API mais recente da OpenAI e oferece suporte a recursos adicionais. Os dois formatos de API têm suporte completo para integração com LLMs personalizados.

Os guias a seguir abrangem os dois casos de uso:

  1. Use sua própria chave da OpenAI: use sua própria chave de API da OpenAI com nossa plataforma.
  2. Servidor de LLM personalizado: hospede e conecte sua própria implementação de servidor de LLM.

Você aprenderá a:

  • Armazenar sua chave de API da OpenAI na ElevenLabs
  • Hospedar um servidor que replique o endpoint Chat Completions ou Responses da OpenAI
  • Direcionar a ElevenLabs ao seu endpoint personalizado
  • Enviar parâmetros extras ao seu LLM conforme necessário

Resumo do raciocínio

Seu endpoint deve retornar o raciocínio separadamente da resposta final. A ElevenLabs não gera o raciocínio a partir da resposta final.

Para solicitar o raciocínio de um endpoint compatível, ative Resumo do raciocínio nas configurações de LLM do agente ou defina enable_reasoning_summary pela API.

Retornar raciocínio

Use o formato correspondente ao seu endpoint:

Transmita o raciocínio no campo reasoning ou reasoning_content de cada delta de resposta.

Para endpoints compatíveis com Gemini, a ElevenLabs solicita pensamentos com google.thinking_config.include_thoughts e lê o conteúdo marcado com extra_content.google.thought.

Consulte Resumo do raciocínio para saber sobre armazenamento, entrega e limitações.

Usando sua própria chave da OpenAI

Para integrar uma chave personalizada da OpenAI, atualize as configurações do seu agente no painel da ElevenLabs para apontar para seu servidor de LLM personalizado e crie um segredo com sua OPENAI_API_KEY:

1

Nas configurações do Agente no painel da ElevenLabs, selecione “Custom LLM” no menu suspenso “LLM” à direita.

Adicionar segredo

2

Clique no campo abaixo de “LLM” e role para baixo para selecionar “Custom LLM”.

3

Insira a URL do servidor e o ID do modelo do seu servidor de LLM personalizado.

Inserir URL

4

Clique no menu suspenso em “API key” e selecione “Create new secret”. Dê à chave o nome OPENAI_API_KEY, adicione a chave ao campo “value” e clique em “Add secret”.

5

Clique no botão “x” para fechar o modal do LLM e em “Publish” para salvar as alterações.

Servidor de LLM personalizado

Para usar um servidor de LLM personalizado, configure um endpoint de servidor compatível no estilo da OpenAI. Você pode implementar a API Chat Completions (/v1/chat/completions) ou a API Responses (/v1/responses).

Ambos os endpoints devem retornar respostas no formato SSE (Server-Sent Events), com Content-Type: text/event-stream.

A API Chat Completions usa o endpoint /v1/chat/completions.

Cada bloco deve ser formatado como data: {json}\n\n, e o stream deve terminar com data: [DONE]\n\n.

Veja um exemplo de implementação de servidor:

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)

Execute esse código ou o código do seu próprio servidor.

Configurar uma URL pública para seu servidor

Para tornar seu servidor acessível, crie uma URL pública usando uma ferramenta de tunelamento como o ngrok:

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

Configurar o CustomLLM da ElevenLabs

Em seguida, atualize as configurações do seu agente no painel da ElevenLabs para apontar para seu servidor de LLM personalizado.

Direcione a URL do seu servidor ao endpoint do ngrok e defina “Limit token usage” como 5000.

Agora você pode começar a interagir com seu agente usando seu próprio servidor de LLM.

Otimização para LLMs com processamento lento

Se o seu LLM personalizado tiver tempos de processamento lentos (talvez devido a raciocínio agêntico ou requisitos de pré-processamento), você poderá melhorar o fluxo da conversa implementando palavras de preenchimento nas suas respostas em streaming. Essa técnica ajuda a manter a prosódia natural da fala enquanto o LLM gera a resposta completa.

Palavras de preenchimento

Quando o LLM precisar de mais tempo para processar a resposta completa, retorne uma resposta inicial terminando com "... " (reticências seguidas de um espaço). Isso permite que o sistema de Text to Speech mantenha um fluxo natural e deixe a conversa dinâmica. Isso cria pausas naturais que se conectam bem ao conteúdo subsequente sobre o qual o LLM pode raciocinar por mais tempo. O espaço extra é essencial para garantir que o conteúdo subsequente não seja anexado a "...", o que pode causar distorções no áudio.

Implementação

Veja como modificar seu servidor de LLM personalizado para implementar palavras de preenchimento:

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

Integração de ferramentas do sistema

Seu LLM personalizado pode acionar ferramentas do sistema para controlar o fluxo e o estado da conversa. Essas ferramentas são incluídas automaticamente no parâmetro tools das suas solicitações de conclusão de chat quando configuradas no seu agente.

Como as ferramentas do sistema funcionam

  1. Decisão do LLM: seu LLM personalizado decide quando chamar essas ferramentas com base no contexto da conversa
  2. Resposta da ferramenta: o LLM responde com chamadas de função no formato padrão da OpenAI
  3. Processamento de backend: a ElevenLabs processa as chamadas de ferramenta e atualiza o estado da conversa

Para mais informações sobre ferramentas do sistema, consulte nosso guia

Ferramentas do sistema disponíveis

Objetivo: encerrar automaticamente conversas quando as condições adequadas forem atendidas.

Condições de acionamento: o LLM deve chamar esta ferramenta quando:

  • A tarefa principal foi concluída e o usuário está satisfeito
  • A conversa chegou a uma conclusão natural com concordância mútua
  • O usuário indica explicitamente que deseja encerrar a conversa

Parâmetros:

  • reason (string, obrigatório): o motivo para encerrar a chamada
  • message (string, opcional): uma mensagem de despedida para enviar ao usuário antes de encerrar a chamada

Formato da chamada de função:

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

Implementação: configure como uma ferramenta do sistema nas configurações do seu agente. O LLM receberá instruções detalhadas sobre quando chamar esta função.

Saiba mais: ferramenta de encerramento de chamada

Objetivo: mudar automaticamente para o idioma detectado do usuário durante as conversas.

Condições de acionamento: o LLM deve chamar esta ferramenta quando:

  • O usuário fala em um idioma diferente do idioma atual da conversa
  • O usuário solicita explicitamente a troca de idioma
  • É necessário suporte a vários idiomas para a conversa

Parâmetros:

  • reason (string, obrigatório): o motivo para a troca de idioma
  • language (string, obrigatório): o código do idioma para o qual mudar (deve estar na lista de idiomas compatíveis)

Formato da chamada de função:

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

Implementação: configure os idiomas compatíveis nas configurações do agente e adicione a ferramenta do sistema de detecção de idioma. O agente mudará automaticamente a voz e as respostas para corresponder aos idiomas detectados.

Saiba mais: ferramenta de detecção de idioma

Objetivo: transferir conversas entre agentes de IA especializados com base nas necessidades do usuário.

Condições de acionamento: o LLM deve chamar esta ferramenta quando:

  • A solicitação do usuário exigir conhecimento especializado ou recursos de outro agente
  • O agente atual não puder lidar adequadamente com a consulta
  • O fluxo da conversa indicar a necessidade de outro tipo de agente

Parâmetros:

  • reason (string, opcional): o motivo da transferência de agente
  • agent_number (integer, obrigatório): número com índice zero do agente para o qual transferir (com base nas regras de transferência configuradas)

Formato da chamada de função:

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

Implementação: defina regras de transferência que mapeiem condições para IDs específicos de agentes. Configure para quais agentes o agente atual pode transferir. Os agentes são referenciados por números com índice zero na configuração de transferência.

Saiba mais: ferramenta de transferência de agente

Objetivo: encaminhar conversas sem interrupções para operadores humanos quando a assistência de IA não for suficiente.

Condições de acionamento: o LLM deve chamar esta ferramenta quando:

  • Houver problemas complexos que exijam julgamento humano
  • O usuário solicitar explicitamente assistência humana
  • A IA atingir os limites de capacidade para a solicitação específica
  • Protocolos de escalonamento forem acionados

Parâmetros:

  • reason (string, opcional): o motivo da transferência
  • transfer_number (string, obrigatório): o número de telefone para o qual transferir (deve corresponder aos números configurados)
  • client_message (string, obrigatório): mensagem lida ao cliente enquanto aguarda a transferência
  • agent_message (string, obrigatório): mensagem para o operador humano que recebe a chamada

Formato da chamada de função:

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

Implementação: configure números de telefone e condições de transferência. Defina mensagens tanto para o cliente quanto para o operador humano que receberá a chamada. Funciona com Twilio e entroncamento SIP.

Saiba mais: ferramenta de transferência para humano

Objetivo: permitir que o agente pause e aguarde a entrada do usuário sem falar.

Condições de acionamento: o LLM deve chamar esta ferramenta quando:

  • O usuário indicar que precisa de um momento (“Me dê um segundo”, “Deixe-me pensar”)
  • O usuário solicitar uma pausa no fluxo da conversa
  • O agente detectar que o usuário precisa de tempo para processar informações

Parâmetros:

  • reason (string, opcional): motivo livre que explica por que a pausa é necessária

Formato da chamada de função:

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

Implementação: nenhuma configuração adicional é necessária. A ferramenta apenas sinaliza para o agente permanecer em silêncio até que o usuário fale novamente.

Saiba mais: ferramenta de pular turno

Parâmetros:

  • reason (string, obrigatório): o motivo para detectar a caixa postal (por exemplo, “saudação automática detectada”, “nenhuma resposta humana”)

Formato de chamada da função:

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

Saiba mais: ferramenta de detecção de caixa postal

Exemplo de solicitação com ferramentas do sistema

Quando as ferramentas do sistema estiverem configuradas, seu LLM personalizado receberá solicitações que incluem as ferramentas no formato padrão da OpenAI:

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

Seu LLM personalizado deve oferecer suporte a chamadas de função para usar ferramentas do sistema. Garanta que seu modelo possa gerar respostas adequadas de chamada de função no formato da OpenAI.

Recursos adicionais

Você pode passar parâmetros adicionais para sua implementação de LLM personalizado.

1

Definir os parâmetros extras

Crie um objeto contendo seus parâmetros personalizados:

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

Atualizar a implementação do LLM

Modifique o código do seu LLM personalizado para processar os parâmetros adicionais:

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)

Exemplo de solicitação

Com essa configuração de mensagem personalizada, seu LLM receberá solicitações neste 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"
}
}