Was this page helpful?
프로그래밍 방식 도구 호출을 사용하면 Claude가 각 도구 호출마다 모델을 통한 왕복을 요구하는 대신, 코드 실행 컨테이너 내에서 프로그래밍 방식으로 도구를 호출하는 코드를 작성할 수 있습니다. 이를 통해 다중 도구 워크플로우의 지연 시간을 줄이고, Claude가 데이터를 모델의 컨텍스트 윈도우에 도달하기 전에 필터링하거나 처리할 수 있어 토큰 소비를 줄일 수 있습니다.
이 기능을 사용하려면 코드 실행 도구가 활성화되어 있어야 합니다.
This feature is not covered by Zero Data Retention (ZDR) arrangements. Data is retained according to the feature's standard retention policy.
프로그래밍 방식 도구 호출은 다음 모델에서 사용할 수 있습니다:
| 모델 | 도구 버전 |
|---|---|
Claude Opus 4.6 (claude-opus-4-6) | code_execution_20250825 |
Claude Sonnet 4.6 (claude-sonnet-4-6) | code_execution_20250825 |
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | code_execution_20250825 |
Claude Opus 4.5 (claude-opus-4-5-20251101) | code_execution_20250825 |
프로그래밍 방식 도구 호출은 Claude API 및 Microsoft Foundry를 통해 사용할 수 있습니다.
다음은 Claude가 프로그래밍 방식으로 데이터베이스를 여러 번 쿼리하고 결과를 집계하는 간단한 예제입니다:
코드 실행에서 호출 가능하도록 도구를 구성하고 Claude가 해당 도구를 사용하기로 결정하면:
tool_use 블록을 반환합니다이 접근 방식은 특히 다음과 같은 경우에 유용합니다:
커스텀 도구는 병렬 도구 호출을 지원하기 위해 비동기 Python 함수로 변환됩니다. Claude가 도구를 호출하는 코드를 작성할 때 await를 사용하며 (예: result = await query_database("<sql>")), 적절한 비동기 래퍼 함수를 자동으로 포함합니다.
이 문서의 코드 예제에서는 명확성을 위해 비동기 래퍼가 생략되어 있습니다.
allowed_callers 필드allowed_callers 필드는 도구를 호출할 수 있는 컨텍스트를 지정합니다:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}가능한 값:
["direct"] - Claude만 이 도구를 직접 호출할 수 있음 (생략 시 기본값)["code_execution_20250825"] - 코드 실행 내에서만 호출 가능["direct", "code_execution_20250825"] - 직접 및 코드 실행 모두에서 호출 가능각 도구에 대해 두 가지를 모두 활성화하는 대신 ["direct"] 또는 ["code_execution_20250825"] 중 하나를 선택하는 것을 권장합니다. 이렇게 하면 Claude가 도구를 가장 잘 사용하는 방법에 대해 더 명확한 안내를 제공할 수 있습니다.
caller 필드모든 도구 사용 블록에는 호출 방식을 나타내는 caller 필드가 포함됩니다:
직접 호출 (전통적인 도구 사용):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {"type": "direct"}
}프로그래밍 방식 호출:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}tool_id는 프로그래밍 방식 호출을 수행한 코드 실행 도구를 참조합니다.
프로그래밍 방식 도구 호출은 코드 실행과 동일한 컨테이너를 사용합니다:
container 필드를 통해 응답에서 반환됩니다도구가 프로그래밍 방식으로 호출되고 컨테이너가 도구 결과를 기다리고 있을 때, 컨테이너가 만료되기 전에 응답해야 합니다. expires_at 필드를 모니터링하세요. 컨테이너가 만료되면 Claude가 도구 호출을 시간 초과로 처리하고 재시도할 수 있습니다.
다음은 완전한 프로그래밍 방식 도구 호출 흐름이 작동하는 방식입니다:
코드 실행과 프로그래밍 방식 호출을 허용하는 도구가 포함된 요청을 보냅니다. 프로그래밍 방식 호출을 활성화하려면 도구 정의에 allowed_callers 필드를 추가합니다.
도구 설명에 도구의 출력 형식에 대한 자세한 설명을 제공하세요. 도구가 JSON을 반환한다고 지정하면 Claude가 코드에서 결과를 역직렬화하고 처리하려고 시도합니다. 출력 스키마에 대해 더 자세히 제공할수록 Claude가 응답을 프로그래밍 방식으로 더 잘 처리할 수 있습니다.
Claude가 도구를 호출하는 코드를 작성합니다. API가 일시 중지되고 다음을 반환합니다:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "results = await query_database('<sql>')\ntop_customers = sorted(results, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2025-01-15T14:30:00Z"
},
"stop_reason": "tool_use"
}전체 대화 기록과 도구 결과를 포함합니다:
코드 실행이 계속되어 결과를 처리합니다. 추가 도구 호출이 필요한 경우 모든 도구 호출이 충족될 때까지 3단계를 반복합니다.
코드 실행이 완료되면 Claude가 최종 응답을 제공합니다:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers by revenue:\n1. Customer C1: $45,000\n2. Customer C2: $38,000\n3. Customer C5: $32,000\n4. Customer C8: $28,500\n5. Customer C3: $24,000",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Claude는 여러 항목을 효율적으로 처리하는 코드를 작성할 수 있습니다:
# async wrapper omitted for clarity
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
data = await query_database(f"<sql for {region}>")
results[region] = sum(row["revenue"] for row in data)
# Process results programmatically
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")이 패턴은:
Claude는 성공 기준이 충족되면 즉시 처리를 중단할 수 있습니다:
# async wrapper omitted for clarity
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health(endpoint)
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remaining# async wrapper omitted for clarity
file_info = await get_file_info(path)
if file_info["size"] < 10000:
content = await read_full_file(path)
else:
content = await read_file_summary(path)
print(content)# async wrapper omitted for clarity
logs = await fetch_logs(server_id)
errors = [log for log in logs if "ERROR" in log]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)코드 실행이 도구를 호출할 때:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_xyz789"
}
}도구 결과는 실행 중인 코드로 다시 전달됩니다:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000, \"orders\": 23}, {\"customer_id\": \"C2\", \"revenue\": 38000, \"orders\": 18}, ...]"
}
]
}모든 도구 호출이 충족되고 코드가 완료되면:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_xyz789",
"content": {
"type": "code_execution_result",
"stdout": "Analysis complete. Top 5 customers identified from 847 total records.",
"stderr": "",
"return_code": 0,
"content": []
}
}| 오류 | 설명 | 해결 방법 |
|---|---|---|
invalid_tool_input | 도구 입력이 스키마와 일치하지 않음 | 도구의 input_schema를 검증하세요 |
tool_not_allowed | 도구가 요청된 호출자 유형을 허용하지 않음 | allowed_callers에 올바른 컨텍스트가 포함되어 있는지 확인하세요 |
missing_beta_header | 필수 베타 헤더가 제공되지 않음 | 요청에 필수 베타 헤더를 추가하세요 |
도구가 응답하는 데 너무 오래 걸리면 코드 실행이 TimeoutError를 받습니다. Claude는 이를 stderr에서 확인하고 일반적으로 재시도합니다:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out.",
"return_code": 0,
"content": []
}
}시간 초과를 방지하려면:
expires_at 필드를 모니터링하세요도구가 오류를 반환하는 경우:
# Provide error information in the tool result
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds",
}Claude의 코드가 이 오류를 받아 적절하게 처리할 수 있습니다.
strict: true가 설정된 도구는 프로그래밍 방식 호출에서 지원되지 않습니다tool_choice를 통해 특정 도구의 프로그래밍 방식 호출을 강제할 수 없습니다disable_parallel_tool_use: true는 프로그래밍 방식 호출에서 지원되지 않습니다다음 도구는 현재 프로그래밍 방식으로 호출할 수 없지만, 향후 릴리스에서 지원이 추가될 수 있습니다:
프로그래밍 방식 도구 호출에 응답할 때 엄격한 형식 요구 사항이 있습니다:
도구 결과만 포함하는 응답: 결과를 기다리는 보류 중인 프로그래밍 방식 도구 호출이 있는 경우, 응답 메시지에는 tool_result 블록만 포함해야 합니다. 도구 결과 뒤에도 텍스트 콘텐츠를 포함할 수 없습니다.
// ❌ 유효하지 않음 - 프로그래밍 방식 도구 호출에 응답할 때 텍스트를 포함할 수 없음
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"},
{"type": "text", "text": "What should I do next?"} // This will cause an error
]
}
// ✅ 유효함 - 프로그래밍 방식 도구 호출에 응답할 때 도구 결과만 포함
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"}
]
}이 제한 사항은 프로그래밍 방식(코드 실행) 도구 호출에 응답할 때만 적용됩니다. 일반 클라이언트 측 도구 호출의 경우 도구 결과 뒤에 텍스트 콘텐츠를 포함할 수 있습니다.
프로그래밍 방식 도구 호출은 일반 도구 호출과 동일한 속도 제한이 적용됩니다. 코드 실행에서의 각 도구 호출은 별도의 호출로 계산됩니다.
프로그래밍 방식으로 호출될 커스텀 도구를 구현할 때:
프로그래밍 방식 도구 호출은 토큰 소비를 크게 줄일 수 있습니다:
예를 들어, 10개의 도구를 직접 호출하면 프로그래밍 방식으로 호출하고 요약을 반환하는 것보다 약 10배의 토큰을 사용합니다.
프로그래밍 방식 도구 호출은 코드 실행과 동일한 가격을 사용합니다. 자세한 내용은 코드 실행 가격을 참조하세요.
프로그래밍 방식 도구 호출의 토큰 계산: 프로그래밍 방식 호출의 도구 결과는 입력/출력 토큰 사용량에 포함되지 않습니다. 최종 코드 실행 결과와 Claude의 응답만 계산됩니다.
좋은 사용 사례:
덜 이상적인 사용 사례:
"Tool not allowed" 오류
"allowed_callers": ["code_execution_20250825"]가 포함되어 있는지 확인하세요컨테이너 만료
expires_at 필드를 모니터링하세요도구 결과가 올바르게 파싱되지 않음
caller 필드를 확인하세요Claude의 학습에는 코드에 대한 광범위한 노출이 포함되어 있어 함수 호출을 추론하고 체이닝하는 데 효과적입니다. 도구가 코드 실행 환경 내에서 호출 가능한 함수로 제시되면 Claude는 이 강점을 활용하여:
이 접근 방식은 전통적인 도구 사용으로는 비실용적인 워크플로우(예: 1M 토큰 이상의 파일 처리)를 가능하게 하며, Claude가 모든 것을 대화 컨텍스트에 로드하는 대신 프로그래밍 방식으로 데이터를 처리할 수 있게 합니다.
프로그래밍 방식 도구 호출은 Anthropic의 관리형 코드 실행 외부에서도 구현할 수 있는 일반화 가능한 패턴입니다. 다음은 접근 방식에 대한 개요입니다:
Claude에게 코드 실행 도구를 제공하고 해당 환경에서 사용 가능한 함수를 설명합니다. Claude가 코드로 도구를 호출하면 애플리케이션이 해당 함수가 정의된 로컬에서 실행합니다.
장점:
단점:
사용 시기: 애플리케이션이 임의의 코드를 안전하게 실행할 수 있고, 간단한 솔루션을 원하며, Anthropic의 관리형 제품이 요구 사항에 맞지 않는 경우.
Claude의 관점에서는 동일한 접근 방식이지만, 코드가 보안 제한(예: 네트워크 이그레스 없음)이 있는 샌드박스 컨테이너에서 실행됩니다. 도구가 외부 리소스를 필요로 하는 경우 샌드박스 외부에서 도구 호출을 실행하기 위한 프로토콜이 필요합니다.
장점:
단점:
사용 시기: 보안이 중요하고 Anthropic의 관리형 솔루션이 요구 사항에 맞지 않는 경우.
Anthropic의 프로그래밍 방식 도구 호출은 Claude에 최적화된 Python 환경을 갖춘 샌드박스 실행의 관리형 버전입니다. Anthropic이 컨테이너 관리, 코드 실행 및 안전한 도구 호출 통신을 처리합니다.
장점:
Claude API를 사용하는 경우 Anthropic의 관리형 솔루션을 사용하는 것을 권장합니다.
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data '{
"model": "claude-opus-4-6",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue"
}
],
"tools": [
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "SQL query to execute"
}
},
"required": ["sql"]
},
"allowed_callers": ["code_execution_20250825"]
}
]
}'response = client.messages.create(
model="claude-opus-4-6",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
}
],
tools=[
{"type": "code_execution_20250825", "name": "code_execution"},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"],
},
],
)response = client.messages.create(
model="claude-opus-4-6",
max_tokens=4096,
container="container_xyz789", # Reuse the container
messages=[
{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue",
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results.",
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."},
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "<sql>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123",
},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": '[{"customer_id": "C1", "revenue": 45000}, {"customer_id": "C2", "revenue": 38000}, ...]',
}
],
},
],
tools=[...],
)Claude와 함께하는 도구 사용의 기본 사항을 이해하세요.