모델 선택

복잡한 도구와 모호한 쿼리의 경우 최신 Claude Sonnet (4.5) 또는 Claude Opus (4.1) 모델을 사용하는 것을 권장합니다. 이들은 여러 도구를 더 잘 처리하고 필요할 때 명확히 하도록 요청합니다. 간단한 도구의 경우 Claude Haiku 모델을 사용하되, 누락된 매개변수를 추론할 수 있다는 점에 유의하세요.
Claude를 도구 사용 및 확장 사고와 함께 사용하는 경우 자세한 내용은 여기의 가이드를 참조하세요.

클라이언트 도구 지정

클라이언트 도구(Anthropic 정의 및 사용자 정의 모두)는 API 요청의 tools 최상위 매개변수에서 지정됩니다. 각 도구 정의에는 다음이 포함됩니다:
매개변수설명
name도구의 이름입니다. 정규식 ^[a-zA-Z0-9_-]{1,64}$와 일치해야 합니다.
description도구가 수행하는 작업, 사용해야 할 때, 동작 방식에 대한 자세한 일반 텍스트 설명입니다.
input_schema도구의 예상 매개변수를 정의하는 JSON Schema 객체입니다.
JSON
{
  "name": "get_weather",
  "description": "Get the current weather in a given location",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "The city and state, e.g. San Francisco, CA"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "The unit of temperature, either 'celsius' or 'fahrenheit'"
      }
    },
    "required": ["location"]
  }
}
이 도구는 get_weather라고 이름이 지어졌으며, 필수 location 문자열과 “celsius” 또는 “fahrenheit” 중 하나여야 하는 선택적 unit 문자열을 포함하는 입력 객체를 예상합니다.

도구 사용 시스템 프롬프트

tools 매개변수를 사용하여 Claude API를 호출하면, 도구 정의, 도구 구성 및 사용자 지정 시스템 프롬프트에서 특수 시스템 프롬프트를 구성합니다. 구성된 프롬프트는 모델에게 지정된 도구를 사용하도록 지시하고 도구가 올바르게 작동하기 위한 필요한 컨텍스트를 제공하도록 설계되었습니다:
In this environment you have access to a set of tools you can use to answer the user's question.
{{ FORMATTING INSTRUCTIONS }}
String and scalar parameters should be specified as is, while lists and objects should use JSON format. Note that spaces for string values are not stripped. The output is not expected to be valid XML and is parsed with regular expressions.
Here are the functions available in JSONSchema format:
{{ TOOL DEFINITIONS IN JSON SCHEMA }}
{{ USER SYSTEM PROMPT }}
{{ TOOL CONFIGURATION }}

도구 정의 모범 사례

Claude를 도구와 함께 사용할 때 최고의 성능을 얻으려면 다음 지침을 따르세요:
  • 매우 자세한 설명을 제공하세요. 이것이 도구 성능에 가장 중요한 요소입니다. 설명에는 다음을 포함하여 도구에 대한 모든 세부 사항을 설명해야 합니다:
    • 도구가 수행하는 작업
    • 사용해야 할 때(그리고 사용하지 말아야 할 때)
    • 각 매개변수의 의미와 도구의 동작에 미치는 영향
    • 도구 이름이 불명확한 경우 도구가 반환하지 않는 정보와 같은 중요한 주의 사항 또는 제한 사항입니다. Claude에게 도구에 대해 제공할 수 있는 컨텍스트가 많을수록 도구를 사용할 시기와 방법을 결정하는 데 더 효과적입니다. 도구 설명당 최소 3-4개 문장을 목표로 하며, 도구가 복잡한 경우 더 많이 작성하세요.
  • 설명을 예시보다 우선시하세요. 도구 설명이나 함께 제공되는 프롬프트에 도구 사용 방법의 예시를 포함할 수 있지만, 이는 도구의 목적과 매개변수에 대한 명확하고 포괄적인 설명을 갖는 것만큼 중요하지 않습니다. 설명을 완전히 작성한 후에만 예시를 추가하세요.
