Claude Code - 컨텍스트 관리

Claude Code - 컨텍스트 관리 (Context Management)

LiteLLM은 Anthropic의 context_management 베타를 Anthropic뿐만 아니라 모든 프로바이더에서 네이티브하게 지원합니다.

context_management 스펙과 함께 /v1/messages(또는 litellm.anthropic.messages.*)에 요청을 보내면, LiteLLM은 요청이 라우팅되는 위치에 따라 두 가지 방식 중 하나로 처리합니다:

라우팅 경로 context_management 적용 방식
Anthropic API Anthropic 서버로 패스스루, 네이티브로 edits 적용
OpenAI Responses API (예: gpt-5.x-*) 패스스루; Responses API가 처리
그 외 다른 프로바이더 (OpenAI, xAI, Gemini, Azure, non-Anthropic Bedrock, …) 게이트웨이 내 폴리필 - LiteLLM이 전달하기 전에 메시지 배열에 edits 적용

이 폴리필은 Claude Code 도구 루프를 한 번만 작성하고, 평소처럼 context_management 를 전달하면, 프록시 뒤의 모델이 무엇이든 동작한다는 뜻입니다.

출처: 문서

본문

지원되는 편집 유형

편집 유형 상태 동작
clear_tool_uses_20250919 ✅ 지원 트리거 임계값이 충족되면 대화 히스토리에서 오래된 tool_result 콘텐츠를 지우고, 가장 최근 N개의 도구 결과만 온전히 유지
clear_thinking_20251015 ❌ 곧 제공 히스토리에서 확장 사고(extended thinking) 블록 제거
compact_20260112 ✅ 지원 요약 편집 - LiteLLM이 구성된 요약 모델을 호출해 요약을 시스템 접두사로 주입하고, 응답에 compaction 블록 반환

동작 방식

Claude Code client
        │
        │  POST /v1/messages  { context_management: { edits: [...] } }
        ▼
┌─────────────────────────────────────────────────────────┐
│                    LiteLLM Proxy                        │
│                                                         │
│  1. Detect routing target                               │
│                                                         │
│  ┌──────────────────────┐   ┌────────────────────────┐  │
│  │  Anthropic / Bedrock │   │  Any other provider    │  │
│  │  Anthropic / OpenAI  │   │  (OpenAI, xAI, Gemini, │  │
│  │  Responses API       │   │   Azure, …)            │  │
│  │                      │   │                        │  │
│  │  Pass context_mgmt   │   │  In-gateway polyfill:  │  │
│  │  spec through as-is  │   │                        │  │
│  │  (server applies it) │   │  clear_tool_uses:      │  │
│  └──────────┬───────────┘   │  • Count input tokens  │  │
│             │               │  • Check trigger       │  │
│             │               │  • Clear old results   │  │
│             │               │  • Keep N most recent  │  │
│             │               │                        │  │
│             │               │  compact_20260112:     │  │
│             │               │  • Slice at compaction │  │
│             │               │    block (if present)  │  │
│             │               │  • Check token trigger │  │
│             │               │  • Call summary model  │  │
│             │               │  • Inject summary as   │  │
│             │               │    system prefix       │  │
│             │               └──────────┬─────────────┘  │
│             │                          │                 │
│             └────────────┬─────────────┘                 │
│                          │                               │
│  2. Forward to provider  │                               │
│     (without context_    │                               │
│      management key)     │                               │
└──────────────────────────┼──────────────────────────────┘
                           ▼
                    Upstream model
                           │
                    Response + usage
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│  LiteLLM attaches applied_edits to response             │
│  { context_management: { applied_edits: [...] } }       │
│  (compact also prepends a compaction block to content)  │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
                    Claude Code client

사용법

기본 요청

import litellm

