LLM 응답 및 기타 트래픽 스트리밍 구성

이 문서에서는 API 게이트웨이에서 스트리밍을 구성하는 방법을 설명합니다.

API Gateway는 스트리밍을 지원합니다. 스트리밍을 사용하면 게이트웨이가 장기 실행 연결을 제공하고 요청 및 응답 스트리밍 모두에 대해 데이터를 청크로 전송할 수 있습니다.

스트리밍의 일반적인 용도는 대규모 언어 모델 (LLM)을 제공하는 것입니다. 모델은 한 번에 하나의 토큰씩 답변을 전송하므로 모델이 아직 답변을 생성하는 동안 클라이언트가 텍스트를 표시할 수 있습니다. vLLM이 Cloud Run에서 제공하는 Gemma 모델의 응답을 스트리밍하는 전체 예시는 LLM에서 응답 스트리밍을 참고하세요.

지원되는 스트리밍 프로토콜

사용 설정된 경우 API Gateway는 다음 스트리밍 메서드를 지원합니다.

  • 증분 응답 전송: 클라이언트가 협상하는 내용에 따라 HTTP/2 DATA 프레임 또는 HTTP/1.1 청크 전송 인코딩
  • 서버 전송 이벤트 (SSE): 서버에서 클라이언트로의 단방향 스트리밍입니다.
  • WebSockets: 단일 TCP 연결을 통한 전이중 통신 채널입니다.
  • gRPC 양방향 스트리밍: gRPC를 사용한 전이중 스트리밍입니다.

기본 요건

스트리밍을 사용하려면 백엔드 서비스가 필수 프로토콜 (예: HTTP/2 또는 WebSockets)을 지원하고 API 구성이 올바르게 설정되어 있어야 합니다.

백엔드 프로토콜 구성

스트리밍 트래픽을 지원하려면 스트리밍 유형에 따라 백엔드의 프로토콜을 구성해야 합니다.

  • gRPC: HTTP/2 (h2)를 사용하도록 백엔드를 구성해야 합니다.
  • WebSockets: http/1.1를 사용해야 합니다. WebSocket에는 HTTP/1.1 Connection: Upgrade 핸드셰이크가 필요합니다.
  • 서버 전송 이벤트 (SSE) 및 증분 응답 전송: 백엔드에서 HTTP/1.1 또는 HTTP/2 (h2)를 사용할 수 있습니다. 성능 향상을 위해 HTTP/2 (h2)를 사용하는 것이 좋습니다.

OpenAPI 사양에서 백엔드 프로토콜을 다음과 같이 구성합니다.

예 (OpenAPI 3.x)

x-google-api-management.backends 객체 내의 명명된 백엔드 정의에서 protocol 필드를 설정합니다. 루트 또는 작업 수준에서 x-google-backend를 사용하여 이 백엔드를 참조해야 합니다.

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

예 (OpenAPI 2.0)

x-google-backend 확장 프로그램에서 protocol 필드를 설정합니다.

x-google-backend:
  address: https://my-gemma-service.run.app
  protocol: h2 # Use 'http/1.1' for WebSockets

스트림 기한 설정

deadline 필드는 요청 (단항 또는 스트리밍)이 실행될 수 있는 기간을 관리합니다.

다음 표는 각 요청 종류에 타임아웃이 적용되는 방식을 보여줍니다.

메서드 유휴 상태 제한 시간
(메시지 간 최대 간격)
요청 제한 시간
(최대 총 요청 기간)
비스트리밍 해당 사항 없음: 유휴 제한 시간은 스트림에만 적용됩니다. 기본값은 15초입니다. deadline를 설정하여 변경할 수 있으며 스트리밍 지원 게이트웨이의 경우 최대 3,600초까지 가능합니다.
HTTP를 통한 스트리밍
(SSE, 청크 전송)
해당 사항 없음: 사실상 무한대입니다. 요청 시간 제한만 스트림을 종료합니다. 기본값은 15초입니다. deadline를 설정하여 변경할 수 있으며 스트리밍 지원 게이트웨이의 경우 최대 3,600초까지 가능합니다.
gRPC 또는 WebSocket을 통한 스트리밍 기본값은 300초입니다. deadline를 설정하여 변경할 수 있으며 스트리밍 지원 게이트웨이의 경우 최대 3,600초입니다. WebSocket에서는 deadline이 300초 미만이면 무시되고 300초 최소값이 적용됩니다. 스트리밍 지원 게이트웨이의 경우 항상 3,600초이며 구성할 수 없음

예 (OpenAPI 3.x)

이름이 지정된 백엔드 정의에서 deadline 필드를 설정합니다.

