본문 바로가기
카테고리 없음

Sonnet 5.5 캐시 읽기 단가 인하 이후 LLM 호출 비용을 프롬프트 캐싱과 배치 API로 줄이는 순서

by Juelria 2026. 10. 18.
728x90
반응형
SMALL

Anthropic은 2026년 10월 7일 릴리스 노트에서 Claude Sonnet 5.5의 프롬프트 캐시 읽기 단가를 100만 토큰당 0.20달러에서 0.10달러로 낮췄다고 밝혔습니다. 기본 입력 단가의 0.05배이고, 캐시 쓰기와 나머지 단가는 그대로입니다. 긴 시스템 프롬프트를 매 요청마다 보내는 서비스라면 TypeScript 호출부에 cache_control 한 줄을 넣는 것이 가장 먼저 할 일입니다. 바로 답을 받을 필요가 없는 작업은 배치 API로 돌려 입출력 단가를 절반으로 줄입니다.

4만 토큰짜리 프롬프트를 열 번 보내면

공식 가격표에서 Sonnet 5.5는 기본 입력이 100만 토큰당 2달러, 출력이 10달러입니다. 5분 캐시 쓰기는 2.5달러, 1시간 캐시 쓰기는 4달러, 캐시 읽기는 0.10달러로 적혀 있습니다.

이 숫자로 간단히 계산해 봤습니다. 고정 프롬프트가 4만 토큰이고 전부 캐시 대상이며 5분 안에 열 번 보낸다고 치면, 캐시 없이는 한 번에 0.08달러라 합계가 0.80달러입니다. 캐시를 쓰면 첫 요청의 쓰기가 0.10달러, 이후 아홉 번의 읽기가 0.004달러씩이라 0.136달러 정도입니다. 질문과 답변 토큰은 따로 더해집니다.

5분 캐시를 쓰면 첫 요청은 캐시 없이 보낼 때보다 25% 비쌉니다. 공식 문서는 5분 캐시는 읽기 한 번, 1시간 캐시는 두 번이면 본전이라고 설명합니다. 같은 프롬프트를 한두 번 쓰고 마는 작업이라면 캐시를 켜지 않는 쪽이 낫습니다.

TypeScript 호출에 cache_control 넣기

가장 쉬운 방법은 자동 캐싱입니다. 공식 문서의 TypeScript 예제처럼 messages.create 요청 최상위에 cache_control: { type: ""ephemeral"" }를 하나 넣으면 마지막 캐시 가능 블록에 중단점이 잡히고, 대화가 길어지면 알아서 뒤로 이동합니다. 기본 유지 시간은 5분이고, 1시간으로 늘리려면 ttl: ""1h""를 함께 적습니다. 대신 쓰기 단가가 기본 입력의 2배가 됩니다.

캐시가 되는 최소 길이는 Sonnet 5.5 기준 512토큰입니다. 이보다 짧으면 에러 없이 그냥 캐시가 안 됩니다. 그래서 응답의 usage를 꼭 찍어 봐야 합니다. cache_creation_input_tokens와 cache_read_input_tokens가 둘 다 0이면 캐시가 안 된 것입니다. input_tokens는 마지막 중단점 뒤의 토큰만 센다는 점도 헷갈리기 쉽습니다. 전체 입력은 세 필드를 더해야 나옵니다.

캐시가 계속 안 맞을 때

자주 만나는 원인은 프롬프트 끝에 매번 바뀌는 내용이 있는 경우입니다. 자동 캐싱은 마지막 블록에 중단점을 놓기 때문에, 그 블록이 현재 시각이나 사용자 입력처럼 요청마다 달라지면 접두부 해시가 한 번도 맞지 않습니다. 쓰기 요금만 계속 내고 읽기는 영영 없는 상태입니다. 이럴 때는 요청마다 같은 마지막 블록, 보통 시스템 프롬프트나 도구 정의에 중단점을 직접 둡니다.

대화가 길어지는 경우에는 조회 범위가 20블록이라는 제약이 있습니다. 한 턴에 블록이 20개 넘게 늘면 이전 쓰기 기록을 못 찾으니, 중간에 중단점을 하나 더 두라는 것이 공식 문서의 안내입니다. 도구 정의를 고치면 캐시 전체가 무효화되고, tool_choice를 바꾸면 메시지 부분의 캐시가 무효화됩니다.

원인을 모르겠으면 cache diagnostics를 켜 볼 수 있습니다. 2026년 9월 23일 베타에서 정식으로 바뀌었고 베타 헤더는 필요 없습니다. 요청에 diagnostics 객체를 넣고 previous_message_id에 직전 응답 ID를 주면, 접두부가 어디서 달라졌는지 cache_miss_reason으로 알려 줍니다.

배치 API로 넘길 일

대량 평가, 콘텐츠 검수, 데이터 요약처럼 몇 시간 늦어도 되는 일은 client.messages.batches.create에 requests 배열을 넘깁니다. 각 항목에 custom_id와 params를 넣고, params는 평소 Messages 호출과 같습니다. Sonnet 5.5의 배치 단가는 입력 1달러, 출력 5달러입니다. 한 배치는 요청 10만 건 또는 256MB까지이고 대부분 1시간 안에 끝나지만, 24시간 안에 못 끝난 요청은 만료됩니다. 결과는 생성 후 29일 동안 받을 수 있습니다.

결과는 for await (const result of await client.messages.batches.results(id))로 한 줄씩 읽고, result.result.type이 succeeded, errored, expired 중 무엇인지 나눠 처리합니다. errored 가운데 invalid_request_error는 요청을 고쳐야 하고 서버 오류는 그대로 다시 보내면 됩니다.

캐시와 배치 할인은 겹쳐서 적용됩니다. 다만 배치는 요청이 동시에 순서 없이 처리되기 때문에 캐시 적중은 최선 노력이고, 문서에는 보통 30%에서 98% 사이라고 나옵니다. 모든 요청에 똑같은 cache_control 블록을 넣고, 배치에는 1시간 캐시를 쓰라는 팁이 있습니다. 미리 데워 두는 max_tokens 0 호출은 배치 안에서는 지원하지 않습니다.

참고한 자료

728x90
반응형
LIST