JSON
{
  "name": "get_stock_price",
  "description": "Retrieves the current stock price for a given ticker symbol. The ticker symbol must be a valid symbol for a publicly traded company on a major US stock exchange like NYSE or NASDAQ. The tool will return the latest trade price in USD. It should be used when the user asks about the current or most recent price of a specific stock. It will not provide any other information about the stock or company.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string",
        "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
      }
    },
    "required": ["ticker"]
  }
}
JSON
{
  "name": "get_stock_price",
  "description": "Gets the stock price for a ticker.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string"
      }
    },
    "required": ["ticker"]
  }
}
좋은 설명은 도구가 수행하는 작업, 사용 시기, 반환되는 데이터, ticker 매개변수의 의미를 명확하게 설명합니다. 나쁜 설명은 너무 간단하고 Claude에게 도구의 동작과 사용법에 대해 많은 미해결 질문을 남깁니다.

도구 실행기(베타)

도구 실행기는 Claude를 사용하여 도구를 실행하기 위한 기본 솔루션을 제공합니다. 도구 호출, 도구 결과 및 대화 관리를 수동으로 처리하는 대신 도구 실행기는 자동으로:
  • Claude가 호출할 때 도구 실행
  • 요청/응답 주기 처리
  • 대화 상태 관리
  • 타입 안전성 및 유효성 검사 제공
대부분의 도구 사용 구현에 도구 실행기를 사용하는 것을 권장합니다.
도구 실행기는 현재 베타 상태이며 PythonTypeScript SDK에서만 사용 가능합니다.

기본 사용법

@beta_tool 데코레이터를 사용하여 도구를 정의하고 client.beta.messages.tool_runner()를 사용하여 실행합니다.
비동기 클라이언트를 사용하는 경우 @beta_tool@beta_async_tool로 바꾸고 함수를 async def로 정의하세요.
import anthropic
import json
from anthropic import beta_tool

# Initialize client
client = anthropic.Anthropic()

# Define tools using the decorator
@beta_tool
def get_weather(location: str, unit: str = "fahrenheit") -> str:
    """Get the current weather in a given location.

    Args:
        location: The city and state, e.g. San Francisco, CA
        unit: Temperature unit, either 'celsius' or 'fahrenheit'
    """
    # In a full implementation, you'd call a weather API here
    return json.dumps({"temperature": "20°C", "condition": "Sunny"})

@beta_tool
def calculate_sum(a: int, b: int) -> str:
    """Add two numbers together.

    Args:
        a: First number
        b: Second number
    """
    return str(a + b)

# Use the tool runner
with client.beta.messages.tool_runner(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=[get_weather, calculate_sum],
    messages=[
        {"role": "user", "content": "What's the weather like in Paris? Also, what's 15 + 27?"}
    ]
) as runner:
    for message in runner:
        print(message.content[0].text)
데코레이트된 함수는 텍스트, 이미지 또는 문서 블록을 포함한 콘텐츠 블록 또는 콘텐츠 블록 배열을 반환해야 합니다. 이를 통해 도구는 풍부한 다중 모달 응답을 반환할 수 있습니다. 반환된 문자열은 텍스트 콘텐츠 블록으로 변환됩니다. Claude에 구조화된 JSON 객체를 반환하려면 반환하기 전에 JSON 문자열로 인코딩하세요. 숫자, 부울 또는 기타 비문자열 기본 요소도 문자열로 변환해야 합니다.@beta_tool 데코레이터는 함수 인수와 docstring을 검사하여 주어진 함수의 json 스키마 표현을 추출합니다. 위의 예시에서 calculate_sum은 다음으로 변환됩니다:
{
  "name": "calculate_sum",
  "description": "Adds two integers together.",
  "input_schema": {
    "additionalProperties": false,
    "properties": {
      "left": {
        "description": "The first integer to add.",
        "title": "Left",
        "type": "integer"
      },
      "right": {
        "description": "The second integer to add.",
        "title": "Right",
        "type": "integer"
      }
    },
    "required": ["left", "right"],
    "type": "object"
  }
}
SDK 도구 실행기는 베타 상태입니다. 이 문서의 나머지 부분에서는 수동 도구 구현을 다룹니다.

Claude의 출력 제어

도구 사용 강제

