Claude API 캐시 진단이 두 요청을 비교하는 순서를 그린 대표 이미지
|

AI 기술 설명 – 캐시 진단(Cache Diagnostics) – 프롬프트 캐싱이 빗나간 이유를 알려 주는 Claude API 기능

캐시 진단(Cache Diagnostics)은 Claude API에서 프롬프트 캐싱(Prompt Caching)이 빗나갔을 때, 이전 요청과 비교해 model, system, tools, messages 중 어디가 처음 달라졌는지를 응답에 적어 주는 기능입니다. 캐시 진단 문서는 프롬프트 앞부분이 최근 요청과 바이트 단위로 같아야 캐시가 쓰이고, 도구 순서가 바뀌거나 system에 시각이 끼어드는 것만으로도 조용히 캐시가 무효가 된다고 설명해요.

Claude 플랫폼 공식 아이콘, 캐시 진단을 제공하는 Claude API 문서의 로고
Claude 플랫폼 공식 아이콘 (platform.claude.com, 2026-10-08 확인)

기능이 생기기 전에는 usage.cache_read_input_tokens가 0으로 떨어지는 것만 신호였고, 무엇이 바뀌었는지는 알 수 없었다고 문서는 적습니다. 릴리스 노트에 따르면 이 기능은 2026년 5월 13일에 공개 베타로 나왔고, 9월 23일에 베타 헤더 없이 쓸 수 있게 됐어요.

글의 내용을 도식으로 정리한 영상 (소리 없음)

캐시 진단 전에 알아둘 프롬프트 캐싱의 작동 원리

프롬프트 캐싱 문서에 따르면 요청이 들어오면 시스템은 캐시 지점(breakpoint)까지의 프롬프트 앞부분이 최근 질의로 이미 캐시돼 있는지 확인합니다. 있으면 그것을 쓰고, 없으면 전체를 처리한 뒤 응답이 시작될 때 그 앞부분을 캐시에 저장해요. 캐시 대상은 tools, system, messages 순서로 이어지는 전체 앞부분입니다.

기본 유효 시간은 5분이고, 캐시가 쓰일 때마다 추가 비용 없이 갱신됩니다. 5분은 응답이 끝난 시점이 아닌, 캐시를 읽거나 기록한 요청이 시작된 시점부터 셉니다. 응답을 만드는 데 4분이 걸리면 후속 요청은 그 뒤 1분쯤 안에 시작해야 같은 캐시를 쓸 수 있다고 문서가 풀어 줘요. 5분이 짧으면 "ttl": "1h"로 1시간 캐시를 고를 수 있습니다.

5분기본 유효 시간사용될 때마다 추가 비용 없이 갱신
1.25배5분 캐시 쓰기기본 입력 토큰 가격 대비
2배1시간 캐시 쓰기기본 입력 토큰 가격 대비
0.1배캐시 읽기모델에 따라 예외가 있음

읽기 배수는 문서 표의 각주가 모델별 예외를 적습니다. Claude Opus 5.5와 Claude Sonnet 5.5는 0.05배이고, 릴리스 노트의 10월 7일 항목은 Sonnet 5.5의 캐시 읽기를 100만 토큰당 $0.20에서 $0.10로 낮췄다고 밝혀요. 캐시할 수 있는 최소 길이도 모델마다 달라서 Claude Haiku 4.5는 4,096토큰, Claude Sonnet 5는 1,024토큰, Claude Opus 5.5는 512토큰입니다. 이보다 짧으면 오류 없이 캐시 없이 처리되고, cache_creation_input_tokens와 cache_read_input_tokens가 둘 다 0이면 캐시되지 않은 것이라고 문서가 적어요.

캐시 진단은 이전 응답 id로 두 요청을 비교한다

diagnostics 객체를 넣은 요청마다 API는 응답 id를 키로 가벼운 지문(fingerprint)을 저장합니다. 객체를 넣지 않은 요청은 아무것도 저장하지 않고요. 다음 요청에서 직전 응답의 id를 diagnostics.previous_message_id로 넘기면, API가 새 요청의 지문을 다시 만들어 저장된 것과 비교하고 처음 갈라진 지점을 응답에 붙여 줍니다.

