블로그 • AI / API

Claude API 2026 새 변화: Conversation Compaction은 무엇인가? AI Agent는 JSON으로 긴 컨텍스트와 압축된 상태를 어떻게 저장하는가?

Agent가 오래 돌수록 Messages 배열은 길어진다. 도구 결과, 사고 블록, 사용자 왕복이 컨텍스트 창을 채운다. 2026년 Messages API는 이를 공식 능력으로 접었다: Conversation Compaction.

Compaction은 클라이언트에서 요약을 써서 다시 붙이는 것이 아니다. API가 type: "compaction" JSON을 발급한다. 다음 요청에서 이 블록을 그대로 messages에 넣어야 세션이 압축된 상태에서 이어진다.

이 글에서는:

이것만 기억하라: 디스크에 남기는 것은 「대화 전문」이 아니라, 최신 compaction 블록과 그 뒤에서 아직 먹히지 않은 턴이다. 블록의 content, signature, encrypted_content는 계약이지 주석이 아니다. 아래는 「두 가지 압축 → 블록 모양 → 디스크 목록 → 자리 바꾸기」로 가른다.

Compaction이 압축하는 구간

공식 위치는 분명하다. 서버 측 압축은 긴 대화와 Agent 워크플로의 권장 방법이며, 클라이언트에서 요약 코드를 직접 쓸 필요는 없다. 창이 옛 내용으로 차면 응답 품질이 떨어진다. 압축은 더 이른 내용을 요약으로 바꿔, 유효 컨텍스트가 앞으로 가게 한다. 설명은

Claude API Compaction.

임계값 압축을 켜면 API는 네 단계를 한다. 입력 token이 트리거에 닿고, 요약을 만들고, compaction 블록을 쓰고, 압축된 컨텍스트로 답을 이어 간다. 다음에 assistant 응답 전체를 messages에 붙이면 API는 이 블록 앞의 내용을 버리고 요약부터 대화를 이어 간다.

손실 압축이다. 실제로 쓴 도구 인자, 원문, 초기 사고는 글자 그대로 남지 않는다. 남는 것은 목표, 결정, 뒤에서 쓸 사실이다. 「messages 배열 전체를 데이터베이스에 넣는 것」과 같은 일이 아니다. Agent 기술 스택에서 컨텍스트가 어떻게 늘어나는지는

2026 AI Agent 기술 스택.

두 갈래: 임계값 압축과 온디맨드 압축

2026년에는 beta가 두 줄이다. 같은 요청에 섞지 마라. 공식 문서는 compaction 파라미터를 context_management와 함께 보내지 말라고 적는다.

경로 Beta 헤더 JSON에 무엇을 쓰는가 블록이 나타나는 곳
임계값 압축 compact-2026-01-12 context_management.edits에 compact_20260112 일반 답 맨 앞. 뒤에 text가 이어질 수 있다
온디맨드 압축 compact-2026-09-04 최상위 compaction: {"type":"summarize"} 단독 한 줄, stop_reason는 compaction, 일반 답은 없다

임계값 압축의 트리거 기본값은 input_tokens 150000, 최저는 50000이다. 선택 pause_after_compaction: 요약을 쓴 뒤 먼저 멈추고, 최근 몇 턴이나 지시 메시지를 블록 뒤에 끼운 다음 생성을 이어 간다. 직접 쓴 instructions는 기본 요약 프롬프트를 통째로 바꾸며, 최장 16384자이다.

9월 라인의 핵심은 온디맨드 압축이다. 언제 압축할지는 당신이 정한다. 요약 요청은 백그라운드에서 돌리고 대화는 전체 이력으로 이어 갈 수 있다. 최근 몇 턴의 원문을 요약 뒤에 남겨도 된다. 서명 블록은 messages 맨 앞에 두고, 요약된 메시지는 블록 앞에서 빼야 한다. 그렇지 않으면 400이고 오류 이름은 compaction_block_misplaced이다. Bedrock과 Google Cloud에는 온디맨드 라인이 없다.

압축 전후의 Messages JSON

압축 전부터 보자. 평범한 user / assistant 턴이다.

