컨텍스트 편집
컨텍스트 편집 (Context editing)
컨텍스트 편집은 대화 기록이 커짐에 따라 특정 콘텐츠를 선택적으로 지워 컨텍스트를 자동으로 관리해 줘요. 도구 결과 지우기, thinking 블록 지우기, 클라이언트 측 SDK 컴팩션 같은 전략을 제공해요. 컨텍스트는 유한한 자원이고 관련 없는 콘텐츠는 모델의 집중력을 떨어뜨리므로, 무엇을 볼지 능동적으로 관리하는 데 유용해요.
출처: 문서
본문
개요
컨텍스트 편집은 대화 기록이 커짐에 따라 특정 콘텐츠를 선택적으로 지울 수 있게 해 줘요. 비용 최적화와 한도 내 유지 그 이상으로, 이것은 Claude가 보는 것을 능동적으로 큐레이션하는 일이에요. 컨텍스트는 수익이 감소하는 유한한 자원이고, 관련 없는 콘텐츠는 모델의 집중력을 떨어뜨리기 때문이에요. 컨텍스트 편집은 그 큐레이션에 대한 세밀한 런타임 제어를 줘요. 컨텍스트 관리의 광범위한 원칙은 Effective context engineering을 보세요. 이 페이지는 다음을 다뤄요.
- 도구 결과 지우기 - 도구 사용이 많은 에이전틱 워크플로에서 이제 더는 필요 없게 된 옛 도구 결과가 있을 때 가장 좋아요.
- Thinking 블록 지우기 - 확장 thinking을 쓸 때 thinking 블록을 관리하기 위한 것으로, 컨텍스트 연속성을 위해 최근 thinking을 보존하는 옵션이 있어요.
- 클라이언트 측 SDK 컴팩션 - 요약 기반 컨텍스트 관리를 위한 SDK 기반 대안(서버 측 컴팩션이 일반적으로 선호돼요).
| 접근 방식 | 실행 위치 | 전략 | 동작 방식 |
|---|---|---|---|
| 서버 측 | API | 도구 결과 지우기(clear_tool_uses_20250919) Thinking 블록 지우기(clear_thinking_20251015) |
프롬프트가 Claude에 도달하기 전에 적용돼요. 대화 기록에서 특정 콘텐츠를 지워요. 각 전략은 독립적으로 구성할 수 있어요. |
| 클라이언트 측 | SDK | 컴팩션 | tool_runner를 쓸 때 TypeScript와 Ruby SDK에서 사용할 수 있어요. 요약을 생성하고 전체 대화 기록을 대체해요. 클라이언트 측 컴팩션을 보세요. |
서버 측 전략
이 기능에 대한 피드백은 피드백 양식으로 공유해 주세요.
도구 결과 지우기
clear_tool_uses_20250919 전략은 대화 컨텍스트가 설정한 임계값을 넘으면 도구 결과를 지워요. 도구 사용이 많은 에이전틱 워크플로에 특히 유용해요. 오래된 도구 결과(파일 내용이나 검색 결과 같은)는 Claude가 처리하고 나면 더는 필요 없어요.
활성화되면 API가 가장 오래된 도구 결과를 시간순으로 자동으로 지워요. API는 지워진 각 결과를 Claude에게 제거됐다는 것을 알리는 자리 표시 텍스트로 대체해요. 기본적으로 도구 결과만 지워요. clear_tool_inputs를 true로 설정하면 도구 결과와 도구 호출(도구 사용 매개변수)을 모두 지울 수 있어요.
Thinking 블록 지우기
clear_thinking_20251015 전략은 확장 thinking이 활성화될 때 대화의 thinking 블록을 관리해요. 이 전략은 thinking 보존에 대한 제어를 줘요. 추론 연속성을 유지하기 위해 thinking 블록을 더 많이 남기거나, 컨텍스트 공간을 아끼기 위해 더 공격적으로 지울 수 있어요.
| 모델 계열 | 모든 이전 thinking 유지 | 마지막 턴의 thinking만 유지 |
|---|---|---|
| Opus | Claude Opus 4.5 이상 | Claude Opus 4.1 이하 |
| Sonnet | Claude Sonnet 4.6 이상 | Claude Sonnet 4.5 이하 |
| Haiku | (없음) | Claude Haiku 4.5까지 모든 모델 |
| Fable and Mythos | 모든 모델 | (없음) |
이 전략으로 기본값을 재정의하세요. 코드가 여러 모델 계층에서 실행된다면 모델별 기본값에 기대지 말고 keep을 명시적으로 설정하세요.
도우미 대화 턴은 여러 콘텐츠 블록(예: 도구를 쓸 때)과 여러 thinking 블록(예: 인터리브된 thinking으로)을 포함할 수 있어요.
컨텍스트 편집은 서버 측에서 일어나요
컨텍스트 편집은 프롬프트가 Claude에 도달하기 전에 서버 측에서 적용돼요. 클라이언트 애플리케이션은 완전하고 수정되지 않은 대화 기록을 유지해요. 편집된 버전과 클라이언트 상태를 동기화할 필요 없어요. 평소처럼 전체 대화 기록을 로컬에서 계속 관리하세요.
Claude Fable 5.1과 Claude Opus 5.5에서 서버 측 컨텍스트 관리는 thinking 블록을 절대 무효화하지 않아요. 이전 턴에 대한 클라이언트 측 편집은 이후 모든 도우미 턴의 thinking 블록을 무효화할 수 있어요. 2026년 8월 31일 이후에 생성된 새 계정은 무효화된 블록을 재생하는 요청을, 그것을 버리는 것을 선택하지 않으면 거부해요. 접두사 유지를 보세요.
컨텍스트 편집과 프롬프트 캐싱
컨텍스트 편집과 프롬프트 캐싱의 상호작용은 전략에 따라 달라요.
-
도구 결과 지우기: 콘텐츠가 지워지면 캐시된 프롬프트 접두사를 무효화해요. 이를 감안하려면 캐시 무효화가 그만한 가치가 있게 충분한 토큰을 지우세요.
clear_at_least매개변수로 매번 지워지는 최소 토큰 수를 보장하세요. 콘텐츠를 지울 때마다 캐시 쓰기 비용이 발생하지만, 이후 요청은 새로 캐시된 접두사를 재사용할 수 있어요. -
Thinking 블록 지우기: thinking 블록이 컨텍스트에 유지되면(지워지지 않으면) 프롬프트 캐시가 보존되어 캐시 적중이 가능하고 입력 토큰 비용이 줄어요. thinking 블록이 지워지면 지워지는 지점에서 캐시가 무효화돼요. 캐시 성능과 컨텍스트 창 가용성 중 어느 것을 우선시할지에 따라
keep매개변수를 구성하세요.
지원되는 모델
컨텍스트 편집은 지원되는 모든 Claude 모델에서 사용할 수 있어요.
도구 결과 지우기 사용법
도구 결과 지우기를 활성화하는 가장 간단한 방법은 전략 유형만 지정하는 거예요. 다른 모든 구성 옵션은 기본값을 사용해요.
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Search for recent developments in AI
tools:
- type: web_search_20250305
name: web_search
context_management:
edits:
- type: clear_tool_uses_20250919
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[{"role": "user", "content": "Search for recent developments in AI"}],
tools=[{"type": "web_search_20250305", "name": "web_search"}],
betas=["context-management-2025-06-27"],
context_management={"edits": [{"type": "clear_tool_uses_20250919"}]},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [
{
role: "user",
content: "Search for recent developments in AI"
}
],
tools: [
{
type: "web_search_20250305",
name: "web_search"
}
],
context_management: {
edits: [{ type: "clear_tool_uses_20250919" }]
},
betas: ["context-management-2025-06-27"]
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 4096,
Messages = [
new() { Role = Role.User, Content = "Search for recent developments in AI" }
],
Tools = [
new BetaWebSearchTool20250305()
],
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaClearToolUses20250919Edit()]
},
Betas = [AnthropicBeta.ContextManagement2025_06_27]
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 4096,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Search for recent developments in AI")),
},
Tools: []anthropic.BetaToolUnionParam{
{OfWebSearchTool20250305: &anthropic.BetaWebSearchTool20250305Param{}},
},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{}},
},
},
Betas: []anthropic.AnthropicBeta{
anthropic.AnthropicBetaContextManagement2025_06_27,
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
import com.anthropic.models.beta.messages.BetaWebSearchTool20250305;
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearToolUses20250919Edit;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(4096L)
.addUserMessage("Search for recent developments in AI")
.addTool(BetaWebSearchTool20250305.builder().build())
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearToolUses20250919Edit.builder().build())
.build())
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
}
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: [
['role' => 'user', 'content' => 'Search for recent developments in AI']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
tools: [
['type' => 'web_search_20250305', 'name' => 'web_search']
],
contextManagement: [
'edits' => [
['type' => 'clear_tool_uses_20250919']
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [
{ role: "user", content: "Search for recent developments in AI" }
],
tools: [
{ type: "web_search_20250305", name: "web_search" }
],
context_management: {
edits: [
{ type: "clear_tool_uses_20250919" }
]
},
betas: ["context-management-2025-06-27"]
)
puts response
고급 구성
추가 매개변수로 도구 결과 지우기 동작을 사용자 지정할 수 있어요.
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Create a simple command line calculator app using Python
tools:
- type: text_editor_20250728
name: str_replace_based_edit_tool
max_characters: 10000
- type: web_search_20250305
name: web_search
max_uses: 3
context_management:
edits:
- type: clear_tool_uses_20250919
trigger:
type: input_tokens
value: 30000
keep:
type: tool_uses
value: 3
clear_at_least:
type: input_tokens
value: 5000
exclude_tools:
- web_search
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Create a simple command line calculator app using Python",
}
],
tools=[
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool",
"max_characters": 10000,
},
{"type": "web_search_20250305", "name": "web_search", "max_uses": 3},
],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_tool_uses_20250919",
# Trigger clearing when threshold is exceeded
"trigger": {"type": "input_tokens", "value": 30000},
# Number of tool uses to keep after clearing
"keep": {"type": "tool_uses", "value": 3},
# Optional: Clear at least this many tokens
"clear_at_least": {"type": "input_tokens", "value": 5000},
# Exclude these tools from being cleared
"exclude_tools": ["web_search"],
}
]
},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [
{
role: "user",
content: "Create a simple command line calculator app using Python"
}
],
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool",
max_characters: 10000
},
{
type: "web_search_20250305",
name: "web_search",
max_uses: 3
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_tool_uses_20250919",
// Trigger clearing when threshold is exceeded
trigger: {
type: "input_tokens",
value: 30000
},
// Number of tool uses to keep after clearing
keep: {
type: "tool_uses",
value: 3
},
// Optional: Clear at least this many tokens
clear_at_least: {
type: "input_tokens",
value: 5000
},
// Exclude these tools from being cleared
exclude_tools: ["web_search"]
}
]
}
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 4096,
Messages = [
new() { Role = Role.User, Content = "Create a simple command line calculator app using Python" }
],
Tools = [
new BetaToolTextEditor20250728 { MaxCharacters = 10000 },
new BetaWebSearchTool20250305 { MaxUses = 3 }
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearToolUses20250919Edit
{
Trigger = new BetaInputTokensTrigger(30000),
Keep = new BetaToolUsesKeep(3),
ClearAtLeast = new BetaInputTokensClearAtLeast(5000),
ExcludeTools = ["web_search"]
}
]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 4096,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Create a simple command line calculator app using Python")),
},
Tools: []anthropic.BetaToolUnionParam{
{OfTextEditor20250728: &anthropic.BetaToolTextEditor20250728Param{
MaxCharacters: anthropic.Int(10000),
}},
{OfWebSearchTool20250305: &anthropic.BetaWebSearchTool20250305Param{
MaxUses: anthropic.Int(3),
}},
},
Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaContextManagement2025_06_27},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{
Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{
OfInputTokens: &anthropic.BetaInputTokensTriggerParam{
Value: 30000,
},
},
Keep: anthropic.BetaToolUsesKeepParam{
Value: 3,
},
ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{
Value: 5000,
},
ExcludeTools: []string{"web_search"},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
import com.anthropic.models.beta.messages.BetaToolTextEditor20250728;
import com.anthropic.models.beta.messages.BetaWebSearchTool20250305;
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearToolUses20250919Edit;
import com.anthropic.models.beta.messages.BetaInputTokensTrigger;
import com.anthropic.models.beta.messages.BetaInputTokensClearAtLeast;
import com.anthropic.models.beta.messages.BetaToolUsesKeep;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(4096L)
.addUserMessage("Create a simple command line calculator app using Python")
.addTool(BetaToolTextEditor20250728.builder()
.maxCharacters(10000L)
.build())
.addTool(BetaWebSearchTool20250305.builder()
.maxUses(3L)
.build())
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearToolUses20250919Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(30000L)
.build())
.keep(BetaToolUsesKeep.builder()
.value(3L)
.build())
.clearAtLeast(BetaInputTokensClearAtLeast.builder()
.value(5000L)
.build())
.addExcludeTool("web_search")
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
}
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: [
[
'role' => 'user',
'content' => 'Create a simple command line calculator app using Python'
]
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
tools: [
[
'type' => 'text_editor_20250728',
'name' => 'str_replace_based_edit_tool',
'max_characters' => 10000
],
[
'type' => 'web_search_20250305',
'name' => 'web_search',
'max_uses' => 3
]
],
contextManagement: [
'edits' => [
[
'type' => 'clear_tool_uses_20250919',
'trigger' => [
'type' => 'input_tokens',
'value' => 30000
],
'keep' => [
'type' => 'tool_uses',
'value' => 3
],
'clear_at_least' => [
'type' => 'input_tokens',
'value' => 5000
],
'exclude_tools' => ['web_search']
]
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [
{
role: "user",
content: "Create a simple command line calculator app using Python"
}
],
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool",
max_characters: 10000
},
{
type: "web_search_20250305",
name: "web_search",
max_uses: 3
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_tool_uses_20250919",
trigger: {
type: "input_tokens",
value: 30000
},
keep: {
type: "tool_uses",
value: 3
},
clear_at_least: {
type: "input_tokens",
value: 5000
},
exclude_tools: ["web_search"]
}
]
}
)
puts response
Thinking 블록 지우기 사용법
확장 thinking이 활성화될 때 컨텍스트와 프롬프트 캐싱을 효과적으로 관리하려면 thinking 블록 지우기를 활성화하세요.
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 16000
messages:
- role: user
content: Hello
context_management:
edits:
- type: clear_thinking_20251015
keep:
type: thinking_turns
value: 2
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
messages=[{"role": "user", "content": "Hello"}],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_thinking_20251015",
"keep": {"type": "thinking_turns", "value": 2},
}
]
},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 2
}
}
]
}
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 16000,
Messages = [
new() { Role = Role.User, Content = "Hello" }
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearThinking20251015Edit
{
Keep = new BetaThinkingTurns(2)
}
]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 16000,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello")),
},
Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaContextManagement2025_06_27},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearThinking20251015: &anthropic.BetaClearThinking20251015EditParam{
Keep: anthropic.BetaClearThinking20251015EditKeepUnionParam{
OfThinkingTurns: &anthropic.BetaThinkingTurnsParam{
Value: 2,
},
},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearThinking20251015Edit;
import com.anthropic.models.beta.messages.BetaThinkingTurns;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(16000L)
.addUserMessage("Hello")
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearThinking20251015Edit.builder()
.keep(BetaThinkingTurns.builder()
.value(2L)
.build())
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
}
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'Hello']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
contextManagement: [
'edits' => [
[
'type' => 'clear_thinking_20251015',
'keep' => [
'type' => 'thinking_turns',
'value' => 2
]
]
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 2
}
}
]
}
)
puts response
thinking 블록 지우기 구성 옵션
clear_thinking_20251015 전략은 다음 구성을 지원해요.
| 구성 옵션 | 기본값 | 설명 |
|---|---|---|
keep |
모델별 | thinking 블록이 있는 최근 도우미 턴 몇 개를 보존할지 정의해요. {type: "thinking_turns", value: N}을 쓰되 N은 0보다 커야 하며 마지막 N 턴을 유지하거나, "all"로 모든 thinking 블록을 유지해요. Opus 4.5+와 Sonnet 4.6+: 모든 턴. Fable과 Mythos 모델: 모든 턴. 이전 Opus/Sonnet과 모든 Haiku: 마지막 턴만. |
예시 구성:
마지막 3개 도우미 턴의 thinking 블록 유지:
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 16000
messages:
- role: user
content: Hello
context_management:
edits:
- type: clear_thinking_20251015
keep:
type: thinking_turns
value: 3
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
messages=[{"role": "user", "content": "Hello"}],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_thinking_20251015",
"keep": {"type": "thinking_turns", "value": 3},
}
]
},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 3
}
}
]
}
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 16000,
Messages = [
new() { Role = Role.User, Content = "Hello" }
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearThinking20251015Edit
{
Keep = new BetaThinkingTurns(3)
}
]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 16000,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello")),
},
Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaContextManagement2025_06_27},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearThinking20251015: &anthropic.BetaClearThinking20251015EditParam{
Keep: anthropic.BetaClearThinking20251015EditKeepUnionParam{
OfThinkingTurns: &anthropic.BetaThinkingTurnsParam{
Value: 3,
},
},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(16000L)
.addUserMessage("Hello")
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearThinking20251015Edit.builder()
.keep(BetaThinkingTurns.builder()
.value(3L)
.build())
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'Hello']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
contextManagement: [
'edits' => [
[
'type' => 'clear_thinking_20251015',
'keep' => [
'type' => 'thinking_turns',
'value' => 3
]
]
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 3
}
}
]
}
)
puts response
모든 thinking 블록 유지(캐시 적중 최대화):
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 16000
messages:
- role: user
content: Hello
context_management:
edits:
- type: clear_thinking_20251015
keep: all
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
messages=[{"role": "user", "content": "Hello"}],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_thinking_20251015",
"keep": "all",
}
]
},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: "all"
}
]
}
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 16000,
Messages = [
new() { Role = Role.User, Content = "Hello" }
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearThinking20251015Edit
{
Keep = new All()
}
]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 16000,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello")),
},
Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaContextManagement2025_06_27},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearThinking20251015: &anthropic.BetaClearThinking20251015EditParam{
Keep: anthropic.BetaClearThinking20251015EditKeepUnionParam{
OfAll: constant.ValueOf[constant.All](),
},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(16000L)
.addUserMessage("Hello")
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearThinking20251015Edit.builder()
.keepAll()
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'Hello']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
contextManagement: [
'edits' => [
[
'type' => 'clear_thinking_20251015',
'keep' => 'all'
]
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "Hello" }],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: "all"
}
]
}
)
puts response
전략 결합
thinking 블록 지우기와 도구 결과 지우기를 함께 쓸 수 있어요.
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 16000
messages:
- role: user
content: Search for the latest developments in quantum error correction and summarize the key breakthroughs.
tools:
- type: web_search_20250305
name: web_search
max_uses: 5
context_management:
edits:
- type: clear_thinking_20251015
keep:
type: thinking_turns
value: 2
- type: clear_tool_uses_20250919
trigger:
type: input_tokens
value: 50000
keep:
type: tool_uses
value: 5
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
messages=[
{
"role": "user",
"content": "Search for the latest developments in quantum error correction and summarize the key breakthroughs.",
}
],
tools=[
{
"type": "web_search_20250305",
"name": "web_search",
"max_uses": 5,
}
],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_thinking_20251015",
"keep": {"type": "thinking_turns", "value": 2},
},
{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "input_tokens", "value": 50000},
"keep": {"type": "tool_uses", "value": 5},
},
]
},
)
print(response)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [
{
role: "user",
content:
"Search for the latest developments in quantum error correction and summarize the key breakthroughs."
}
],
tools: [
{
type: "web_search_20250305",
name: "web_search",
max_uses: 5
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 2
}
},
{
type: "clear_tool_uses_20250919",
trigger: {
type: "input_tokens",
value: 50000
},
keep: {
type: "tool_uses",
value: 5
}
}
]
}
});
console.log(response);
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 16000,
Messages = [
new() { Role = Role.User, Content = "Search for the latest developments in quantum error correction and summarize the key breakthroughs." }
],
Tools = [
new BetaWebSearchTool20250305 { MaxUses = 5 }
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearThinking20251015Edit
{
Keep = new BetaThinkingTurns(2)
},
new BetaClearToolUses20250919Edit
{
Trigger = new BetaInputTokensTrigger(50000),
Keep = new BetaToolUsesKeep(5)
}
]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 16000,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Search for the latest developments in quantum error correction and summarize the key breakthroughs.")),
},
Tools: []anthropic.BetaToolUnionParam{
{OfWebSearchTool20250305: &anthropic.BetaWebSearchTool20250305Param{
MaxUses: anthropic.Int(5),
}},
},
Betas: []anthropic.AnthropicBeta{
anthropic.AnthropicBetaContextManagement2025_06_27,
},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearThinking20251015: &anthropic.BetaClearThinking20251015EditParam{
Keep: anthropic.BetaClearThinking20251015EditKeepUnionParam{
OfThinkingTurns: &anthropic.BetaThinkingTurnsParam{
Value: 2,
},
},
}},
{OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{
Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{
OfInputTokens: &anthropic.BetaInputTokensTriggerParam{
Value: 50000,
},
},
Keep: anthropic.BetaToolUsesKeepParam{
Value: 5,
},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
import com.anthropic.models.beta.messages.BetaWebSearchTool20250305;
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearThinking20251015Edit;
import com.anthropic.models.beta.messages.BetaClearToolUses20250919Edit;
import com.anthropic.models.beta.messages.BetaThinkingTurns;
import com.anthropic.models.beta.messages.BetaInputTokensTrigger;
import com.anthropic.models.beta.messages.BetaToolUsesKeep;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(16000L)
.addUserMessage("Search for the latest developments in quantum error correction and summarize the key breakthroughs.")
.addTool(BetaWebSearchTool20250305.builder()
.maxUses(5L)
.build())
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearThinking20251015Edit.builder()
.keep(BetaThinkingTurns.builder()
.value(2L)
.build())
.build())
.addEdit(BetaClearToolUses20250919Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(50000L)
.build())
.keep(BetaToolUsesKeep.builder()
.value(5L)
.build())
.build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
}
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 16000,
messages: [
[
'role' => 'user',
'content' => 'Search for the latest developments in quantum error correction and summarize the key breakthroughs.'
]
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
tools: [
[
'type' => 'web_search_20250305',
'name' => 'web_search',
'max_uses' => 5
]
],
contextManagement: [
'edits' => [
[
'type' => 'clear_thinking_20251015',
'keep' => [
'type' => 'thinking_turns',
'value' => 2
]
],
[
'type' => 'clear_tool_uses_20250919',
'trigger' => [
'type' => 'input_tokens',
'value' => 50000
],
'keep' => [
'type' => 'tool_uses',
'value' => 5
]
]
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [
{
role: "user",
content: "Search for the latest developments in quantum error correction and summarize the key breakthroughs."
}
],
tools: [
{
type: "web_search_20250305",
name: "web_search",
max_uses: 5
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_thinking_20251015",
keep: {
type: "thinking_turns",
value: 2
}
},
{
type: "clear_tool_uses_20250919",
trigger: {
type: "input_tokens",
value: 50000
},
keep: {
type: "tool_uses",
value: 5
}
}
]
}
)
puts response
도구 결과 지우기 구성 옵션
| 구성 옵션 | 기본값 | 설명 |
|---|---|---|
trigger |
100,000 입력 토큰 | 컨텍스트 편집 전략이 활성화되는 시점을 정의해요. 프롬프트가 이 임계값을 넘으면 지우기가 시작돼요. 이 값은 input_tokens 또는 tool_uses로 지정할 수 있어요. |
keep |
3개 도구 사용 | 지우기가 일어난 후 유지할 최근 도구 사용/결과 쌍 몇 개를 정의해요. API는 가장 오래된 도구 상호작용부터 제거하고 가장 최근의 것을 보존해요. |
clear_at_least |
없음 | 전략이 활성화될 때마다 지워지는 최소 토큰 수를 보장해요. API가 지정된 양을 최소한 지울 수 없으면 전략은 적용되지 않아요. 이것은 컨텍스트 지우기가 프롬프트 캐시를 깨뜨릴 가치가 있는지 판단하는 데 도움돼요. |
exclude_tools |
없음 | 도구 사용과 결과를 절대 지우지 않아야 하는 도구 이름 목록이에요. 중요한 컨텍스트 보존에 유용해요. |
clear_tool_inputs |
false |
도구 결과와 함께 도구 호출 매개변수를 지울지 제어해요. 기본적으로 도구 결과만 지우고 Claude의 원래 도구 호출은 계속 보여줘요. |
컨텍스트 편집 응답
context_management 응답 필드로 요청에 적용된 컨텍스트 편집, 그리고 지워진 콘텐츠와 입력 토큰에 대한 유용한 통계를 볼 수 있어요.
{
"id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
"type": "message",
"role": "assistant",
"content": [
// ...
],
"usage": {
// ...
},
"context_management": {
"applied_edits": [
// When using `clear_thinking_20251015`
{
"type": "clear_thinking_20251015",
"cleared_thinking_turns": 3,
"cleared_input_tokens": 15000
},
// When using `clear_tool_uses_20250919`
{
"type": "clear_tool_uses_20250919",
"cleared_tool_uses": 8,
"cleared_input_tokens": 50000
}
]
}
}
스트리밍 응답에서는 컨텍스트 편집이 마지막 message_delta 이벤트에 포함돼요.
{
"type": "message_delta",
"delta": {
"stop_reason": "end_turn",
"stop_sequence": null
},
"usage": {
"output_tokens": 1024
},
"context_management": {
"applied_edits": [
// ...
]
}
}
토큰 계산
토큰 계산 엔드포인트는 컨텍스트 관리를 지원해서, 컨텍스트 편집이 적용된 후 프롬프트가 몇 토큰을 쓸지 미리 볼 수 있어요.
ORIGINAL=$(ant beta:messages count-tokens \
--beta context-management-2025-06-27 \
--transform context_management.original_input_tokens \
--raw-output <<'YAML'
model: claude-opus-5-5
messages:
- role: user
content: Continue our conversation...
context_management:
edits:
- type: clear_tool_uses_20250919
trigger:
type: input_tokens
value: 30000
keep:
type: tool_uses
value: 5
YAML
)
INPUT_TOKENS=$(ant beta:messages count-tokens \
--beta context-management-2025-06-27 \
--transform input_tokens --raw-output <<'YAML'
model: claude-opus-5-5
messages:
- role: user
content: Continue our conversation...
context_management:
edits:
- type: clear_tool_uses_20250919
trigger:
type: input_tokens
value: 30000
keep:
type: tool_uses
value: 5
YAML
)
printf 'Original tokens: %s\n' "$ORIGINAL"
printf 'After clearing: %s\n' "$INPUT_TOKENS"
printf 'Savings: %s tokens\n' "$((ORIGINAL - INPUT_TOKENS))"
response = client.beta.messages.count_tokens(
model="claude-opus-5-5",
messages=[{"role": "user", "content": "Continue our conversation..."}],
betas=["context-management-2025-06-27"],
context_management={
"edits": [
{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "input_tokens", "value": 30000},
"keep": {"type": "tool_uses", "value": 5},
}
]
},
)
print(f"Original tokens: {response.context_management.original_input_tokens}")
print(f"After clearing: {response.input_tokens}")
print(
f"Savings: {response.context_management.original_input_tokens - response.input_tokens} tokens"
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.countTokens({
model: "claude-opus-5-5",
messages: [
{
role: "user",
content: "Continue our conversation..."
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_tool_uses_20250919",
trigger: {
type: "input_tokens",
value: 30000
},
keep: {
type: "tool_uses",
value: 5
}
}
]
}
});
console.log(`Original tokens: ${response.context_management?.original_input_tokens}`);
console.log(`After clearing: ${response.input_tokens}`);
console.log(
`Savings: ${
(response.context_management?.original_input_tokens || 0) - response.input_tokens
} tokens`
);
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCountTokensParams
{
Model = Messages::Model.ClaudeOpus5_5,
Messages = [new() { Role = Role.User, Content = "Continue our conversation..." }],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [
new BetaClearToolUses20250919Edit
{
Trigger = new BetaInputTokensTrigger(30000),
Keep = new BetaToolUsesKeep(5)
}
]
}
};
var response = await client.Beta.Messages.CountTokens(parameters);
Console.WriteLine($"Original tokens: {response.ContextManagement?.OriginalInputTokens}");
Console.WriteLine($"After clearing: {response.InputTokens}");
Console.WriteLine($"Savings: {(response.ContextManagement?.OriginalInputTokens ?? 0) - response.InputTokens} tokens");
client := anthropic.NewClient()
response, err := client.Beta.Messages.CountTokens(context.TODO(), anthropic.BetaMessageCountTokensParams{
Model: anthropic.ModelClaudeOpus5_5,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Continue our conversation...")),
},
Betas: []anthropic.AnthropicBeta{
anthropic.AnthropicBetaContextManagement2025_06_27,
},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{
Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{
OfInputTokens: &anthropic.BetaInputTokensTriggerParam{
Value: 30000,
},
},
Keep: anthropic.BetaToolUsesKeepParam{
Value: 5,
},
}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Original tokens: %d\n", response.ContextManagement.OriginalInputTokens)
fmt.Printf("After clearing: %d\n", response.InputTokens)
fmt.Printf("Savings: %d tokens\n", response.ContextManagement.OriginalInputTokens-response.InputTokens)
import com.anthropic.models.beta.messages.BetaMessageTokensCount;
import com.anthropic.models.beta.messages.MessageCountTokensParams;
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearToolUses20250919Edit;
import com.anthropic.models.beta.messages.BetaInputTokensTrigger;
import com.anthropic.models.beta.messages.BetaToolUsesKeep;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCountTokensParams params = MessageCountTokensParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.addUserMessage("Continue our conversation...")
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearToolUses20250919Edit.builder()
.trigger(BetaInputTokensTrigger.builder()
.value(30000L)
.build())
.keep(BetaToolUsesKeep.builder()
.value(5L)
.build())
.build())
.build())
.build();
BetaMessageTokensCount response = client.beta().messages().countTokens(params);
IO.println("Original tokens: " + response.contextManagement().get().originalInputTokens());
IO.println("After clearing: " + response.inputTokens());
IO.println("Savings: " + (response.contextManagement().get().originalInputTokens() - response.inputTokens()) + " tokens");
}
$client = new Client();
$response = $client->beta->messages->countTokens(
messages: [
['role' => 'user', 'content' => 'Continue our conversation...']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
contextManagement: [
'edits' => [
[
'type' => 'clear_tool_uses_20250919',
'trigger' => [
'type' => 'input_tokens',
'value' => 30000
],
'keep' => [
'type' => 'tool_uses',
'value' => 5
]
]
]
],
);
echo "Original tokens: " . $response->contextManagement->originalInputTokens . "\n";
echo "After clearing: " . $response->inputTokens . "\n";
echo "Savings: " . ($response->contextManagement->originalInputTokens - $response->inputTokens) . " tokens\n";
client = Anthropic::Client.new
response = client.beta.messages.count_tokens(
model: "claude-opus-5-5",
messages: [
{ role: "user", content: "Continue our conversation..." }
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{
type: "clear_tool_uses_20250919",
trigger: {
type: "input_tokens",
value: 30000
},
keep: {
type: "tool_uses",
value: 5
}
}
]
}
)
puts "Original tokens: #{response.context_management.original_input_tokens}"
puts "After clearing: #{response.input_tokens}"
puts "Savings: #{response.context_management.original_input_tokens - response.input_tokens} tokens"
{
"input_tokens": 25000,
"context_management": {
"original_input_tokens": 70000
}
}
응답은 컨텍스트 관리가 적용된 후의 최종 토큰 수(input_tokens)와 어떤 지우기도 일어나기 전의 원래 토큰 수(original_input_tokens)를 모두 보여줘요.
메모리 도구와 함께 사용
컨텍스트 편집은 메모리 도구와 결합할 수 있어요. 대화 컨텍스트가 설정한 지우기 임계값에 가까워지면 Claude가 중요한 정보를 보존하라는 자동 경고를 받아요. 이것은 Claude가 대화 기록에서 지워지기 전에 도구 결과나 컨텍스트를 메모리 파일에 저장하게 해 줘요.
이 조합으로 다음을 할 수 있어요.
- 중요한 컨텍스트 보존: Claude가 도구 결과의 핵심 정보를 지워지기 전에 메모리 파일에 쓸 수 있어요.
- 장기 실행 워크플로 유지: 정보를 영구 저장소로 오프로딩해 컨텍스트 한도를 넘을 에이전틱 워크플로를 가능하게 해요.
- 요청 시 정보 접근: 모든 것을 활성 컨텍스트 창에 두는 대신, 필요할 때 메모리 파일에서 이전에 지워진 정보를 조회할 수 있어요.
예를 들어 Claude가 많은 작업을 수행하는 파일 편집 워크플로에서, 컨텍스트가 커짐에 따라 완료된 변경사항을 메모리 파일로 요약할 수 있어요. 도구 결과가 지워져도 Claude는 메모리 시스템을 통해 그 정보에 접근할 수 있고 계속 효과적으로 작업할 수 있어요.
두 기능을 함께 쓰려면 API 요청에서 둘 다 활성화하세요.
ant beta:messages create --beta context-management-2025-06-27 <<'YAML'
model: claude-opus-5-5
max_tokens: 4096
messages:
- role: user
content: Hello
tools:
- type: memory_20250818
name: memory
context_management:
edits:
- type: clear_tool_uses_20250919
YAML
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
messages=[{"role": "user", "content": "Hello"}],
tools=[{"type": "memory_20250818", "name": "memory"}],
betas=["context-management-2025-06-27"],
context_management={"edits": [{"type": "clear_tool_uses_20250919"}]},
)
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await anthropic.beta.messages.create({
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [{ role: "user", content: "Hello" }],
tools: [
{
type: "memory_20250818",
name: "memory"
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [{ type: "clear_tool_uses_20250919" }]
}
});
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Messages = Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Messages::Model.ClaudeOpus5_5,
MaxTokens = 4096,
Messages = [
new() { Role = Role.User, Content = "Hello" }
],
Tools = [
new BetaMemoryTool20250818()
],
Betas = [AnthropicBeta.ContextManagement2025_06_27],
ContextManagement = new BetaContextManagementConfig
{
Edits = [new BetaClearToolUses20250919Edit()]
}
};
var response = await client.Beta.Messages.Create(parameters);
Console.WriteLine(response);
client := anthropic.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeOpus5_5,
MaxTokens: 4096,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello")),
},
Tools: []anthropic.BetaToolUnionParam{
{OfMemoryTool20250818: &anthropic.BetaMemoryTool20250818Param{}},
},
Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaContextManagement2025_06_27},
ContextManagement: anthropic.BetaContextManagementConfigParam{
Edits: []anthropic.BetaContextManagementConfigEditUnionParam{
{OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{}},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
import com.anthropic.models.beta.messages.BetaMemoryTool20250818;
import com.anthropic.models.beta.messages.BetaContextManagementConfig;
import com.anthropic.models.beta.messages.BetaClearToolUses20250919Edit;
import com.anthropic.models.beta.AnthropicBeta;
// ...
void main() {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5_5)
.maxTokens(4096L)
.addUserMessage("Hello")
.addTool(BetaMemoryTool20250818.builder().build())
.addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
.contextManagement(BetaContextManagementConfig.builder()
.addEdit(BetaClearToolUses20250919Edit.builder().build())
.build())
.build();
BetaMessage response = client.beta().messages().create(params);
IO.println(response);
}
$client = new Client();
$response = $client->beta->messages->create(
maxTokens: 4096,
messages: [
['role' => 'user', 'content' => 'Hello']
],
model: 'claude-opus-5-5',
betas: ['context-management-2025-06-27'],
tools: [
[
'type' => 'memory_20250818',
'name' => 'memory'
]
],
contextManagement: [
'edits' => [
['type' => 'clear_tool_uses_20250919']
]
],
);
echo $response;
client = Anthropic::Client.new
response = client.beta.messages.create(
model: "claude-opus-5-5",
max_tokens: 4096,
messages: [{ role: "user", content: "Hello" }],
tools: [
{
type: "memory_20250818",
name: "memory"
}
],
betas: ["context-management-2025-06-27"],
context_management: {
edits: [
{ type: "clear_tool_uses_20250919" }
]
}
)
puts response
명령과 예시를 포함한 전체 메모리 도구 레퍼런스는 메모리 도구를 보세요.
클라이언트 측 컴팩션 (SDK)
compaction_control 매개변수는 TypeScript와 Ruby SDK에서 폐기되었으며 향후 버전에서 제거될 거예요. SDK는 활성화하면 폐기 경고를 냅니다. Python SDK는 v1.0에서 제거했어요. 도구 러너와 함께 서버 측 컴팩션을 쓰려면 요청의 context_management 매개변수에 compact_20260112 편집을 전달하세요.
컴팩션은 토큰 사용량이 너무 커지면 요약을 생성해 대화 컨텍스트를 자동으로 관리하는 SDK 기능이에요. 콘텐츠를 지우는 서버 측 컨텍스트 편집 전략과 달리, 컴팩션은 Claude에게 대화 기록을 요약하라고 지시한 다음 전체 기록을 그 요약으로 대체해요. 이것은 컨텍스트 창을 초과할 장기 실행 작업을 Claude가 계속할 수 있게 해 줘요.
컴팩션 동작 방식
컴팩션을 활성화하면 SDK가 각 모델 응답 후 토큰 사용량을 모니터링해요.
- 임계값 확인: SDK는 총 토큰을
input_tokens + cache_creation_input_tokens + cache_read_input_tokens + output_tokens로 계산해요(캐시 토큰 필드는 프롬프트 캐싱 참조). - 요약 생성: 임계값을 초과하면 요약 프롬프트가 user 턴으로 주입되고, Claude가
<summary></summary>태그로 감싼 구조화된 요약을 생성해요. - 컨텍스트 교체: SDK는 요약을 추출해 전체 메시지 기록을 그것으로 대체해요.
- 연속: 대화는 요약에서 재개되고 Claude는 중단한 지점에서 이어가요.
컴팩션 사용
토큰 사용량이 임계값을 초과할 때 자동 요약화를 활성화하려면 tool_runner 호출에 compaction_control을 추가하세요.
const runner = client.beta.messages.toolRunner({
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [readFile],
messages: [{ role: "user", content: "What's in config.json?" }],
compactionControl: { enabled: true, contextTokenThreshold: 100000 }
});
for await (const message of runner) {
console.log(`Tokens used: ${message.usage.input_tokens}`);
}
```
runner = client.beta.messages.tool_runner(
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [ReadFile.new],
messages: [{ role: "user", content: "What's in config.json?" }],
compaction_control: { enabled: true, context_token_threshold: 100000 }
)
runner.each_message do |message|
puts "Tokens used: #{message.usage.input_tokens}"
end
```
컴팩션 중에 일어나는 일
대화가 커짐에 따라 메시지 기록이 축적돼요.
컴팩션 전(약 100k 토큰에 근접):
[
{ "role": "user", "content": "Analyze all files and write a report..." },
{ "role": "assistant", "content": "I'll help. Let me start by reading..." },
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "...", "content": "..." }]
},
{ "role": "assistant", "content": "Based on file1.txt, I see..." },
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "...", "content": "..." }]
},
{ "role": "assistant", "content": "After analyzing file2.txt..." }
// ... 50 more exchanges like this ...
]
토큰이 임계값을 초과하면 SDK가 요약 요청을 주입하고 Claude가 요약을 생성해요. 전체 기록이 교체돼요.
컴팩션 후(~2–3k 토큰으로 복귀):
[
{
"role": "assistant",
"content": "# Task Overview\nThe user requested analysis of directory files to produce a summary report...\n\n# Current State\nAnalyzed 52 files across 3 subdirectories. Key findings documented in report.md...\n\n# Important Discoveries\n- Configuration files use YAML format\n- Found 3 deprecated dependencies\n- Test coverage at 67%\n\n# Next Steps\n1. Analyze remaining files in /src/legacy\n2. Complete final report sections...\n\n# Context to Preserve\nUser prefers markdown format with executive summary first..."
}
]
Claude는 이 요약에서 원래 대화 기록인 것처럼 계속 작업해요.
구성 옵션
| 매개변수 | 유형 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
enabled |
boolean | 예 | - | 자동 컴팩션을 활성화할지 여부 |
context_token_threshold |
number | 아니요 | 100,000 | 컴팩션이 트리거되는 토큰 수 |
model |
string | 아니요 | 주 모델과 동일 | 요약 생성에 사용할 모델 |
summary_prompt |
string | 아니요 | 기본 요약 프롬프트 참조 | 요약 생성용 사용자 지정 프롬프트 |
토큰 임계값 선택
임계값은 컴팩션이 언제 일어날지 결정해요. 값이 낮을수록 더 자주 더 작은 컨텍스트 창으로 컴팩션해요. 값이 높을수록 더 많은 컨텍스트를 허용하지만 한도에 부딪힐 위험이 있어요.
const runner = client.beta.messages.toolRunner({
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [readFile],
messages: [{ role: "user", content: "What's in config.json?" }],
// Lower values compact more often; raise to 150000 when the task needs more context
compactionControl: { enabled: true, contextTokenThreshold: 50000 }
});
for await (const message of runner) {
console.log(`Tokens used: ${message.usage.input_tokens}`);
}
```
runner = client.beta.messages.tool_runner(
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [ReadFile.new],
messages: [{ role: "user", content: "What's in config.json?" }],
# Lower values compact more often; raise to 150000 when the task needs more context
compaction_control: { enabled: true, context_token_threshold: 50000 }
)
runner.each_message do |message|
puts "Tokens used: #{message.usage.input_tokens}"
end
```
요약에 다른 모델 사용
요약 생성에 더 빠르거나 저렴한 모델을 사용할 수 있어요.
const runner = client.beta.messages.toolRunner({
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [readFile],
messages: [{ role: "user", content: "What's in config.json?" }],
compactionControl: {
enabled: true,
contextTokenThreshold: 100000,
model: "claude-haiku-4-5"
}
});
for await (const message of runner) {
console.log(`Tokens used: ${message.usage.input_tokens}`);
}
```
runner = client.beta.messages.tool_runner(
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [ReadFile.new],
messages: [{ role: "user", content: "What's in config.json?" }],
compaction_control: {
enabled: true,
context_token_threshold: 100000,
model: "claude-haiku-4-5"
}
)
runner.each_message do |message|
puts "Tokens used: #{message.usage.input_tokens}"
end
```
사용자 지정 요약 프롬프트
도메인별 요구에 사용자 지정 프롬프트를 제공할 수 있어요. 프롬프트는 Claude에게 요약을 <summary></summary> 태그로 감싸라고 지시해야 해요.
const runner = client.beta.messages.toolRunner({
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [readFile],
messages: [{ role: "user", content: "What's in config.json?" }],
compactionControl: {
enabled: true,
contextTokenThreshold: 100000,
summaryPrompt: `Summarize the research conducted so far, including:
- Sources consulted and key findings
- Questions answered and remaining unknowns
- Recommended next steps
Wrap your summary in <summary></summary> tags.`
}
});
for await (const message of runner) {
console.log(`Tokens used: ${message.usage.input_tokens}`);
}
```
runner = client.beta.messages.tool_runner(
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [ReadFile.new],
messages: [{ role: "user", content: "What's in config.json?" }],
compaction_control: {
enabled: true,
context_token_threshold: 100000,
summary_prompt: <<~PROMPT
Summarize the research conducted so far, including:
- Sources consulted and key findings
- Questions answered and remaining unknowns
- Recommended next steps
Wrap your summary in <summary></summary> tags.
PROMPT
}
)
runner.each_message do |message|
puts "Tokens used: #{message.usage.input_tokens}"
end
```
기본 요약 프롬프트
내장 요약 프롬프트는 Claude에게 구조화된 연속 요약을 만들라고 지시해요. 다음을 포함해요.
- 작업 개요: 사용자의 핵심 요청, 성공 기준, 제약.
- 현재 상태: 완료된 것, 수정된 파일, 생성된 산출물.
- 중요한 발견: 기술적 제약, 내린 결정, 해결된 에러, 실패한 접근.
- 다음 단계: 필요한 구체적 행동, 차단 요소, 우선순위.
- 보존할 컨텍스트: 사용자 선호, 도메인별 세부 사항, 한 약속.
이 구조는 Claude가 중요한 컨텍스트를 잃거나 실수를 반복하지 않고 효율적으로 작업을 재개하게 해 줘요.
-
Task Overview The user's core request and success criteria Any clarifications or constraints they specified
-
Current State What has been completed so far Files created, modified, or analyzed (with paths if relevant) Key outputs or artifacts produced
-
Important Discoveries Technical constraints or requirements uncovered Decisions made and their rationale Errors encountered and how they were resolved What approaches were tried that didn't work (and why)
-
Next Steps Specific actions needed to complete the task Any blockers or open questions to resolve Priority order if multiple steps remain
-
Context to Preserve User preferences or style requirements Domain-specific details that aren't obvious Any promises made to the user
Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task.
Wrap your summary in
</Accordion>
#### 제한 사항
##### 서버 측 도구
<Warning>
컴팩션은 [웹 검색](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool)이나 [웹 패치](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) 같은 서버 측 도구를 사용할 때 특별한 주의가 필요해요.
</Warning>
서버 측 도구를 쓸 때 SDK가 토큰 사용량을 잘못 계산해 컴팩션이 잘못된 시점에 트리거될 수 있어요.
예를 들어 웹 검색 후 API 응답이 이렇게 보일 수 있어요.
```json Output
{
"usage": {
"input_tokens": 63000,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 270000,
"output_tokens": 1400
}
}
SDK는 총 사용량을 63,000 + 0 + 270,000 + 1,400 = 334,400 토큰으로 계산해요. 하지만 cache_read_input_tokens 값은 서버 측 도구가 수행한 여러 내부 API 호출로부터의 누적 읽기를 포함하는 것이지, 실제 대화 컨텍스트가 아니에요. 실제 컨텍스트 길이는 63,000 input_tokens뿐인데 SDK는 334k를 보고 컴팩션을 조기에 트리거할 수 있어요.
해결 방법:
- 토큰 계산 엔드포인트를 사용해 정확한 컨텍스트 길이를 얻으세요.
- 서버 측 도구를 많이 쓸 때는 컴팩션을 피하세요.
도구 사용 엣지 케이스
SDK가 도구 사용 응답이 보류된 동안 컴팩션을 트리거하면, 요약을 생성하기 전에 메시지 기록에서 도구 사용 블록을 제거해요. Claude는 요약에서 재개한 후 여전히 필요하면 도구 호출을 다시 발행해요.
컴팩션 모니터링
컴팩션이 언제 트리거되는지 이해하면 임계값을 조정하고 예상 동작을 검증하는 데 도움돼요.
```typescript TypeScript
let prevMsgCount = 0;
for await (const message of runner) {
const currMsgCount = runner.params.messages.length;
if (currMsgCount < prevMsgCount) {
console.log(`Compaction occurred: ${prevMsgCount} -> ${currMsgCount} messages`);
console.log(`Input tokens after compaction: ${message.usage.input_tokens}`);
}
prevMsgCount = currMsgCount;
}
```
```ruby Ruby
client = Anthropic::Client.new
runner = client.beta.messages.tool_runner(
model: "claude-opus-5-5",
max_tokens: 1024,
tools: [ReadFile.new],
messages: [{ role: "user", content: "What's in config.json?" }],
compaction_control: {
enabled: true,
context_token_threshold: 100000,
on_compact: ->(tokens_before, tokens_after) do
puts "Compaction occurred: #{tokens_before} -> #{tokens_after} tokens"
end
}
)
runner.each_message do |message|
puts "Tokens: #{message.usage.input_tokens}"
end
```
컴팩션을 언제 쓸까
좋은 사용 사례:
- 많은 파일이나 데이터 소스를 처리하는 장기 실행 에이전트 작업
- 많은 정보를 축적하는 연구 워크플로
- 명확하고 측정 가능한 진전이 있는 다단계 작업
- 대화 밖에 지속되는 산출물(파일, 보고서)을 만드는 작업
덜 이상적인 사용 사례:
- 초기 대화 세부 사항을 정확히 회상해야 하는 작업
- 서버 측 도구를 많이 사용하는 워크플로
- 많은 변수에 걸쳐 정확한 상태를 유지해야 하는 작업
더 알아보기 (Learn more)
- 컴팩션 (Compaction): 대부분의 사용 사례에 권장되는 전략인 서버 측 컴팩션으로 긴 대화를 관리하세요.
- 프롬프트 캐싱 (Prompt caching): 프롬프트 접두사를 캐시해 비용과 레이턴시를 줄이고, 컨텍스트 편집이 캐시와 어떻게 상호작용하는지 알아보세요.