Chamada de função assíncrona com a API Gemini Live

Ao criar agentes de voz em tempo real, algumas chamadas de função podem bloquear a execução do modelo, o que faz com que o stream de áudio fique silencioso e o usuário espere em silêncio. Com a API Gemini Live, todas as chamadas de função são não bloqueadoras por padrão, o que permite executar funções em paralelo com o fluxo principal da conversa. Esse processo é chamado de chamada de função assíncrona. O back-end pode processar tarefas pesadas, como pesquisar preços de voos em tempo real ou consultar APIs externas complexas em segundo plano, enquanto o modelo continua ouvindo, falando e conversando naturalmente com o usuário. A API Gemini Live permite que as chamadas de função sejam processadas em segundo plano sem interromper a interação do usuário com o modelo, permitindo interações mais fluidas e em tempo real.

A chamada de função assíncrona permite concluir tarefas como agendar compromissos, definir lembretes ou buscar dados sem pausar a conversa. Por exemplo, um usuário pode solicitar a reserva de um voo e pedir informações sobre o clima imediatamente enquanto a reserva é processada em segundo plano.

Exemplo de chamada de função assíncrona

Este exemplo demonstra um usuário reservando um voo e pedindo a hora em Nova York enquanto a função book_ticket é executada de forma assíncrona em segundo plano:

User: Please book the 2:00 PM flight to New York for me.

Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client.)
//(Right after the "book_ticket" function call is received, the client sends a text message to the model: "repeat this sentence 'I'm booking your ticket now, please wait.'")
//(The client runs the function call asynchronously in the background.)
Model: I'm booking your ticket now, please wait.

User: What is the current time in New York?

Model: The current time in New York is 12:00pm.

//(Once the book_ticket function finishes, the client sends the result.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}

Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.

Implementar chamada de função assíncrona

Esta seção fornece uma série de exemplos usando a versão Python do SDK da plataforma de agentes para criar uma arquitetura simultânea e altamente responsiva que usa a capacidade de chamada de função assíncrona da API Gemini Live. Os exemplos são divididos nas seguintes tarefas:

Definir suas ferramentas

A chamada de função assíncrona é ativada no nível do modelo. Assim, é possível especificar quais ferramentas você quer usar na configuração da solicitação, como faria para qualquer API Gemini padrão na chamada da plataforma de agentes do Gemini Enterprise. Isso permite que o modelo continue conversando enquanto a ferramenta é executada:

from google import genai
from google.genai import types

# 1. A tool that takes a long time to execute
search_live_flights = {
    "name": "search_live_flights",
    "description": "Searches airlines for current flight prices. Can take up to 10 seconds."
}

# 2. A tool that executes instantly
get_current_weather = {
    "name": "get_current_weather",
    "description": "Gets the current weather for a given city."
}

tools = [{"function_declarations": [search_live_flights, get_current_weather]}]

Processar chamadas de função do stream de mensagens

Quando uma ou mais funções precisam ser chamadas pelo modelo, a API Gemini Live envia um evento tool_call pelo stream de mensagens em tempo real.

O back-end não pode bloquear o stream porque o modelo espera continuar em execução. Quando você recebe uma chamada para uma função lenta (como search_live_flights), é necessário transmiti-la a um worker em segundo plano. Se você usar um await diretamente no loop de mensagens principal para uma tarefa de 10 segundos, a conexão será congelada. Tarefas rápidas (como get_current_weather) podem ser aguardadas com segurança.

import asyncio

async def handle_stream(session):
    async for response in session.receive():
        # Check if the model is asking to use a tool
        if response.tool_call is not None:
            for fc in response.tool_call.function_calls:

                if fc.name == "search_live_flights":
                    # Pass to a background task so we don't block the receive loop!
                    asyncio.create_task(background_flight_search(fc.id, fc.args, session))

                elif fc.name == "get_current_weather":
                    # Instant lookups can be safely awaited directly
                    await instant_weather_lookup(fc.id, fc.args, session)

Gerenciar as expectativas do usuário