response = await litellm.anthropic.messages.acreate(
    model="xai/grok-4",          # any provider
    max_tokens=1024,
    messages=[...],              # your multi-turn tool history
    tools=[{"name": "get_weather", "description": "...", "input_schema": {...}}],
    context_management={
        "edits": [
            {
                "type": "clear_tool_uses_20250919",
                "trigger": {
                    "type": "input_tokens",
                    "value": 80000          # activate when history exceeds 80k tokens
                },
                "keep": {
                    "type": "tool_uses",
                    "value": 3              # keep the 3 most-recent tool results
                }
            }
        ]
    }
)

토큰 대신 도구 사용 수로 트리거할 수도 있습니다:

"trigger": {"type": "tool_uses", "value": 10}   # activate after 10 tool calls

프록시를 통한 요청 (curl)

curl -X POST http://localhost:4000/v1/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-5.6-luna",
    "max_tokens": 1024,
    "messages": [...],
    "tools": [...],
    "context_management": {
      "edits": [
        {
          "type": "clear_tool_uses_20250919",
          "trigger": {"type": "input_tokens", "value": 80000},
          "keep":    {"type": "tool_uses",    "value": 3}
        }
      ]
    }
  }'

compact_20260112 - 대화 압축

compact_20260112 편집 유형은 입력 토큰 수가 임계값을 초과하면 대화 히스토리를 요약합니다. LiteLLM의 폴리필은 이를 Anthropic뿐만 아니라 어떤 프로바이더에서도 동작하게 합니다.

설정 - 요약 모델 구성

폴리필은 별도로 구성된 모델을 호출해 요약을 생성합니다. proxy config의 general_settingscontext_management_summary_model 을 추가하세요:

# proxy_server_config.yaml
general_settings:
  context_management_summary_model: claude-sonnet-5   # any model alias in your model_list

이 설정이 없으면 폴리필은 no-op 이고 applied_edits[0].error: "summary_model_not_configured" 가 반환됩니다.

사용법

import litellm

response = await litellm.anthropic.messages.acreate(
    model="gpt-5.6-luna",          # any non-Anthropic provider
    max_tokens=1024,
    messages=[...],                # multi-turn history
    context_management={
        "edits": [
            {
                "type": "compact_20260112",
                "trigger": {
                    "type": "input_tokens",
                    "value": 80000          # compact when history exceeds 80k tokens
                }
            }
        ]
    }
)

프록시를 통한 요청 (curl)

curl -X POST http://localhost:4000/v1/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{
    "model": "gpt-5.6-luna",
    "max_tokens": 1024,
    "messages": [...],
    "context_management": {
      "edits": [
        {
          "type": "compact_20260112",
          "trigger": {"type": "input_tokens", "value": 80000}
        }
      ]
    }
  }'

동작 방식 (3단계)

Phase A: 기존 compaction 블록 슬라이스 — 메시지 히스토리에 이미 compaction 블록(이전 압축 라운드에서)이 있으면 그 블록 이전의 모든 것을 버리고 요약 텍스트를 시스템 프롬프트에 앞에 붙입니다. 이는 이전 컨텍스트를 이어 나가기 위함이에요.

Phase B: 임계값 검사 — LiteLLM은 (슬라이스된) 메시지 히스토리의 유효 입력 토큰을 셉니다. 트리거 임계값 이하이면 요청을 즉시 전달하며 요약 호출을 하지 않습니다.

Phase C: 요약 (임계값을 초과할 때만) — LiteLLM은 구성된 context_management_summary_model 을 전체 대화 히스토리와 요약 프롬프트로 호출합니다. 요약은:

  • 다운스트림 모델 호출의 시스템 메시지에 "Previous conversation summary: ..." 접두사로 주입
  • 응답 콘텐츠 배열 앞에 compaction 콘텐츠 블록으로 반환되어 Claude Code 클라이언트가 롤링 압축 상태를 유지할 수 있게 함

커스텀 요약 프롬프트

instructions 필드로 기본 요약 지침을 오버라이드할 수 있어요:

