접두사 캐시와 시맨틱 캐시의 차이
← 전체 목차 · 이전: 다중 턴 대화에서 왜 이력을 그냥 밀어 넣으면 안 되나 · 다음: 프롬프트는 도대체 어떻게 쓰나
"둘 다 token을 아끼기 위한 것"이라고만 답하면 너무 거칠다. 올바른 진입점은 세 차원이며, 두 캐시는 이 셋이 완전히 다르다: 적중 조건, 리스크, 적용 시나리오.
| 차원 | 접두사 캐시 (Prefix Cache) | 시맨틱 캐시 (Semantic Caching) |
|---|
| 위치 | 추론 가속에 가까움 | 애플리케이션 층 재사용에 가까움 |
| 절약하는 것 | 동일 컨텍스트의 중복 계산 | 유사 질문의 중복 생성 |
| 재사용 대상 | 이미 계산한 KV 결과 | 과거에 이미 산출한 답변 |
| 적중 조건 | 입력 앞부분이 글자 단위로 완전 일치 | 질문의 의미가 유사하면 됨 |
| 직접 수익 | 프리필(prefill) 오버헤드 감소 | 모델 호출 횟수 감소 |
| 주요 리스크 | 접두사가 깨짐 → 적중률이 극도로 낮아짐 | 오적중(엉뚱한 답 / 만료된 답 사용) |
| 계층 | 저수준 성능 측 | 애플리케이션 전략 측 |
접두사 캐시: "글자 단위 일치"여야 하고 "의미가 비슷한 것"으로는 안 된다
- 전형적으로 재사용 가능한 접두사 내용: 시스템 프롬프트, 도구 설명, 고정 지식 조각.
- 이 내용이 같으면 모델이 이미 계산한 KV 결과를 재사용해 프리필 오버헤드를 대폭 줄일 수 있다.
- 핵심 제약: 텍스트 접두사가 안정적이어야 하며, 의미가 비슷한 정도로는 안 된다 — 시맨틱 캐시와의 가장 큰 분수령이다.
시맨틱 캐시: 의미 유사도를 본다
- 예: 사용자가 "경비 정산은 어떻게 신청하나요"와 "정산 절차는 어디 있나요"를 물으면 — 글자는 다르지만 의미가 가깝기 때문에 시스템이 과거 답변을 그대로 재사용할 수 있다.
- 수익은 명확하다: 한 번의 완전한 모델 호출을 절약한다.
- 리스크도 명확하다: 오적중. 그래서 시맨틱 캐시는 네 가지를 반드시 함께 처리해야 한다.
| 반드시 처리할 요소 | 설명 |
|---|
| 권한 (권한 통제) | 재사용된 답변이 사용자/역할의 가시 범위를 넘어서면 안 된다 |
| 시효 (시간 유효성) | 답변에는 유효 기간이 있고 만료되면 다시 쓸 수 없다 |
| 지식 버전 | 하위 지식베이스가 갱신되면 옛 답변은 실효되어야 한다 |
| 유사도 임계값 | 임계값이 너무 느슨하면 오적중이 발생한다 |
엔지니어링 함정: 동적 내용을 앞에 두면 접두사 캐시가 깨진다
- 잘못된 시범(동적 전치): 타임스탬프 / 랜덤 ID → 동적 변수 → 공용 시스템 프롬프트 순서로 배치해 동적 내용을 프롬프트 가장 앞에 둔다.
- 결과: 접두사가 매번 달라진다 → 접두사가 깨진다 → 캐시 적중률이 매우 나빠진다.
- 올바른 방식: 고정 부분은 앞에, 동적 부분은 되도록 뒤로.
- 인식의 전환: 이것은 프롬프트의 구조 설계에 속하지 서버 측 최적화만이 아니다 — 프롬프트를 쓰는 사람도 캐시 적중률에 책임이 있다.
판단 흐름
「돈을 아끼고 싶다 / 속도를 올리고 싶다」는 요구를 받았을 때
│
├── 질문①: 입력의 앞부분이 본래 안정적인가?
│ (시스템 프롬프트, 도구 설명, 고정 지식 조각의 비중이 높은가?)
│ 예 → 【접두사 캐시】 도입
│ └── 점검: 프롬프트 구조가
│ [공용 시스템 프롬프트] → [도구 설명] → [고정 지식]
│ → [동적 변수] → [타임스탬프/랜덤ID] → [사용자 질문]
│ 인가? 동적 내용이 앞에 있으면 재배치부터 하고 적중률을 논할 것
│
└── 질문②: 프로덕션에 「표현만 바꿔 같은 것을 묻는」 요청이 대량으로 있는가?
예 → 【시맨틱 캐시】 도입
└── 네 개의 관문을 함께 설정할 것:
권한 통제 / 시간 유효성 / 지식 버전 / 유사도 임계값
└── 핵심 취사선택: 임계값을 높이면 적중률↓ 오적중↓
임계값을 낮추면 적중률↑ 오적중↑
다중 Agent 관점: 접두사를 맞추면 KV Cache도 여러 Agent가 같이 쓸 수 있다
**"여러 Agent가 같은 KV Cache를 공유할 수 있는가"**는 단일 요청 관점의 접두사 캐시론에 한 겹을 더 얹는 질문이다. 기본 규칙은 추론 엔진이 요청 단위로 KV Cache를 할당한다는 것 — Agent라는 개념 자체를 엔진은 모른다. 두 Agent의 시스템 프롬프트가 완전히 같아도, 기본 독립 추론 모드에서는 각자 따로 계산해 완전히 동일한 사본을 두 벌 저장한다. 이것이 다중 Agent 시스템에서 가장 흔한 숨은 비용이다: 길고 고정적인 시스템 프롬프트·도구 정의를 Agent 수만큼 반복 계산·반복 저장한다.
해법은 접두사 캐시를 다중 Agent 단위로 "의도적으로 맞추는" 것이다.
1. 모든 Agent가 동일한 시스템 프롬프트를 공유 (순서까지 고정 — 순서가 다르면 접두사가 다르다)
2. 모든 Agent가 동일한 도구 정의 / 스키마 포맷을 공유
3. 고정 부분(시스템 프롬프트 + 도구 정의)을 앞에, Agent별 차이 내용을 뒤에 배치
4. 추론 프레임워크에서 전위 캐시 개폐(예: RadixAttention)를 켬
→ 엔진이 RadixTree로 여러 요청의 공통 접두사를 자동 식별, 겹치는 부분만 한 번 계산
5. 시나리오에 따라 시맨틱 캐시까지 겹쳐 씀
이 방식의 실익은 두 가지다: (1) 매 Agent가 시스템 프롬프트를 처음부터 다시 계산하는 걸 피하고, (2) 완전히 동일한 KV Cache를 GPU 메모리에 여러 벌 쌓아두는 낭비를 피한다. 함정도 그대로 이식된다 — 다중 Agent 협업·배치 작업 시나리오에서 Agent마다 시스템 프롬프트 순서가 다르거나 도구 정의 포맷이 다르면 적중률이 그대로 0에 수렴하고, 캐시 조회 자체의 오버헤드 때문에 캐시를 안 켠 것보다 오히려 느려질 수 있다. "공유되는가"의 답은 엔진이 허락하는가가 아니라, 접두사 정렬을 능동적으로 설계했는가에 달려 있다.
핵심 통찰
- "token을 아낀다"는 현상이지 답이 아니다 — 묻는 것은 계층을 나눌 수 있는가이다. 접두사 캐시가 아끼는 것은 계산(prefill 단계의 KV 재계산)이고, 시맨틱 캐시가 아끼는 것은 호출(LLM 요청 1회 전체)이다. 아끼는 대상이 같은 층에 있지 않으므로 구현 방식도 자연히 다르다.
- 적중 조건의 엄격성이 그것이 어느 층에 속하는지를 결정한다 — "글자 단위 일치"를 요구하는 메커니즘은 추론 엔진 안에서만 만들 수 있고(Prefix Cache), "의미가 비슷한 것"을 용인할 수 있는 메커니즘은 필연적으로 벡터 검색과 임계값을 끌어들이므로 애플리케이션 층에서만 만들 수 있다(Semantic Caching). 이 판정 기준은 어떤 캐시 설계에도 이식된다.
- 접두사 캐시에는 정확성 리스크가 없고 시맨틱 캐시에는 있다 — 접두사 캐시가 실효하면 기껏해야 조금 느리고 조금 비싸질 뿐이지만, 시맨틱 캐시의 오적중은 곧바로 틀린 답을 준다. 따라서 둘의 출시 문턱, 카나리 전략, 회귀 테스트 요구 수준은 전혀 다른 등급이다.
- 프롬프트의 필드 순서는 가독성 문제가 아니라 성능 파라미터다 — 타임스탬프, 랜덤 ID,
user_id 같은 고엔트로피 내용을 머리에 두는 것은 매 요청마다 캐시를 능동적으로 포기하는 것과 같다. "고정은 앞, 동적은 뒤"는 팀의 프롬프트 규범에 명문화되어야 한다.
- 시맨틱 캐시의 네 관문은 하나도 빠질 수 없다 — 권한, 시효, 지식 버전, 유사도 임계값. 어느 하나가 빠져도 **"답이 매우 자신 있어 보이지만 이미 틀렸다"**는 형태로 드러난다: 월권 유출, 만료된 정책, 구 버전 지식, 엉뚱한 대상.
- 두 캐시는 양자택일이 아니라 서로 다른 층에 겹쳐진다 — 접두사 캐시는 모든 요청에 기본 유효하고(접두사만 안정적이면), 시맨틱 캐시는 고빈도 반복 문답에만 유효하다. 실제 시스템에서는 동시에 켤 수 있다.
- 수익의 예측 가능성이 다르다 — 접두사 캐시의 수익은 "고정 접두사 길이 / 총 입력 길이" 비율에 따라 선형으로 변해 추산이 가능하다. 시맨틱 캐시의 수익은 프로덕션 질문의 반복률 분포에 좌우되므로 먼저 트래픽 분석을 해야 할 가치가 있는지 알 수 있다.
- 다중 Agent에서 접두사 캐시는 "엔진 기능"이 아니라 "아키텍처 결정"이 된다 — 엔진은 Agent라는 개념을 모르고 요청 단위로만 KV Cache를 다룬다. 여러 Agent가 공통 접두사를 실제로 공유하게 하려면 시스템 프롬프트·도구 정의의 내용과 순서를 Agent 간에 통일하는 설계 결정이 선행돼야 한다 — 이것은 성능팀만의 일이 아니라 다중 Agent 아키텍처를 설계하는 사람의 책임이다.
엔지니어링 실전 Tips
- 프롬프트 편집이 곧 캐시 전략이다:
System Prompt / 도구 스키마 / 고정 지식 조각을 가장 앞에 고정하고, {{timestamp}}, {{request_id}}, {{user_name}}은 일률적으로 뒤로 보낼 것.
- "보이지 않는 동적 내용"을 경계할 것: 도구 목록의 순서가 불안정하거나, JSON 필드의 직렬화 순서가 무작위이거나, 프롬프트 템플릿에 현재 날짜가 들어 있는 것 — 전부 조용히 접두사를 깨뜨리며 모니터링에서 직접 보이지도 않는다.
- 시맨틱 캐시는 권한별로 버킷을 나눌 것: 역할/테넌트별 캐시 키에 반드시 권한 차원을 포함시켜야 "A의 답변이 B에게 적중되는" 월권 사고를 막는다.
- 지식베이스가 갱신되면 시맨틱 캐시를 일괄 실효시킬 수 있어야 한다: 지식 버전 번호를 캐시 키의 일부로 삼는 것이 가장 손쉬운 방법이다.
- 시맨틱 캐시에 수동 다운그레이드 스위치를 남길 것: 금융, 경비 정산, 주문처럼 정확성이 강하게 요구되는 시나리오에서는 적중하지 않을지언정 오적중은 안 된다.
- 적중률은 관측해야 할 지표다: 접두사 캐시 적중률, 시맨틱 캐시 적중률, 시맨틱 캐시 오적중률(샘플링 사람 심사나 사용자 부정 피드백으로 추정)을 모니터링에 올릴 것.
- 다중 Agent 시스템은 시스템 프롬프트·도구 스키마를 팀 차원에서 표준화할 것: 각 Agent가 프롬프트를 자유롭게 조립하게 두면 접두사가 미묘하게 갈라지며 캐시 적중률이 조용히 무너진다. 공용 템플릿 + 고정 필드 순서를 강제할 것.
- 다중 Agent 환경에서는 캐시 적중률을 Agent 전체 평균이 아니라 Agent별로 쪼개 관측할 것: 평균값이 정상이어도 특정 Agent 하나의 프롬프트 포맷이 어긋나 있으면 전체 지표에 묻혀 안 보인다.
- 더 파고들 방향: 각 추론 프레임워크(vLLM, SGLang 등)와 각 API의 접두사 캐시 발효 조건·과금 할인 규칙 차이, 시맨틱 캐시 임계값의 오프라인 데이터셋 기반 튜닝과 오적중률 측정, 그리고 접두사 캐시 + 시맨틱 캐시 + 결과 캐시(정확 query 적중) 3단 캐시의 조합 설계.