Vertex AI Context Caching과 Priority PayGo, 실제로 얼마나 빨라질까?

Cloudturing Team 발행: 2026. 02. 12 16:09 수정: 2026. 02. 12 18:36

Gemini 3 Flash Preview 모델 기준, 실서비스 챗봇 시스템 프롬프트(~7,500토큰)를 사용한 400회 벤치마크 결과

들어가며

AI 챗봇 서비스를 운영하다 보면 자연스럽게 응답 레이턴시에 민감해집니다. 특히 시스템 프롬프트가 길어질수록 — 페르소나 설정, 인텐트 데이터, 환영/폴백 메시지 등을 모두 포함하면 수천 토큰에 달하기도 합니다 — "이 긴 프롬프트가 매 요청마다 처리되면서 레이턴시에 영향을 주지 않을까?" 하는 의문이 생깁니다.

Google Cloud Vertex AI에서는 이런 상황을 위해 두 가지 옵션을 제공합니다:

  1. Context Caching — 시스템 프롬프트를 서버 측에 캐싱하여 재사용
  2. Priority PayGo — 우선 처리 요금제로 레이턴시 개선 (2025년 2월 신규 출시)

저희 Cloudturing 팀에서는 실서비스에서 사용하는 시스템 프롬프트를 그대로 사용하여 이 두 기능의 실제 레이턴시 개선 효과를 벤치마크해 보았습니다.


테스트 환경

항목
모델 gemini-3-flash-preview
GCP 프로젝트 리전 global
시스템 프롬프트 크기 27,235자 (~7,544토큰)
시나리오 4가지 (Standard/Priority × 캐싱/비캐싱)
시나리오당 요청 수 100회
총 요청 수 400회 (에러 0건)
요청 방식 1초 간격 Staggered Start
SDK @google/genai (Vertex AI mode)
캐시 TTL 30분

시스템 프롬프트 구성

테스트에 사용된 시스템 프롬프트는 실제 상용 챗봇에서 사용하는 구조를 따릅니다:

  • 페르소나 설정: 챗봇의 이름, 성격, 응답 톤
  • 환영 인텐트: 초기 인사 메시지 및 버튼 구성 (JSON)
  • 폴백 인텐트: 미인식 시 응답 (JSON)
  • 학습된 인텐트 목록: 영업시간, 배송 조회, 반품/교환, FAQ 등 5개 인텐트 (JSON 배열)

이런 데이터가 합쳐지면 프롬프트 하나가 약 7,500토큰에 달합니다.

테스트 질문

다국어 환경을 반영하여 한국어, 영어, 일본어를 포함한 10개 질문을 순환 사용했습니다:

영업시간이 어떻게 되나요?
예약하고 싶습니다. 어떻게 하나요?
주차 가능한가요?
What is your return policy?
配送状況を確認したいです
반품하고 싶은데 어떻게 하나요?
택배가 아직 안 왔어요
Do you offer free shipping?
고객센터 전화번호 알려주세요
5만원 이상 구매하면 배송비 무료인가요?

테스트 방법론

Staggered Start 방식

순차 요청은 시간이 너무 오래 걸리고, 동시 대량 요청은 비현실적입니다. 그래서 1초 간격으로 요청을 시작하되, 각 요청은 독립적으로 완료되는 방식을 사용했습니다.

t=0s   → Request #1 시작
t=1s   → Request #2 시작
t=2s   → Request #3 시작
...
t=99s  → Request #100 시작
t=~120s → 마지막 요청 완료

이 방식은 실제 서비스 트래픽 패턴(지속적으로 들어오는 요청)과 유사하면서도, 총 벤치마크 시간을 Phase당 약 2분으로 단축할 수 있었습니다.

Implicit Caching 방지

첫 번째 벤치마크에서 흥미로운 현상을 발견했습니다. 비캐싱 시나리오에서도 cachedContentTokenCount가 277,440으로 찍히는 것이었습니다.

Vertex AI가 동일한 시스템 프롬프트를 감지하여 내부적으로 자동 캐싱(Implicit Caching)을 하고 있었던 것입니다. 이러면 명시적 캐싱과 비캐싱의 공정한 비교가 불가능합니다.

