Claude API context_length_exceeded (invalid_request_error): 원인과 해결법
Claude API context_length_exceeded invalid_request_error는 messages 누적 토큰 + max_tokens가 모델의 context window 초과에 발생합니다 (2026 기준). 컨텍스트 길이 초과이며, 재시도하지 말고 요청 자체를 수정해야 합니다. 이 글은 5가지 흔한 원인과 Python/TypeScript 코드 예시를 다룹니다.
전반적인 Claude API 에러 처리 패턴은 Claude API Error Handling 가이드를 참고하세요.
무엇을 의미하는가?
context_length_exceeded 에러 서브타입는 messages 누적 토큰 + max_tokens가 모델의 context window 초과을 의미합니다. Anthropic API의 에러 응답 본문에는 error.type이 "invalid_request_error"로 명시되며, error.message에 구체적 사유가 옵니다.
응답 예시:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "..."
}
}
흔한 원인 5가지
- Sonnet 4.5 1M context를 사용 중인데 max_tokens가 1M-요청토큰보다 큼
- 긴 system prompt + 누적된 conversation history
- PDF/document 첨부의 token 사용량 미고려
- Tool result가 messages에 누적되어 폭증
해결 코드 (Python)
import anthropic
# Pre-compute token usage with the count_tokens endpoint
client = anthropic.Anthropic()
response = client.messages.count_tokens(
model="claude-sonnet-4-5",
messages=conversation_history,
system="You are a helpful assistant.",
)
input_tokens = response.input_tokens
context_window = 200_000 # or 1_000_000 for Sonnet 4.5 1M context
budget = context_window - input_tokens
if budget < 1024:
# Trim conversation: drop oldest messages
while budget < 4096 and len(conversation_history) > 2:
conversation_history.pop(0)
# recount...
해결 코드 (TypeScript)
const tokenCount = await client.messages.countTokens({
model: "claude-sonnet-4-5",
messages: conversationHistory,
system: "You are a helpful assistant.",
});
const budget = 200_000 - tokenCount.input_tokens;
if (budget < 1024) {
while (budget < 4096 && conversationHistory.length > 2) {
conversationHistory.shift();
}
}
장기 대화 관리 전략
conversation history가 누적될수록 토큰이 쌓여 결국 context window를 초과합니다. 세 가지 전략으로 이를 방지합니다:
전략 1: 슬라이딩 윈도우 (가장 단순) 항상 최근 N개 메시지만 유지합니다. 구현이 쉽지만 초기 컨텍스트(중요한 초기 설정 등)가 유실될 수 있습니다.
MAX_HISTORY = 20
conversation = conversation[-MAX_HISTORY:]
전략 2: 요약 압축 오래된 메시지들을 Claude로 요약한 다음 summary 메시지 하나로 대체합니다. 맥락은 유지하면서 토큰을 대폭 줄일 수 있습니다.
import anthropic
def compress_history(client: anthropic.Anthropic, old_messages: list) -> str:
"""오래된 메시지를 요약으로 압축."""
summary_resp = client.messages.create(
model="claude-haiku-4-5", # 비용 절감을 위해 Haiku 사용
max_tokens=512,
messages=[
*old_messages,
{"role": "user", "content": "위 대화 내용을 핵심만 3~5문장으로 요약해줘."}
]
)
return summary_resp.content[0].text
전략 3: RAG (Retrieval-Augmented Generation) 전체 대화 히스토리를 벡터 DB(pgvector, Pinecone 등)에 저장하고, 현재 질문과 관련 있는 과거 메시지만 검색해 컨텍스트에 추가합니다. 매우 긴 세션에서 효과적입니다.
재시도하지 마세요
이 에러는 클라이언트 측 문제라 재시도해도 같은 결과입니다. 위 원인을 확인하고 요청을 수정한 뒤 재발송하세요.
비용 영향
이 에러는 요청이 처리되지 않았으므로 비용이 청구되지 않습니다. 단, 잘못된 모델로 요청을 반복하다가 다른 에러가 발생할 수 있으니 모니터링이 필요합니다.
자세한 비용 절감 패턴은 Claude API Cost and Prompt Caching Break-Even 또는 무료 비용 계산기를 참고하세요.
빠른 진단 체크리스트
컨텍스트 초과 원인을 파악하는 체크리스트:
-
client.messages.count_tokens()로 요청 전 실제 토큰 수를 확인했는가? -
input_tokens + max_tokens <= context_window수식이 성립하는가? (양쪽 합이 한도를 넘으면 에러) - system prompt의 토큰 수를 개별적으로 측정했는가? (긴 시스템 프롬프트는 의외로 큼)
- conversation history에서 오래된 메시지를 정기적으로 제거하고 있는가?
- PDF/이미지 첨부 시 해당 파일의 토큰 사용량을 고려했는가? (PDF 1페이지 ≈ 1,500~3,000 토큰)
모델별 컨텍스트 한도표
| 모델 | 컨텍스트 윈도우 | max_tokens 최대값 |
|---|---|---|
claude-haiku-4-5 |
200,000 토큰 | 8,192 |
claude-sonnet-4-5 |
200,000 토큰 | 8,192 |
claude-sonnet-4-5 (확장) |
1,000,000 토큰 | 8,192 |
claude-opus-4 |
200,000 토큰 | 32,768 |
중요: max_tokens는 응답 최대 길이이며, 입력 + 출력의 합이 context_window를 초과하면 에러가 납니다. 예를 들어 Sonnet 4.5 200K 사용 시 입력이 195,000 토큰이면 max_tokens를 5,000 이하로 설정해야 합니다.
프로덕션 모니터링
API 호출 전 토큰 수를 측정해 자동으로 히스토리를 압축하는 패턴:
import anthropic, logging
logger = logging.getLogger("claude.context")
def send_with_trim(
client: anthropic.Anthropic,
model: str,
messages: list,
system: str = "",
max_tokens: int = 1024,
context_window: int = 200_000,
):
"""context window 초과 전 자동 히스토리 압축."""
while True:
count = client.messages.count_tokens(
model=model,
messages=messages,
system=system,
)
available = context_window - count.input_tokens
if available >= max_tokens:
break # 여유 있음
if len(messages) <= 2:
raise RuntimeError(
f"최소 메시지만 남겼는데도 컨텍스트 초과. "
f"입력 토큰: {count.input_tokens}, 필요: {max_tokens}"
)
# 가장 오래된 user/assistant 쌍 제거
messages = messages[2:]
logger.warning(
"컨텍스트 초과 임박 — 오래된 메시지 2개 제거",
extra={
"input_tokens": count.input_tokens,
"available": available,
"remaining_messages": len(messages),
}
)
return client.messages.create(
model=model,
messages=messages,
system=system,
max_tokens=max_tokens,
)
언제 지원팀에 연락해야 하나요?
context_length_exceeded는 항상 클라이언트 코드 수정으로 해결됩니다. 다음 경우에만 support.anthropic.com에 문의하세요:
-
count_tokens로 측정한 토큰 수가 한도 이하인데도 context_length_exceeded가 반환되는 경우 (API 집계 불일치 가능성) - Sonnet 4.5 1M 컨텍스트 확장 기능 활성화 방법을 확인해야 하는 경우
- tool_result 메시지가 포함된 요청에서 실제보다 훨씬 높은 토큰 수가 집계되는 경우
관련 에러
- 400 invalid_request_error — 잘못된 요청 형식
- 401 authentication_error — 인증 실패
- 403 permission_error — 권한 부족
- 429 rate_limit_error — Rate limit 초과
- 529 overloaded_error — API 일시 과부하
자주 묻는 질문
context_length_exceeded 에러가 떴을 때 비용이 청구되나요?
처리되지 않은 요청이므로 청구되지 않습니다. 단, 무한 재시도 루프는 다른 에러로 비용을 발생시킬 수 있습니다.
context_length_exceeded와 다른 에러의 차이는?
context_length_exceeded는 클라이언트 측 문제로 요청 수정 없이는 재시도해도 같은 결과입니다. 5xx 에러 (500/529)는 일시적 서버 이슈라 재시도가 효과적입니다.
Bedrock/Vertex에서도 같은 에러 코드인가요?
네, Anthropic의 error.type 명명 규칙은 모든 deployment (Direct API, AWS Bedrock, GCP Vertex AI)에서 동일합니다. 다만 HTTP 상태 코드는 platform 별로 wrapping되어 다를 수 있습니다 (예: Bedrock은 에러 type을 다른 prefix로 변경).
다음 단계
- 프로덕션 코드에 retry 로직을 추가하려면 Production Patterns for Claude Agents를
- 비용을 모니터링하려면 Claude API 비용 모니터링 가이드를
- 에러 분류 자동화는 무료 /cheatsheet-한국어에서 30개 프롬프트로
에러 처리 패턴 30개 + Pydantic 검증 코드 — Claude API Cost Optimization 마스터클래스 ($59)에 retry 미들웨어, 비용 가드레일, 에러 알림 패턴 12편 포함.