대화 요약 한 번에 36초, Claude API가 그 대기를 요청 밖으로 옮긴 새 베타
Anthropic이 9월 14일 Messages API에 온디맨드 압축 베타를 열었습니다. 요약을 별도 요청으로 부르면 답변 없이 서명된 블록 하나가 오고, 최근 턴은 원문 그대로 남길 수 있습니다.
- 요약을 별도 요청으로 부르는 Claude API 압축 베타가 열렸습니다.
- 답변 없이 서명된 블록 하나만 오고, 최근 턴은 원문으로 남습니다.
- 요약 호출도 과금되는데 최상위
input_tokens는 0으로 찍힙니다.
Anthropic이 2026년 9월 14일 Messages API에 온디맨드 압축(on-demand compaction) 베타를 열었습니다. 베타 헤더는 compact-2026-09-04입니다.
압축은 길어진 대화를 요약문 한 덩어리로 바꿔 넣는 기능입니다. 에이전트가 파일을 읽고 도구를 부를수록 대화 기록이 불어나고, 그 기록 전체가 매 요청마다 다시 모델로 들어갑니다. 800줄 PR 한 건에 캐시 읽기 1억 5,280만 토큰이 청구된 Sonar의 계측이 그 비용을 수치로 남겼습니다. 압축은 그 기록을 요약으로 줄여 다음 요청부터 보내는 양을 낮춥니다.
서버측 압축은 이미 있었고, 바뀐 건 시점을 누가 정하느냐입니다
Claude API는 2026년 1월 베타(compact-2026-01-12)부터 서버측 압축을 지원했습니다. 이 방식은 임계값 압축입니다. 입력 토큰이 설정한 값에 닿으면 API가 요청을 처리하는 도중에 요약을 만들고, 그 요약으로 문맥을 줄인 뒤 답변을 이어서 씁니다. 기본 임계값은 입력 토큰 150,000이고 최소 50,000입니다.

