Qwen-Audio-Realtime API WebSocket
Qwen-Audio-Realtime Protocolo de conexão WebSocket, cabeçalhos de solicitação, conceitos básicos e fluxos de interação
O Qwen-Audio A API em tempo real fornece conversação por voz em tempo real via WebSocket. O cliente interage com o servidor enviando e recebendo eventos JSON, suportando entrada de voz, entrada de texto, detecção de atividade de voz (VAD) e streaming de voz e saída de texto.
Guia do usuário: Conversa por voz em tempo real (Qwen-Audio-Realtime). Para obter detalhes sobre eventos de cliente e servidor, consulte Eventos de cliente e Eventos do servidor.
Terminal de serviço
Use o seguinte URL do WebSocket. O model parâmetro de consulta especifica o modelo a ser chamado (substitua <model_name> com o nome real do modelo):
wss://maas.qwencloudapi.com/api-ws/v1/realtime?model=<model_name>
A URL deve usar o wss:// esquema. Defina autorização nos cabeçalhos da solicitação; especifique o modelo através do model parâmetro de consulta.
Solicitar cabeçalhos
Inclua os seguintes campos nos cabeçalhos da solicitação:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Autorização | corda | Sim | Token de autenticação no formato Bearer $DASHSCOPE_API_KEY. Substituir $DASHSCOPE_API_KEY com sua chave de API real. |
| agente do usuário | corda | Não | Identificador do cliente que ajuda o servidor a rastrear fontes de solicitação. |
| X-DashScope-WorkSpace | corda | Não | QwenCloud ID do espaço de trabalho. |
A autorização é verificada durante o handshake do WebSocket. Se a chave de API for inválida ou estiver ausente, o handshake falhará com um erro HTTP 401 ou 403.
Conceitos básicos
- Sessão: Cada conexão WebSocket corresponde a uma sessão, que mantém a configuração e o contexto da conversa.
- Item de conversa: cada mensagem na conversa, organizada como uma lista vinculada em ordem.
- Resposta: A saída produzida por uma rodada de inferência de modelo, contendo um ou mais itens de saída. Um item de saída pode ser uma mensagem do assistente ou uma chamada de função.
- Chamada de função: um item de saída produzido quando o modelo solicita ao cliente que execute uma função de ferramenta. Após a execução, o cliente escreve de volta o resultado via
function_call_outpute desencadeia a próxima rodada de inferência comresponse.create. - Detecção de curva: controla quando a inferência é acionada.
Modos de interação
O Qwen-Audio A API Realtime oferece suporte a três modos de interação, configurados por meio do turn_detection.type parâmetro no session.update evento:
| Modo | turn_detection.type | Descrição | Caso de uso |
|---|---|---|---|
| servidor_vad | server_vad |
O servidor usa VAD para detectar o início e o fim da fala e acionar automaticamente a inferência. | Conversa em viva-voz, assistentes de voz |
| inteligente_turn | smart_turn |
Combina a percepção acústica com a compreensão semântica para determinar os limites das curvas, em vez de depender apenas de sinais de voz. Sons não semânticos (como "um" ou "uh") não acionam uma virada de conversa nem interrompem a reprodução do modelo. | Conversa natural de baixa latência, interrupção de alta qualidade |
| aperte para falar | null |
O cliente envia áudio manualmente e aciona manualmente a inferência. | Controle preciso e push-to-talk |
Fluxos de interação
Para obter detalhes sobre eventos de cliente e servidor, consulte Eventos de cliente e Eventos do servidor.
modo servidor_vad
O servidor realiza detecção de atividade de voz no áudio recebido e aciona automaticamente a inferência assim que detecta o fim da fala.
Para ativar: Definir turn_detection.type para server_vad no session.update evento.
Uma conversa completa
Em ordem cronológica, o cliente e o servidor interagem da seguinte forma:
- O cliente estabelece uma conexão WebSocket; o servidor retorna um
session.createdevento. - O cliente envia
session.updateconfigurar parâmetros de sessão; o servidor retornasession.updated. - O cliente envia continuamente
input_audio_buffer.appendeventos para anexar dados de áudio. - O servidor detecta o início da fala e retorna
input_audio_buffer.speech_started, enquanto transmite transcrição ASR incremental viaconversation.item.input_audio_transcription.delta. - O servidor detecta o fim da fala e retorna
input_audio_buffer.speech_stopped,input_audio_buffer.committedeconversation.item.created. - O servidor gera automaticamente uma resposta, streaming de texto e deltas de áudio (
response.audio_transcript.delta,response.audio.delta) e finalmente retornaresponse.done.
Sequência completa do evento:
| Fase | Direção | Evento |
|---|---|---|
| Inicialização da sessão | Cliente -> Servidor | connect |
| Servidor -> Cliente | session.created |
|
| Cliente -> Servidor | session.update |
|
| Servidor -> Cliente | session.updated |
|
| Entrada de voz (loop) | Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
| Servidor -> Cliente | input_audio_buffer.speech_started |
|
| Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
|
| Servidor -> Cliente | conversation.item.input_audio_transcription.delta (transmitido) |
|
| Servidor -> Cliente | input_audio_buffer.speech_stopped |
|
| Servidor -> Cliente | conversation.item.input_audio_transcription.completed |
|
| Servidor (interno) | confirmar buffer de áudio | |
| Servidor -> Cliente | input_audio_buffer.committed |
|
| Servidor -> Cliente | conversation.item.created |
|
| Geração de resposta | Servidor -> Cliente | response.created |
| Servidor -> Cliente | response.output_item.added |
|
| Servidor -> Cliente | conversation.item.created |
|
| Servidor -> Cliente | response.content_part.added |
|
| Saída de streaming (loop) | Servidor -> Cliente | response.audio_transcript.delta (transmitido) |
| Servidor -> Cliente | response.audio.delta (transmitido) |
|
| Saída concluída | Servidor -> Cliente | response.audio_transcript.done |
| Servidor -> Cliente | response.audio.done |
|
| Servidor -> Cliente | response.content_part.done |
|
| Servidor -> Cliente | response.output_item.done |
|
| Servidor -> Cliente | response.done |
Interrupção do usuário
Se o VAD detectar que o usuário está começando a falar enquanto o modelo está reproduzindo uma resposta, o servidor cancela a resposta atual (retornando response.done com status cancelled) e, em seguida, inicia uma nova rodada de entrada e resposta de voz.
Sequência de eventos de interrupção:
- O servidor está transmitindo
response.audio.delta(laço). - O cliente envia
input_audio_buffer.append(o usuário começa a falar). - O servidor retorna
response.done(status=cancelled), cancelando a resposta atual. - O servidor retorna
input_audio_buffer.speech_started. - O cliente continua enviando
input_audio_buffer.append; os fluxos do servidorconversation.item.input_audio_transcription.delta. - O servidor detecta o fim da fala e retorna
input_audio_buffer.speech_stoppedeconversation.item.input_audio_transcription.completed. - O servidor confirma o buffer de áudio internamente, retornando
input_audio_buffer.committedeconversation.item.created. - O servidor inicia automaticamente uma nova rodada de inferência e retorna
response.created.
modo inteligente_turn
Combina percepção acústica com compreensão semântica para detectar o final da fala, filtrando backchannels, ruído de fundo e outros sons sem significado. Sons não semânticos são transmitidos através do conversation.item.ambient_audio_transcription.delta evento e não aciona um turno de conversa.
Para ativar: Definir turn_detection.type para smart_turn no session.update evento.
Uma conversa completa
Principais diferenças do modo server_vad:
- Sons não semânticos (como “um” ou “uh”) não desencadeiam inferência; em vez disso, eles são devolvidos através do
ambient_audio_transcriptioneventos. - Discurso inicialmente julgado válido poderá posteriormente ser retratado (
input_audio_buffer.speech_stoppedretorna comreason=turn_invalid), caso em que a inferência não é acionada. - Enquanto aguarda a próxima entrada do usuário, o cliente pode enviar explicitamente
response.createpara desencadear inferência.
Sequência completa do evento:
| Fase | Direção | Evento |
|---|---|---|
| Inicialização da sessão | Cliente -> Servidor | connect |
| Servidor -> Cliente | session.created |
|
| Cliente -> Servidor | session.update |
|
| Servidor -> Cliente | session.updated |
|
| Entrada de voz (loop) | Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
| Fala inválida (0 a N vezes) | Servidor -> Cliente | conversation.item.ambient_audio_transcription.delta (transmitido) |
| Servidor -> Cliente | conversation.item.ambient_audio_transcription.completed |
|
| Entrada de fala válida | Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
| Servidor -> Cliente | input_audio_buffer.speech_started |
|
| Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
|
| Servidor -> Cliente | conversation.item.input_audio_transcription.delta (transmitido) |
|
| Servidor -> Cliente | input_audio_buffer.speech_stopped |
|
| Servidor -> Cliente | conversation.item.input_audio_transcription.completed |
|
| Servidor (interno) | confirmar buffer de áudio | |
| Servidor -> Cliente | input_audio_buffer.committed |
|
| Servidor -> Cliente | conversation.item.created |
|
| Geração de resposta | Servidor -> Cliente | response.created |
| Servidor -> Cliente | response.output_item.added |
|
| Servidor -> Cliente | conversation.item.created |
|
| Servidor -> Cliente | response.content_part.added |
|
| Saída de streaming (loop) | Servidor -> Cliente | response.audio_transcript.delta (transmitido) |
| Servidor -> Cliente | response.audio.delta (transmitido) |
|
| Saída concluída | Servidor -> Cliente | response.audio_transcript.done |
| Servidor -> Cliente | response.audio.done |
|
| Servidor -> Cliente | response.content_part.done |
|
| Servidor -> Cliente | response.output_item.done |
|
| Servidor -> Cliente | response.done |
Interrupção do usuário
O tratamento de interrupções é basicamente o mesmo que no modo server_vad:
- O servidor está transmitindo
response.audio.delta(laço). - O cliente envia
input_audio_buffer.append(o usuário começa a falar). - O servidor retorna
response.done(status=cancelled), cancelando a resposta atual. - O servidor retorna
input_audio_buffer.speech_started. - O cliente continua enviando
input_audio_buffer.append; os fluxos do servidorconversation.item.input_audio_transcription.delta. - O servidor retorna
conversation.item.input_audio_transcription.completedeinput_audio_buffer.speech_stopped. - O servidor confirma o buffer de áudio internamente, retornando
input_audio_buffer.committedeconversation.item.created. - O servidor inicia automaticamente uma nova rodada de inferência e retorna
response.created.
Turnos inválidos
Discurso inicialmente julgado válido poderá posteriormente ser retratado (input_audio_buffer.speech_stopped retorna com reason=turn_invalid), caso em que a inferência não é acionada. O cliente deverá continuar enviando áudio e aguardar o próximo turno de fala válido.
Sequência de eventos de turno inválida:
- O cliente envia continuamente
input_audio_buffer.append. - O servidor retorna
input_audio_buffer.speech_started. - O cliente continua enviando
input_audio_buffer.append; os fluxos do servidorconversation.item.input_audio_transcription.delta. - O servidor retorna
input_audio_buffer.speech_stopped(motivo=turn_inválido). - O cliente continua enviando áudio, aguardando o próximo turno de fala válido.
Fluxo de registro de impressão de voz
No modo smart_turn, quando voiceprint_audio_urls está incluído no primeiro session.update, o servidor executa o registro de impressão de voz de forma assíncrona (carregando os recursos de áudio do locutor alvo) e notifica o progresso do registro por meio de eventos. Uma falha no registro de impressão de voz não bloqueia o fluxo normal da conversa.
Em ordem cronológica, o fluxo de interação de registro de impressão de voz é o seguinte:
- O cliente envia
session.update, incluindo o URL do áudio de impressão de voz emturn_detection.voiceprint_audio_urls; o servidor retornasession.updated. - O servidor inicia imediatamente o registro de impressão de voz de forma assíncrona, pressionando um
voiceprint_audio_list.in_progressevento antes de retornarsession.updated, carregando um únicoitem_idpara esta tarefa de inscrição. - O servidor retorna
session.updated, confirmando que a configuração da sessão entrou em vigor. - Após a conclusão do registro de impressão de voz, o servidor envia um evento de terminal (com o mesmo
item_idcomo na etapa 2):- Em caso de sucesso:
voiceprint_audio_list.completed. - Em caso de falha:
voiceprint_audio_list.failed, com umreasoncampo explicando a falha (por exemplo, não foi possível fazer download do URL do áudio).
- Em caso de sucesso:
voiceprint_audio_urls só entra em vigor no primeiro session.update. As ocorrências subsequentes deste campo são ignoradas.
modo apertar para falar
O cliente controla manualmente o envio de áudio e o disparo de inferência. Adequado para cenários push-to-talk.
Para ativar: Definir turn_detection para null no session.update evento.
Uma conversa completa
Em ordem cronológica, o cliente e o servidor interagem da seguinte forma:
- O cliente envia continuamente
input_audio_buffer.appendeventos para anexar dados de áudio. - Após o usuário terminar de falar, o cliente envia
input_audio_buffer.commitpara confirmar o buffer. - O cliente envia
response.createpara acionar manualmente a inferência. - O servidor gera uma resposta, transmitindo texto e áudio.
Sequência completa do evento:
| Fase | Direção | Evento |
|---|---|---|
| Inicialização da sessão | Cliente -> Servidor | connect |
| Servidor -> Cliente | session.created |
|
| Cliente -> Servidor | session.update |
|
| Servidor -> Cliente | session.updated |
|
| Entrada de voz (loop) | Cliente -> Servidor | input_audio_buffer.append (enviado continuamente) |
| Servidor -> Cliente | conversation.item.input_audio_transcription.delta (transmitido) |
|
| Confirmação manual | Cliente -> Servidor | input_audio_buffer.commit (o usuário libera a tecla push to talk) |
| Servidor -> Cliente | conversation.item.input_audio_transcription.completed |
|
| Servidor -> Cliente | input_audio_buffer.committed |
|
| Servidor -> Cliente | conversation.item.created |
|
| Acionar inferência manualmente | Cliente -> Servidor | response.create (aciona inferência manualmente) |
| Geração de resposta | Servidor -> Cliente | response.created |
| Servidor -> Cliente | response.output_item.added |
|
| Servidor -> Cliente | conversation.item.created |
|
| Servidor -> Cliente | response.content_part.added |
|
| Saída de streaming (loop) | Servidor -> Cliente | response.audio_transcript.delta (transmitido) |
| Servidor -> Cliente | response.audio.delta (transmitido) |
|
| Saída concluída | Servidor -> Cliente | response.audio_transcript.done |
| Servidor -> Cliente | response.audio.done |
|
| Servidor -> Cliente | response.content_part.done |
|
| Servidor -> Cliente | response.output_item.done |
|
| Servidor -> Cliente | response.done |
Interrupção do usuário
O cliente envia response.cancel para cancelar a resposta atual; o servidor retorna response.done (estado cancelled, razão client_cancelled).
Sequência de eventos de interrupção:
- O servidor está transmitindo
response.audio_transcript.deltaeresponse.audio.delta(laço). - O cliente envia
response.cancel. - O servidor retorna
response.done(status=cancelado, motivo=cliente_cancelado). - O cliente continua enviando
input_audio_buffer.append; os fluxos do servidorconversation.item.input_audio_transcription.delta. - O cliente envia
input_audio_buffer.commitpara confirmar o buffer. - O servidor retorna
conversation.item.input_audio_transcription.completed,input_audio_buffer.committedeconversation.item.created. - O cliente envia
response.createpara acionar manualmente uma nova rodada de inferência. - O servidor retorna
response.created, iniciando uma nova rodada de resposta.
Restrições de operação por modo
| Operação | aperte para falar | servidor_vad | inteligente_turn |
|---|---|---|---|
| sessão.atualização | Todos os campos podem ser alterados quando IDLE; alguns são restritos quando não estão IDLE | Todos os campos podem ser alterados quando IDLE; alguns são restritos quando não estão IDLE | Todos os campos podem ser alterados quando IDLE; alguns são restritos quando não estão IDLE |
| input_audio_buffer.append | Permitido | Permitido | Permitido |
| input_audio_buffer.commit | Permitido | Ignorado | Ignorado |
| entrada_audio_buffer.clear | Permitido | Ignorado | Ignorado |
| resposta.criar | Permitido (requer commit do buffer via input_audio_buffer.commit primeiro; não permitido enquanto uma resposta já estiver sendo gerada) |
Permitido quando nenhuma resposta está sendo gerada no momento; não permitido enquanto uma resposta já estiver sendo gerada | Permitido enquanto aguarda a próxima entrada do usuário; não permitido dentro de um turno ativo (de input_audio_buffer.speech_started para response.done) |
| resposta.cancelar | Permitido (durante a inferência) | Permitido (durante a inferência) | Permitido (durante a inferência) |
| conversa.item.create/delete/retrieve | Permitido | Permitido | Permitido |
turn_detection e input_audio_format só pode ser alterado antes do primeiro áudio ser enviado (estado IDLE).
Tratamento de erros
| Tipo | Comportamento | Exemplo |
|---|---|---|
Erro do cliente (invalid_request_error) |
A conexão permanece aberta; cliente só é notificado | Parâmetros inválidos, estado não permitido, item_id duplicado |
Erro no servidor (server_error) |
A conexão foi encerrada | Falha de conexão LLM, falha de armazenamento |