x-google-api-management:
  backends:
    gemma:
      address: https://my-gemma-service.run.app
      protocol: h2
      deadline: 3600.0
x-google-backend: gemma

예 (OpenAPI 2.0)

x-google-backend 확장 프로그램에서 deadline 필드를 설정합니다.

x-google-backend:
  address: https://my-gemma-service.run.app
  protocol: h2
  deadline: 3600.0

스트리밍 연결에 적용되는 기타 한도는 제한사항을 참고하세요.

게이트웨이에서 스트리밍 사용 설정

스트리밍은 게이트웨이 생성 시 지정됩니다. 다음 동작에 유의하세요.

  • 명시적 사용 중지 없음: 스트리밍을 명시적으로 사용 중지하는 플래그가 없습니다. --enable-streaming 플래그를 생략하면 API Gateway는 생성 시 API 구성과 플랫폼 기본값에서 모드를 확인합니다. 모델 라우터를 구성하는 API 구성은 항상 스트리밍 게이트웨이를 생성합니다. 게이트웨이의 출력 전용 effectiveStreamingMode 필드를 읽어 생성된 모드를 확인합니다.
  • 불변성: 스트리밍 모드는 생성 시 고정되며 나중에 수정할 수 없습니다.

게이트웨이에서 스트리밍을 지정하려면 gcloud api-gateway gateways create 명령어와 함께 --enable-streaming 플래그를 사용합니다.

gcloud api-gateway gateways create GATEWAY_ID \
    --api=API_ID \
    --api-config=CONFIG_ID \
    --location=GCP_REGION \
    --enable-streaming

게이트웨이 배포 옵션에 관한 자세한 내용은 게이트웨이에 API 배포를 참고하세요.

게이트웨이 스트리밍 속성

게이트웨이 리소스의 다음 필드는 스트리밍 동작을 제어합니다.

필드 속성 값
streamingMode 문자열 (변경 불가, 선택사항)
  • STREAMING_MODE_UNSPECIFIED (기본값: 서비스에서 모드 선택)
  • STREAMING_MODE_ENABLED
effectiveStreamingMode 문자열 (OUTPUT_ONLY)
  • EFFECTIVE_STREAMING_MODE_DISABLED
  • EFFECTIVE_STREAMING_MODE_ENABLED

REST API를 사용하여 게이트웨이를 만들 때 요청 본문에서 스트리밍을 지정할 수 있습니다.

{
  "apiConfig": "projects/...",
  "streamingMode": "STREAMING_MODE_ENABLED"
}

스트리밍이 사용 설정되어 있는지 확인

게이트웨이에서 스트리밍이 활성 상태인지 확인하려면 gcloud CLI를 사용하여 게이트웨이를 설명합니다.

gcloud api-gateway gateways describe GATEWAY_ID \
    --location=GCP_REGION

출력에서 effectiveStreamingMode 필드를 찾습니다. 스트리밍이 사용 설정된 경우 출력에 다음이 포함됩니다.

effectiveStreamingMode: EFFECTIVE_STREAMING_MODE_ENABLED

LLM의 응답 스트리밍

이 예에서는 vLLM이 Cloud Run에서 제공하는 Gemma 모델 앞에 스트리밍 게이트웨이를 배치하고 게이트웨이를 통해 채팅 완성 기능을 스트리밍합니다. vLLM은 서버 전송 이벤트 (SSE)로 응답을 스트리밍하는 OpenAI 호환 API를 제공합니다.

시작하기 전에 API 구성을 만드는 데 사용되는 서비스 계정 구성을 비롯한 개발 환경 구성을 완료하세요. 게이트웨이는 이 서비스 계정을 사용하여 Cloud Run 서비스를 호출합니다.

모델 배포

vLLM 컨테이너로 Gemma 4 모델 배포에 따라 Gemma 모델을 배포합니다. 서비스 이름, 서비스 URL, 리전, 배포하는 모델 이름(예: google/gemma-4-E4B-it)을 기록해 둡니다.

게이트웨이에 서비스 액세스 권한 부여

가이드에서는 --no-allow-unauthenticated을 사용하여 서비스를 배포합니다. 게이트웨이는 서비스 계정의 ID 토큰을 사용하여 서비스를 호출합니다. 이 토큰은 API 구성을 만들 때 --backend-auth-service-account로 전달됩니다. 서비스에서 해당 서비스 계정에 Cloud Run 호출자 역할 (roles/run.invoker)을 부여합니다.

gcloud run services add-iam-policy-binding SERVICE_NAME \
    --region=REGION \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role=roles/run.invoker