context_management={
    "edits": [
        {
            "type": "compact_20260112",
            "trigger": {"type": "input_tokens", "value": 80000},
            "instructions": "Summarize the key decisions made and open questions. Wrap in <summary></summary> tags."
        }
    ]
}

요약 텍스트는 <summary>...</summary> 태그로 감싸야 합니다. 모델이 이 태그 없이 텍스트를 반환하면 applied_edits[0].error: "summary_extraction_failed" 가 설정되고 원래(압축되지 않은) 대화가 전달됩니다.

compact_20260112 - 노브

필드 필수 기본 설명
trigger.type 아니요 "input_tokens" "input_tokens" 만 지원; 다른 값은 경고와 함께 폴백
trigger.value 아니요 150000 토큰 임계값. ≥ 50,000이어야 하며, 그보다 낮으면 400으로 거부
instructions 아니요 Anthropic 기본 프롬프트 커스텀 요약 프롬프트; 모델이 출력을 <summary> 태그로 감싸도록 지시해야 함
pause_after_compaction 수락됨 요청에서 수락되지만 무시됨 (경고가 applied_edits 에 기록)

compact_20260112 - 응답

압축이 발동하면 응답에 context_management.applied_edits 와 content 앞에 붙은 compaction 블록이 포함됩니다:

{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "compaction",
      "content": "The user is building a Python CLI tool. We have implemented the argument parser and file reader. Next step is to add the output formatter."
    },
    {"type": "text", "text": "Sure, here's the output formatter..."}
  ],
  "model": "gpt-5.6-luna",
  "stop_reason": "end_turn",
  "usage": {"input_tokens": 420, "output_tokens": 120},
  "context_management": {
    "applied_edits": [
      {
        "type": "compact_20260112",
        "summary_input_tokens": 8400,
        "summary_output_tokens": 210
      }
    ]
  }
}

트리거가 충족되지 않으면 context_management 이 없고 compaction 블록도 붙지 않습니다.

오류 처리

폴리필은 best-effort입니다. 요약 호출이 실패하거나 파싱 가능한 요약을 반환하지 않으면 원래 대화가 그대로 전달되고 applied_edits[0].error 가 설정됩니다:

error 값 원인
"summary_model_not_configured" general_settingscontext_management_summary_model 이 설정되지 않음
"summary_call_failed" 요약 모델 호출이 예외 발생
"summary_extraction_failed" 요약 모델 응답에 <summary>...</summary> 블록이 없음

클라이언트 측 compaction 블록 (context_management 편집 없음)

요청에 compact_20260112 편집이 없지만 메시지 히스토리에 이미 compaction 블록이 있으면(예: 이전 Claude Code 클라이언트 측 압축), LiteLLM이 자동으로 슬라이스-전용 전달을 적용합니다: 이전 요약을 시스템 접두사로 옮기고 최신 사용자 질문만 다운스트림으로 보냅니다. 요약 모델 호출은 하지 않습니다.

clear_tool_uses_20250919 - 노브

필드 필수 기본 설명
trigger.type 아니요 "input_tokens" "input_tokens" 또는 "tool_uses"
trigger.value 아니요 100000 임계값; 현재 값이 이를 초과하면 edits가 발동
keep.type 아니요 "tool_uses" 반드시 "tool_uses"
keep.value 아니요 3 보존할 가장 최근 도구 결과 수
clear_at_least 수락됨 요청에서 수락되지만 폴리필이 무시 (v0)
exclude_tools 수락됨 요청에서 수락되지만 폴리필이 무시 (v0)
clear_tool_inputs 수락됨 요청에서 수락되지만 폴리필이 무시 (v0)

하드 플로어: keep 와 무관하게 LiteLLM의 폴리필은 가장 최근에 완료된 tool_result — 모델이 이제 막 답변하려는 것 — 를 절대 지우지 않습니다.

응답

비스트리밍

적어도 하나의 편집이 발동하면 응답에 context_management 필드가 포함됩니다:

{
  "id": "msg_01XFDUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "content": [{"type": "text", "text": "Based on the latest weather data..."}],
  "model": "gpt-5.6-luna",
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 620,
    "output_tokens": 45
  },
  "context_management": {
    "applied_edits": [
      {
        "type": "clear_tool_uses_20250919",
        "cleared_tool_uses": 3,
        "cleared_input_tokens": 8240
      }
    ]
  }
}

트리거가 충족되지 않으면(컨텍스트가 여전히 작으면) context_management 가 응답에 없습니다.

스트리밍

context_management.applied_edits 필드는 마지막 message_delta SSE 이벤트에 포함됩니다:

event: message_start
data: {"type":"message_start","message":{"id":"msg_01...","type":"message","role":"assistant","content":[],"model":"gpt-5.6-luna","stop_reason":null,"usage":{"input_tokens":620,"output_tokens":0}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Based on"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the latest weather data..."}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {
  "type": "message_delta",
  "delta": {"stop_reason": "end_turn", "stop_sequence": null},
  "usage": {"output_tokens": 45},
  "context_management": {
    "applied_edits": [
      {
        "type": "clear_tool_uses_20250919",
        "cleared_tool_uses": 3,
        "cleared_input_tokens": 8240
      }
    ]
  }
}

event: message_stop
data: {"type":"message_stop"}

컨텍스트 관리 비활성화

요청별 - 필드 생략

요청 본문에 context_management 을 포함하지 마세요.

모델별 - additional_drop_params

모델을 폴리필에서 제외하려면 그 모델의 additional_drop_paramscontext_management 를 나열하세요. LiteLLM은 폴리필을 실행하는 대신 그 모델로의 요청에서 context_management 를 조용히 제거합니다:

# proxy_server_config.yaml
model_list:
  - model_name: gpt-4.1
    litellm_params:
      model: openai/gpt-4.1
      additional_drop_params: ["context_management"]

또는 호출 시점:

import litellm
litellm.completion(..., additional_drop_params=["context_management"])

drop_params: true 는 폴리필을 비활성화하지 않습니다. context_management 는 LiteLLM 지원 파라미터(Anthropic에서는 네이티브, 그 외는 폴리필)이고, drop_params 는 진짜로 지원되지 않는 파라미터만 버리기 때문입니다.

프로바이더 지원 매트릭스

프로바이더 clear_tool_uses_20250919 compact_20260112
anthropic/* 네이티브 패스스루 네이티브 패스스루
bedrock/anthropic.* 네이티브 패스스루 네이티브 패스스루
openai/* (Responses API) 네이티브 패스스루 네이티브 패스스루
openai/* (chat completions) 폴리필 폴리필
azure/* 폴리필 폴리필
xai/* 폴리필 폴리필
gemini/* 폴리필 폴리필
vertex_ai/* 폴리필 폴리필
그 외 모든 프로바이더 폴리필 폴리필

참고

  • compact_20260112general_settingscontext_management_summary_model 이 설정된 것을 요구합니다. 없으면 편집은 인지되지만 압축은 수행되지 않습니다.
  • 폴리필 임계값 검사의 토큰 카운팅은 litellm.token_counter 를 사용합니다 (알 수 없는 모델은 tiktoken cl100k_base 폴백).
  • clear_tool_uses_20250919 는 메시지 배열 구조를 보존합니다: 같은 수의 메시지, 같은 역할 순서. 일치하는 메시지 안의 tool_result.content"[Cleared by context management]" 로 교체됩니다.
  • compact_20260112 는 이전 히스토리 전체를 단일 시스템 접두사 요약 + 마지막 사용자 질문으로 축소합니다. 응답의 compaction 블록은 Claude Code 클라이언트가 다음 턴으로 이어갈 요약 텍스트를 제공합니다.
  • compact_20260112 트리거의 50,000 토큰 최소값은 프록시에서 강제되며, 더 낮은 값이 포함된 요청은 HTTP 400으로 거부됩니다.

더 알아보기 (Learn more)