온디맨드 압축 요청(공식 문서에서 발췌)
{
  "model": "claude-opus-5",
  "max_tokens": 4096,
  "messages": [
    {
      "role": "user",
      "content": "I am building a recipe app. Help me name the main entities in the data model."
    },
    {
      "role": "assistant",
      "content": "Start with Recipe, Ingredient, and Step."
    },
    {
      "role": "user",
      "content": "Good. Now suggest field names for Recipe."
    }
  ],
  "compaction": { "type": "summarize" }
}

응답은 서명된 compaction 블록 하나뿐이고, stop_reason는 compaction이다. 이후 매 요청에서 이 블록이 맨 앞에 있어야 하고, 뒤에는 「이번 요약에 먹히지 않은」 턴만 온다.

압축 후 대화 이어 가기: 블록이 맨 앞, 옛 메시지는 이미 빠졌다
{
  "model": "claude-opus-5",
  "max_tokens": 2048,
  "messages": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "compaction",
          "content": "Summary of the conversation: the user is designing the data model for a recipe app...",
          "signature": "EuYBCkQY..."
        }
      ]
    },
    {
      "role": "assistant",
      "content": "For Recipe, use title, description, servings..."
    },
    {
      "role": "user",
      "content": "Now do the same for Ingredient."
    }
  ]
}

임계값 압축의 블록은 답 안에 「끼워진」 형태다. assistant의 content 배열은 먼저 compaction, 그다음 text다. 여러 번 압축하면 마지막 블록이 기준이고, 그것이 현재 프롬프트의 최종 상태다. API는 이 블록을 보면 그 앞의 콘텐츠 블록을 무시한다. 통째로 되돌려 보내도 되고, 옛 메시지를 버리고 이 블록부터 보내도 된다.

필드 무엇인가 바꿀 수 있는가
type 고정 compaction 안 됨
content 요약 텍스트. 실패하면 null 글자를 바꾸지 마라. 빈 문자열은 불법이다
signature 온디맨드 압축이 돌려주는 서명 반드시 그대로 되돌려 보내라
encrypted_content 불투명 메타데이터. SDK 타입은 verbatim 회신을 요구한다 있으면 그대로 두고, 파싱하지 마라
cache_control 선택. 요약만 따로 cache 중단점을 둔다 당신이 더하는 것이지, 발급 필드가 아니다

SDK는 encrypted_content를 「이전 압축이 남긴 불투명 메타데이터이며 그대로 round-trip해야 한다」고 적는다. 클라이언트는 분해하지 말고, 요약 본문으로 보여 주지도 마라. 실패 블록의 content가 null이면 서버는 빈 동작으로 본다. 되돌려 보낼 수는 있지만 유효한 요약으로 쓰지 않는다.

session 복구에 남겨야 하는 필드

Agent가 재시작되면 메모리의 messages는 사라진다. 복구할 것은 「압축 전 채팅 기록 전체」가 아니라, 압축 후에도 요청을 이어 갈 수 있는 상태다.

  1. 1
    최신 compaction 블록

    블록 JSON 전체. content, signature, encrypted_content를 포함한다. 여러 블록이 있으면 최신 하나만 있으면 된다. 한 번 더 압축하면 옛 요약과 그 뒤 내용을 함께 먹는다.

  2. 2
    블록 뒤의 messages

    이번 요약이 덮지 않은 user / assistant 턴, 원래 순서 그대로. 백그라운드 압축 동안 새로 생긴 턴도 여기에 있다.

  3. 3
    당시의 system과 tools

    온디맨드 압축에서 요약 요청은 대화의 나머지와 같은 system와 tools를 실어야 한다. 사고를 보존하는 모델에서, 블록 뒤 턴의 thinking이 살아 있는지는 이 둘이 바뀌었는지, 그리고 꼬리가 요약된 메시지에 바로 붙어 있는지에 달렸다.

  4. 4
    어느 beta를 탔는가

    임계값 압축은 계속 compact-2026-01-12를 단다. 온디맨드 압축 블록은 이후 매 요청에 compact-2026-09-04를 달아야 한다. 헤더가 틀리면 블록을 인정하지 않을 수 있다.