경우에 따라 Claude가 도구 없이 답변을 제공할 수 있다고 생각하더라도 특정 도구를 사용하여 사용자의 질문에 답하도록 Claude를 강제하고 싶을 수 있습니다. tool_choice 필드에서 도구를 지정하여 이를 수행할 수 있습니다:
tool_choice = {"type": "tool", "name": "get_weather"}
tool_choice 매개변수로 작업할 때 네 가지 가능한 옵션이 있습니다:
  • auto는 Claude가 제공된 도구를 호출할지 여부를 결정하도록 허용합니다. 이는 tools가 제공될 때의 기본값입니다.
  • any는 Claude가 제공된 도구 중 하나를 사용해야 하지만 특정 도구를 강제하지 않도록 합니다.
  • tool은 Claude가 항상 특정 도구를 사용하도록 강제할 수 있습니다.
  • none은 Claude가 도구를 사용하지 못하도록 합니다. 이는 tools가 제공되지 않을 때의 기본값입니다.
프롬프트 캐싱을 사용할 때 tool_choice 매개변수의 변경 사항은 캐시된 메시지 블록을 무효화합니다. 도구 정의 및 시스템 프롬프트는 캐시된 상태로 유지되지만 메시지 콘텐츠는 다시 처리되어야 합니다.
이 다이어그램은 각 옵션이 어떻게 작동하는지 보여줍니다:
tool_choiceany 또는 tool일 때 도구를 강제하기 위해 어시스턴트 메시지를 미리 채운다는 점에 유의하세요. 이는 명시적으로 요청받더라도 모델이 tool_use 콘텐츠 블록 전에 자연어 응답이나 설명을 내보내지 않음을 의미합니다.
도구 사용과 함께 확장 사고를 사용할 때 tool_choice: {"type": "any"}tool_choice: {"type": "tool", "name": "..."} 는 지원되지 않으며 오류가 발생합니다. tool_choice: {"type": "auto"} (기본값) 및 tool_choice: {"type": "none"} 만 확장 사고와 호환됩니다.
우리의 테스트에 따르면 이것이 성능을 감소시키지 않아야 합니다. 모델이 특정 도구를 사용하도록 요청하면서도 자연어 컨텍스트나 설명을 제공하기를 원한다면 tool_choice{"type": "auto"} (기본값)를 사용하고 user 메시지에 명시적 지침을 추가할 수 있습니다. 예를 들어: What's the weather like in London? Use the get_weather tool in your response.

JSON 출력

도구가 반드시 클라이언트 함수일 필요는 없습니다. 모델이 제공된 스키마를 따르는 JSON 출력을 반환하기를 원할 때마다 도구를 사용할 수 있습니다. 예를 들어 특정 스키마를 가진 record_summary 도구를 사용할 수 있습니다. 완전한 작동 예시는 Claude를 사용한 도구 사용을 참조하세요.

도구를 사용한 모델 응답

도구를 사용할 때 Claude는 종종 수행 중인 작업에 대해 설명하거나 도구를 호출하기 전에 사용자에게 자연스럽게 응답합니다. 예를 들어 “지금 샌프란시스코의 날씨는 어떻고 거기 시간은 몇 시인가요?”라는 프롬프트가 주어지면 Claude는 다음과 같이 응답할 수 있습니다:
JSON
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll help you check the current weather and time in San Francisco."
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA"}
    }
  ]
}
이 자연스러운 응답 스타일은 사용자가 Claude가 수행하는 작업을 이해하는 데 도움이 되고 더 대화식 상호 작용을 만듭니다. 시스템 프롬프트를 통해 이러한 응답의 스타일과 콘텐츠를 안내하고 프롬프트에 <examples>를 제공하여 안내할 수 있습니다. Claude가 자신의 행동을 설명할 때 다양한 표현과 접근 방식을 사용할 수 있다는 점에 유의하는 것이 중요합니다. 코드는 이러한 응답을 다른 어시스턴트 생성 텍스트처럼 처리해야 하며 특정 형식 규칙에 의존하지 않아야 합니다.

병렬 도구 사용

