AI 뉴스

Show GN: Ephemeral System Prompt — 매번 바뀌는 지시사항을 캐시 적중률 그대로 유지하는 방법

노동1호 2026. 8. 7. 03:01

Ephemeral System Prompt cache prefix 분리 다이어그램

캐시 적중률 모니터링 대시보드 예시

도입 — 시스템 프롬프트는 고정인데 "오늘 날짜"는 매번 바뀐다

LLM 에이전트를 만들다 보면 마주치는 딜레마가 있습니다. 시스템 프롬프트는 그대로 유지하면서도 현재 시각, 세션 상태, 사용자 컨텍스트, 호스트 정책처럼 실행마다 달라지는 지시사항을 추가해야 하는 경우죠. 그런데 이런 내용을 시스템 프롬프트에 직접 합치면 매 요청마다 prefix가 달라져서 provider의 prompt caching이 캐시 적중률을 잃어버립니다. Anthropic과 OpenAI 모두 prefix cache를 제공하는데, 캐시 키는 처음 N토큰의 바이트 시퀀스이기 때문입니다.

오늘 GeekNews에 올라온 Ephemeral System Prompt는 이 문제를 깔끔하게 푸는 작은 라이브러리를 소개합니다. 핵심 아이디어는 단순합니다 — 고정 prefix를 그대로 두고, 캐시 영역 바깥에서만 동적 지시사항을 끼워 넣으면 됩니다. Anthropic은 캐시 영역을 cache_control 마커로 명시적으로 표시하기 때문에, 그 마커 뒤쪽을 비워두고 매 요청마다 다른 컨텐츠를 채워 넣으면 prefix 캐시는 그대로 살아 있습니다.

핵심 메커니즘 — 캐시 prefix를 고정 영역으로 격리

대부분의 provider가 prompt cache를 "앞쪽 N토큰"에 적용합니다. 따라서 동적 컨텐츠가 앞쪽에 들어가면 캐시 적중이 0%로 떨어집니다. Ephemeral System Prompt는 이를 두 단계로 분리합니다.

  1. 고정 prefix (캐시 영역): 시스템 프롬프트 + 도구 스키마 + few-shot 예시
  2. ephemeral 영역 (캐시 비적용): 현재 시각, 사용자 ID, 세션 토큰, 호스트 이름

구조적으로는 단일 메시지 배열이지만, provider API는 prefix 매칭을 토큰 단위로 하기 때문에 ephemeral 영역이 뒤쪽에 배치되면 prefix hash가 동일하게 유지됩니다. 라이브러리는 이 배치를 자동으로 관리해 주는 thin wrapper입니다.

실전 코드 — Anthropic Messages API 기준

Anthropic의 cache_control 마커를 쓰면 명시적으로 캐시 영역을 지정할 수 있습니다. 아래 코드는 시스템 프롬프트를 캐시 영역으로, 사용자 메시지의 prefix 일부를 ephemeral 영역으로 분리합니다.


import anthropic
from ephemeral_prompt import split_messages

client = anthropic.Anthropic()

SYSTEM_PROMPT = """당신은 데이터 분석 어시스턴트입니다. ... (5,000 토큰 분량의 가이드라인)"""

def ask(user_query: str, session_ctx: dict):
    # 1) 캐시 영역: 시스템 프롬프트만 (고정)
    fixed = [{"type": "text", "text": SYSTEM_PROMPT,
              "cache_control": {"type": "ephemeral"}}]

    # 2) ephemeral 영역: 매번 바뀌는 컨텍스트
    ephemeral = (
        f"[now={session_ctx['now']}] "
        f"[user={session_ctx['user_id']}] "
        f"[host={session_ctx['host']}]"
    )

    response = client.messages.create(
        model="claude-sonnet-4.5",
        system=fixed,
        messages=[{"role": "user",
                   "content": ephemeral + "\n\n" + user_query}],
        extra_headers={"anthropic-beta": "prompt-caching-2024-07-31"},
    )
    return response.content[0].text

OpenAI 쪽 적용 — 구조적 차이 한 줄

OpenAI는 명시적 캐시 마커가 없고, 자동 prefix 매칭만 지원합니다. 따라서 동적 컨텐츠를 시스템 메시지 맨 끝이나 사용자 메시지 prefix에 두지 말고, 메시지 배열의 가장 마지막에 두면 prefix hash가 안 깨집니다. OpenAI의 캐시는 1024토큰 단위로 동작하기 때문에 동적 영역이 1KB 미만이라면 prefix cache 적중이 유지됩니다.

실용 팁 — 캐시 적중률 모니터링

  • Anthropic 응답 헤더의 cache_read_input_tokens 값을 로그로 남겨 prefix 적중률 추적
  • OpenAI Responses API의 cached_tokens 필드를 메트릭으로 export (Prometheus/OpenTelemetry)
  • 동적 영역이 prefix로 새는 회귀를 잡으려면 매 요청 prefix hash를 MD5로 비교하는 테스트를 CI에 포함
  • ephemeral 영역은 256토큰 이내로 유지 — 너무 크면 비용 이득보다 컨텍스트 점유율 손해

전망 — 캐시 granularity는 더 작아진다

Anthropic은 2024년 4토큰 단위 fine-grained cache 실험을, OpenAI는 prefix 외 세션/도구 단위 캐시 옵션을 베타로 공개했습니다. 결국 캐시 단위는 더 작아지고, ephemeral 영역을 따로 표시하는 SDK 패턴이 표준으로 자리 잡을 가능성이 큽니다. 지금부터 prefix 분리를 습관화해 두면 마이그레이션 비용이 거의 0이 됩니다.

요약

  • Ephemeral System Prompt는 캐시 영역 prefix와 동적 영역을 분리하는 thin wrapper
  • 핵심은 "동적 컨텐츠를 prefix 안에 넣지 않는다"는 단일 원칙
  • Anthropic은 cache_control 마커로 명시 분리, OpenAI는 메시지 순서로 암묵 분리
  • 캐시 적중률은 응답 헤더 메트릭으로 추적, CI에 prefix hash 회귀 테스트 추가 권장

📰 원본 출처 · https://news.hada.io/topic?id=32189 (#N=32189)

이 글은 GeekNews(긱뉴스)에 게제된 글을 기반으로 작성되었습니다. 원본의 라이선스와 저작권은 원작자에게 있습니다.