최소 session 디스크 형태(예시. 공식 schema 아님)
{
  "beta": "compact-2026-09-04",
  "model": "claude-opus-5",
  "system": "You are a coding agent.",
  "tools": [],
  "compaction_block": {
    "type": "compaction",
    "content": "Summary of the conversation: ...",
    "signature": "EuYBCkQY...",
    "encrypted_content": "..."
  },
  "tail": [
    {
      "role": "assistant",
      "content": "For Recipe, use title, description..."
    },
    {
      "role": "user",
      "content": "Now do the same for Ingredient."
    }
  ]
}

요청을 다시 만들 때 messages[0]에는 이 블록을 가진 assistant를 두거나, 블록을 첫 메시지의 첫 content에 넣고, 그다음 tail를 이어 붙인다. 압축 전 옛 user 메시지를 블록 앞에 다시 넣지 마라.

권한 평가와는 층이 다르다. 그쪽은 Tool Call을 돌려도 되는지를 맡고, 이쪽은 창이 먹힌 뒤에도 상태가 남아 있는지를 맡는다. 권한 글은

Claude Managed Agents는 Tool Call을 어떻게 자동 판단하는가. 긴 흐름에서 Agent가 어떻게 협업하는지는

Claude는 AI 연구개발 워크플로에 어떻게 참여하는가.

백그라운드 압축과 꼬리를 남길 때 자리 바꾸기

온디맨드 압축 요청은 받은 메시지만 요약한다. 그래서 옛 턴만 보내 압축하고, 최근 몇 턴의 원문은 로컬에 둘 수 있다. 끝나면 블록을 그 턴 앞에 끼운다. 공식이 부르는 이름은 keep-tail이다.

백그라운드 압축(async)은 한 걸음 더 간다. 요약이 도는 동안 대화는 전체 이력으로 이어진다. 돌아온 뒤에는 이력 전체를 블록 하나로 바꾸면 안 된다. 그때 압축에 보낸 몇 줄만 큐 앞에서 빼고, 돌아온 assistant 메시지를 넣으며, 뒤에 새로 생긴 턴은 그대로 둔다.

백그라운드 압축 자리 바꾸기(공식 예시)
if response.stop_reason == "compaction":
    compaction_message = {
        "role": "assistant",
        "content": response.content,
    }
    history = [compaction_message] + history[sent_count:]
# sent_count = number of messages sent in the compaction request

이미 이력에 있는 메시지는 중간에 고치지 마라. 자리 바꾸기는 블록이 도착한 뒤 첫 요청에서 해야, 요약 동안 생긴 thinking이 유효하다. 블록이 없으면 전체 이력을 유지하고 나중에 다시 시도한다.

임계값 압축에서 pause_after_compaction를 켜면 응답에는 대체로 이 블록만 있고, stop_reason도 compaction이다. 남길 원문을 블록 뒤에 붙인 뒤 다음 요청을 보낸다. 주의: Claude Fable 5.1에서 옛 assistant 턴을 블록 뒤에 다시 끼우면 그 안의 thinking / redacted_thinking를 빼거나, thinking-binding-controls-2026-08-01를 달고 prefix_mismatch_behavior: "drop_block"를 설정하지 않으면 400이 날 수 있다. 그 사고 블록은 전체 이력을 보고 만들어진 것이라 압축 후 대화와 맞지 않는다.

prompt cache와 어떻게 겹치는가

압축과 prompt caching은 같이 쓸 수 있다. compaction 블록에 cache_control: {"type":"ephemeral"}를 달면 요약만 따로 캐시에 들어간다. 시스템 프롬프트 끝에 중단점을 하나 더 두면, 압축이 일어나도 시스템 프롬프트 캐시는 맞고 요약 구간만 다시 쓴다.

과금은 최상위 usage만 보지 마라. 압축 반복 token은 usage.iterations에 잡힐 수 있다. 디스크 측은 여전히 블록과 꼬리만 보면 된다. usage를 세션 복구 계약으로 쓰지 마라.