기본적으로 Claude는 사용자 쿼리에 답하기 위해 여러 도구를 사용할 수 있습니다. 다음을 수행하여 이 동작을 비활성화할 수 있습니다:
  • tool_choice 타입이 auto일 때 disable_parallel_tool_use=true를 설정하면 Claude가 최대 하나의 도구를 사용하도록 보장합니다.
  • tool_choice 타입이 any 또는 tool일 때 disable_parallel_tool_use=true를 설정하면 Claude가 정확히 하나의 도구를 사용하도록 보장합니다.
도구 실행기를 사용하면 더 간단합니다: 아래 예시는 수동 병렬 도구 처리를 보여줍니다. 대부분의 사용 사례에서 도구 실행기는 훨씬 적은 코드로 병렬 도구 실행을 자동으로 처리합니다.
메시지 기록에서 병렬 도구 호출을 올바르게 형식화하는 방법을 보여주는 완전한 예시입니다:
import anthropic

client = anthropic.Anthropic()

# Define tools
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                }
            },
            "required": ["location"]
        }
    },
    {
        "name": "get_time",
        "description": "Get the current time in a given timezone",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "The timezone, e.g. America/New_York"
                }
            },
            "required": ["timezone"]
        }
    }
]

# Initial request
response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=tools,
    messages=[
        {
            "role": "user",
            "content": "What's the weather in SF and NYC, and what time is it there?"
        }
    ]
)

# Claude's response with parallel tool calls
print("Claude wants to use tools:", response.stop_reason == "tool_use")
print("Number of tool calls:", len([c for c in response.content if c.type == "tool_use"]))

# Build the conversation with tool results
messages = [
    {
        "role": "user",
        "content": "What's the weather in SF and NYC, and what time is it there?"
    },
    {
        "role": "assistant",
        "content": response.content  # Contains multiple tool_use blocks
    },
    {
        "role": "user",
        "content": [
            {
                "type": "tool_result",
                "tool_use_id": "toolu_01",  # Must match the ID from tool_use
                "content": "San Francisco: 68°F, partly cloudy"
            },
            {
                "type": "tool_result",
                "tool_use_id": "toolu_02",
                "content": "New York: 45°F, clear skies"
            },
            {
                "type": "tool_result",
                "tool_use_id": "toolu_03",
                "content": "San Francisco time: 2:30 PM PST"
            },
            {
                "type": "tool_result",
                "tool_use_id": "toolu_04",
                "content": "New York time: 5:30 PM EST"
            }
        ]
    }
]

# Get final response
final_response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=tools,
    messages=messages
)

print(final_response.content[0].text)
병렬 도구 호출이 있는 어시스턴트 메시지는 다음과 같습니다:
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll check the weather and time for both San Francisco and New York City."
    },
    {
      "type": "tool_use",
      "id": "toolu_01",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA"}
    },
    {
      "type": "tool_use",
      "id": "toolu_02",
      "name": "get_weather",
      "input": {"location": "New York, NY"}
    },
    {
      "type": "tool_use",
      "id": "toolu_03",
      "name": "get_time",
      "input": {"timezone": "America/Los_Angeles"}
    },
    {
      "type": "tool_use",
      "id": "toolu_04",
      "name": "get_time",
      "input": {"timezone": "America/New_York"}
    }
  ]
}
병렬 도구 호출이 올바르게 작동하는지 테스트하고 확인하기 위한 완전하고 실행 가능한 스크립트입니다:
#!/usr/bin/env python3
"""Test script to verify parallel tool calls with the Claude API"""

import os
from anthropic import Anthropic

# Initialize client
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))

# Define tools
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                }
            },
            "required": ["location"]
        }
    },
    {
        "name": "get_time",
        "description": "Get the current time in a given timezone",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "The timezone, e.g. America/New_York"
                }
            },
            "required": ["timezone"]
        }
    }
]

# Test conversation with parallel tool calls
messages = [
    {
        "role": "user",
        "content": "What's the weather in SF and NYC, and what time is it there?"
    }
]

# Make initial request
print("Requesting parallel tool calls...")
response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=messages,
    tools=tools
)