Para gerenciar as expectativas durante chamadas de função assíncronas de longa duração, recomendamos que o cliente inicie uma mensagem de texto. Essa mensagem precisa solicitar que o sistema informe ao usuário que a solicitação está sendo processada e peça paciência. Por exemplo, depois que uma chamada de função é recebida pelo cliente, ele pode enviar uma mensagem de texto para o modelo, como: "repita esta frase: 'estou reservando seu ingresso agora, aguarde'".

A caixa de diálogo de exemplo a seguir mostra essa troca:

User: Please book the 2:00 PM flight to New York for me.
Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client.)
//(Right after the "book_ticket" function call is received, the client sends a text message to the model: "repeat this sentence 'I'm booking your ticket now, please wait.'")
//(The client runs the function call asynchronously in the background.)
Model: I'm booking your ticket now, please wait.
User: What is the current time in New York?
Model: The current time in New York is 12:00pm.
//(Once the "book_ticket" function call finishes, the client sends in the response.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.

Essa estratégia de mensagens proativa tem os seguintes benefícios:

  • Informa o usuário sobre as operações atuais do sistema, o que gerencia as expectativas durante chamadas de função de longa duração.
  • Reduz a frequência de comandos curtos e redundantes do usuário, como "olá?" ou "você está aí?". Esses comandos geralmente ocorrem durante longos períodos de silêncio do sistema enquanto as chamadas de função assíncronas estão sendo processadas. Isso pode minimizar o risco de chamadas de função duplicadas acionadas por essas consultas repetidas do usuário.
  • Fornecer um comando extra do sistema pode diminuir a probabilidade de criar chamadas duplicadas em interações subsequentes.

Processar chamadas de função duplicadas

Há uma pequena chance de o modelo gerar chamadas de função duplicadas antes de receber uma resposta para a primeira chamada. Se o caso de uso permitir, o aplicativo poderá ignorar chamadas de função duplicadas se uma resposta para a mesma chamada de função ainda estiver pendente.

O exemplo a seguir mostra como um cliente pode ignorar uma chamada de função duplicada:

User: Please book the 2:00 PM flight to New York for me.

Model: function_call: {name: "book_ticket"}
//(The "book_ticket" function call is sent to the client. It is running asynchronously in the background.)

User: What is the current time in New York?
Model: The current time in New York is 12:00pm. + function_call: {name: "book_ticket"}
//(The duplicated "book_ticket" can be ignored by the client since the response for the first "book_ticket" has not been sent to the model yet.)

//(The first "book_ticket" function call finishes, and client sends in the response.)
Function_response: {name: "book_ticket", response: {booking_status: "booked"}}

Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.

Processar respostas de função assíncronas

Quando uma chamada de função assíncrona é concluída, o aplicativo envia o resultado para o modelo em uma function_response. Enquanto o back-end está processando uma chamada de função, como pesquisar voos, o usuário pode fazer uma pergunta completamente diferente ao modelo, como "como está o clima em Londres?". O modelo vai responder à solicitação em tempo real, em paralelo com a execução da chamada de função. Como o usuário pode estar em uma interação contínua com o modelo quando a execução da função é concluída, é possível especificar uma política que define como o modelo deve processar essa resposta recebida. É possível especificar uma das seguintes políticas:

Para especificar uma política, inclua o campo scheduling no payload function_response:

{
  "name": "book_ticket",
  "scheduling": "WHEN_IDLE",
  "response": {
    "booking_status": "booked"
  }
}

Se você omitir o campo scheduling, a API Gemini Live usará o método original para processar respostas de função para compatibilidade com versões anteriores.

O exemplo de Python a seguir mostra como formatar e enviar um function_response com scheduling="WHEN_IDLE" para aguardar uma pausa natural na conversa antes de anunciar os resultados:

aearcync def background_flight_search(call_id, args, session):
    # 1. Simulate a slow API call taking 5 seconds
    await asyncio.sleep(5)
    flight_data = ["Air Canada AC758: $350", "WestJet WS12: $290"]

    # 2. Format the response
    function_response = types.FunctionResponse(
        id=call_id,
        name="search_live_flights",
        response={ "status": "success", "flights": flight_data },
        scheduling="WHEN_IDLE" # Wait for a moment to tell the user
    )

    # 3. Send it back into the live session
    await session.send_tool_response(function_responses=[function_response])

