Configurar o streaming para respostas de LLM e outros tráfegos
Neste documento, descrevemos como configurar o streaming no gateway de API.
O gateway de API é compatível com streaming. O streaming permite que os gateways atendam conexões de longa duração e transmitam dados em partes para streaming de solicitação e resposta.
Um uso comum do streaming é a veiculação de um modelo de linguagem grande (LLM). O modelo envia a resposta um token por vez, para que um cliente possa mostrar o texto enquanto o modelo ainda está gerando. Para um exemplo completo que transmite respostas de um modelo do Gemma que o vLLM disponibiliza no Cloud Run, consulte Transmitir respostas de um LLM.
Protocolos de streaming compatíveis
Quando ativado, o gateway de API é compatível com os seguintes métodos de streaming:
- Entrega incremental de respostas: quadros DATA HTTP/2 ou codificação de transferência em blocos HTTP/1.1, dependendo do que o cliente negocia.
- Eventos enviados pelo servidor (SSE): streaming unidirecional do servidor para o cliente.
- WebSockets: canais de comunicação full-duplex em uma única conexão TCP.
- Streaming bidirecional gRPC: streaming full-duplex usando gRPC.
Pré-requisitos
Antes de usar o streaming, verifique se o serviço de back-end é compatível com o protocolo necessário (por exemplo, HTTP/2 ou WebSockets) e se a configuração da API está definida corretamente.
Configurar o protocolo de back-end
Para oferecer suporte ao tráfego de streaming, configure o protocolo do back-end com base no tipo de streaming:
- gRPC: configure seu back-end para usar HTTP/2 (
h2). - WebSockets: use
http/1.1. Os WebSockets exigem o handshakeConnection: Upgradedo HTTP/1.1. - Eventos enviados pelo servidor (SSE) e entrega incremental de respostas: seu back-end pode usar HTTP/1.1 ou HTTP/2 (
h2). Recomendamos o HTTP/2 (h2) para melhorar o desempenho.
Na especificação OpenAPI, configure o protocolo de back-end da seguinte maneira:
Exemplo (OpenAPI 3.x)
Defina o campo protocol na definição de back-end nomeada dentro do objeto x-google-api-management.backends. Você também precisa fazer referência a esse back-end usando x-google-backend na raiz ou no nível da operação.
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2 # Use 'http/1.1' for WebSockets
x-google-backend: gemma
Exemplo (OpenAPI 2.0)
Defina o campo protocol na extensão x-google-backend.
x-google-backend:
address: https://my-gemma-service.run.app
protocol: h2 # Use 'http/1.1' for WebSockets
Definir o prazo do stream
O campo deadline controla por quanto tempo uma solicitação (unária ou de streaming) pode ser executada.
A tabela a seguir mostra como os tempos limite se aplicam a cada tipo de solicitação:
| Método | Tempo limite de inatividade (intervalo máximo entre mensagens) |
Tempo limite da solicitação (duração total máxima da solicitação) |
|---|---|---|
| Não streaming | N/A: o tempo limite de inatividade se aplica apenas a streams | O padrão é 15 segundos. Defina deadline para mudar esse valor, até 3.600 segundos para gateways compatíveis com streaming. |
| Streaming por HTTP (SSE, transferência em partes) |
N/A aplicável: efetivamente infinito. Somente o tempo limite da solicitação encerra o fluxo. | O padrão é 15 segundos. Defina deadline para mudar esse valor, até 3.600 segundos para gateways compatíveis com streaming. |
| Streaming por gRPC ou WebSockets | O padrão é 300 segundos. Defina deadline para mudar esse valor, até 3.600 segundos para gateways compatíveis com streaming. Em WebSockets, um deadline de menos de 300 segundos é ignorado, e um mínimo de 300 segundos é aplicado. |
Sempre 3.600 segundos para gateways habilitados para streaming, não configurável |
Exemplo (OpenAPI 3.x)
Defina o campo deadline na definição do back-end nomeado.
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 3600.0
x-google-backend: gemma
Exemplo (OpenAPI 2.0)
Defina o campo deadline na extensão x-google-backend.
x-google-backend:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 3600.0
Para os outros limites que se aplicam a conexões de streaming, consulte Limitações.
Ativar o streaming em um gateway
O streaming é especificado no momento da criação do gateway. Observe o seguinte comportamento:
- Nenhuma desativação explícita: não há uma flag para desativar explicitamente o streaming. Se você omitir a flag
--enable-streaming, o gateway de API vai resolver o modo na criação com base na configuração da API e no padrão da plataforma. Uma configuração de API que configura um roteador de modelo sempre produz um gateway de streaming. Leia o campoeffectiveStreamingModesomente de saída do gateway para conferir o modo em que ele foi criado. - Imutabilidade: o modo de streaming é fixado na criação e não pode ser modificado depois.
Para especificar o streaming em um gateway, use a flag --enable-streaming com o comando gcloud api-gateway gateways create:
gcloud api-gateway gateways create GATEWAY_ID \
--api=API_ID \
--api-config=CONFIG_ID \
--location=GCP_REGION \
--enable-streamingPara mais informações sobre as opções de implantação de gateway, consulte Implantar uma API em um gateway.
Propriedades de streaming do gateway
Os campos a seguir no recurso Gateway controlam o comportamento de streaming:
| Campo | Atributos | Valores |
|---|---|---|
streamingMode |
String (IMMUTABLE, OPTIONAL) |
|
effectiveStreamingMode |
String (OUTPUT_ONLY) |
|
Ao usar a API REST para criar um gateway, é possível especificar o streaming no corpo da solicitação:
{
"apiConfig": "projects/...",
"streamingMode": "STREAMING_MODE_ENABLED"
}
Verificar se o streaming está ativado
Para confirmar se o streaming está ativo no gateway, descreva-o usando a CLI gcloud:
gcloud api-gateway gateways describe GATEWAY_ID \
--location=GCP_REGIONProcure o campo effectiveStreamingMode na saída. Se o streaming estiver ativado, a saída vai incluir:
effectiveStreamingMode: EFFECTIVE_STREAMING_MODE_ENABLED
Transmitir respostas de um LLM
Este exemplo coloca um gateway de streaming na frente de um modelo do Gemma que o vLLM disponibiliza no Cloud Run e transmite uma conclusão de chat pelo gateway. O vLLM disponibiliza uma API compatível com a OpenAI que transmite respostas como eventos enviados pelo servidor (SSE, na sigla em inglês).
Antes de começar, conclua Configurar o ambiente de desenvolvimento, incluindo Configurar a conta de serviço usada para criar configurações de API. O gateway usa essa conta de serviço para chamar o serviço do Cloud Run.
Implantar o modelo
Implante um modelo Gemma seguindo as instruções em Implantar um modelo Gemma 4 com um contêiner vLLM. Anote o nome do serviço, o URL do serviço, a região e o nome do modelo que você implanta, como google/gemma-4-E4B-it.
Conceder ao gateway acesso ao serviço
O guia implanta o serviço com --no-allow-unauthenticated. O gateway chama o serviço com um token de ID para a conta de serviço, que você transmite como --backend-auth-service-account ao criar a configuração da API. Conceda a essa conta de serviço o papel de invocador do Cloud Run (roles/run.invoker) no serviço:
gcloud run services add-iam-policy-binding SERVICE_NAME \
--region=REGION \
--member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
--role=roles/run.invokerSubstitua:
SERVICE_NAME: o nome do serviço do Cloud RunREGION: a região em que você implantou o serviçoSERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço do gateway
Criar a configuração de API
Salve a especificação OpenAPI a seguir como gemma-api.yaml, substituindo https://my-gemma-service.run.app pelo URL do seu serviço:
openapi: 3.0.3
info:
title: Gemma API
version: 1.0.0
x-google-api-management:
backends:
gemma:
address: https://my-gemma-service.run.app
protocol: h2
deadline: 570.0
x-google-backend: gemma
components:
securitySchemes:
google_id_token:
type: oauth2
flows:
implicit:
authorizationUrl: ""
scopes: {}
x-google-auth:
issuer: https://accounts.google.com
jwksUri: https://www.googleapis.com/oauth2/v3/certs
audiences:
- gemma-api
security:
- google_id_token: []
paths:
/v1/chat/completions:
post:
operationId: createChatCompletion
responses:
'200':
description: A chat completion, streamed as SSE when the request sets "stream" to true.
O deadline de 570 segundos é 30 segundos menor que o --timeout 600 definido pelo guia da Gemma no serviço. Como resultado, o deadline do gateway, e não o tempo limite do serviço, encerra um fluxo que dura muito tempo. Um x-google-backend de nível superior é definido como pathTranslation: APPEND_PATH_TO_ADDRESS por padrão. O gateway anexa o caminho da solicitação ao endereço do back-end. Assim, uma solicitação para /v1/chat/completions chega ao endpoint de conclusão de chat do vLLM.
O requisito security faz com que o gateway rejeite qualquer solicitação que não tenha um token de ID assinado pelo Google com o público-alvo gemma-api. Você pode escolher uma string de público-alvo diferente, desde que os autores da chamada peçam a mesma quando gerarem um token. Para mais informações, consulte Usar tokens de ID do Google para autenticar usuários.
Crie a configuração da API:
gcloud api-gateway api-configs create CONFIG_ID \
--api=API_ID \
--openapi-spec=gemma-api.yaml \
--backend-auth-service-account=SERVICE_ACCOUNT_EMAILSubstitua:
CONFIG_ID: um ID para a configuração da API.API_ID: o ID da API. Se a API não existir, o comando vai criá-la.
Criar o gateway
Crie um gateway de streaming com a configuração de API:
gcloud api-gateway gateways create GATEWAY_ID \
--api=API_ID \
--api-config=CONFIG_ID \
--location=GCP_REGION \
--enable-streamingSubstitua:
GATEWAY_ID: um ID para o gatewayGCP_REGION: a região do gateway, que pode ser diferente deREGION. Para valores permitidos, consulte Implantar uma API em um gateway.
Quando o gateway estiver pronto, extraia o nome do host:
gcloud api-gateway gateways describe GATEWAY_ID \
--location=GCP_REGION \
--format="value(defaultHostname)"Receber um token de ID para o autor da chamada
Uma conta de usuário não pode escolher o público-alvo do token de ID. Por isso, o exemplo cria o token para uma conta de serviço que você representa. Para o autor da chamada, use uma conta de serviço ou crie uma. Para mais informações, consulte Criar contas de serviço. Conceda a si mesmo o papel Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) nessa conta de serviço, que a CLI gcloud precisa representar:
gcloud iam service-accounts add-iam-policy-binding CALLER_SERVICE_ACCOUNT_EMAIL \
--member=user:USER_EMAIL \
--role=roles/iam.serviceAccountTokenCreatorSubstitua:
CALLER_SERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço que chama o gateway.USER_EMAIL: seu endereço de email
Enviar uma solicitação de streaming
Envie uma solicitação de conclusão de chat que defina "stream": true, com um token de ID para a conta de serviço do autor da chamada no cabeçalho Authorization. A flag -N desativa o buffer de saída em curl, para que cada evento seja impresso quando chegar:
curl -N https://DEFAULT_HOSTNAME/v1/chat/completions \
-H "Authorization: Bearer $(gcloud auth print-identity-token \
--impersonate-service-account=CALLER_SERVICE_ACCOUNT_EMAIL \
--audiences=gemma-api)" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_NAME",
"messages": [{"role": "user", "content": "Why is the sky blue?"}],
"stream": true
}'Substitua:
DEFAULT_HOSTNAME: o nome do host do gatewayCALLER_SERVICE_ACCOUNT_EMAIL: a conta de serviço da etapa anterior.MODEL_NAME: o modelo que você implantou, comogoogle/gemma-4-E4B-it
A resposta é um fluxo de SSE. O primeiro evento tem a função assistant, cada evento posterior tem a próxima parte da resposta, e o último evento antes de data: [DONE] define finish_reason. O resultado será o seguinte:
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"prompt_token_ids":null}
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"content":"The"},"logprobs":null,"finish_reason":null,"token_ids":null}]}
...
data: {"id":"chatcmpl-7bcd57ad-1c3c-4779-91be-2973b875e517","object":"chat.completion.chunk","created":1790099706,"model":"google/gemma-4-E4B-it","choices":[{"index":0,"delta":{"content":""},"logprobs":null,"finish_reason":"stop","stop_reason":106,"token_ids":null}]}
data: [DONE]
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste exemplo, exclua o gateway e a configuração da API:
gcloud api-gateway gateways delete GATEWAY_ID \
--location=GCP_REGIONgcloud api-gateway api-configs delete CONFIG_ID \
--api=API_IDSe você criou a API para este exemplo, exclua-a:
gcloud api-gateway apis delete API_ID
Exclua o serviço do Cloud Run:
gcloud run services delete SERVICE_NAME \
--region=REGIONPreços
Durante o pré-lançamento público do streaming, os clientes não recebem cobranças pela saída de rede em gateways habilitados para streaming. No entanto, o faturamento do Service Control ainda se aplica no nível da API, independente da fase de lançamento.
Limitações
As seguintes limitações se aplicam ao streaming no gateway de API durante o pré-lançamento público:
Imutabilidade: não é possível atualizar um gateway para ativar ou desativar o streaming. Você precisa criar um novo gateway. Um gateway habilitado para streaming recebe um formato de nome de host diferente, exigindo que você atualize seus clientes ou registros DNS. Se quiser que atualizemos seu registro de gateway para usar o novo formato, entre em contato com o suporte. O gateway de API usa os seguintes padrões de nome de host:
- Sem streaming:
{gateway_id}-{base36_project_number}.{shard_hash}.gateway.dev, por exemplo,test-gateway-4jcaz8x.uc.gateway.dev - Streaming:
{gateway_id}-{project_number}.{region}.gateway.dev, por exemplo,test-gateway-9876654321.us-central1.gateway.dev - Streaming (legado):
{service}-{tenant_project_number}.{region}.run.app, por exemplo,test-gateway-834512064953.us-central1.run.app. Os gateways criados antes da disponibilidade dos nomes de host regionais*.gateway.devmantêm esse nome de host permanentemente e não são migrados para o novo padrão.
Um novo gateway habilitado para streaming recebe o padrão Streaming. Os dois primeiros exemplos são o mesmo gateway no mesmo projeto: no padrão Streaming, o número do projeto aparece em decimal em vez de base36. Portanto, o primeiro rótulo tem menos espaço do que em um gateway não streaming. O primeiro rótulo é a string
{gateway_id}-{project_number}combinada, que precisa se adequar ao limite de 63 caracteres do rótulo DNS. O limite de 49 caracteres para o ID do gateway mantém o ID dentro desse limite para números de projeto de até 13 dígitos. Um número de projeto mais longo precisa de um ID do gateway mais curto.- Sem streaming:
Terraform: não é possível ativar o streaming usando o Terraform. Isso está previsto para uma versão futura.
Balanceamento de carga e domínios personalizados: gateways com um
effectiveStreamingModedeEFFECTIVE_STREAMING_MODE_ENABLEDnão são compatíveis com o balanceamento de carga HTTP(S) para o gateway de API ou NEGs sem servidor. Não é possível colocar um gateway desse tipo atrás de um NEG sem servidor ou de um balanceador de carga de aplicativo externo. Consequentemente, os domínios personalizados (que dependem do balanceamento de carga) não são compatíveis com esses gateways durante o pré-lançamento público.Comportamento de prazo: ativar o streaming em um gateway não muda o comportamento do campo
deadlineem um caminho de SSE ou transferência em partes. O prazo continua sendo um limite de tempo real para a resposta completa. Portanto, um fluxo é interrompido quando o prazo expira, independentemente da quantidade de dados que ele está enviando. O padrão é 15 segundos e o máximo é 3.600 segundos. Em um WebSocket,deadlinelimita a lacuna entre as mensagens, e a conexão é encerrada após 3.600 segundos. Consulte Definir o prazo da transmissão.Protocolo de Contexto de Modelo (MCP): criar o gateway com
--enable-streamingnão faz um fluxo de endpoint do MCP. As respostas da MCP permanecem um único corpoapplication/json, independentemente do modo de streaming do gateway. Para mais detalhes, consulte Limitações do MCP.