# Check for parallel tool calls
tool_uses = [block for block in response.content if block.type == "tool_use"]
print(f"\n✓ Claude made {len(tool_uses)} tool calls")

if len(tool_uses) > 1:
    print("✓ Parallel tool calls detected!")
    for tool in tool_uses:
        print(f"  - {tool.name}: {tool.input}")
else:
    print("✗ No parallel tool calls detected")

# Simulate tool execution and format results correctly
tool_results = []
for tool_use in tool_uses:
    if tool_use.name == "get_weather":
        if "San Francisco" in str(tool_use.input):
            result = "San Francisco: 68°F, partly cloudy"
        else:
            result = "New York: 45°F, clear skies"
    else:  # get_time
        if "Los_Angeles" in str(tool_use.input):
            result = "2:30 PM PST"
        else:
            result = "5:30 PM EST"

    tool_results.append({
        "type": "tool_result",
        "tool_use_id": tool_use.id,
        "content": result
    })

# Continue conversation with tool results
messages.extend([
    {"role": "assistant", "content": response.content},
    {"role": "user", "content": tool_results}  # All results in one message!
])

# Get final response
print("\nGetting final response...")
final_response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=messages,
    tools=tools
)

print(f"\nClaude's response:\n{final_response.content[0].text}")

# Verify formatting
print("\n--- Verification ---")
print(f"✓ Tool results sent in single user message: {len(tool_results)} results")
print("✓ No text before tool results in content array")
print("✓ Conversation formatted correctly for future parallel tool use")
이 스크립트는 다음을 보여줍니다:
  • 병렬 도구 호출 및 결과를 올바르게 형식화하는 방법
  • 병렬 호출이 이루어지고 있는지 확인하는 방법
  • 향후 병렬 도구 사용을 장려하는 올바른 메시지 구조
  • 피해야 할 일반적인 실수(도구 결과 전의 텍스트 등)
이 스크립트를 실행하여 구현을 테스트하고 Claude가 병렬 도구 호출을 효과적으로 수행하고 있는지 확인하세요.

병렬 도구 사용 최대화

Claude 4 모델은 기본적으로 우수한 병렬 도구 사용 기능을 가지고 있지만, 대상 프롬프팅을 통해 모든 모델에서 병렬 도구 실행의 가능성을 높일 수 있습니다:
Claude 4 모델(Opus 4.1, Opus 4 및 Sonnet 4)의 경우 시스템 프롬프트에 다음을 추가하세요:
For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.
더 강력한 병렬 도구 사용을 위해(기본값이 충분하지 않은 경우 권장), 다음을 사용하세요:
<use_parallel_tool_calls>
For maximum efficiency, whenever you perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially. Prioritize calling tools in parallel whenever possible. For example, when reading 3 files, run 3 tool calls in parallel to read all 3 files into context at the same time. When running multiple read-only commands like `ls` or `list_dir`, always run all of the commands in parallel. Err on the side of maximizing parallel tool calls rather than running too many tools sequentially.
</use_parallel_tool_calls>
특정 사용자 메시지 내에서 병렬 도구 사용을 장려할 수도 있습니다:
# Instead of:
"What's the weather in Paris? Also check London."

# Use:
"Check the weather in Paris and London simultaneously."

# Or be explicit:
"Please use parallel tool calls to get the weather for Paris, London, and Tokyo at the same time."
Claude Sonnet 3.7을 사용한 병렬 도구 사용Claude Sonnet 3.7은 disable_parallel_tool_use를 설정하지 않았더라도 응답에서 병렬 도구 호출을 할 가능성이 낮을 수 있습니다. 이를 해결하기 위해 토큰 효율적인 도구 사용을 활성화하는 것을 권장합니다. 이는 Claude가 병렬 도구를 사용하도록 장려하는 데 도움이 됩니다. 이 베타 기능은 또한 지연 시간을 줄이고 평균 14%의 출력 토큰을 절약합니다.토큰 효율적인 도구 사용 베타에 옵트인하지 않으려면 다른 도구에 대한 호출을 동시에 래핑할 수 있는 메타 도구로 작동할 수 있는 “배치 도구”를 도입할 수도 있습니다. 이 도구가 있으면 모델이 이를 사용하여 여러 도구를 동시에 병렬로 호출합니다.이를 사용하는 방법은 우리 쿠크북의 이 예시를 참조하세요.