첫 요청에서 옵트인하고 지문이 저장된 뒤, 다음 요청에 이전 응답 id를 넘기면 갈라진 지점이 응답에 붙는 네 단계 도식
캐시 진단이 두 요청을 비교하는 순서

이 비교는 캐시가 실제로 적중했는지와 별개로 요청 구조만 봅니다. 지문에는 해시와 토큰 수 추정치만 들어가고 프롬프트 원문은 저장되지 않으며, 조직과 워크스페이스 안에서만 쓰이고 일정 기간 뒤 만료된다고 문서가 적어요. 문서는 이 기능을 ZDR(데이터 무보존) 대상으로 표시하되, 일부 모델은 제외된다는 단서를 붙입니다.

함께 읽기컨텍스트 엔지니어링 – AI가 읽는 양을 설계하는 방법컨텍스트 엔지니어링의 정의와 프롬프트 엔지니어링과의 차이, 공식 글에 나온 기법 4가지, CLAUDE.md 200줄 권고를 정리하고 미니…

캐시 진단을 켜는 방법은 diagnostics 객체 하나

켜려면 모든 턴에 diagnostics를 넣으면 돼요. 첫 턴은 비교할 이전 메시지가 없으니 previous_message_id에 null을 넣어 옵트인만 하고, 이후 턴에는 직전 응답의 id를 넣어요. 아래는 문서의 Python 예제에서 두 번째 턴 호출과 결과 처리 부분을 그대로 가져왔어요. r1은 같은 예제의 첫 번째 응답이고, 문서 예제는 client.beta.messages.create를 씁니다.

cache_diagnostics.pypython
# Turn 2: reference the previous response id
r2 = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system=SYSTEM,
    messages=[
        {"role": "user", "content": "Summarize section 1."},
        {"role": "assistant", "content": r1.content},
        {"role": "user", "content": "Now summarize section 2."},
    ],
    diagnostics={"previous_message_id": r1.id},
)

diagnostics = r2.diagnostics
if diagnostics is None:
    print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
    print("Comparison still pending.")
else:
    print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")

베타 헤더와 옵트인 규칙의 변화

릴리스 노트의 9월 9일 항목에 따르면 요청에 diagnostics 객체가 있을 때만 지문이 저장됩니다. 베타 헤더만 보낸 요청은 받아들여지지만 지문이 없어서, 다음 턴이 그 요청을 가리키면 previous_message_not_found가 나와요. 9월 23일에는 베타 헤더가 필요 없어졌고, 응답에는 항상 diagnostics 필드가 들어가며 객체를 보내지 않은 요청에서는 null입니다.

캐시 진단 베타 헤더가 필요 없어졌다는 9월 23일 릴리스 노트 항목 화면
Claude 릴리스 노트 화면, 2026-10-08 확인 (platform.claude.com)

스트리밍에서는 message_start 이벤트에 diagnostics가 실려 옵니다. 여러 턴을 도는 대화 루프에서는 매 턴 마지막 응답의 id를 다음 턴의 previous_message_id로 넘기면 된다고 문서가 안내해요.

응답의 diagnostics 값과 캐시 미스 원인 여섯 종류

응답의 diagnostics는 세 가지 값 중 하나입니다. null은 객체를 보내지 않았거나, 첫 턴이거나, 비교했더니 갈라진 곳이 없다는 뜻이에요. {"cache_miss_reason": null}은 응답을 직렬화할 때까지 비교가 끝나지 않은 경우라서 결론을 내리지 말고 다음 턴을 보라고 문서가 적습니다. 원인이 붙으면 그 type이 아래 여섯 가지 중 하나입니다.

캐시 진단 응답의 diagnostics 필드가 가질 수 있는 세 가지 값을 정리한 공식 문서 표
Claude API 공식 문서 화면, 2026-10-08 확인 (Response format)