다음을 바꿉니다.

  • SERVICE_NAME: Cloud Run 서비스의 이름
  • REGION: 서비스를 배포한 리전
  • SERVICE_ACCOUNT_EMAIL: 게이트웨이의 서비스 계정 이메일 주소

API 구성 만들기

다음 OpenAPI 사양을 gemma-api.yaml로 저장하고 https://my-gemma-service.run.app을 서비스 URL로 바꿉니다.

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.

570초의 deadline는 Gemma 가이드에서 서비스에 설정한 --timeout 600보다 30초 짧습니다. 따라서 서비스 제한 시간이 아닌 게이트웨이의 deadline가 너무 오래 실행되는 스트림을 종료합니다. 최상위 x-google-backend는 기본적으로 pathTranslation: APPEND_PATH_TO_ADDRESS입니다. 게이트웨이는 요청 경로를 백엔드 주소에 추가하므로 /v1/chat/completions에 대한 요청이 vLLM 채팅 완성 엔드포인트에 도달합니다.

security 요구사항으로 인해 게이트웨이는 잠재고객 gemma-api이 포함된 Google 서명 ID 토큰을 전달하지 않는 요청을 거부합니다. 호출자가 토큰을 생성할 때 동일한 문자열을 요청하는 한 다른 대상 문자열을 선택할 수 있습니다. 자세한 내용은 Google ID 토큰을 사용하여 사용자 인증을 참고하세요.

API 구성을 만듭니다.

gcloud api-gateway api-configs create CONFIG_ID \
    --api=API_ID \
    --openapi-spec=gemma-api.yaml \
    --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL

다음을 바꿉니다.

  • CONFIG_ID: API 구성의 ID
  • API_ID: API의 ID입니다. API가 없으면 명령어가 API를 만듭니다.

게이트웨이 만들기

API 구성에서 스트리밍 게이트웨이를 만듭니다.

gcloud api-gateway gateways create GATEWAY_ID \
    --api=API_ID \
    --api-config=CONFIG_ID \
    --location=GCP_REGION \
    --enable-streaming

다음을 바꿉니다.

  • GATEWAY_ID: 게이트웨이의 ID
  • GCP_REGION: 게이트웨이의 리전입니다. REGION와 다를 수 있습니다. 허용되는 값은 게이트웨이에 API 배포를 참고하세요.

게이트웨이가 준비되면 호스트 이름을 가져옵니다.

gcloud api-gateway gateways describe GATEWAY_ID \
    --location=GCP_REGION \
    --format="value(defaultHostname)"

호출자의 ID 토큰 가져오기

사용자 계정은 ID 토큰의 대상을 선택할 수 없으므로 이 예에서는 사용자가 가장하는 서비스 계정의 토큰을 생성합니다. 호출자의 경우 기존 서비스 계정을 사용하거나 서비스 계정을 만듭니다. 자세한 내용은 서비스 계정 만들기를 참고하세요. gcloud CLI가 서비스 계정을 가장하는 데 필요한 서비스 계정 토큰 생성자 역할 (roles/iam.serviceAccountTokenCreator)을 자신에게 부여합니다.

gcloud iam service-accounts add-iam-policy-binding CALLER_SERVICE_ACCOUNT_EMAIL \
    --member=user:USER_EMAIL \
    --role=roles/iam.serviceAccountTokenCreator

다음을 바꿉니다.

  • CALLER_SERVICE_ACCOUNT_EMAIL: 게이트웨이를 호출하는 서비스 계정의 이메일 주소
  • USER_EMAIL: 이메일 주소

스트리밍 요청 보내기

Authorization 헤더에 호출자 서비스 계정의 ID 토큰이 포함된 "stream": true을 설정하는 채팅 완성 요청을 전송합니다. -N 플래그는 curl에서 출력 버퍼링을 사용 중지하므로 각 이벤트는 도착할 때 출력됩니다.

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
    }'

다음을 바꿉니다.

  • DEFAULT_HOSTNAME: 게이트웨이의 호스트 이름
  • CALLER_SERVICE_ACCOUNT_EMAIL: 이전 단계의 서비스 계정
  • MODEL_NAME: 배포한 모델(예: google/gemma-4-E4B-it)

대답은 SSE 스트림입니다. 첫 번째 이벤트는 assistant 역할을 수행하고, 각 후속 이벤트는 대답의 다음 부분을 전달하며, data: [DONE] 전의 마지막 이벤트는 finish_reason을 설정합니다. 출력은 다음과 비슷합니다.

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]

삭제

이 예시에서 사용한 리소스에 대한 비용이 Google Cloud 계정에 청구되지 않도록 하려면 게이트웨이와 API 구성을 삭제하세요.

