Anthropic
Anthropic (Claude)
Anthropic의 Claude 모델은 PydanticAI에서 AnthropicModel로 쓰면 돼요. 설치하고 API 키를 환경 변수로 설정하면 모델 이름으로 바로 에이전트를 만들 수 있고, AWS Bedrock이나 Google Vertex 같은 클라우드 플랫폼을 통해서도 Claude를 사용할 수 있어요. 이 모델 통합은 Anthropic 전용 설정이 많아서, 필요한 것만 골라 보시면 돼요.
출처: 공식문서
설치
AnthropicModel을 쓰려면 pydantic-ai를 설치하거나 pydantic-ai-slim을 anthropic 옵션 그룹과 함께 설치해야 해요.
Terminal
pip install "pydantic-ai-slim[anthropic]"
Terminal
uv add "pydantic-ai-slim[anthropic]"
설정
Anthropic API를 쓰려면 console.anthropic.com/settings/keys에서 API 키를 생성해요.
AnthropicModelName에는 사용 가능한 Anthropic 모델 목록이 들어 있어요.
환경 변수
API 키를 받았으면 환경 변수로 설정해요.
Terminal
export ANTHROPIC_API_KEY='your-api-key'
이제 AnthropicModel을 이름으로 쓸 수 있어요.
from pydantic_ai import Agent
agent = Agent('anthropic:claude-sonnet-4-6')
...
또는 모델 이름만으로 직접 초기화할 수도 있어요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
model = AnthropicModel('claude-sonnet-4-5')
agent = Agent(model)
...
Claude Opus 4.7 / 4.8 / 5 마이그레이션: Anthropic의 Claude Opus 마이그레이션 가이드는 Opus 4.7·4.8·5 요청에서 temperature, top_p, top_k를 제거할 것을 권장해요. PydanticAI는 claude-opus-4-7, claude-opus-4-8, claude-opus-5, claude-sonnet-5, claude-fable-5, claude-mythos-5에서 extra_body 오버라이드 포함해 그 키들을 자동으로 버려요.
같은 가이드는 Opus 4.6에서 마이그레이션할 때 max_tokens과 토큰 수 가정을 재평가할 것도 권장해요. Opus 4.7이 업데이트된 토큰화를 도입했기 때문이죠(4.8로 이어짐). count_tokens()이나 count_tokens_before_request에 의존한다면 새 모델에 맞춰 임계값을 검증하세요.
provider 인자
provider 인자로 커스텀 Provider를 제공할 수 있어요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
model = AnthropicModel(
'claude-sonnet-4-5', provider=AnthropicProvider(api_key='your-api-key')
)
agent = Agent(model)
...
커스텀 HTTP 클라이언트
AnthropicProvider를 커스텀 httpx2.AsyncClient로 커스터마이즈할 수 있어요.
from httpx2 import AsyncClient
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
custom_http_client = AsyncClient(timeout=30)
model = AnthropicModel(
'claude-sonnet-4-5',
provider=AnthropicProvider(api_key='your-api-key', http_client=custom_http_client),
)
agent = Agent(model)
...
레거시 httpx.AsyncClient는 받지 않아요. anthropic 1.0은 httpx2 위에 만들어져서 클라이언트 생성 시 레거시 클라이언트를 거부해요.
provider가 만드는 AsyncAnthropic 클라이언트도 실패한 요청을 자체적으로 재시도해요. max_retries=2가 기본값이라, 요청이 당신의 코드가 에러를 보기 전에 네트워크에 최대 세 번 도달할 수 있어요. 직접 클라이언트를 만들 때(예: anthropic_client=) 재시도 정책을 오직 transport에만 두고 싶다면 max_retries=0을 넘기세요. 이 레이어가 언제 발화하는지는 Provider SDK retries를 보세요.
모델 설정
AnthropicModelSettings로 모델 동작을 커스터마이즈할 수 있어요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelSettings
model = AnthropicModel('claude-sonnet-4-5')
settings = AnthropicModelSettings(
temperature=0.2,
top_k=40,
service_tier='auto',
)
agent = Agent(model, model_settings=settings)
...
서비스 티어
Anthropic은 지연 시간과 처리량을 관리하기 위해 service tier를 지원해요. 통합된 service_tier 필드나 provider별 anthropic_service_tier 필드를 쓸 수 있어요. 둘 다 설정되면 anthropic_service_tier가 우선하고, Anthropic의 네이티브 값('auto' 또는 'standard_only')을 받아요.
통합 필드는 Anthropic에서 이렇게 매핑돼요.
'auto':'auto'그대로 통과해요(Anthropic 네이티브 값 — 가능하면 priority 용량을 써요).'default':'standard_only'로 매핑돼요(standard 티어를 강제해서 priority 용량을 사용하지 않아요).'flex'와'priority'는 Anthropic의 티어 모델에 없어서 조용히 무시돼요.
클라우드 플랫폼 통합
AnthropicProvider에 커스텀 클라이언트를 넘기면 클라우드 플랫폼을 통해 Anthropic 모델을 쓸 수 있어요.
AWS Bedrock
AWS Bedrock으로 Claude 모델을 쓰려면 Anthropic 문서를 따라 Bedrock 클라이언트를 설정하고 AnthropicProvider에 넘기면 돼요. Anthropic이 권장하는 최신 AsyncAnthropicBedrockMantle 클라이언트(Messages API 사용)와 레거시 AsyncAnthropicBedrock 클라이언트(InvokeModel API를 ARN-버전 모델 ID로 사용)가 모두 지원돼요.
from anthropic import AsyncAnthropicBedrockMantle
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
bedrock_client = AsyncAnthropicBedrockMantle() # Uses AWS credentials from environment
provider = AnthropicProvider(anthropic_client=bedrock_client)
model = AnthropicModel('anthropic.claude-haiku-4-5', provider=provider)
agent = Agent(model)
...
Bedrock vs BedrockConverseModel: 이 접근은 AWS Bedrock 자격 증명과 함께 Anthropic의 SDK를 써요. AWS SDK(boto3)를 직접 쓰는 대안은 BedrockConverseModel을 보세요.
레거시 AsyncAnthropicBedrock 클라이언트의 도구 검색: 레거시 InvokeModel API는 bm25 도구 검색 변형을 지원하지 않아서, AsyncAnthropicBedrock 클라이언트에서 ToolSearch는 기본적으로 'regex'로 설정되고('bm25' 대신), ToolSearch(strategy='bm25')를 넘기면 UserError가 나요.
레거시 AsyncAnthropicBedrock 클라이언트의 토큰 카운팅: Anthropic SDK는 Bedrock에서 고수준 토큰 카운팅 메서드를 차단하므로, count_tokens()(와 count_tokens_before_request)는 대신 Bedrock 자체의 /model/{model}/count-tokens 엔드포인트를 호출해요. 그 엔드포인트는 base foundation-model ID(예: anthropic.claude-sonnet-4-20250514-v1:0)만 받아요. 크로스 리전 추론 프로필 ID(us./eu./global. 프리픽스)와 수명이 끝난 모델 버전은 Bedrock이 거부해요.
Google Cloud
Google Cloud Vertex AI로 Claude 모델을 쓰려면 Anthropic 문서를 따라 AsyncAnthropicVertex 클라이언트를 설정하고 AnthropicProvider에 넘기면 돼요.
from anthropic import AsyncAnthropicVertex
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
vertex_client = AsyncAnthropicVertex(region='us-east5', project_id='your-project-id')
provider = AnthropicProvider(anthropic_client=vertex_client)
model = AnthropicModel('claude-sonnet-4-5', provider=provider)
agent = Agent(model)
...
Microsoft Foundry
Microsoft Foundry로 Claude 모델을 쓰려면 Anthropic 문서를 따라 AsyncAnthropicFoundry 클라이언트를 설정하고 AnthropicProvider에 넘기면 돼요.
from anthropic import AsyncAnthropicFoundry
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
foundry_client = AsyncAnthropicFoundry(
api_key='your-foundry-api-key', # Or set ANTHROPIC_FOUNDRY_API_KEY
resource='your-resource-name',
)
provider = AnthropicProvider(anthropic_client=foundry_client)
model = AnthropicModel('claude-sonnet-4-5', provider=provider)
agent = Agent(model)
...
Entra ID 인증을 포함한 설정 지침은 Anthropic의 Microsoft Foundry 문서를 보세요.
태스크 예산 (Beta)
Anthropic의 task budgets는 완전한 에이전트 루프(thinking, 도구 호출, 도구 결과, 출력 포함)에 대한 권고 토큰 예산을 Claude에 줄 수 있게 해줘요. 그래서 모델이 스스로 페이스를 조절하고 예산이 소비되면 우아하게 마무리할 수 있죠. AnthropicModelSettings.anthropic_task_budget으로 구성하며, AnthropicTaskBudget 페이로드를 받아 output_config.task_budget으로 매핑돼요.
PydanticAI는 이 설정이 있으면 Anthropic이 요구하는 task-budgets-2026-03-13 베타를 자동으로 활성화해요. 현재 지원은 네이티브 Anthropic claude-fable-5, claude-fable-5-1, claude-mythos-5, claude-mythos-5-1, claude-opus-4-7, claude-opus-4-8, claude-opus-5, claude-sonnet-5 요청에만 국한되고, Bedrock, Vertex, Microsoft Foundry Anthropic 모델 ID는 안 돼요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelSettings
model = AnthropicModel('claude-opus-4-8')
settings = AnthropicModelSettings(
anthropic_task_budget={'type': 'tokens', 'total': 20_000},
)
agent = Agent(model, model_settings=settings)
...
태스크 예산은 anthropic_effort와 구성돼요. effort는 단계별 추론 깊이를 조정하고, 태스크 예산은 루프 전체의 총 작업량을 제한해요. 두 필드는 같은 output_config 객체 아래에 들어가요.
참고: 태스크 예산은 하드 캡이 아니라 권고예요. 강제 상한이 필요하면 max_tokens와 함께 쓰세요.
컴팩션에 걸쳐 예산 유지하기
서버 측 컴팩션에 AnthropicCompaction을 쓴다면 이 섹션은 건너뛰어도 돼요. 서버가 카운트다운을 스스로 추적하므로 remaining은 설정하지 말고 total이 스스로 조절하게 두세요.
task_budget의 remaining 필드는 클라이언트 측 컴팩션 패턴용이에요. 요청 사이에서 이전 턴을 직접 요약하는 경우죠. 이때 서버는 재작성 전에 얼마나 예산을 썼는지 기억하지 못해요. PydanticAI는 remaining을 추적해 주지 않아요. 요청 간 토큰 사용량을 직접 누적하고(예: 매 실행의 RunUsage) 다음 요청에 업데이트된 값을 넘겨서 카운트다운이 total로 리셋되지 않고 이어지게 해야 해요. remaining을 설정하면 예산을 포함한 프롬프트 캐시 접두사도 무효화돼요. 캐싱을 보존하려면 total을 한 번 설정하고 서버가 진행 중인 카운트다운에 맞춰 스스로 조절하게 두세요.
주의: task_budget.remaining은 AnthropicCompaction과 상호 배타적이에요. 서버 측 컴팩션이 예산을 스스로 추적하기 때문에 Anthropic은 둘을 결합한 요청을 거부해요. PydanticAI는 이 조합이 구성되면 요청을 보내기 전에 UserError를 일으켜요. 클라이언트 측 예산 추적에는 remaining, 서버 측 컴팩션에는 AnthropicCompaction 중 하나를 선택하세요.
프롬프트 캐싱
Anthropic은 프롬프트 캐싱으로 프롬프트의 일부를 캐싱해서 비용을 줄이는 걸 지원해요. PydanticAI는 자동 캐싱, 블록별 메시지 캐싱, 명시적 캐시 중단점을 지원해요.
자동 캐싱
프롬프트 캐싱을 켜는 가장 간단한 방법은 AnthropicModelSettings.anthropic_cache를 쓰는 거예요. Anthropic의 자동 캐싱을 사용해서 최상위 cache_control 파라미터를 넘기므로 서버가 각 요청의 마지막 캐시 가능 블록에 캐시 중단점을 자동 적용해요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='You are a helpful assistant.',
model_settings=AnthropicModelSettings(
anthropic_cache=True,
),
)
result1 = agent.run_sync('What is the capital of France?')
result2 = agent.run_sync(
'What is the capital of Germany?', message_history=result1.all_messages()
)
print(f'Cache write: {result1.usage.cache_write_tokens}')
print(f'Cache read: {result2.usage.cache_read_tokens}')
print(f'Cache hit ratio: {result2.usage.cache_hit_ratio}')
이건 대화가 커짐에 따라 캐시 중단점이 앞으로 이동해야 하는 멀티턴 대화에 이상적이에요. anthropic_cache='1h'로 커스텀 TTL을 지정할 수도 있어요.
Bedrock과 Vertex: Bedrock과 Vertex는 아직 자동 캐싱을 지원하지 않아요. 이 플랫폼에서 anthropic_cache는 마지막 사용자 메시지의 블록별 캐싱으로 폴백해서, 멀티턴 대화에서 같은 이점을 제공해요.
블록별 메시지 캐싱
anthropic_cache의 대안으로, AnthropicModelSettings.anthropic_cache_messages는 Anthropic의 최상위 자동 캐싱 파라미터 대신 마지막 메시지의 마지막 콘텐츠 블록에 블록별 cache_control을 추가해요. Anthropic 메시지 형식을 받지만 최상위 자동 캐싱은 지원하지 않는 Anthropic 호환 게이트웨이·프록시(MiniMax, OpenRouter, LiteLLM 등)에서 쓰세요.
from anthropic import AsyncAnthropic
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelSettings
from pydantic_ai.providers.anthropic import AnthropicProvider
client = AsyncAnthropic(
api_key='your-api-key',
base_url='https://your-anthropic-compatible-gateway.example.com',
)
model = AnthropicModel(
'claude-sonnet-4-6',
provider=AnthropicProvider(anthropic_client=client),
)
agent = Agent(
model,
model_settings=AnthropicModelSettings(
anthropic_cache_messages=True,
),
)
result = agent.run_sync('What is the capital of France?')
print(result.output)
anthropic_cache_messages='1h'로 커스텀 TTL을 지정할 수도 있어요. anthropic_cache_messages는 anthropic_cache와 함께 쓸 수 없어요.
명시적 캐시 중단점
자동 캐싱 외에도 PydanticAI는 특정 콘텐츠에 캐시 중단점을 놓는 여러 방법을 제공해요.
CachePoint로 사용자 메시지 캐시하기: 사용자 메시지에CachePoint마커를 넣으면 그 앞의 모든 것을 캐시해요.- 마지막 메시지 블록 캐시하기:
AnthropicModelSettings.anthropic_cache_messages를True로 설정(기본 5m TTL)하거나'5m'/'1h'를 직접 지정해요. - 시스템 지시 캐시하기:
AnthropicModelSettings.anthropic_cache_instructions를True로 설정(기본 5m TTL)하거나'5m'/'1h'를 직접 지정해요. - 도구 정의 캐시하기:
AnthropicModelSettings.anthropic_cache_tool_definitions를True로 설정(기본 5m TTL)하거나'5m'/'1h'를 직접 지정해요.
예시: 종합 캐싱 전략
최대 절감을 위해 자동 캐싱과 명시적 중단점을 결합해요. 자동 캐싱이 대화를 처리하고, 명시적 중단점이 시스템 지시와 도구 정의를 고정해요.
from pydantic_ai import Agent, RunContext
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Detailed instructions...',
model_settings=AnthropicModelSettings(
anthropic_cache=True, # Server auto-caches last block
anthropic_cache_instructions=True, # Explicitly cache system instructions
anthropic_cache_tool_definitions='1h', # Explicitly cache tool definitions with 1h TTL
),
)
@agent.tool
def search_docs(ctx: RunContext, query: str) -> str:
"""Search documentation."""
return f'Results for {query}'
result = agent.run_sync('Search for Python best practices')
print(result.output)
스마트 지시 캐싱
정적·동적 지시와 함께 anthropic_cache_instructions를 쓰면 PydanticAI가 캐시 경계를 최적 지점에 자동으로 놓아요. 정적 지시(Agent(instructions=...)에서)는 동적 지시(@agent.instructions 함수나 toolsets에서)보다 먼저 정렬되고, 캐시 지점은 마지막 정적 지시 파트 뒤에 놓여요.
즉 안정적인 정적 지시는 효율적으로 캐시되고, 요청마다 바뀔 수 있는 동적 지시는 캐시 경계 밖에 남아 캐시 무효화를 일으키지 않아요.
from datetime import date
from pydantic_ai import Agent, RunContext
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
deps_type=str,
instructions='You are a helpful customer service agent. Follow company policy.', # (1)
model_settings=AnthropicModelSettings(
anthropic_cache_instructions=True, # (2)
),
)
@agent.instructions
def dynamic_context(ctx: RunContext[str]) -> str: # (3)
return f"Customer name: {ctx.deps}. Today's date: {date.today()}."
result = agent.run_sync('What is your return policy?', deps='Alice')
print(result.output)
정적 지시는 요청 간에 캐시돼요.
정적/동적 경계에서 스마트 캐시 배치를 가능하게 해요.
동적 지시는 요청마다 바뀌고 캐시되지 않아요.
CachePoint로 세밀하게 제어하기
수동 CachePoint 마커로 캐시 위치를 정확히 제어할 수 있어요.
from pydantic_ai import Agent, CachePoint
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Instructions...',
)
# Manually control cache points for specific content blocks
result = agent.run_sync([
'Long context from documentation...',
CachePoint(), # Cache everything up to this point
'First question'
])
print(result.output)
캐시 사용 통계 접근
result.usage로 캐시 사용 통계에 접근해요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Instructions...',
model_settings=AnthropicModelSettings(
anthropic_cache=True,
),
)
result = agent.run_sync('Your question')
usage = result.usage
print(f'Cache write tokens: {usage.cache_write_tokens}')
print(f'Cache read tokens: {usage.cache_read_tokens}')
캐시 지점 한도
Anthropic은 요청당 캐시 지점을 최대 4개 강제해요. PydanticAI가 이 한도를 자동 관리해서 요청이 항상 에러 없이 규칙을 준수하게 해줘요.
캐시 지점 배분 방식
캐시 지점은 여러 원천에서 나올 수 있어요.
- 자동 캐싱:
anthropic_cache를 통해(서버가 마지막 캐시 가능 블록에 캐시 지점 1개 적용) - 마지막 메시지 블록:
anthropic_cache_messages설정을 통해(마지막 메시지 콘텐츠 블록에 캐시 지점 추가) - 시스템 프롬프트:
anthropic_cache_instructions설정을 통해(마지막 시스템 프롬프트 블록에 캐시 지점 추가) - 도구 정의:
anthropic_cache_tool_definitions설정을 통해(마지막 도구 정의에 캐시 지점 추가) - 메시지:
CachePoint마커를 통해(메시지 콘텐츠에 캐시 지점 추가)
각 설정은 캐시 지점 최대 1개를 쓰지만 결합할 수 있어요. 다만 anthropic_cache와 anthropic_cache_messages는 상호 배타적이에요. 총합이 4를 넘으면 PydanticAI가 오래된 메시지에서 초과 캐시 지점을 자동으로 잘라내요.
예시: 자동·명시적 캐싱 결합
자동 캐싱과 명시적 중단점을 가진 에이전트를 정의해요.
from pydantic_ai import Agent, CachePoint
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Detailed instructions...',
model_settings=AnthropicModelSettings(
anthropic_cache=True, # 1 cache point (server-applied)
anthropic_cache_instructions=True, # 1 cache point
anthropic_cache_tool_definitions=True, # 1 cache point
),
)
@agent.tool_plain
def my_tool() -> str:
return 'result'
# 3 of 4 slots used (1 automatic + 1 instructions + 1 tools)
# Room for 1 more explicit CachePoint marker
result = agent.run_sync([
'Context', CachePoint(), # 4th cache point - OK
'Question'
])
print(result.output)
usage = result.usage
print(f'Cache write tokens: {usage.cache_write_tokens}')
print(f'Cache read tokens: {usage.cache_read_tokens}')
자동 캐시 지점 제한
모든 원천(설정 + CachePoint 마커)의 명시적 캐시 지점이 사용 가능한 예산을 넘으면, PydanticAI가 오래된 메시지 콘텐츠에서 초과 캐시 지점을 자동으로 제거해요(가장 최근 것 유지).
설정에서 캐시 지점 2개를 가진 에이전트를 정의해요.
from pydantic_ai import Agent, CachePoint
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
instructions='Instructions...',
model_settings=AnthropicModelSettings(
anthropic_cache_instructions=True, # 1 cache point
anthropic_cache_tool_definitions=True, # 1 cache point
),
)
@agent.tool_plain
def search() -> str:
return 'data'
# Already using 2 cache points (instructions + tools)
# Can add 2 more CachePoint markers (4 total limit)
result = agent.run_sync([
'Context 1', CachePoint(), # Oldest - will be removed
'Context 2', CachePoint(), # Will be kept (3rd point)
'Context 3', CachePoint(), # Will be kept (4th point)
'Question'
])
# Final cache points: instructions + tools + Context 2 + Context 3 = 4
print(result.output)
usage = result.usage
print(f'Cache write tokens: {usage.cache_write_tokens}')
print(f'Cache read tokens: {usage.cache_read_tokens}')
핵심 포인트:
- 시스템·도구 캐시 지점은 항상 보존돼요.
anthropic_cache는anthropic_cache_instructions·anthropic_cache_tool_definitions처럼 캐시 지점 1개로 계산돼요.- 메시지의 초과
CachePoint마커는 한도를 넘으면 오래된 것부터 새 것으로 제거돼요. - 이로써 지시·도구 같은 중요한 캐싱이 유지되면서 메시지 수준 캐싱의 이점도 누릴 수 있어요.
대화 중간 시스템 메시지
긴 세션 도중 에이전트의 system_prompt에 지시를 추가하면 프롬프트의 앞부분이 다시 쓰여서 뒤의 모든 캐시된 접두사가 무효화돼요. Anthropic은 이 문제를 대화 _내부_의 앞부분이 아닌 그 지시의 자체 위치에 시스템 메시지를 받아들여서 해결해요. 그래서 그 지점까지 캐시된 모든 것이 캐시된 채 유지되죠.
첫 ModelRequest 밖의 모든 SystemPromptPart는 대화 중간 지시예요. 저장된 message_history에서 왔든 실행 중 RunContext.enqueue에서 왔든 상관없어요. 켤 게 추가로 없어요.
from pydantic_ai import Agent, RunContext, SystemPromptPart
agent = Agent('anthropic:claude-opus-4-8', system_prompt='You are a code reviewer.')
@agent.tool
def require_type_annotations(ctx: RunContext[None]) -> str:
ctx.enqueue(SystemPromptPart(content='Every suggestion must include explicit type annotations.'))
return 'rule added'
지시를 제자리에 두면 앞의 접두사를 재사용 가능하게 하지만, 그 자체로 캐싱을 켜지는 않아요. 캐싱은 여전히 anthropic_cache, anthropic_cache_messages, 또는 명시적 CachePoint에서 옵니다. 큐에 넣은 배치 끝의 CachePoint는 그 배치에서 그 앞의 모든 것(지시 포함)을 캐시해요. 그 뒤에 더 많은 콘텐츠가 있는 지점은 놓인 곳까지 캐시하고 지시는 밖에 남겨요. 지시는 동행한 콘텐츠 뒤에 보내지므로, 콘텐츠가 밖에 있는 경계 안에 있을 수 없거든요.
지원은 모델과 transport에 따라 달라져요. Microsoft Foundry 통합은 그 역할을 제공하지 않고, 일부 Claude 모델은 항목을 받아들이되 반응하지 않아요. Anthropic의 대화 중간 시스템 메시지 문서에 현재 목록이 있어요. PydanticAI는 쓰는 모델과 transport에 맞는 렌더링을 골라서, 같은 위치의 <system> 태그 사용자 메시지로 폴백해요. 그래서 지시는 어느 쪽이든 놓인 곳에 적용돼요.
두 방식의 차이는 모델이 사용자에게서 가져오는 걸 경계해야 하는 지시에서 드러나요. 네이티브 항목을 주면 Claude는 최상위 프롬프트가 정한 제한을 오히려 들어올릴 수 있고, <system> 태그에 같은 텍스트를 주면 거부해요. 형식 변경처럼 신뢰할 만한 게 없는 지시라면 둘 다 동작해요.
이 지시들이 provider 간에 어떻게 동작하는지, 문구를 어떻게 짜는지, 신뢰할 수 없는 콘텐츠가 왜 들어가면 안 되는지는 대화 중간 시스템 프롬프트를 보세요.
배치: Anthropic은 시스템 메시지가 사용자 턴과 모델의 답변 사이에 있어야 해요. 그래서 히스토리가 이미 그 조건을 만족하지 않으면 PydanticAI가 위치를 조정해요. 동행한 사용자 콘텐츠 없이 도착한 지시에는 뒤따를 최소한의 . 사용자 메시지를 붙이고, 다른 사용자 턴 앞에 놓일 지시는 그게 다스리는 답변 바로 앞으로 이동시켜요. 어느 쪽도 지시가 적용되는 턴을 바꾸지 않아요. 와이어상의 위치만 바뀔 뿐이에요.
빠른 모드
Fast mode는 초당 더 많은 출력 토큰을 제공하며 현재 Claude Opus 4.6, Claude Opus 4.7, Claude Opus 4.8, Claude Opus 5에서 지원돼요. 연구 프리뷰예요. anthropic_speed를 'fast'로 설정하면 켜지고, PydanticAI가 필요한 fast-mode-2026-02-01 베타를 자동 추가해요. 미지원 모델에서 anthropic_speed='fast'는 UserWarning과 함께 무시돼요. 가격, rate limit, 최신 지원 모델 목록은 Anthropic fast mode 문서를 보세요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-opus-4-8',
model_settings=AnthropicModelSettings(anthropic_speed='fast'),
)
...
프롬프트 캐시 상호작용: 'fast'와 'standard' 사이를 오가면 프롬프트 캐시가 무효화돼요. 속도가 다른 요청은 캐시된 접두사를 공유하지 않으므로, 캐시에 민감한 대화에서는 속도를 하나로 정하세요.
Bedrock, Vertex, Foundry: Fast mode는 직접 Anthropic API에서만 쓸 수 있어요. Bedrock, Vertex, Foundry 클라이언트는 speed 파라미터를 지원하지 않아서 그 클라이언트에서는 anthropic_speed='fast'가 UserWarning과 함께 무시돼요.
강제 도구 선택
대부분의 Anthropic 모델은 tool_choice='required'(또는 도구 이름 목록)로 도구 호출을 강제할 수 있게 해줘요. 단, extended thinking이 켜진 동안은 예외예요. adaptive thinking은 강제와 호환돼요. Anthropic은 Claude Fable 5.1과 Claude Mythos 5.1이 thinking 없이도 강제 도구 선택을 무조건 거부한다고 문서화했고, PydanticAI는 그 두 모델을 anthropic_supports_forced_tool_choice=False로 표시해요.
강제를 지원하지 않는 모델에서는:
- 명시적
tool_choice='required'(또는 도구 이름 목록)는UserError를 일으켜요.tool_choice='auto'를 대신 쓰세요. - PydanticAI가 당신을 대신해 결정한
required선택(예: output tool에서)은'auto'로 부드럽게 폴백돼요. 결정된 선택이 단일 도구를 지명했다면,tool_choice가'auto'로 남은 채 사용 가능한 도구 목록이 그 도구로 필터링돼요. 이건 캐시된 접두사가 도구 배열을 포함하므로 Anthropic의 프롬프트 캐시를 무효화해요. 그래서 모델이 그것을 호출하는 대신 텍스트로 답할 수 있어요. output tool이 필요할 때 PydanticAI는 도구를 호출하라는 프롬프트로 재시도해요.
Tool Output이 강제 도구 선택으로 이어지기 때문에 extended thinking도 그것과 호환되지 않아요. 맨 structured output_type은 Native Output(또는 JSON 스키마 지원이 없는 모델에서는 Prompted Output)으로 전환되고, 명시적 ToolOutput(...)는 UserError를 일으켜요. Adaptive thinking은 Tool Output을 유지해요. 단, 위에서 강제를 아예 거부하는 모델은 예외예요. thinking 설정이 구성되면 그 모델들은 항상 그래 왔던 대로 동작해요. 맨 structured output_type은 Tool Output에서 벗어나고, 명시적 ToolOutput(...)는 UserError를 일으켜요.
Thinking 블록 바인딩
Claude Fable 5.1은 각 thinking 블록을 그것을 만든 대화 접두사에 바인딩해요. 그 접두사가 바뀐 뒤에 메시지 히스토리를 재생하면 400(The block is bound to a different conversation)으로 실패해요. 그리고 두 가지 일반 PydanticAI 기능이 그것을 바꿔요.
- 실행 간에 텍스트가 다른 동적 지시 함수, 그리고
- 대화 중간에 새 도구를 광고하는 필터링된 toolset. 단, 도구가 deferred loading을 쓰면 예외예요.
둘 다 provider의 프롬프트 캐시를 잃게 만드는 것과 같은 불안정성이에요. 턴 사이에 바뀌는 요청 접두사죠. Thinking 블록은 그걸 당신이 볼 수 있는 400으로 만들고, 캐시는 당신이 볼 수 없는 청구서로 만들어요. 변경 후의 모든 요청이 캐시되지 않은 단가로 전체 대화를 다시 보내니 조용히 말이죠. 접두사를 안정적으로 유지할 수 있다면 그게 거부를 처리하는 것보다 가치가 있어요.
Anthropic은 2026년 8월 31일 이후에 생성된 계정에 대해 이 검사를 강제해요. 오래된 계정은 불일치를 기록하지만 요청이 thinking.block_binding.prefix_mismatch_behavior를 설정한 경우에만 그에 따라 행동해요.
PydanticAI는 기본적으로 아무것도 설정하지 않으므로, 오래된 계정은 추론을 건드리지 않고 계속 재생해요. 검사가 강제되는 곳에서는 거부된 요청이 prefix_mismatch_behavior='drop_block'으로 한 번 재시도돼요. 오래된 블록이 버려지고 실행이 계속되며, AnthropicStaleThinkingBlockWarning이 무슨 일이 있었는지 설명해요. 모델은 이제 그 턴의 추론을 보지 못해요. 실패한 실행 하나를 그 턴의 thinking 하나와 맞바꾸는 거예요. anthropic_binds_thinking_blocks=True로 표시된 모델만 재시도해요.
Anthropic은 drop을 요청 하나에만 적용해요. 그 응답은 변환을 기록하므로 PydanticAI는 그 응답 히스토리を使って 영향을 받은 대화의 나머지 동안 계속 drop_block을 보내요. 이렇게 하면 모델에 가변 상태를 저장하거나 무관한 대화를 바꾸지 않고 이후 매 턴 거부를 피할 수 있어요. 같은 행동이 count_tokens()에도 적용돼요. 토큰 카운팅은 첫 번째 일치하는 거부를 한 번 재시도하고, 회복 히스토리를 가진 이후 카운트는 즉시 drop을 보내요. 카운팅 중에만 본 회복은 이후 카운트에만 적용돼요. 그 엔드포인트는 서버 측 도구를 생략하고 추론과 다른 접두사를 가질 수 있기 때문이에요. 명시적 block_binding은 카운팅과 추론 양쪽 모두에서 여전히 이겨요.
자동 행동은 직접 Anthropic API, Pydantic AI Gateway와 다른 AsyncAnthropic 호환 프록시, AWS의 Claude Platform, 레거시 Amazon Bedrock, Google Vertex AI에서 쓸 수 있어요. AWS 운영 Bedrock Messages API 클라이언트(AsyncAnthropicBedrockMantle)에서는 활성화되지 않는데, 그 클라이언트는 Anthropic 베타 헤더를 받지 않으며 Microsoft Foundry는 현재 이 베타가 문서화되지 않았어요. 명시적 설정은 어느 transport에서든 pass-through로 남아요.
Anthropic은 모든 drop을 보고하고 PydanticAI는 두 가지 방식으로 표면화해요. instrumentation에서 PydanticAI 모델 요청 스팬이 anthropic.input_transformations 이벤트를 담아서, 발생하는 대로 트레이스에서 drop이 보여요. 무관한 주변 애플리케이션 스팬은 절대 수정되지 않아요. 응답에서는 항상 provider_details에 기록돼요.
from pydantic_ai import Agent
from pydantic_ai.messages import ModelResponse
agent = Agent('anthropic:claude-fable-5-1')
result = agent.run_sync('What is the capital of France?')
for message in result.new_messages():
if isinstance(message, ModelResponse) and message.provider_details:
for transformation in message.provider_details.get('input_transformations', []):
print(transformation['path'], transformation['reason'])
거부된 요청과 경고를 건너뛰려면 drop을 먼저 요청하세요. PydanticAI는 필드가 요구하는 베타와 함께 명시적 block_binding을 주어진 대로 보내고 절대 재시도하지 않아요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModelSettings
settings: AnthropicModelSettings = {
'anthropic_thinking': {
'type': 'adaptive',
'block_binding': {'prefix_mismatch_behavior': 'drop_block'},
}
}
agent = Agent('anthropic:claude-fable-5-1', model_settings=settings)
...
추론을 잃는 대신 크게 실패하게 하려면 같은 자리에 'error'를 설정하세요. 재시도를 유지하되 알림만 끄려면 경고를 필터링하세요.
import warnings
from pydantic_ai.models.anthropic import AnthropicStaleThinkingBlockWarning
warnings.simplefilter('ignore', AnthropicStaleThinkingBlockWarning)
세 번째 행동은 없어요. prefix_mismatch_behavior는 'error'나 'drop_block' 둘 중 하나예요. None을 넘기면 Anthropic의 계정 기본값을 명시적으로 요청하는 것이며, 검사가 강제되지 않는 곳에서만 블록을 유지해요.
thinking 블록을 바인딩하지 않는 모델은 기본적으로 영향을 받지 않아요. 명시적 block_binding이 없으면 요청은 필드도 바인딩 베타도 담지 않고, 그들의 400은 절대 재시도되지 않아요. block_binding을 직접 설정하면 어떤 모델이든 둘 다 와이어에 올라가요. 베타는 프로필 플래그가 아니라 필드를 따라가죠. 그런 요청도 절대 재시도되지 않아요. Anthropic은 Claude Mythos 5.1이 이 검사를 실행하지 않는다고 문서화했으므로 표시되지 않아요.
메시지 컴팩션
Anthropic은 긴 대화를 관리하기 위해 자동 컨텍스트 컴팩션을 지원해요. 입력 토큰이 구성된 임계값을 넘으면 API가 컨텍스트를 보존하면서 이전 메시지를 대체하는 요약을 자동 생성해요.
컴팩션 후 후속 요청은 최신 컴팩션 블록부터 압축된 창만 보내서 요청 크기를 줄여요. API는 그보다 앞의 콘텐츠를 어느 쪽이든 무시하죠. 상시 시스템 프롬프트는 영향을 받지 않아요. 컴팩션이 대체하지 않는 별도 system 파라미터로 보내지기 때문이에요.
컴팩션을 켜는 가장 쉬운 방법은 AnthropicCompaction capability를 쓰는 거예요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicCompaction
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[AnthropicCompaction(token_threshold=100_000)],
)
이 capability는 받아요.
token_threshold(기본: 150,000, 최소: 50,000): 입력 토큰이 이 값을 넘으면 컴팩션이 트리거돼요.instructions: 요약이 어떻게 생성될지에 대한 커스텀 지시.pause_after_compaction:True면 응답이stop_reason='compaction'으로 컴팩션 블록 뒤에서 멈춰서, 계속하기 전에 명시적 처리를 할 수 있어요.
대안으로 모델 설정으로 anthropic_context_management를 통해 직접 컴팩션을 구성할 수도 있어요.
from pydantic_ai import Agent
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent('anthropic:claude-sonnet-4-6')
result = agent.run_sync(
'Hello!',
model_settings=AnthropicModelSettings(
anthropic_context_management={
'edits': [{'type': 'compact_20260112', 'trigger': {'type': 'input_tokens', 'value': 100_000}}]
}
),
)
참고: Anthropic이 반환한 컴팩션 블록은 읽을 수 있는 텍스트 요약을 담아요. 메시지 히스토리에 포함되면 후속 요청에서 자동으로 왕복돼요.
코드 실행 도구 버전
기본적으로 PydanticAI는 선택된 모델에 호환되는 Anthropic 코드 실행 도구 버전을 골라요. 특정 지원 Anthropic 도구 버전이 필요할 때 AnthropicModelSettings.anthropic_code_execution_tool_version으로 덮어쓸 수 있어요.
from pydantic_ai import Agent, CodeExecutionTool
from pydantic_ai.capabilities import NativeTool
from pydantic_ai.models.anthropic import AnthropicModelSettings
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[NativeTool(CodeExecutionTool())],
model_settings=AnthropicModelSettings(anthropic_code_execution_tool_version='20260120'),
)
모델이 지원하지 않는 도구 버전을 명시적으로 선택하면 PydanticAI가 UserError를 일으켜요.
코드 실행 컨테이너
메시지 히스토리에서 실행을 이어갈 때 PydanticAI는 그 히스토리에 기록된 Anthropic 코드 실행 컨테이너를 자동 재사용해요. Anthropic 컨테이너는 30일 후 만료되고, 만료된 컨테이너를 참조하는 요청은 에러를 반환해요.
요청이 CodeExecutionTool로 파일을 업로드하는데 Anthropic이 히스토리에서 유래한 컨테이너에 대해 HTTP 500을 반환하면, PydanticAI는 거부된 컨테이너 ID 없이 한 번 재시도해서 Anthropic이 새 컨테이너를 만들고 업로드를 받게 해요. 다른 에러는 이 재시도 없이 발생해요. 새 컨테이너는 만료된 컨테이너의 상태·파일을 담지 않아요.
컨테이너 연속성이 필요하면 anthropic_container를 명시적으로 설정하세요. 명시적으로 구성된 컨테이너는 절대 자동 교체되지 않고, Anthropic의 원래 에러가 대신 발생해요.
더 알아보기 (Learn more)
- Anthropic 프롬프트 캐싱 문서 — 자동·명시적 캐싱
- Task budgets 문서 — 에이전트 루프 토큰 예산
- 대화 중간 시스템 프롬프트 — provider 간 동작