model_changed, system_changed, tools_changed, messages_changed, previous_message_not_found, unavailable 여섯 원인을 세 칸씩 두 줄로 나눈 도식
cache_miss_reason 여섯 종류

캐시 진단 문서의 원인 표를 옮긴 카드. 각 type의 설명과 문서가 권하는 조치가 한 줄씩 보인다
문서의 원인 표를 HTML 카드로 옮긴 것 (platform.claude.com)

캐시 진단 공식 문서의 cache_miss_reason 원인 표 화면. 여섯 type의 설명과 조치가 보인다
Claude API 공식 문서 화면, 2026-10-08 확인 (Cache miss reason types)

원인 뜻 문서의 조치
model_changed model이 달라짐 대화 안에서 모델 고정
system_changed system이 달라짐 동적 값을 첫 user 메시지로
tools_changed tools가 달라짐 같은 순서, 결정적 직렬화
messages_changed 앞쪽 기록이 바뀜 기록은 덧붙이기만

문서는 응답이 가장 이른 갈라짐 하나만 알려 주므로 그것부터 고치라고 하고, 뒤의 변경은 가려질 수 있다고 적어요.

previous_message_not_found는 저장된 지문이 없다는 뜻이고, 요청이 바뀌었다는 증거는 아니에요. unavailable은 model, system, tools는 같은데 tool_choice, thinking, context_management, output_config, output_format, 활성화된 anthropic-beta 헤더 같은 다른 매개변수가 달라진 경우와, 아주 긴 대화에서 갈라진 곳이 비교 범위 밖인 경우를 포함합니다. 네 가지 *_changed에는 갈라진 뒤 토큰 수의 추정치 cache_missed_input_tokens가 붙고, 문서는 청구 금액으로 쓰지 말고 규모를 보는 지표로 읽으라고 해요.

diagnostics가 null이거나 cache_miss_reason이 붙은 응답의 JSON 형식과 세 가지 값의 뜻을 정리한 카드
문서의 응답 예시에서 형식을 옮긴 카드 (제가 실행한 출력이 아님)

함께 읽기오토 모드(Auto Mode) – 승인 대신 분류기가 검사하는 구조Claude Code 오토 모드가 승인 버튼 대신 분류기로 행동을 검사하는 구조를 공식 문서 기준으로 정리했습니다. 권한 모드 6가지,…

usage와 함께 읽어야 하는 캐시 진단 결과

문서는 diagnostics가 “내 요청이 바뀌었나”에 답하고 cache_read_input_tokens가 “캐시가 적중했나”에 답한다고 구분합니다. 실제 previous_message_id를 넣은 턴에서 둘을 합친 해석은 네 가지입니다.

캐시 진단 결과와 cache_read_input_tokens를 함께 읽는 공식 문서 표 화면
Claude API 공식 문서 화면, 2026-10-08 확인 (Reading diagnostics alongside usage)

`null`이고 읽은 토큰이 많으면 접두부가 안정적이고 캐시가 적중한 정상입니다. `null`인데 읽은 토큰이 적거나 0이면 요청은 같은데 캐시 항목이 이미 없어진 경우라서, 턴 사이 간격을 줄이거나 1시간 캐시를 고려하라고 문서가 적어요.

`*_changed`에 읽은 토큰이 적거나 0이면 요청이 바뀐 것이니 `type`이 가리키는 원인을 고칩니다. `*_changed`인데 읽은 토큰이 많으면 드문 경우로, 프롬프트 뒤쪽이 바뀌었지만 앞선 `cache_control` 지점은 적중한 것이라 영향이 작아요.

첫 턴(previous_message_id: null)은 diagnostics가 항상 null이고 캐시를 쓰는 중이라 읽은 토큰이 보통 0이라서 따로 살필 것이 없다고 문서가 적습니다. 이 글에서는 컨텍스트 엔지니어링 글에서 다룬 “모델에 무엇을 어떤 순서로 줄지 설계한다”는 주제와 이어서 읽었는데, 안정적인 앞부분을 먼저 두는 구조가 그 설계의 일부라는 연결은 문서가 한 말이 아니라 제 해석입니다.