이를 방지하기 위해 비캐싱 시나리오에서는 각 요청의 시스템 프롬프트 앞에 [Request #N]이라는 고유 프리픽스를 추가하여 매번 다른 프롬프트로 인식되게 했습니다:

// implicit caching 방지: 요청마다 시스템 프롬프트 앞에 고유 번호 삽입
const uniquePrompt = `[Request #${i}]\n${systemPrompt}`;

결과적으로 비캐싱 Standard의 캐시 토큰이 277,440 → 0으로 줄어 방지에 성공했습니다.

Priority PayGo 적용 방법

Priority PayGo는 HTTP 헤더 하나로 활성화됩니다:

X-Vertex-AI-LLM-Shared-Request-Type: priority

@google/genai SDK에서는 클라이언트 초기화 시 httpOptions.headers에 설정합니다:

const clientPriority = new GoogleGenAI({
    vertexai: true,
    project: PROJECT_ID,
    location: LOCATION,
    httpOptions: {
        apiVersion: "v1",
        headers: {
            "X-Vertex-AI-LLM-Shared-Request-Type": "priority"
        }
    }
});

벤치마크 결과

응답 시간 비교

시나리오 최소 최대 평균 중간값
캐싱 + Standard 4,805ms 17,004ms 7,624ms 7,194ms
비캐싱 + Standard 3,921ms 17,577ms 7,393ms 6,980ms
캐싱 + Priority 4,587ms 15,922ms 7,884ms 7,519ms
비캐싱 + Priority 4,095ms 18,865ms 7,889ms 7,503ms

토큰 생성 속도 비교

시나리오 최소 최대 평균 중간값
캐싱 + Standard 90.2 137.2 114.3 tok/s 114.4
비캐싱 + Standard 74.2 146.3 116.8 tok/s 119.2
캐싱 + Priority 83.7 146.3 113.8 tok/s 113.2
비캐싱 + Priority 81.7 142.0 118.7 tok/s 119.7

핵심 비교

비교 항목 결과
Standard 캐싱 효과 캐싱이 232ms 느림 (+3.1%)
Priority 캐싱 효과 캐싱이 5ms 빠름 (-0.1%)
비캐싱에서 Priority 효과 Priority가 496ms 느림 (+6.7%)
캐싱에서 Priority 효과 Priority가 260ms 느림 (+3.4%)

토큰 사용량 총계

항목 사용량
총 입력 토큰 3,017,480 (~301만)
총 출력 토큰 49,774 (~5만)
총 토큰 3,067,254 (~307만)

분석 및 인사이트

1. Context Caching은 기대만큼 빠르지 않았다

가장 놀라운 결과입니다. 7,500토큰 규모의 시스템 프롬프트를 캐싱했음에도, 응답 시간에 유의미한 차이가 없었습니다. Standard 기준으로는 캐싱이 오히려 3.1% 느렸고, Priority에서는 사실상 동일(0.1% 차이)했습니다.

이에 대한 몇 가지 가설이 있습니다:

  • 프롬프트 크기가 캐싱 효과를 체감하기엔 작을 수 있음: Google 문서에서는 Context Caching이 "대규모 컨텍스트"에서 효과적이라고 안내합니다. 7,500토큰은 Gemini 3 Flash의 최대 컨텍스트(1M 토큰) 대비 매우 작은 수준입니다.
  • 프리뷰 모델의 최적화 수준: gemini-3-flash-preview는 아직 프리뷰 단계이므로, 캐싱 최적화가 완전하지 않을 수 있습니다.
  • 캐시 조회 오버헤드: 캐시를 조회하고 로드하는 과정 자체가 소규모 프롬프트에서는 직접 전송과 큰 차이가 없을 수 있습니다.

2. Implicit Caching의 존재

벤치마크 과정에서 Vertex AI가 동일한 시스템 프롬프트를 자동으로 캐싱한다는 사실을 발견했습니다. 첫 번째 테스트에서 비캐싱 시나리오의 cachedContentTokenCount가 0이 아닌 277,440이었습니다.

이는 곧, 명시적으로 Context Caching API를 사용하지 않더라도 Vertex AI가 내부적으로 최적화를 수행하고 있다는 의미입니다. 이것이 캐싱과 비캐싱의 성능 차이가 거의 없는 근본적인 이유일 수 있습니다.

3. Priority PayGo는 혼잡 시간대에 진가를 발휘할 것

비혼잡 시간대(테스트 시간: 평일 오후 34시 KST)에서 Priority PayGo는 오히려 37% 느린 결과를 보였습니다. 이는 우선 처리를 위한 내부 라우팅 오버헤드가 추가되기 때문으로 추정됩니다.

Priority PayGo의 설계 의도는 트래픽이 혼잡할 때 Standard 대비 안정적인 레이턴시를 보장하는 것이므로, 비혼잡 시간대의 테스트로는 진정한 가치를 측정하기 어렵습니다. 피크 시간대에 추가 테스트가 필요합니다.

응답의 trafficType 필드가 Standard는 ON_DEMAND, Priority는 ON_DEMAND_PRIORITY로 정상 구분되어, 헤더는 올바르게 적용되고 있음을 확인했습니다.

4. 숨겨진 변수: Thinking 토큰

앞선 테스트에서 의도치 않게 thinkingBudget을 설정하지 않아, 모델이 기본값(DEFAULT)으로 동작하고 있었습니다. gemini-3-flash-preview는 Thinking 모델로, 사용자에게 보이지 않는 내부 추론(Thinking) 토큰을 생성합니다.

DEFAULT 상태에서의 토큰 구성을 보면:

항목 평균
입력 토큰 ~7,544
Thinking 토큰 760835
출력 토큰 ~123

사용자에게 보이는 출력은 123토큰뿐이지만, 모델은 내부적으로 760토큰 이상을 추가로 생성하고 있었습니다. 토큰 속도 ~115 tok/s 기준으로 계산하면:

(760 + 123) 토큰 ÷ 115 tok/s ≈ 7.7초

이는 실측 평균 응답시간 ~7.5초와 거의 일치합니다. 즉, 앞선 벤치마크의 응답시간 대부분이 Thinking 토큰 생성에 소요되고 있었던 것입니다. 캐싱이 효과가 없었던 이유도 여기 있습니다 — 캐싱이 최적화할 수 있는 프리필(prefill) 단계가 아니라, 디코딩 단계에서 시간이 소요되고 있었기 때문입니다.

5. 실서비스 기준으로 보정 — Thinking LOW 재벤치마크

실제 저희 서비스에서는 thinkingBudget: 1024 (LOW)를 사용하고 있습니다. 앞선 결과는 이를 누락한 채 DEFAULT로 테스트한 것이었으므로, 실서비스와 동일 조건으로 4가지 시나리오를 다시 벤치마크했습니다.

보정 후 응답 시간 비교

시나리오 DEFAULT (실수) LOW (실서비스) 차이
비캐싱 + Standard 7,393ms 3,036ms -59%
비캐싱 + Priority 7,889ms 3,122ms -60%
캐싱 + Standard 7,624ms 3,893ms -49%
캐싱 + Priority 7,884ms 4,048ms -49%

Thinking 토큰 변화

시나리오 DEFAULT LOW (실서비스) 감소율
비캐싱 + Standard 759 75 -90%
비캐싱 + Priority 835 56 -93%
캐싱 + Standard 764 154 -80%
캐싱 + Priority 787 192 -76%

실서비스 기준(LOW)으로 보정하면 평균 응답시간은 약 3초입니다. 그리고 여기서도 캐싱과 Priority의 효과는 여전히 없었습니다 — 비캐싱+Standard(3,036ms)가 캐싱+Standard(3,893ms)보다 오히려 빨랐습니다.

6. Thinking Level 3단계 비교 — MINIMAL은 얼마나 빠를까?

추가로, LOW보다 한 단계 아래인 thinkingLevel: "MINIMAL"로도 비캐싱+Standard 기준 100회 벤치마크를 진행했습니다.

Thinking Level 평균 응답 Thinking 토큰 출력 토큰 vs DEFAULT
DEFAULT (HIGH) 7,393ms 759 123
LOW 3,036ms 75 96 -59%
MINIMAL 2,552ms 0 99 -65%

MINIMAL은 Thinking 토큰을 아예 생성하지 않아 가장 빠르지만, LOW 대비 추가 단축은 484ms(-16%) 에 그쳤습니다. DEFAULT→LOW에서 4,357ms(-59%) 가 줄어든 것과 비교하면, LOW가 속도와 응답 품질 사이의 최적 균형점입니다.


결론

기능 효과 권장
Context Caching ~7,500토큰에서는 레이턴시 개선 효과 없음 수만 토큰 이상의 대규모 컨텍스트에서만 고려
Priority PayGo 비혼잡 시간대에서는 오히려 3~7% 느림 고가용성이 중요한 프로덕션 환경에서 피크 대응용으로 고려
Implicit Caching Vertex AI가 자동으로 수행 중 별도 API 호출 없이도 내부 최적화 혜택을 받고 있음

그래서 어떻게 해야 할까?

이번 벤치마크의 핵심 교훈은, 현재 구조에서 캐싱이나 우선 처리로는 레이턴시를 줄이기 어렵다는 것입니다. Thinking Level을 실서비스 기준(LOW)으로 맞춰도 평균 3초의 응답시간이 발생하며, 여기에 캐싱이나 Priority를 적용해도 변하지 않았습니다.

이는 레이턴시 최적화의 방향이 "같은 구조를 더 빠르게 처리하는 것"이 아니라, "구조 자체를 바꾸는 것" 에 있다는 시사점을 줍니다:

  • 다단계 파이프라인 도입: 7,500토큰의 긴 시스템 프롬프트를 한 번에 보내는 대신, 짧은 프롬프트로 빠른 1차 응답을 먼저 생성하고, 후속 단계에서 데이터를 보강하여 사용자에게 점진적으로 피드백하는 방식
  • 프롬프트 경량화: 1차 요청에 포함하는 데이터를 최소화하여 First Response까지의 시간을 단축
  • 스트리밍 응답: 전체 응답 완료를 기다리지 않고 토큰 단위로 스트리밍하여 체감 대기 시간 최소화

결국, 단일 LLM 호출의 속도를 높이려는 시도보다, 사용자가 체감하는 대기 시간을 줄이는 구조적 접근이 현 시점에서 가장 효과적입니다.


이 글은 2025년 2월 12일에 작성되었으며, gemini-3-flash-preview 모델 기준 결과입니다. 모델 업데이트나 GA 출시 이후 결과가 달라질 수 있습니다.