JSONNote로 블록과 이력을 대조하기

압축 전후 JSON 크기는 크게 다르고, 필드는 눈으로 훑을 수 없다. 디버그는 문장이 아니라 위치를 본다.

  1. 1
    먼저 디스크 파일을 포맷한다

    session JSON을 JSON 포맷에 넣고 compaction_block.type이 compaction인지, signature가 남아 있는지 확인한다.

  2. 2
    블록 모양을 검증한다

    JSON Schema로 최소 schema를 쓴다. type 열거는 compaction만. content는 string 또는 null. signature / encrypted_content가 있으면 string으로 본다. 빈 문자열은 금지.

  3. 3
    압축 전후 messages를 비교한다

    JSON Diff로 큐 앞에서 빠진 턴과 블록 뒤에 생긴 것을 본다. 온디맨드 압축 뒤에는 블록 앞에 요약된 user 메시지가 있으면 안 된다.

  4. 4
    회고할 때 서명을 마스킹한다

    요약 본문은 사람에게 보여도 된다. 서명과 불투명 필드는 Hash 공유 전에 먼저 마스킹한다. 세션을 이어 주는 값이니 일반 텍스트로 보내지 마라.

자주 묻는 질문

Conversation Compaction은 대화 전체를 지우는가?

아니다. API는 이미 압축된 옛 메시지를 요약으로 바꾼다. 요약은 type이 compaction인 콘텐츠 블록에 들어 있다. 이 블록을 그대로 되돌려 보내야 세션이 요약부터 이어진다.

session을 복구하려면 최소한 어떤 JSON을 남겨야 하는가?

적어도 최신 compaction 블록(content, signature, encrypted_content 포함), 블록 뒤의 messages 전부, 그리고 당시의 system과 tools를 남겨라. 서명이나 불투명 필드를 빼면 다음 요청이 이어지지 않는다.

임계값 압축과 9월 온디맨드 압축은 무엇이 다른가?

임계값 압축은 compact-2026-01-12를 타고, 일반 요청에서 token으로 발동한다. 온디맨드 압축은 compact-2026-09-04를 타고, 따로 compaction: {type: summarize}를 보낸다. 서명된 블록이 돌아오며, messages 맨 앞에 두어야 한다.

직접 쓴 요약 텍스트로 compaction 블록을 대신할 수 있는가?

같은 계약으로는 쓸 수 없다. 플랫폼이 인정하는 것은 자신이 발급한 블록이다. 직접 쓴 user 텍스트는 다른 메시지일 뿐이다. signature가 없고, API가 블록 앞의 옛 내용을 버리게 하지도 못한다.

compaction 블록의 content를 고쳐서 다시 보낼 수 있는가?

고치지 마라. 공식은 그대로 되돌려 보내라고 한다. content가 빈 문자열이면 불법이다. content가 null이면 압축 실패이고, 서버는 빈 동작으로 본다. signature나 encrypted_content를 바꾸면 이후 요청이 실패하거나 요약을 잃는다.

요약

Conversation Compaction은 「창이 터지기 직전」을 되돌려 보낼 수 있는 JSON 한 덩어리로 접는다. 임계값 압축은 일반 요청에서 자동으로 일어나고, 9월 온디맨드 압축은 언제 압축하든, 백그라운드로 돌릴 수 있든, 최근 몇 턴의 원문을 남길지를 당신이 정한다.

session 복구는 최신 compaction 블록과 그 뒤 tail이지, 압축 전 전문이 아니다. content, signature, encrypted_content는 그대로 두고 그대로 보낸다. 블록 위치가 틀리면 API는 그 이력을 아직 들고 있는 척하지 않는다.

블록과 tail을 두 계약으로 읽어라. 사람이 지켜야 하는 긴 작업은 요약 instructions에 남겨야 할 엔티티와 미결 문제를 밝힌다. 덜 끊기는 Agent는 온디맨드 압축으로 백그라운드에서 블록을 바꾸고, 메모리에 직접 쓴 설명만 남기지 마라.

← 블로그로