도구 사용 및 도구 결과 콘텐츠 블록 처리

도구 실행기를 사용하면 더 간단합니다: 이 섹션에서 설명하는 수동 도구 처리는 도구 실행기에서 자동으로 관리됩니다. 도구 실행에 대한 사용자 정의 제어가 필요할 때 이 섹션을 사용하세요.
Claude의 응답은 클라이언트 도구 또는 서버 도구를 사용하는지 여부에 따라 다릅니다.

클라이언트 도구의 결과 처리

응답은 tool_usestop_reason과 다음을 포함하는 하나 이상의 tool_use 콘텐츠 블록을 가집니다:
  • id: 이 특정 도구 사용 블록에 대한 고유 식별자입니다. 나중에 도구 결과와 일치시키는 데 사용됩니다.
  • name: 사용 중인 도구의 이름입니다.
  • input: 도구의 input_schema를 준수하는 도구에 전달되는 입력을 포함하는 객체입니다.
JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-sonnet-4-5",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "I'll check the current weather in San Francisco for you."
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": {"location": "San Francisco, CA", "unit": "celsius"}
    }
  ]
}
클라이언트 도구에 대한 도구 사용 응답을 받으면 다음을 수행해야 합니다:
  1. tool_use 블록에서 name, idinput을 추출합니다.
  2. 해당 도구 이름에 해당하는 코드베이스에서 실제 도구를 실행하고 도구 input을 전달합니다.
  3. roleuser이고 다음 정보를 포함하는 tool_result 타입의 content 블록을 포함하는 새 메시지를 보내 대화를 계속합니다:
    • tool_use_id: 이것이 결과인 도구 사용 요청의 id입니다.
    • content: 도구의 결과로, 문자열(예: "content": "15 degrees"), 중첩된 콘텐츠 블록의 목록(예: "content": [{"type": "text", "text": "15 degrees"}]) 또는 문서 블록의 목록(예: "content": ["type": "document", "source": {"type": "text", "media_type": "text/plain", "data": "15 degrees"}])입니다. 이러한 콘텐츠 블록은 text, image 또는 document 타입을 사용할 수 있습니다.
    • is_error (선택 사항): 도구 실행으로 인해 오류가 발생한 경우 true로 설정합니다.
중요한 형식 요구 사항:
  • 도구 결과 블록은 메시지 기록에서 해당 도구 사용 블록 바로 뒤에 와야 합니다. 어시스턴트의 도구 사용 메시지와 사용자의 도구 결과 메시지 사이에 메시지를 포함할 수 없습니다.
  • 도구 결과를 포함하는 사용자 메시지에서 tool_result 블록은 콘텐츠 배열의 첫 번째에 와야 합니다. 모든 텍스트는 모든 도구 결과 이후에 와야 합니다.
예를 들어, 이는 400 오류를 발생시킵니다:
{"role": "user", "content": [
  {"type": "text", "text": "Here are the results:"},  // ❌ Text before tool_result
  {"type": "tool_result", "tool_use_id": "toolu_01", ...}
]}
이것이 올바릅니다:
{"role": "user", "content": [
  {"type": "tool_result", "tool_use_id": "toolu_01", ...},
  {"type": "text", "text": "What should I do next?"}  // ✅ Text after tool_result
]}
“tool_use ids were found without tool_result blocks immediately after”와 같은 오류가 발생하면 도구 결과가 올바르게 형식화되었는지 확인하세요.
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "15 degrees"
    }
  ]
}
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": [
        {"type": "text", "text": "15 degrees"},
        {
          "type": "image",
          "source": {
            "type": "base64",
            "media_type": "image/jpeg",
            "data": "/9j/4AAQSkZJRg...",
          }
        }
      ]
    }
  ]
}
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
    }
  ]
}
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": [
        {"type": "text", "text": "The weather is"},
        {
          "type": "document",
          "source": {
            "type": "text",
            "media_type": "text/plain",
            "data": "15 degrees"
          }
        }
      ]
    }
  ]
}
도구 결과를 받은 후 Claude는 해당 정보를 사용하여 원래 사용자 프롬프트에 대한 응답을 계속 생성합니다.