gcloud api-gateway gateways delete GATEWAY_ID \
    --location=GCP_REGION
gcloud api-gateway api-configs delete CONFIG_ID \
    --api=API_ID

이 예의 API를 만든 경우 삭제합니다.

gcloud api-gateway apis delete API_ID

Cloud Run 서비스를 삭제합니다.

gcloud run services delete SERVICE_NAME \
    --region=REGION

가격 책정

스트리밍 공개 미리보기 기간에는 스트리밍 지원 게이트웨이의 네트워크 이그레스에 대해 고객에게 요금이 청구되지 않습니다. 하지만 출시 단계와 관계없이 Service Control 결제는 API 수준에서 계속 적용됩니다.

제한사항

공개 미리보기 기간 동안 API Gateway의 스트리밍에는 다음과 같은 제한사항이 적용됩니다.

  • 불변성: 기존 게이트웨이를 업데이트하여 스트리밍을 사용 설정하거나 사용 중지할 수 없습니다. 새 게이트웨이를 만들어야 합니다. 스트리밍 지원 게이트웨이는 다른 호스트 이름 모양을 수신하므로 클라이언트 또는 DNS 레코드를 업데이트해야 합니다. 새 형식을 사용하도록 게이트웨이 레코드를 업데이트하려면 지원팀에 문의하세요. API Gateway는 다음 호스트 이름 패턴을 사용합니다.

    • 비스트리밍: {gateway_id}-{base36_project_number}.{shard_hash}.gateway.dev(예: test-gateway-4jcaz8x.uc.gateway.dev)
    • 스트리밍: {gateway_id}-{project_number}.{region}.gateway.dev(예: test-gateway-9876654321.us-central1.gateway.dev)
    • 스트리밍(기존): {service}-{tenant_project_number}.{region}.run.app(예: test-gateway-834512064953.us-central1.run.app) 지역별 *.gateway.dev 호스트 이름을 사용할 수 있기 전에 생성된 게이트웨이는 이 호스트 이름을 영구적으로 유지하며 새 패턴으로 이전되지 않습니다.

    새 스트리밍 지원 게이트웨이가 스트리밍 패턴을 수신합니다. 처음 두 예는 동일한 프로젝트의 동일한 게이트웨이입니다. 스트리밍 패턴에서는 프로젝트 번호가 base36이 아닌 10진수로 표시되므로 첫 번째 라벨의 공간이 스트리밍이 아닌 게이트웨이보다 적습니다. 첫 번째 라벨은 결합된 {gateway_id}-{project_number} 문자열로, 63자 DNS 라벨 제한을 충족해야 합니다. 49자 게이트웨이 ID 제한으로 인해 최대 13자리 프로젝트 번호의 경우 이 제한 내에 유지됩니다. 프로젝트 번호가 더 긴 경우 게이트웨이 ID가 더 짧아야 합니다.

  • Terraform: Terraform을 사용한 스트리밍 사용 설정은 지원되지 않습니다 (향후 출시 예정).

  • 부하 분산 및 커스텀 도메인: effectiveStreamingMode이 EFFECTIVE_STREAMING_MODE_ENABLED인 게이트웨이는 API Gateway용 HTTP(S) 부하 분산 또는 서버리스 NEG와 호환되지 않습니다. 이러한 게이트웨이는 서버리스 NEG 또는 외부 애플리케이션 부하 분산기 뒤에 배치할 수 없습니다. 따라서 공개 미리보기 중에는 이러한 게이트웨이에 부하 분산을 사용하는 커스텀 도메인이 지원되지 않습니다.

  • 기한 동작: 게이트웨이에서 스트리밍을 사용 설정해도 SSE 또는 청크 전송 경로에서 deadline 필드의 동작은 변경되지 않습니다. 기한은 완전 응답에 대한 벽시계 바운드로 유지되므로 스트림은 전송 중인 데이터의 양과 관계없이 기한이 지나면 잘립니다. 기본값은 15초이고 최댓값은 3,600초입니다. WebSocket에서는 deadline이 메시지 간 간격을 제한하며 연결은 3,600초 후에 종료됩니다. 스트림 기한 설정을 참고하세요.

  • 모델 컨텍스트 프로토콜 (MCP): --enable-streaming로 게이트웨이를 만들어도 MCP 엔드포인트 스트림이 생성되지 않습니다. MCP 응답은 게이트웨이의 스트리밍 모드와 관계없이 단일 application/json 본문으로 유지됩니다. 자세한 내용은 MCP 제한사항을 참고하세요.