병렬 도구 사용
병렬 도구 호출을 활성화, 포맷, 비활성화하는 방법과 메시지 기록 지침 및 문제 해결을 다룹니다.
기본적으로 Claude는 단일 응답에서 여러 도구를 호출할 수 있습니다. 이 페이지에서는 이러한 호출을 실행하는 방법, 병렬 처리가 계속 작동하도록 메시지 기록을 포맷하는 방법, 그리고 필요할 때 "parallel tool use"(병렬 도구 사용)를 비활성화하는 방법을 다룹니다. 단일 호출 흐름에 대해서는 도구 호출 처리를 참조하세요.
실행 의미론
Claude가 도구를 호출하면 응답의 stop_reason은 tool_use가 되며, 단일 어시스턴트 턴에 여러 개의 tool_use 블록이 포함될 수 있습니다. 이러한 호출을 어떻게 실행할지는 여러분의 결정입니다. API는 실행 순서를 규정하지 않습니다. 호출을 동시에 실행하거나(Promise.all, asyncio.gather), 나타나는 순서대로 순차적으로 실행하거나, 도구에 적합한 어떤 조합으로든 실행할 수 있습니다.
도구가 수행하는 작업에 따라 전략을 선택하세요. 독립적인 읽기 전용 작업은 일반적으로 더 낮은 latency(지연 시간)를 위해 병렬로 실행해도 안전합니다. 부작용, 공유 상태 또는 순서 요구 사항이 있는 도구는 순차적으로 실행하는 것이 더 나을 수 있습니다.
어떤 전략을 사용하든, 각 tool_use 블록마다 하나의 tool_result를 반환하고, 이를 모두 다음 사용자 메시지에 함께 담으세요. tool_use_id로 각 결과를 해당 호출과 매칭하고, 해당 메시지에서 모든 tool_result 블록을 텍스트 콘텐츠보다 앞에 배치하세요. 전체 포맷 규칙은 도구 호출 처리를 참조하세요. 특정 호출을 실행하지 않기로 선택한 경우(예: 배치를 순차적으로 실행했는데 이전 호출이 실패한 경우)에도 is_error: true와 간단한 설명을 포함한 tool_result를 반환하세요.
{
"type": "tool_result",
"tool_use_id": "toolu_02",
"is_error": true,
"content": "Not executed: the preceding write_file call failed."
}컴퓨터 사용 도구와 브라우저 사용 도구는 더 엄격합니다. Claude가 한 턴에 이들의 멤버 도구 호출을 여러 개 반환하는 경우(배치 액션), 나타나는 순서대로 순차적으로 실행하고 첫 번째 실패에서 중단하세요. 각 도구는 건너뛴 호출에 대해 반환해야 할 정확한 텍스트를 정의합니다.
병렬 도구 호출 테스트
다음 스크립트는 병렬 도구 호출을 트리거해야 하는 요청을 보내고, 응답에 병렬 호출이 포함되어 있는지 확인하며, 병렬 처리가 계속 작동하도록 도구 결과를 포맷합니다. 환경에 ANTHROPIC_API_KEY를 설정한 상태로 실행하세요:
client = Anthropic()
# 도구 정의
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"],
},
},
]
# 병렬 도구 호출로 대화 테스트
messages = [
{
"role": "user",
"content": "What's the weather in SF and NYC, and what time is it there?",
}
]
# 초기 요청 보내기
print("Requesting parallel tool calls...")
response = client.messages.create(
model="claude-opus-5-5", max_tokens=1024, messages=messages, tools=tools
)
# 병렬 도구 호출 확인
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")
# 도구 실행을 시뮬레이션하고 결과를 올바르게 포맷
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}
)
# 도구 결과로 대화 계속하기
messages.extend(
[
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}, # All results in one message!
]
)
# 최종 응답 가져오기
print("\nGetting final response...")
final_response = client.messages.create(
model="claude-opus-5-5", max_tokens=1024, messages=messages, tools=tools
)
final_text = next(
block.text for block in final_response.content if block.type == "text"
)
print(f"\nClaude's response:\n{final_text}")
# 포맷 검증
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 4 및 이후 모델은 요청이 여러 도구의 이점을 얻을 수 있을 때 기본적으로 병렬 도구 호출을 수행합니다. 모든 모델에서 타겟 프롬프팅을 통해 병렬 도구 호출 가능성을 높일 수 있습니다:
Claude 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."병렬 도구 사용 비활성화
병렬 도구 사용은 기본적으로 켜져 있습니다. 이를 끄려면 tool_choice 객체 내부에 disable_parallel_tool_use: true를 설정하세요. 이는 최상위 요청 매개변수가 아닙니다. 효과는 tool_choice 유형에 따라 달라집니다.
최대 하나의 도구 호출
tool_choice 유형이 auto(기본값)인 경우, disable_parallel_tool_use: true를 설정하면 Claude는 응답당 최대 하나의 도구를 호출합니다. Claude는 여전히 도구를 호출하지 않고 일반 텍스트로 답변할 수 있습니다. 강조 표시된 줄이 표준 도구 사용 요청과의 유일한 차이점입니다:
client = Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
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"],
},
}
],
tool_choice={"type": "auto", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)정확히 하나의 도구 호출
tool_choice 유형이 any 또는 tool인 경우, disable_parallel_tool_use: true를 설정하면 Claude는 정확히 하나의 도구를 호출합니다. Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1 및 Claude Mythos 5.1은 이러한 tool_choice 유형을 지원하지 않습니다(도구 사용 강제하기 참조). 다음 예제는 any를 사용합니다. 동일한 필드가 tool에서도 작동합니다:
client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
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"],
},
}
],
tool_choice={"type": "any", "disable_parallel_tool_use": True},
messages=[
{
"role": "user",
"content": "What is the weather in San Francisco and New York?",
}
],
)
print(response.content)문제 해결
Claude가 예상대로 병렬 도구 호출을 수행하지 않는 경우 다음과 같은 일반적인 문제를 확인하세요:
1. 잘못된 도구 결과 포맷
가장 흔한 문제는 대화 기록에서 도구 결과를 잘못 포맷하는 것입니다. 이는 Claude에게 병렬 호출을 피하도록 "가르칩니다".
특히 병렬 도구 사용의 경우:
- 잘못된 예: 각 도구 결과마다 별도의 사용자 메시지
- 올바른 예: 모든 도구 결과를 단일 사용자 메시지에 함께 포함
// Wrong: separate user messages reduce 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
]
// Correct: one user message with all results 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. 약한 프롬프팅
기본 프롬프팅이 충분하지 않을 수 있습니다. 병렬 도구 사용 극대화의 더 강력한 시스템 프롬프트를 사용하세요.
3. 병렬 도구 사용량 측정
병렬 도구 호출이 작동하는지 확인하려면:
messages = [] # Message objects returned by client.messages.create across your run
tool_call_messages = [
msg for msg in messages if any(block.type == "tool_use" for block in msg.content)
]
total_tool_calls = sum(
len([block for block in msg.content if block.type == "tool_use"])
for msg in tool_call_messages
)
avg_tools_per_message = (
total_tool_calls / len(tool_call_messages) if tool_call_messages else 0.0
)
print(f"Average tools per message: {avg_tools_per_message}")
# 병렬 호출이 작동 중이면 1.0보다 커야 합니다4. 배치 내 호출이 서로 의존하는 것처럼 보이는 경우
실행 순서는 여러분의 선택입니다. 도구에 순서 의존성이 있는 경우, 배치를 순차적으로 실행하고 첫 번째 실패에서 중단하는 것은 유효한 전략입니다(컴퓨터 사용 및 브라우저 사용 도구에서는 필수 전략입니다). 실행하지 않은 호출에 대해서는 is_error: true를 반환하세요. 병렬로 실행했는데 선행 조건이 완료되지 않아 호출이 실패한 경우, 자연스러운 오류 메시지와 함께 is_error: true를 반환하세요. Claude는 다음 턴에 해당 호출을 다시 발행합니다. 의존적인 호출이 함께 나타나는 것을 줄이려면 시스템 프롬프트에 다음을 추가하세요: "Only batch tool calls that are independent of each other."
다음 단계
SDK의 Tool Runner 추상화를 사용하여 에이전트 루프, 오류 래핑 및 타입 안전성을 자동으로 처리하세요.
tool_use 블록을 파싱하고, tool_result 응답을 포맷하며, is_error로 오류를 처리하세요.
도구 스키마를 지정하고, 효과적인 설명을 작성하며, Claude가 도구를 호출하는 시점을 제어하세요.
Was this page helpful?