서버 도구의 결과 처리

Claude는 도구를 내부적으로 실행하고 추가 사용자 상호 작용 없이 결과를 응답에 직접 통합합니다.
다른 API와의 차이점도구 사용을 분리하거나 tool 또는 function과 같은 특수 역할을 사용하는 API와 달리 Claude API는 도구를 userassistant 메시지 구조에 직접 통합합니다.메시지에는 text, image, tool_usetool_result 블록의 배열이 포함됩니다. user 메시지에는 클라이언트 콘텐츠와 tool_result가 포함되고, assistant 메시지에는 AI 생성 콘텐츠와 tool_use가 포함됩니다.

max_tokens 중지 이유 처리

Claude의 응답이 max_tokens 제한으로 인해 잘린 경우 잘린 응답에 불완전한 도구 사용 블록이 포함되어 있으면 더 높은 max_tokens 값으로 요청을 다시 시도하여 전체 도구 사용을 얻어야 합니다.
# Check if response was truncated during tool use
if response.stop_reason == "max_tokens":
    # Check if the last content block is an incomplete tool_use
    last_block = response.content[-1]
    if last_block.type == "tool_use":
        # Send the request with higher max_tokens
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,  # Increased limit
            messages=messages,
            tools=tools
        )

pause_turn 중지 이유 처리

웹 검색과 같은 서버 도구를 사용할 때 API는 pause_turn 중지 이유를 반환할 수 있으며, 이는 API가 장시간 실행되는 턴을 일시 중지했음을 나타냅니다. pause_turn 중지 이유를 처리하는 방법은 다음과 같습니다:
import anthropic

client = anthropic.Anthropic()

# Initial request with web search
response = client.messages.create(
    model="claude-3-7-sonnet-latest",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Search for comprehensive information about quantum computing breakthroughs in 2025"
        }
    ],
    tools=[{
        "type": "web_search_20250305",
        "name": "web_search",
        "max_uses": 10
    }]
)

# Check if the response has pause_turn stop reason
if response.stop_reason == "pause_turn":
    # Continue the conversation with the paused content
    messages = [
        {"role": "user", "content": "Search for comprehensive information about quantum computing breakthroughs in 2025"},
        {"role": "assistant", "content": response.content}
    ]

    # Send the continuation request
    continuation = client.messages.create(
        model="claude-3-7-sonnet-latest",
        max_tokens=1024,
        messages=messages,
        tools=[{
            "type": "web_search_20250305",
            "name": "web_search",
            "max_uses": 10
        }]
    )

    print(continuation)
else:
    print(response)
pause_turn을 처리할 때:
  • 대화 계속: 일시 중지된 응답을 후속 요청에서 그대로 전달하여 Claude가 턴을 계속하도록 합니다.
  • 필요한 경우 수정: 대화를 중단하거나 리디렉션하려면 계속하기 전에 콘텐츠를 선택적으로 수정할 수 있습니다.
  • 도구 상태 유지: 기능을 유지하기 위해 계속 요청에 동일한 도구를 포함합니다.

오류 문제 해결