그런데 요약을 만드는 동안에도 사용자의 요청은 계속 진행 중입니다. 오픈소스 에이전트 oh-my-pi는 임계값 압축을 자기 코드에 연결하면서 측정값을 남겼습니다. 약 8만 토큰짜리 대화 하나를 압축하는 데 thinking 설정에 따라 36초에서 55초가 걸렸습니다. 공식 수치가 아니라 프로젝트 한 곳의 측정입니다. 압축이 요청 안에서 돌면 사용자는 그 36초에서 55초를 그대로 기다립니다. 같은 기록에서 압축 이후 후속 턴은 캐시 재사용으로 입력 3토큰까지 떨어졌습니다.
새 베타에서는 요약을 별도 요청으로 떼어 만듭니다. 요청에 최상위 compaction 파라미터를 넣으면 API는 그 요청에 담긴 메시지를 전부 한 번 요약하고, 답변은 만들지 않은 채 요약 블록 하나만 돌려줍니다. 대화는 원래 기록으로 계속 진행하다가, 블록이 도착하면 그때 갈아 끼웁니다.
| 항목 | 임계값 압축 (1월 베타) | 온디맨드 압축 (9월 베타) |
|---|---|---|
| 요약 시점 | 입력 토큰이 임계값에 닿을 때 자동 | 개발자가 요청을 보내는 시점 |
| 요약 중 대기 | 요청 처리 안에서 발생 | 없음, 백그라운드 실행 가능 |
| 블록의 위치 | 요약한 메시지 뒤에 붙고 앞은 서버가 버림 | 요약한 메시지를 대체하며 맨 앞에 옴 |
| 최근 턴 원문 보존 |
| 압축 요청에서 빼두면 그대로 남음 |
| 쓸 수 있는 곳 | Claude API, AWS, Bedrock, Google Cloud, Microsoft Foundry | Claude API만 |
요약 요청은 답변을 돌려주지 않습니다
요청은 평소 보내던 대화에 파라미터 한 줄과 베타 헤더를 더한 형태입니다.
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: compact-2026-09-04" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 4096,
"messages": [ ... ],
"compaction": {"type": "summarize"}
}'
돌아오는 응답에는 텍스트 답변이 없습니다. content에 compaction 블록 하나가 들어 있고 stop_reason은 "compaction"입니다. 블록에는 요약문과 함께 signature 값이 붙습니다. 이 서명을 포함해 블록을 원형 그대로 다시 보내야 API가 받아들입니다.
이후 요청에서는 블록을 messages 맨 앞에 두고, 요약된 메시지들은 지웁니다. 블록 앞에 옛 메시지가 남아 있으면 400 오류 compaction_block_misplaced가 납니다. 블록 뒤의 메시지는 손대지 않고 그대로 모델에 전달됩니다.
API는 보낸 메시지를 전부 요약하므로, 남기고 싶은 최근 턴을 압축 요청에 아예 넣지 않으면 됩니다. 그러면 요약 블록 뒤에 그 턴들이 이어집니다. thinking을 보존하는 모델에서는 남긴 턴의 thinking도 두 조건을 지키면 유효하게 남습니다. 남긴 턴이 요약된 메시지 바로 뒤에 이어졌을 것, 그리고 system과 defer_loading: true가 아닌 tools가 압축 요청과 같을 것입니다. 긴 작업을 하던 에이전트의 생각이 요약 직후에도 끊기지 않습니다.
요약 프롬프트도 바꿀 수 있습니다. instructions에 최대 16,384자까지 쓰면 기본 요약 프롬프트를 통째로 대체합니다. Fable 5.1과 Mythos 5.1에서 임계값 압축은 커스텀 instructions를 쓰면 이전 thinking을 요약 입력에서 뺐는데, 온디맨드 압축은 instructions 유무와 상관없이 이전 thinking까지 읽습니다.
청구서에는 0토큰으로 찍힙니다
요약 호출은 공짜가 아닙니다. 그 요청의 model, system, tools, thinking 설정, max_tokens를 그대로 쓰는 실제 모델 호출이고, 일반 요청처럼 과금되고 레이트 리밋에도 걸립니다. 그런데 응답의 최상위 토큰 필드는 0입니다. 답변을 만들지 않았기 때문입니다. 실제 사용량은 usage.iterations 안의 compaction 항목에만 들어갑니다.
{
"stop_reason": "compaction",
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
}
}
비용 집계가 응답의 usage.input_tokens만 더하고 있다면 압축 호출은 장부에 0으로 남습니다. 요약은 긴 대화 전체를 입력으로 넣는 호출이라 단건 비용이 작지 않습니다. 켜기 전에 집계 코드부터 iterations를 합산하도록 고쳐야 전후 비교가 됩니다.
요약이 항상 나오는 것도 아닙니다. 요약 호출이 도구를 부르지 않고 텍스트로 정상 종료했을 때만 블록이 만들어집니다. 그 외에는 200 응답에 content가 비어서 오고, 호출은 그대로 과금됩니다. 원인은 stop_reason으로 구분합니다. "max_tokens"면 요약이 잘린 것이라 max_tokens를 키워 다시 부르고, "model_context_window_exceeded"면 instructions를 줄이거나 보내는 메시지를 줄입니다. "tool_use"면 모델이 요약 대신 도구를 불렀다는 뜻이라 instructions에 도구를 부르지 말라고 적어야 합니다. "refusal"은 안전 정책에 걸린 경우이고 stop_details에 정책 범주가 담깁니다.
지금 켤 수 있는 조건
개발자용 기능입니다. Claude 앱이나 Claude Code 설정에서 켜는 항목이 아닙니다. Claude API를 직접 호출하는 코드에 헤더를 더해야 켜집니다.
| 항목 | 조건 |
|---|---|
| 대상 | Claude API를 쓰는 개발자, API 키 필요 |
| 요금 | 별도 요금 없음, 요약 호출이 일반 요청처럼 토큰 과금 |
| 한국 사용 | 가능, 지역 제한 없음 (Anthropic 지원 국가 목록에 한국 포함) |
| 필요 조건 | 헤더 |
| 모델 | Fable 5.1, Mythos 5.1, Fable 5, Mythos 5, Mythos Preview, Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 5, Sonnet 4.6 |
막히는 곳도 있습니다. Amazon Bedrock과 Google Cloud에서는 못 씁니다. 임계값 압축이 두 곳에서 베타로 돌아가는 것과 다릅니다. 한 요청에 compaction과 context_management를 같이 보낼 수 없고, 서명된 블록을 실은 요청에서는 임계값 압축(compact_20260112)이 동작하지 않습니다. stop_sequences, 구조화 출력 output_config.format, tool_choice의 any와 tool 타입은 압축 요청에 넣으면 거부됩니다. 마지막 assistant 턴이 결과 없는 도구 호출로 끝난 상태여도 거부되므로 도구 결과를 먼저 보내야 합니다.
눈치채기 가장 어려운 쪽은 데이터입니다. 요약되는 범위 안의 이미지, 문서, container_upload 블록, 가져온 URL은 블록이 그 자리를 대체하는 순간 사라집니다. 뒤 턴에서 다시 필요하면 내용을 다시 넣거나 파일을 다시 올려야 합니다. 대화가 여전히 모델 컨텍스트 창 안에 들어가야 요약도 가능하므로, 창을 넘기고 나서가 아니라 넘기기 전에 압축해야 합니다.
에이전트에 자체 요약 로직을 이미 돌리고 있다면, 다음 긴 세션 하나에서 요약을 부르던 그 시점의 messages를 그대로 압축 요청으로 보내 보세요. usage.iterations의 토큰 수를 지금 쓰는 요약 호출 옆에 적어 두면 차이가 바로 드러납니다. Amazon Bedrock이나 Google Cloud로 트래픽을 보내는 팀에는 이번 베타가 아직 해당되지 않습니다. 그쪽은 임계값 압축에 pause_after_compaction을 켜 두는 것이 지금 남은 선택지이고, 두 플랫폼 지원 여부는 Claude Platform 릴리스 노트에 올라옵니다.