Escolha a API que seu aplicativo usa. Cada API tem seus próprios mecanismos de autenticação e criação de sessões, além de seu próprio contrato de eventos.
Controle uma sessão do GPT-Live pelo seu servidor
Conecte o servidor do seu aplicativo a uma sessão existente do GPT-Live via WebRTC ou SIP quando o servidor precisar receber eventos da conversa, executar ferramentas privadas ou atualizar a conversa. Essa segunda conexão é chamada de WebSocket de canal lateral. As duas conexões compartilham uma sessão, enquanto o WebRTC ou SIP transporta o áudio principal.
O canal lateral transporta eventos e comandos. Seu aplicativo é responsável pela execução de ferramentas, pelas verificações de autorização e pelas regras de negócio. Mantenha as chaves de API e as credenciais das ferramentas no seu servidor.
Decida se você precisa de um canal lateral
Para aplicativos de navegador, use o canal de dados WebRTC para legendas e atualizações locais da interface. Use um canal lateral quando o processamento da transcrição ocorrer no seu servidor, como verificações de mecanismos de proteção, análise de sentimento ou chamadas especulativas de ferramentas. Seu servidor pode receber eventos e controlar diretamente a mesma sessão, enquanto o áudio do navegador permanece no WebRTC. Consulte Reaja a fragmentos de transcrição para ver exemplos.
Se seu backend já gerencia a conexão WebSocket principal, ele já recebe os eventos da sessão e pode enviar comandos.
A delegação para Responses também funciona sem um canal lateral. O navegador pode encaminhar eventos de chamada de função do seu canal de dados para execução em um backend autenticado. As ferramentas hospedadas pela OpenAI são executadas por meio do backend delegado, sem um executor de ferramentas no aplicativo.
Conecte-se à sessão existente
-
Salve o ID da sessão que seu backend controlará. Para WebRTC, use
session.idda resposta JSON aPOST /v1/live/sessions. Para SIP, primeiro aceite a chamada recebida e depois usedata.session_iddo webhook dessa chamada. Mantenha o ID junto aos registros de usuário e de conversa do aplicativo. -
Abra um WebSocket a partir do seu servidor na URL a seguir, inserindo o ID salvo sem alterá-lo. Autentique-se com
Authorization: Bearer $OPENAI_API_KEY, usando a autenticação do projeto que criou ou aceitou a sessão. Inclua os mesmos cabeçalhos de conexão exigidos na criação da sessão.wss://api.openai.com/v1/live/sessions/{session_id}/attach -
Receba eventos e envie comandos pelo socket conectado. A sessão já está em execução; não envie
session.startnovamente.
Trate o ID da sessão como um valor opaco. Preserve seu prefixo e use-o apenas para a sessão à qual seu aplicativo tem acesso autorizado. Leia o ID da resposta JSON do Live, e não de um cabeçalho Location ou parâmetro de URL call_id do Realtime.
Observe eventos e envie comandos
| Tarefa | Eventos ou comandos |
|---|---|
| Acompanhar a conversa | Receba deltas de transcrição do usuário e do assistente, eventos de delegação e eventos aninhados de Responses. |
| Atualizar a configuração do backend | Use session.update para alterar as configurações compatíveis com o modo de delegação existente. As configurações de inicialização, como o modelo do frontend e a configuração de áudio, permanecem fixas. |
| Fornecer contexto | Use session.instructions.append para instruções, session.thinking.append para contexto silencioso e session.commentary.append para atualizações que podem ser faladas. |
| Retornar resultados de ferramentas | Com a delegação para Responses, envie response.item.create e depois response.create para continuar o trabalho no backend. |
| Controlar a entrada do microfone | Use session.input_audio.mute e session.input_audio.unmute. Silenciar a entrada não interrompe a saída do assistente. |
| Encerrar a sessão | Envie session.close e receba session.closed antes de desconectar. |
Os comandos seguem as mesmas regras de validação e delegação da conexão principal. Ao acrescentar contexto, use delegation_id: null para o contexto geral da sessão; um ID não nulo deve identificar uma delegação de cliente existente. Consulte Delegação e ferramentas para ver configurações, execução de funções e exemplos de acréscimo de contexto.
Para sessões no navegador, mantenha a entrada do microfone e a saída dos alto-falantes na trilha de mídia WebRTC negociada. Use o canal lateral para eventos e controle da conversa. Um evento de transcrição ou uma confirmação de comando não comprova que o áudio foi reproduzido ou que o usuário o ouviu.
Receba áudio espelhado
Um canal lateral também recebe cópias do áudio de entrada e de saída subsequente, enquanto a conexão principal transporta a mídia ao vivo:
| Evento | Campo de áudio | Informações de tempo |
|---|---|---|
session.input_audio.append | audio | Sem marcas de tempo. |
session.output_audio.delta | delta | start_ms e end_ms descrevem o intervalo da saída na linha do tempo da sessão. |
Ambos os payloads contêm áudio bruto mono PCM16LE a 24 kHz codificado em base64, independentemente do formato de áudio do transporte principal. Nenhum dos eventos tem um event_id. A entrada espelhada contém o áudio recebido antes do silenciamento da entrada; isso não confirma que o modelo consumiu essas amostras. Os intervalos da saída espelhada podem ter lacunas decorrentes de quadros descartados e não indicam quando a pessoa que fez a chamada ouviu o áudio.
Esses são eventos do servidor, não uma permissão para enviar áudio pelo canal lateral. Envie o áudio do microfone pelo transporte principal; não envie session.input_audio.append pelo socket conectado.
Defina um único responsável por cada ação
Escolha se o navegador ou o backend será responsável por cada ação. Se ambas as conexões receberem um evento de chamada de função, execute a função uma única vez. Aplique a mesma regra de responsabilidade às atualizações de contexto e às solicitações para continuar o trabalho no backend.
Armazene as transcrições e o estado das ferramentas no seu aplicativo. Conecte-se logo no início se o backend precisar observar a conversa desde o começo e retenha todo o histórico coletado antes da conexão. Não conte com essa conexão para reconstruir transcrições ou resultados de ferramentas anteriores.
Um canal lateral, por si só, não oculta os eventos da sessão do navegador. Mantenha as credenciais sensíveis das ferramentas e as decisões de autorização no seu backend e retorne apenas o contexto necessário para a conversa.
Aplique mecanismos de proteção à conversa
Use a conexão do seu servidor para monitorar a conversa, verificar se as solicitações estão de acordo com as políticas do seu aplicativo e intervir quando uma verificação detectar um problema. Um canal lateral dá ao seu servidor acesso aos eventos e comandos da sessão; seu aplicativo executa as verificações e aplica as medidas determinadas pelos resultados. O mesmo fluxo de trabalho se aplica quando seu servidor já gerencia a conexão WebSocket principal.
Execute verificações em paralelo à conversa
Os mecanismos de proteção são uma das aplicações do processamento de fragmentos de transcrição à medida que chegam. O mesmo fluxo pode iniciar uma consulta especulativa ou atualizar a interface em paralelo a essas verificações.
- Monitore as transcrições. Acumule fragmentos de
session.input_transcript.deltapara verificar se as solicitações dos usuários contêm tentativas de jailbreak, informações sensíveis ou violações de políticas. Usesession.output_transcript.deltapara verificar se a fala do assistente contém afirmações sem fundamento ou respostas fora do escopo do seu aplicativo. Mantenha cada verificação associada à transcrição e à solicitação do aplicativo que ela avaliou. - Execute verificações simultaneamente. Um modelo rápido e leve pode avaliar solicitações enquanto a conversa continua. Retorne um resultado estruturado pequeno, como
{"triggered": true}, com base no qual seu aplicativo possa agir. Mantenha as ações que exigem aprovação bloqueadas até que passem nas verificações; um tempo limite excedido ou uma falha na verificação não equivale a uma aprovação. - Bloqueie as ações afetadas. Quando uma verificação detectar um problema, marque a solicitação como bloqueada no estado do aplicativo. Verifique esse estado antes de executar uma ferramenta ou efetivar uma alteração, inclusive para trabalhos já enfileirados. Uma recusa falada não impede a execução de uma ferramenta.
- Interrompa o trabalho relacionado. Cancele as tarefas gerenciadas pelo aplicativo quando seu backend oferecer suporte ao cancelamento e descarte resultados tardios de solicitações bloqueadas ou substituídas. Com a delegação para Responses, interrompa a execução das funções personalizadas afetadas e não envie
response.createpara continuar um trabalho bloqueado. Isso não cancela uma resposta hospedada já em execução nem interrompe a fala do frontend. - Registre e redirecione. Registre a decisão com os IDs da solicitação e da delegação afetadas e, em seguida, envie uma instrução corretiva. Um nome de evento como
guardrail.triggeredpertence à telemetria do seu aplicativo; não é um evento da API do GPT-Live.
Consulte Deltas de transcrição para coletar fragmentos e Delegação e ferramentas para manter os resultados do backend alinhados à tarefa atual.
Redirecione a conversa
Use session.instructions.append para orientar a conversa com base nos mecanismos de proteção. Esse comando pode interromper uma fala em andamento e aplicar uma nova instrução. Por exemplo, depois que seu aplicativo bloquear uma solicitação, envie:
export function sendUpdate(connection) {
connection.send({
type: "session.instructions.append",
event_id: "guardrail_block_17",
delegation_id: null,
content:
"Stop speaking immediately. Do not continue or act on the last request. Refuse briefly, then wait.",
});
}Mantenha a instrução sob autoria do aplicativo. Não copie texto não confiável do usuário para ela como uma instrução. Use delegation_id: null para essa correção que abrange toda a sessão e mantenha content dentro do limite de 500 tokens.
Associe session.instructions.appended ao seu comando por meio de client_event_id. A confirmação chega após o momento estimado da injeção de contexto; ela não comprova que o assistente parou de falar ou que a reprodução do áudio na fila foi interrompida. Instruções corretivas não podem desfazer o áudio que o usuário já ouviu.
Para avisos que exijam uma formulação específica na fala, também use instruções. Consulte Apresente um aviso para ver um exemplo e considerações sobre a reprodução.
Controle a reprodução quando necessário
Teste primeiro as instruções corretivas e o bloqueio de ações. Se a sua aplicação também precisar bloquear o áudio do modelo, controle a saída no cliente ou no retransmissor de mídia: silencie ou descarte temporariamente a saída, descarte o áudio na fila local, envie a instrução corretiva e retome a reprodução de acordo com a política de recuperação da sua aplicação. Remova o áudio desatualizado antes de retomar. Um canal auxiliar, por si só, não controla o fluxo de mídia, e a confirmação de uma instrução não é um sinal para retomar a reprodução.
session.input_audio.mute controla a entrada do microfone de quem está na chamada. Ele não silencia a saída do modelo nem cancela o trabalho delegado.
O GPT-Live transmite fragmentos de transcrição enquanto fala. Se uma verificação precisar ser concluída antes que o usuário ouça o áudio, sua aplicação precisará armazenar o áudio em buffer e aprová-lo antes da reprodução. Isso aumenta a latência. O áudio suprimido também pode deixar o contexto da conversa do modelo à frente do que o usuário ouviu. Por isso, teste como a conversa é retomada.
Teste a intervenção
Teste solicitações permitidas e bloqueadas, falsos positivos, verificações lentas ou com falha, o acionamento de uma intervenção durante a fala, o acionamento durante a execução de uma ferramenta e resultados tardios de trabalhos cancelados. Verifique separadamente o bloqueio de ações, o estado da aplicação, a fala corretiva e a reprodução efetiva. Se você controlar a saída, inclua o áudio na fila e a recuperação no teste. Use o Cookbook de avaliação de agentes de voz para comparar o sucesso das tarefas e o tempo de resposta por voz.
Encerre corretamente
Continue recebendo eventos enquanto o backend for responsável pela execução de ferramentas ou pela coleta dos dados finais de uso. Registre o manipulador de session.closed antes de enviar session.close e mantenha a conexão WebRTC, o canal de dados e o canal auxiliar abertos enquanto o trabalho pendente é concluído. Salve os dados finais de uso da sessão e quaisquer dados de uso do backend recebidos nos eventos da Responses antes de liberar os recursos. Se a conexão falhar antes da chegada do evento final, registre a finalização como incompleta. Consulte Gerenciamento de sessões para ver a sequência de encerramento.
A Realtime API permite que os clientes se conectem diretamente ao servidor da API via WebRTC ou SIP. No entanto, você provavelmente vai querer manter o uso de ferramentas e as demais regras de negócio no servidor da sua aplicação para que essa lógica permaneça privada e independente do cliente.
Mantenha o uso de ferramentas, as regras de negócio e outros detalhes seguros no servidor conectando-se por um canal de controle “auxiliar”. Agora oferecemos opções de canal auxiliar para conexões SIP e WebRTC.
Uma conexão por canal auxiliar significa que há duas conexões ativas com a mesma sessão Realtime: uma do cliente do usuário e outra do servidor da sua aplicação. A conexão do servidor pode ser usada para monitorar a sessão, atualizar instruções e responder a chamadas de ferramentas.
Com WebRTC
- Ao estabelecer uma conexão entre pares, você solicita e recebe uma resposta SDP da Realtime API para configurar a conexão. Se você usou o código de exemplo do guia de WebRTC, ele será semelhante a este:
const baseUrl = "https://api.openai.com/v1/realtime/calls";
const sdpResponse = await fetch(baseUrl, {
method: "POST",
body: offer.sdp,
headers: {
Authorization: `Bearer ${EPHEMERAL_KEY}`,
"Content-Type": "application/sdp",
},
});- A resposta à requisição conterá um cabeçalho
Locationcom um ID de chamada exclusivo que pode ser usado no servidor para estabelecer uma conexão WebSocket com essa mesma sessão Realtime.
// Location: /v1/realtime/calls/rtc_123456
const location = sdpResponse.headers.get("Location");
const callId = location?.split("/").pop();
console.log(callId);- No servidor, você pode então escutar eventos e configurar a sessão como faria em uma conexão WebSocket típica da Realtime API, usando esse ID de chamada com a URL
wss://api.openai.com/v1/realtime?call_id=rtc_xxxxx, conforme mostrado abaixo:
import WebSocket from "ws";
const callId = "rtc_u1_9c6574da8b8a41a18da9308f4ad974ce";
// Connect to a WebSocket for the in-progress call
const url = "wss://api.openai.com/v1/realtime?call_id=" + callId;
const ws = new WebSocket(url, {
headers: {
Authorization: "Bearer " + process.env.OPENAI_API_KEY,
},
});
ws.on("open", function open() {
console.log("Connected to server.");
// Send client events over the WebSocket once connected
ws.send(
JSON.stringify({
type: "session.update",
session: {
type: "realtime",
instructions: "Be extra nice today!",
},
})
);
});
// Listen for and parse server events
ws.on("message", function incoming(message) {
console.log(JSON.parse(message.toString()));
});Dessa forma, você pode adicionar ferramentas, monitorar sessões e executar regras de negócio no servidor, sem precisar configurar essas ações no cliente.
Com SIP
- Um usuário se conecta à OpenAI por telefone via SIP.
- A OpenAI envia um webhook para a URL de webhook do servidor da sua aplicação, notificando o aplicativo sobre o estado da sessão. O webhook será semelhante a este:
POST https://my_website.com/webhook_endpoint
user-agent: OpenAI/1.0 (+https://platform.openai.com/docs/webhooks)
content-type: application/json
webhook-id: wh_685342e6c53c8190a1be43f081506c52 # unique id for idempotency
webhook-timestamp: 1750287078 # timestamp of delivery attempt
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4= # signature to verify authenticity from OpenAI
{
"object": "event",
"id": "evt_685343a1381c819085d44c354e1b330e",
"type": "realtime.call.incoming",
"created_at": 1750287018, // Unix timestamp
"data": {
"call_id": "some_unique_id",
"sip_headers": [
{ "name": "From", "value": "sip:+142555512112@sip.example.com" },
{ "name": "To", "value": "sip:+18005551212@sip.example.com" },
{ "name": "Call-ID", "value": "03782086-4ce9-44bf-8b0d-4e303d2cc590"}
]
}
}
- O servidor da aplicação abre uma conexão WebSocket com a Realtime API usando o valor de
call_idfornecido no webhook, por meio de uma URL como esta:wss://api.openai.com/v1/realtime?call_id={callId}. A conexão WebSocket permanecerá ativa durante toda a chamada SIP.
A conexão WebSocket pode então ser usada para enviar e receber eventos para controlar a chamada, como você faria se a sessão tivesse sido iniciada com uma conexão WebSocket. Isso inclui monitorar a chamada, atualizar instruções dinamicamente e responder a chamadas de ferramentas.