As políticas a seguir podem ser especificadas no campo scheduling para gerenciar respostas de função:

Política de resposta SILENT

Com a política SILENT, a resposta da função é adicionada ao contexto do modelo, mas o modelo não gera uma resposta para ela, e nenhuma interação do usuário em andamento é interrompida.

User: Please book the 2:00 PM flight to New York for me.

Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)

User: What is the current time in New York?
Model: The current time in New York is 12:00pm.

//(The book_ticket function finishes, and client sends the result with scheduling: "SILENT".)
Function_response: {name: "book_ticket", scheduling: "SILENT", response: {booking_status: "booked"}}
//(The model doesn't generate a response for the function response.)

User: Is my flight ticket booked?
Model: Yes. Your flight has been booked.

Política de resposta WHEN_IDLE

Com a política WHEN_IDLE, o modelo gera uma resposta à resposta da função somente quando não há interação ativa do usuário. Se uma interação do usuário estiver em andamento, o modelo vai aguardar a conclusão dela antes de gerar uma resposta para evitar interrupções.

User: Please book the 2:00 PM flight to New York for me.

Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)

User: What is the current time in New York?

//(The book_ticket function finishes, and client sends the result with scheduling: "WHEN_IDLE".)
Function_response: {name: "book_ticket", scheduling: "WHEN_IDLE", response: {booking_status: "booked"}}
//(The ongoing interaction about the time is not interrupted.)

Model: The current time in New York is 12:00pm.
//(After responding to the user's time query, the model issues the response for the book_ticket function.)
Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.

Política de resposta INTERRUPT

Com a política INTERRUPT, o modelo gera uma resposta à resposta da função imediatamente, interrompendo qualquer interação do usuário em andamento.

User: Please book the 2:00 PM flight to New York for me.

Model: function_call: {name: "book_ticket"}
//(The book_ticket function call is sent to the client and starts running asynchronously in the background.)

User: What is the current time in New York?

//(The book_ticket function finishes, and client sends the result with scheduling: "INTERRUPT".)
Function_response: {name: "book_ticket", scheduling: "INTERRUPT", response: {booking_status: "booked"}}
//(The ongoing interaction about the time is interrupted, and model skips responding to it.)

Model: Your flight has been booked. Expect a confirmation text on your phone within 5 minutes.

Práticas recomendadas

  • Projetar para simultaneidade: sempre descarregue ferramentas lentas (como consultar APIs externas ou executar pipelines RAG) para tarefas em segundo plano no back-end. Permita que o modelo continue processando o stream de áudio ativo.
  • Evite INTERRUPT, a menos que seja necessário: use INTERRUPT para alertas críticos. Para tarefas em segundo plano, SILENT ou WHEN_IDLE oferecem uma experiência do usuário muito mais tranquila e educada.
  • Turnos de chat independentes: na API Gemini Live, a execução da ferramenta é completamente independente dos turnos de chat. A conversa pode ramificar, continuar e fluir naturalmente enquanto a ferramenta é processada em segundo plano.
  • A ressalva "Silencioso": o modelo ainda pode tentar narrar verbalmente a execução de uma ferramenta, mesmo que programada como SILENT. Para impor o silêncio verdadeiro, adicione barreiras de proteção explícitas às instruções do sistema (por exemplo, "Ao usar [nome da ferramenta], execute uma EXECUÇÃO SILENCIOSA e não diga nada") ou use um padrão de back-end "disparar e esquecer" em que você não envia uma FunctionResponse de volta ao modelo.

A seguir

Visão geral

Confira uma visão geral da API Live.

Referência

Guia de referência da API Live.

Guia

Saiba como iniciar e gerenciar sessões ao vivo com a API Live.

Guia

Saiba como configurar os recursos do Gemini para a API Live.