내장 오류 처리: 도구 실행기는 대부분의 일반적인 시나리오에 대한 자동 오류 처리를 제공합니다. 이 섹션에서는 고급 사용 사례에 대한 수동 오류 처리를 다룹니다.
Claude와 함께 도구를 사용할 때 발생할 수 있는 몇 가지 다른 유형의 오류가 있습니다:
도구 자체가 실행 중에 오류를 발생시키는 경우(예: 날씨 데이터를 가져올 때 네트워크 오류), content에 오류 메시지를 "is_error": true와 함께 반환할 수 있습니다:
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "ConnectionError: the weather service API is not available (HTTP 500)",
      "is_error": true
    }
  ]
}
Claude는 이 오류를 응답에 통합하여 사용자에게 “죄송하지만 날씨 서비스 API를 사용할 수 없어 현재 날씨를 검색할 수 없습니다. 나중에 다시 시도해주세요.”와 같이 응답합니다.
Claude의 도구 사용 시도가 잘못된 경우(예: 필수 매개변수 누락), 이는 Claude가 도구를 올바르게 사용할 수 있는 충분한 정보가 없었음을 의미합니다. 개발 중에 가장 좋은 방법은 도구 정의에서 더 자세한 description 값으로 요청을 다시 시도하는 것입니다.그러나 오류를 나타내는 tool_result로 대화를 계속 진행할 수도 있으며, Claude는 누락된 정보를 채워 도구를 다시 사용하려고 시도합니다:
JSON
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "Error: Missing required 'location' parameter",
      "is_error": true
    }
  ]
}
도구 요청이 잘못되었거나 매개변수가 누락된 경우 Claude는 2-3번 수정을 시도한 후 사용자에게 사과합니다.
Claude가 <search_quality_reflection> 태그로 검색 품질을 반영하지 않도록 하려면 프롬프트에 “Do not reflect on the quality of the returned search results in your response”를 추가하세요.
서버 도구에서 오류가 발생하면(예: 웹 검색의 네트워크 문제) Claude는 이러한 오류를 투명하게 처리하고 사용자에게 대체 응답이나 설명을 제공하려고 시도합니다. 클라이언트 도구와 달리 서버 도구에 대해 is_error 결과를 처리할 필요가 없습니다.웹 검색의 경우 가능한 오류 코드는 다음과 같습니다:
  • too_many_requests: 속도 제한 초과
  • invalid_input: 잘못된 검색 쿼리 매개변수
  • max_uses_exceeded: 최대 웹 검색 도구 사용 횟수 초과
  • query_too_long: 쿼리가 최대 길이를 초과합니다
  • unavailable: 내부 오류 발생
Claude가 예상대로 병렬 도구 호출을 하지 않는 경우 다음 일반적인 문제를 확인하세요:1. 잘못된 도구 결과 형식가장 일반적인 문제는 대화 기록에서 도구 결과를 잘못 형식화하는 것입니다. 이는 Claude에게 병렬 호출을 피하도록 “가르칩니다”.특히 병렬 도구 사용의 경우:
  • 잘못됨: 각 도구 결과에 대해 별도의 사용자 메시지 전송
  • 올바름: 모든 도구 결과는 단일 사용자 메시지에 있어야 합니다
// ❌ This reduces parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1]},
  {"role": "user", "content": [tool_result_2]}  // Separate message
]

// ✅ This maintains parallel tool use
[
  {"role": "assistant", "content": [tool_use_1, tool_use_2]},
  {"role": "user", "content": [tool_result_1, tool_result_2]}  // Single message
]
다른 형식 규칙은 위의 일반 형식 요구 사항을 참조하세요.2. 약한 프롬프팅기본 프롬프팅은 충분하지 않을 수 있습니다. 더 강한 언어를 사용하세요:
<use_parallel_tool_calls>
For maximum efficiency, whenever you perform multiple independent operations,
invoke all relevant tools simultaneously rather than sequentially.
Prioritize calling tools in parallel whenever possible.
</use_parallel_tool_calls>
3. 병렬 도구 사용 측정병렬 도구 호출이 작동하는지 확인하려면:
# Calculate average tools per tool-calling message
tool_call_messages = [msg for msg in messages if any(
    block.type == "tool_use" for block in msg.content
)]
total_tool_calls = sum(
    len([b for b in msg.content if b.type == "tool_use"])
    for msg in tool_call_messages
)
avg_tools_per_message = total_tool_calls / len(tool_call_messages)
print(f"Average tools per message: {avg_tools_per_message}")
# Should be > 1.0 if parallel calls are working
4. 모델별 동작
  • Claude Opus 4.1, Opus 4 및 Sonnet 4: 최소한의 프롬프팅으로 병렬 도구 사용에 탁월합니다
  • Claude Sonnet 3.7: 더 강한 프롬프팅이나 토큰 효율적인 도구 사용이 필요할 수 있습니다
  • Claude Haiku: 명시적 프롬프팅 없이는 병렬 도구를 사용할 가능성이 낮습니다