캐시 진단의 한계와 쓰기 전 주의점

문서에 적힌 제한

  • Claude API 전용이며 Amazon Bedrock과 Google Cloud에서는 쓸 수 없다
  • 지문은 짧은 기간 뒤 만료되므로 가까운 요청끼리 비교해야 한다
  • 이전 요청이 같은 조직과 워크스페이스에서 실행돼야 한다 (두 응답의 anthropic-workspace-id 헤더로 확인)
  • 아주 긴 대화에서 바뀐 곳이 메시지 목록 깊은 곳이면 정확한 위치 대신 unavailable이 나올 수 있다
  • 최선 노력 방식이라 진단이 요청을 막거나 실패시키지는 않는다

문서 머리의 지원 플랫폼 표시를 보면 Claude API만 정식(ga)이고, AWS 위 Claude 플랫폼, Amazon Bedrock, Google Cloud, Microsoft Foundry는 모두 사용 불가로 나옵니다. 제한 항목에는 Bedrock과 Google Cloud만 적혀 있어서 두 곳의 표기가 다르고, 이 글은 더 넓은 쪽인 머리 표시까지 함께 옮겼어요.

프롬프트 캐싱 문서의 문제 해결 절도 캐시 진단을 쓰라고 안내하면서, 키 순서가 무작위인 언어(Swift, Go 등)가 tool_use 블록을 직렬화할 때 캐시를 깨뜨릴 수 있다는 점을 따로 적습니다. 캐시 진단으로 어디가 바뀌었는지 찾은 뒤 이런 항목을 점검하는 순서로 읽으면 됩니다.

이 글에서 읽은 범위

읽은 것은 캐시 진단 문서 전체, 프롬프트 캐싱 문서, 릴리스 노트의 5월 13일, 9월 9일, 9월 23일, 10월 7일 항목입니다. 직접 API를 호출해 캐시 진단을 돌려 본 결과는 없어서, 문서가 설명한 동작을 정리한 글로 읽어 주세요. 위 코드는 문서 예제를 그대로 옮긴 것이고 실행 출력이 아니며, 카드 속 JSON도 문서의 응답 예시에서 형식을 옮긴 것입니다.

참고한 공식 문서

본문은 캐시 진단, 프롬프트 캐싱, 릴리스 노트를 읽고 정리했습니다. 기능과 가격이 바뀔 수 있으니 쓰기 전에 원문을 확인하세요.

캐시 진단 자주 묻는 질문

캐시 진단은 어떻게 켜나요?

요청에 diagnostics 객체를 넣으면 됩니다. 첫 턴에는 previous_message_id에 null을, 다음 턴부터는 직전 응답의 id를 넣어요. 공식 문서는 2026년 9월 23일부터 cache-diagnosis-2026-04-07 베타 헤더가 필요 없고, 그 헤더를 계속 보내는 요청도 전과 같이 동작한다고 적습니다.

캐시 진단이 알려 주는 원인에는 어떤 것이 있나요?

model_changed, system_changed, tools_changed, messages_changed 네 가지는 요청의 어느 부분이 처음 달라졌는지를 가리킵니다. previous_message_not_found와 unavailable은 비교 결과를 만들지 못한 경우예요.

Amazon Bedrock이나 Google Cloud에서도 쓸 수 있나요?

문서의 제한 항목은 Claude API 전용이며 Amazon Bedrock과 Google Cloud에서는 쓸 수 없다고 적습니다. 문서 머리의 지원 플랫폼 표시에서도 Claude API만 정식이고, AWS 위 Claude 플랫폼과 Microsoft Foundry까지 사용 불가로 나와 있습니다.

글에 나온 규칙 파일과 에이전트는 Claude Code에서 쓰는 방식이고, 공식 안내는 Claude Code 공식 문서에 있습니다.

이 글은 직접 만들고 운영하며 남긴 기록입니다. 적힌 수치는 작성 시점의 제 계정 기준이며, 같은 결과나 수익을 보장하지 않습니다.

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다