---
title: Claude와 함께하는 도구 사용
url: https://platform.claude.com/docs/ko/agents-and-tools/tool-use/overview
description: Claude를 외부 도구 및 API에 연결하세요. 도구가 어디에서 실행되는지, Claude가 언제 도구를 호출하는지, 어떤 도구가 작업에 적합한지 알아보세요.
---

"Tool use"(도구 사용, function calling이라고도 함)를 통해 Claude는 사용자가 정의하거나 Anthropic이 제공하는 함수를 호출할 수 있습니다. Claude는 사용자의 요청과 도구의 설명을 바탕으로 언제 도구를 호출할지 결정합니다. 그런 다음 애플리케이션이 실행하는(클라이언트 도구) 또는 Anthropic이 실행하는(서버 도구) 구조화된 호출을 반환합니다.

다음은 Anthropic이 대신 실행해 주는 서버 도구인 [웹 검색 도구](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/web-search-tool)를 사용하는 최소한의 예시입니다:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "tools": [{"type": "web_search_20260209", "name": "web_search"}],
      "messages": [{"role": "user", "content": "What'\''s the latest on the Mars rover?"}]
    }'
  ```

  ```bash CLI
  ant messages create --transform content --format yaml \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --tool '{type: web_search_20260209, name: web_search}' \
    --message '{role: user, content: "What is the latest on the Mars rover?"}'
  ```

  ```python Python
  client = anthropic.Anthropic()
  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=[{"type": "web_search_20260209", "name": "web_search"}],
      messages=[{"role": "user", "content": "What's the latest on the Mars rover?"}],
  )
  print(response.content)
  ```

  ```typescript TypeScript
  const client = new Anthropic();
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [{ type: "web_search_20260209", name: "web_search" }],
    messages: [{ role: "user", content: "What's the latest on the Mars rover?" }]
  });
  console.log(response.content);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = [new ToolUnion(new WebSearchTool20260209())],
      Messages = [new() { Role = Role.User, Content = "What's the latest on the Mars rover?" }]
  };

  var message = await client.Messages.Create(parameters);
  Console.WriteLine(message.Content);
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 1024,
  	Tools: []anthropic.ToolUnionParam{
  		{OfWebSearchTool20260209: &anthropic.WebSearchTool20260209Param{}},
  	},
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("What's the latest on the Mars rover?")),
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(response.Content)
  ```

  ```java Java
  import com.anthropic.models.messages.WebSearchTool20260209;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(WebSearchTool20260209.builder().build())
          .addUserMessage("What's the latest on the Mars rover?")
          .build();

      Message response = client.messages().create(params);
      IO.println(response.content());
  }
  ```

  ```php PHP
  $client = new Client();

  $message = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: [
          ['type' => 'web_search_20260209', 'name' => 'web_search'],
      ],
      messages: [
          ['role' => 'user', 'content' => "What's the latest on the Mars rover?"],
      ],
  );

  echo $message;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: [{ type: "web_search_20260209", name: "web_search" }],
    messages: [{ role: "user", content: "What's the latest on the Mars rover?" }]
  )
  puts message.content
  ```
</CodeGroup>

Claude는 Anthropic의 인프라에서 검색을 실행하고 동일한 응답에서 인용된 결과를 반환합니다. Claude가 사용자가 정의한 함수를 호출하도록 하려면 `input_schema`가 포함된 도구를 전달한 다음, Claude가 `tool_use` 블록을 반환할 때 해당 호출을 실행하세요. [도구 사용 작동 방식](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/overview#how-tool-use-works)에서 이 왕복 과정을 처음부터 끝까지 보여줍니다. [도구 정의](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/define-tools) 및 [도구 호출 처리](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/handle-tool-calls)에 대해 자세히 알아보세요.

## 도구 사용 작동 방식

도구는 주로 코드가 실행되는 위치에 따라 구분됩니다. **클라이언트 도구**(사용자 정의 도구 및 `bash`, `text_editor`와 같이 Anthropic이 정의한 스키마를 가진 도구 포함)는 애플리케이션에서 실행됩니다. Claude는 `stop_reason: "tool_use"`와 하나 이상의 `tool_use` 블록으로 응답합니다. 코드가 작업을 실행하고 `tool_result`를 다시 보냅니다. **서버 도구**(`web_search`, `web_fetch`, `code_execution`, `tool_search` 등)는 Anthropic의 인프라에서 실행됩니다. Claude가 클라이언트 도구 중 하나와 동일한 병렬 도구 호출 그룹에서 해당 도구를 호출하지 않는 한, 실행을 처리하지 않고도 결과를 직접 확인할 수 있습니다([중지 이유 및 폴백](https://platform.claude.com/docs/ko/build-with-claude/handling-stop-reasons#tool-use) 참조).

다음은 클라이언트 도구에 대한 전체 왕복 과정입니다. 첫 번째 요청은 `get_weather` 도구를 정의하고, Claude는 이를 호출하여 질문에 답합니다. 응답에는 `tool_use` 블록이 포함되고, 코드가 조회를 실행하며, 두 번째 요청이 결과를 `tool_result` 블록에 담아 다시 보내면 Claude가 답변으로 응답할 수 있습니다.

<CodeGroup>
  ```bash cURL
  # Claude는 도구 이름과 인수를 담은 tool_use 블록으로 응답합니다.
  TOOLS='[
    {
      "name": "get_weather",
      "description": "Get the current weather for a given location.",
      "input_schema": {
        "type": "object",
        "properties": {
          "location": {"type": "string", "description": "City and state, e.g. San Francisco, CA"}
        },
        "required": ["location"]
      }
    }
  ]'
  USER_MSG="What's the weather in San Francisco?"
  RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "$(jq -n --argjson tools "$TOOLS" --arg msg "$USER_MSG" '{
      model: "claude-opus-5-5",
      max_tokens: 1024,
      tools: $tools,
      # 턴당 최대 한 번의 도구 호출만 요청합니다.
      tool_choice: {type: "auto", disable_parallel_tool_use: true},
      messages: [{role: "user", content: $msg}]
    }')")
  TOOL_USE=$(echo "$RESPONSE" | jq '.content[] | select(.type == "tool_use")')
  echo "Claude called $(echo "$TOOL_USE" | jq -r '.name') with $(echo "$TOOL_USE" | jq -c '.input')"

  # 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
  # Claude는 이 결과를 사용해 원래 질문에 답합니다.
  WEATHER="15 degrees Celsius, partly cloudy"
  curl -s https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "$(jq -n \
      --argjson tools "$TOOLS" \
      --arg msg "$USER_MSG" \
      --argjson assistant "$(echo "$RESPONSE" | jq '.content')" \
      --arg tool_use_id "$(echo "$TOOL_USE" | jq -r '.id')" \
      --arg weather "$WEATHER" \
      '{
        model: "claude-opus-5-5",
        max_tokens: 1024,
        tools: $tools,
        tool_choice: {type: "auto", disable_parallel_tool_use: true},
        messages: [
          {role: "user", content: $msg},
          {role: "assistant", content: $assistant},
          {role: "user", content: [
            {type: "tool_result", tool_use_id: $tool_use_id, content: $weather}
          ]}
        ]
      }')"
  ```

  ```bash CLI
  # ant는 stdin에서 요청 본문을 YAML로 읽고, jq는 대화
  # 상태를 두 번째 요청으로 전달합니다.
  USER_MSG="What's the weather in San Francisco?"
  MESSAGES=$(jq -n --arg msg "$USER_MSG" '[{role: "user", content: $msg}]')
  call_api() {
    {
      cat <<'YAML'
  model: claude-opus-5-5
  max_tokens: 1024
  # 턴당 최대 한 번의 도구 호출만 요청합니다.
  tool_choice: {type: auto, disable_parallel_tool_use: true}
  tools:
    - name: get_weather
      description: Get the current weather for a given location.
      input_schema:
        type: object
        properties:
          location: {type: string, description: "City and state, e.g. San Francisco, CA"}
        required: [location]
  YAML
      printf 'messages: %s\n' "$MESSAGES"
    } | ant messages create --format json
  }

  # Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  RESPONSE=$(call_api)
  TOOL_USE=$(jq '.content[] | select(.type == "tool_use")' <<<"$RESPONSE")
  echo "Claude called $(jq -r '.name' <<<"$TOOL_USE") with $(jq -c '.input' <<<"$TOOL_USE")"

  # 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
  WEATHER="15 degrees Celsius, partly cloudy"
  MESSAGES=$(jq \
    --argjson assistant "$(jq '.content' <<<"$RESPONSE")" \
    --arg tool_use_id "$(jq -r '.id' <<<"$TOOL_USE")" \
    --arg weather "$WEATHER" \
    '. + [
      {role: "assistant", content: $assistant},
      {role: "user", content: [
        {type: "tool_result", tool_use_id: $tool_use_id, content: $weather}
      ]}
    ]' <<<"$MESSAGES")

  # Claude는 그 결과를 사용해 원래 질문에 답합니다.
  call_api
  ```

  ```python Python
  client = anthropic.Anthropic()

  tools = [
      {
          "name": "get_weather",
          "description": "Get the current weather for a given location.",
          "input_schema": {
              "type": "object",
              "properties": {
                  "location": {
                      "type": "string",
                      "description": "City and state, e.g. San Francisco, CA",
                  }
              },
              "required": ["location"],
          },
      }
  ]
  messages = [{"role": "user", "content": "What's the weather in San Francisco?"}]

  # Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  response = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=tools,
      # 턴당 최대 한 번의 도구 호출만 요청하세요.
      tool_choice={"type": "auto", "disable_parallel_tool_use": True},
      messages=messages,
  )
  tool_use = next(block for block in response.content if block.type == "tool_use")
  print(f"Claude called {tool_use.name} with {json.dumps(tool_use.input)}")

  # 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보내세요.
  weather = "15 degrees Celsius, partly cloudy"  # your weather lookup goes here
  messages += [
      {"role": "assistant", "content": response.content},
      {
          "role": "user",
          "content": [
              {"type": "tool_result", "tool_use_id": tool_use.id, "content": weather}
          ],
      },
  ]
  followup = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      tools=tools,
      tool_choice={"type": "auto", "disable_parallel_tool_use": True},
      messages=messages,
  )

  # Claude는 이 결과를 사용해 원래 질문에 답합니다.
  final_text = next(block for block in followup.content if block.type == "text")
  print(final_text.text)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const tools: Anthropic.Tool[] = [
    {
      name: "get_weather",
      description: "Get the current weather for a given location.",
      input_schema: {
        type: "object",
        properties: {
          location: { type: "string", description: "City and state, e.g. San Francisco, CA" }
        },
        required: ["location"]
      }
    }
  ];
  const messages: Anthropic.MessageParam[] = [
    { role: "user", content: "What's the weather in San Francisco?" }
  ];

  // Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools,
    // 턴당 최대 한 번의 도구 호출만 요청하세요.
    tool_choice: { type: "auto", disable_parallel_tool_use: true },
    messages
  });
  const toolUse = response.content.find(
    (block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
  )!;
  console.log(`Claude called ${toolUse.name} with ${JSON.stringify(toolUse.input)}`);

  // 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보내세요.
  const weather = "15 degrees Celsius, partly cloudy"; // your weather lookup goes here
  messages.push(
    { role: "assistant", content: response.content },
    {
      role: "user",
      content: [{ type: "tool_result", tool_use_id: toolUse.id, content: weather }]
    }
  );
  const followup = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools,
    tool_choice: { type: "auto", disable_parallel_tool_use: true },
    messages
  });

  // Claude는 결과를 사용하여 원래 질문에 답합니다.
  const finalText = followup.content.find(
    (block): block is Anthropic.TextBlock => block.type === "text"
  )!;
  console.log(finalText.text);
  ```

  ```csharp C#
  AnthropicClient client = new();

  List<ToolUnion> tools =
  [
      new ToolUnion(new Tool()
      {
          Name = "get_weather",
          Description = "Get the current weather for a given location.",
          InputSchema = new InputSchema()
          {
              Properties = new Dictionary<string, JsonElement>
              {
                  ["location"] = JsonSerializer.SerializeToElement(new
                  {
                      type = "string",
                      description = "City and state, e.g. San Francisco, CA",
                  }),
              },
              Required = ["location"],
          },
      }),
  ];

  // 턴당 최대 한 번의 도구 호출만 요청합니다.
  var toolChoice = new ToolChoice(new ToolChoiceAuto { DisableParallelToolUse = true });

  const string userPrompt = "What's the weather in San Francisco?";

  // Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  var response = await client.Messages.Create(new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = tools,
      ToolChoice = toolChoice,
      Messages = [new() { Role = Role.User, Content = userPrompt }],
  });
  ToolUseBlock? toolUse = null;
  foreach (var block in response.Content)
  {
      if (block.TryPickToolUse(out var picked))
      {
          toolUse = picked;
          break;
      }
  }
  Console.WriteLine($"Claude called {toolUse!.Name} with {JsonSerializer.Serialize(toolUse.Input)}");

  // 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
  var weather = "15 degrees Celsius, partly cloudy";
  List<ContentBlockParam> toolResults =
  [
      new ContentBlockParam(new ToolResultBlockParam()
      {
          ToolUseID = toolUse.ID,
          Content = weather,
      }),
  ];
  var followup = await client.Messages.Create(new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Tools = tools,
      ToolChoice = toolChoice,
      Messages =
      [
          new() { Role = Role.User, Content = userPrompt },
          new() { Role = Role.Assistant, Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList() },
          new() { Role = Role.User, Content = new MessageParamContent(toolResults) },
      ],
  });

  // Claude는 그 결과를 사용해 원래 질문에 답합니다.
  foreach (var block in followup.Content)
  {
      if (block.TryPickText(out var text))
      {
          Console.WriteLine(text.Text);
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()
  ctx := context.Background()

  tools := []anthropic.ToolUnionParam{
  	{OfTool: &anthropic.ToolParam{
  		Name:        "get_weather",
  		Description: anthropic.String("Get the current weather for a given location."),
  		InputSchema: anthropic.ToolInputSchemaParam{
  			Properties: map[string]any{
  				"location": map[string]any{
  					"type":        "string",
  					"description": "City and state, e.g. San Francisco, CA",
  				},
  			},
  			Required: []string{"location"},
  		},
  	}},
  }
  // 턴당 최대 한 번의 도구 호출만 요청합니다.
  toolChoice := anthropic.ToolChoiceUnionParam{
  	OfAuto: &anthropic.ToolChoiceAutoParam{DisableParallelToolUse: anthropic.Bool(true)},
  }
  messages := []anthropic.MessageParam{
  	anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in San Francisco?")),
  }

  // Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  response, err := client.Messages.New(ctx, anthropic.MessageNewParams{
  	Model:      anthropic.ModelClaudeOpus5_5,
  	MaxTokens:  1024,
  	Tools:      tools,
  	ToolChoice: toolChoice,
  	Messages:   messages,
  })
  if err != nil {
  	log.Fatal(err)
  }
  var toolUse anthropic.ContentBlockUnion
  for _, block := range response.Content {
  	if block.Type == "tool_use" {
  		toolUse = block
  		break
  	}
  }
  fmt.Printf("Claude called %s with %s\n", toolUse.Name, string(toolUse.Input))

  // 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
  weather := "15 degrees Celsius, partly cloudy"
  var assistantContent []anthropic.ContentBlockParamUnion
  for _, block := range response.Content {
  	assistantContent = append(assistantContent, block.ToParam())
  }
  messages = append(messages,
  	anthropic.NewAssistantMessage(assistantContent...),
  	anthropic.NewUserMessage(anthropic.NewToolResultBlock(toolUse.ID, weather, false)),
  )
  followup, err := client.Messages.New(ctx, anthropic.MessageNewParams{
  	Model:      anthropic.ModelClaudeOpus5_5,
  	MaxTokens:  1024,
  	Tools:      tools,
  	ToolChoice: toolChoice,
  	Messages:   messages,
  })
  if err != nil {
  	log.Fatal(err)
  }

  // Claude는 이 결과를 사용해 원래 질문에 답합니다.
  for _, block := range followup.Content {
  	if block.Type == "text" {
  		fmt.Println(block.Text)
  	}
  }
  ```

  ```java Java
  import com.anthropic.core.JsonValue;
  import com.anthropic.models.messages.ContentBlockParam;
  // ...
  import com.anthropic.models.messages.Tool;
  import com.anthropic.models.messages.Tool.InputSchema;
  import com.anthropic.models.messages.ToolChoiceAuto;
  import com.anthropic.models.messages.ToolResultBlockParam;
  import com.anthropic.models.messages.ToolUseBlock;
  // ...

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      Tool weatherTool = Tool.builder()
          .name("get_weather")
          .description("Get the current weather for a given location.")
          .inputSchema(InputSchema.builder()
              .properties(JsonValue.from(Map.of(
                  "location", Map.of(
                      "type", "string",
                      "description", "City and state, e.g. San Francisco, CA"
                  )
              )))
              .required(List.of("location"))
              .build())
          .build();

      // 턴당 최대 한 번의 도구 호출만 요청합니다.
      ToolChoiceAuto toolChoice = ToolChoiceAuto.builder()
          .disableParallelToolUse(true)
          .build();

      String userPrompt = "What's the weather in San Francisco?";

      // Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
      Message response = client.messages().create(MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(weatherTool)
          .toolChoice(toolChoice)
          .addUserMessage(userPrompt)
          .build());
      ToolUseBlock toolUse = response.content().stream()
          .flatMap(block -> block.toolUse().stream())
          .findFirst()
          .orElseThrow();
      IO.println("Claude called " + toolUse.name() + " with " + toolUse._input());

      // 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
      String weather = "15 degrees Celsius, partly cloudy";
      Message followup = client.messages().create(MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addTool(weatherTool)
          .toolChoice(toolChoice)
          .addUserMessage(userPrompt)
          .addMessage(response)
          .addUserMessageOfBlockParams(List.of(ContentBlockParam.ofToolResult(
              ToolResultBlockParam.builder()
                  .toolUseId(toolUse.id())
                  .content(weather)
                  .build())))
          .build());

      // Claude는 이 결과를 사용해 원래 질문에 답합니다.
      followup.content().stream()
          .flatMap(block -> block.text().stream())
          .forEach(textBlock -> IO.println(textBlock.text()));
  }
  ```

  ```php PHP
  use Anthropic\Messages\ToolChoiceAuto;

  $client = new Client();

  $tools = [
      [
          'name' => 'get_weather',
          'description' => 'Get the current weather for a given location.',
          'input_schema' => [
              'type' => 'object',
              'properties' => [
                  'location' => [
                      'type' => 'string',
                      'description' => 'City and state, e.g. San Francisco, CA',
                  ],
              ],
              'required' => ['location'],
          ],
      ],
  ];
  $userMessage = ['role' => 'user', 'content' => "What's the weather in San Francisco?"];

  // 턴당 최대 한 번의 도구 호출만 요청합니다.
  $toolChoice = ToolChoiceAuto::with(disableParallelToolUse: true);

  // Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  $response = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: $tools,
      toolChoice: $toolChoice,
      messages: [$userMessage],
  );
  $toolUse = null;
  foreach ($response->content as $block) {
      if ($block->type === 'tool_use') {
          $toolUse = $block;
          break;
      }
  }
  printf("Claude called %s with %s\n", $toolUse->name, json_encode($toolUse->input));

  // 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보냅니다.
  $weather = '15 degrees Celsius, partly cloudy';
  $followup = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      tools: $tools,
      toolChoice: $toolChoice,
      messages: [
          $userMessage,
          ['role' => 'assistant', 'content' => $response->content],
          [
              'role' => 'user',
              'content' => [
                  [
                      'type' => 'tool_result',
                      'tool_use_id' => $toolUse->id,
                      'content' => $weather,
                  ],
              ],
          ],
      ],
  );

  // Claude는 이 결과를 사용해 원래 질문에 답합니다.
  foreach ($followup->content as $block) {
      if ($block->type === 'text') {
          echo $block->text, "\n";
      }
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  tools = [
    {
      name: "get_weather",
      description: "Get the current weather for a given location.",
      input_schema: {
        type: "object",
        properties: {
          location: {type: "string", description: "City and state, e.g. San Francisco, CA"}
        },
        required: ["location"]
      }
    }
  ]
  messages = [{role: "user", content: "What's the weather in San Francisco?"}]

  # Claude는 도구 이름과 인수를 지정한 tool_use 블록으로 응답합니다.
  response = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: tools,
    # 턴당 최대 한 번의 도구 호출만 요청하세요.
    tool_choice: {type: "auto", disable_parallel_tool_use: true},
    messages: messages
  )
  tool_use = response.content.find { |block| block.type == :tool_use }
  puts "Claude called #{tool_use.name} with #{JSON.generate(tool_use.input)}"

  # 도구를 실행한 다음 결과를 tool_result 블록에 담아 다시 보내세요.
  weather = "15 degrees Celsius, partly cloudy"
  messages += [
    {role: "assistant", content: response.content},
    {
      role: "user",
      content: [
        {type: "tool_result", tool_use_id: tool_use.id, content: weather}
      ]
    }
  ]
  followup = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    tools: tools,
    tool_choice: {type: "auto", disable_parallel_tool_use: true},
    messages: messages
  )

  # Claude는 이 결과를 사용해 원래 질문에 답합니다.
  final_text = followup.content.find { |block| block.type == :text }
  puts final_text.text
  ```
</CodeGroup>

```text Output wrap
Claude called get_weather with {"location": "San Francisco, CA"}
The current weather in San Francisco is 15 degrees Celsius with partly cloudy skies.
```

[도구 호출 처리](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/handle-tool-calls)에서는 결과 형식 지정 및 오류 신호 전달을 포함하여 각 단계를 자세히 다룹니다. [병렬 도구 사용](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/parallel-tool-use)에서는 여러 도구를 한 번에 호출하는 응답을 다룹니다. 이 왕복 과정을 직접 작성하지 않으려면 [Tool Runner](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/tool-runner)를 사용하세요. SDK가 도구를 실행하고 결과를 자동으로 다시 보냅니다.

에이전트 루프와 각 접근 방식을 선택해야 하는 경우를 포함한 전체 개념 모델은 [도구 사용 작동 방식](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/how-tool-use-works)을 참조하세요.

"Model Context Protocol", 즉 MCP 서버에 연결하려면 [MCP 커넥터](https://platform.claude.com/docs/ko/agents-and-tools/mcp-connector)를 참조하세요. 자체 MCP 클라이언트를 구축하려면 Model Context Protocol 가이드의 [MCP 클라이언트 구축](https://modelcontextprotocol.io/docs/develop/build-client)을 참조하세요.

## Claude가 도구를 사용하는 경우

기본 `tool_choice`인 `{"type": "auto"}`를 사용하면 Claude는 매 턴마다 도구를 호출할지 직접 응답할지 결정합니다. 요청이 해당 도구에 설명된 기능에 부합하고 답변이 아직 컨텍스트에 없는 경우 도구를 호출합니다. 안정적인 지식, 창의적인 작업, 대화형 턴에 대해서는 직접 응답합니다.

이 경계는 시스템 프롬프트를 통해 조정할 수 있습니다. 예상한 시점에 Claude가 도구를 호출하지 않는다면 `"Use the tools to investigate before responding."`과 같은 가벼운 지시로 도구 사용을 늘릴 수 있습니다. `"Always call a tool first before responding."`과 같은 더 강한 형태는 이를 더욱 밀어붙입니다. 반대로 `"Use your judgment about whether to call a tool or respond directly."`는 트리거 동작을 보수적으로 유지합니다.

프롬프트에 의존하지 않고 도구 호출을 필수로 하려면 [`tool_choice`](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/define-tools#forcing-tool-use)를 설정하세요.

<Tip>
  **엄격한 도구 사용으로 스키마 준수 보장**

  사용자 정의 도구 정의에 `strict: true`를 추가하면 Claude의 도구 호출이 항상 스키마와 정확히 일치하도록 보장할 수 있습니다. [엄격한 도구 사용](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/strict-tool-use)을 참조하세요.
</Tip>

각 서버 도구의 페이지에서는 해당 도구의 트리거 경계를 더 자세히 설명합니다.

<Accordion title="필수 매개변수가 누락된 경우">
  사용자의 프롬프트에 도구의 모든 필수 매개변수를 채우기에 충분한 정보가 포함되어 있지 않은 경우, Claude Opus는 매개변수가 누락되었음을 인식하고 이를 요청할 가능성이 훨씬 높습니다. Claude Sonnet은 특히 도구 요청을 출력하기 전에 생각하도록 프롬프트된 경우 요청할 수 있습니다. 하지만 합리적인 값을 추론할 수도 있습니다.

  예를 들어, `location` 매개변수가 필요한 `get_weather` 도구가 주어졌을 때 위치를 지정하지 않고 Claude에게 "What's the weather?"라고 물으면, Claude(특히 Claude Sonnet)는 사용자가 제공하지 않은 값을 추측할 수 있습니다:

  ```json JSON
  {
    "type": "tool_use",
    "id": "toolu_01A09q90qw90lq917835lq9",
    "name": "get_weather",
    "input": { "location": "New York, NY", "unit": "fahrenheit" }
  }
  ```

  이 동작은 보장되지 않으며, 특히 더 모호한 프롬프트와 성능이 낮은 모델의 경우 더욱 그렇습니다.
</Accordion>

## 도구 선택

`type` 문자열, 버전 및 베타 헤더는 [도구 레퍼런스](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/tool-reference)를 참조하세요.

### 자체 도구

사용자가 정의하는 도구의 경우, 사용자가 스키마를 작성하고 애플리케이션이 각 호출을 실행합니다.

<CardGroup cols={2}>
  <Card title="도구 정의" icon="hammer" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/define-tools">
    도구 스키마를 지정하고, 설명을 작성하고, Claude가 도구를 호출하는 시점을 제어하세요.
  </Card>

  <Card title="도구 호출 처리" icon="arrows-left-right" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/handle-tool-calls">
    `tool_use` 블록을 파싱하고, `tool_result` 응답 형식을 지정하고, 오류를 처리하세요.
  </Card>
</CardGroup>

### Anthropic 스키마 클라이언트 도구

Anthropic이 스키마를 게시하고 Claude를 해당 스키마로 학습시킵니다. 애플리케이션은 여전히 각 호출을 실행하고 `tool_result`를 반환합니다.

<CardGroup cols={2}>
  <Card title="메모리 도구" icon="brain" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/memory-tool">
    사용자가 제어하는 파일에 대화 전반에 걸쳐 정보를 저장하고 검색하세요.
  </Card>

  <Card title="Bash 도구" icon="terminal" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/bash-tool">
    상태를 유지하는 지속적인 세션에서 셸 명령을 실행하세요.
  </Card>

  <Card title="텍스트 편집기 도구" icon="edit" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/text-editor-tool">
    텍스트 파일을 보고 수정하여 코드를 디버그하고, 수정하고, 개선하세요.
  </Card>

  <Card title="컴퓨터 사용 도구" icon="computer" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/computer-use-tool">
    데스크톱 환경에서 스크린샷을 찍고 마우스와 키보드를 제어하세요.
  </Card>

  <Card title="브라우저 사용 도구" icon="browser" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/browser-use-tool">
    자체 브라우저 환경에서 웹페이지를 탐색하고, 읽고, 상호작용하세요.
  </Card>
</CardGroup>

### 서버 도구

서버 도구는 애플리케이션에 핸들러 코드 없이 Anthropic의 인프라에서 실행됩니다. 이들이 공유하는 메커니즘은 [서버 도구](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/server-tools)를 참조하세요.

<CardGroup cols={2}>
  <Card title="웹 검색 도구" icon="magnifying-glass" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/web-search-tool">
    인용된 출처와 함께 지식 마감일 이후의 정보를 웹에서 검색하세요.
  </Card>

  <Card title="웹 가져오기 도구" icon="download" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/web-fetch-tool">
    지정된 웹 페이지 및 PDF 문서의 전체 콘텐츠를 가져오세요.
  </Card>

  <Card title="코드 실행 도구" icon="code" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/code-execution-tool">
    샌드박스 컨테이너에서 Python 및 bash 코드를 실행하여 데이터를 분석하고 파일을 생성하세요.
  </Card>

  <Card title="어드바이저 도구" icon="lightbulb" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/advisor-tool">
    더 빠른 실행자 모델이 생성 도중에 더 높은 지능의 어드바이저 모델에 자문을 구할 수 있게 하세요.
  </Card>

  <Card title="도구 검색 도구" icon="library" href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/tool-search-tool">
    필요에 따라 도구를 발견하고 로드하여 수천 개의 도구로 작업하세요.
  </Card>

  <Card title="MCP 커넥터" icon="link" href="https://platform.claude.com/docs/ko/agents-and-tools/mcp-connector">
    별도의 MCP 클라이언트 없이 Messages API에서 원격 MCP 서버에 연결하세요.
  </Card>
</CardGroup>

<Note>
  [Claude Managed Agents](https://platform.claude.com/docs/ko/managed-agents/overview)는 Claude가 세션 내에서 자율적으로 사용하는 내장 도구 세트를 제공합니다. 해당 도구 세트와 Managed Agents 방식으로 사용자 정의 도구를 추가하는 방법은 [도구](https://platform.claude.com/docs/ko/managed-agents/tools) 페이지를 참조하세요.
</Note>

## 가격

도구 사용 요청의 가격은 다음을 기준으로 책정됩니다:

1. 모델에 전송된 총 입력 토큰 수(`tools` 매개변수에 포함된 것 포함)
2. 생성된 출력 토큰 수
3. 서버 측 도구의 경우, 추가적인 사용량 기반 가격(예: 웹 검색은 수행된 검색당 요금 부과)

클라이언트 측 도구는 다른 모든 Claude API 요청과 동일하게 가격이 책정되지만, 서버 측 도구는 특정 사용량에 따라 추가 요금이 발생할 수 있습니다.

도구 사용으로 인한 추가 토큰은 다음에서 발생합니다:

* API 요청의 `tools` 매개변수(도구 이름, 설명 및 스키마)
* API 요청 및 응답의 `tool_use` 콘텐츠 블록
* API 요청의 `tool_result` 콘텐츠 블록

`tools`를 사용하면 API는 도구 사용을 가능하게 하는 특별한 "system prompt"(시스템 프롬프트)를 모델에 자동으로 포함합니다. 각 모델에 필요한 도구 사용 토큰 수는 다음 표에 나와 있습니다(앞서 나열한 추가 토큰 제외). 이 표는 최소 1개의 도구가 제공된다고 가정합니다. `tools`가 제공되지 않으면 `none` 도구 선택은 추가 시스템 프롬프트 토큰을 0개 사용합니다.

| Model                                                                                                                                | Tool use system prompt tokens: auto, none | Tool use system prompt tokens: any, tool |
| :----------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- | :--------------------------------------- |
| Claude Opus 5.5                                                                                                                      | 286 tokens                                |                                          |
| Claude Opus 5                                                                                                                        | 286 tokens                                | 406 tokens                               |
| Claude Opus 4.8                                                                                                                      | 290 tokens                                | 410 tokens                               |
| Claude Opus 4.7                                                                                                                      | 675 tokens                                | 804 tokens                               |
| Claude Opus 4.6                                                                                                                      | 497 tokens                                | 589 tokens                               |
| Claude Opus 4.5                                                                                                                      | 496 tokens                                | 588 tokens                               |
| Claude Opus 4.1 ([retired, except on Bedrock and Google Cloud](https://platform.claude.com/docs/ko/about-claude/model-deprecations)) | 313 tokens                                | 315 tokens                               |
| Claude Opus 4 ([retired, except on Google Cloud](https://platform.claude.com/docs/ko/about-claude/model-deprecations))               | 313 tokens                                | 315 tokens                               |
| Claude Sonnet 5.5                                                                                                                    | 286 tokens                                |                                          |
| Claude Sonnet 5                                                                                                                      | 354 tokens                                | 474 tokens                               |
| Claude Sonnet 4.6                                                                                                                    | 497 tokens                                | 589 tokens                               |
| Claude Sonnet 4.5                                                                                                                    | 496 tokens                                | 588 tokens                               |
| Claude Sonnet 4 ([retired, except on Bedrock and Google Cloud](https://platform.claude.com/docs/ko/about-claude/model-deprecations)) | 313 tokens                                | 315 tokens                               |
| Claude Haiku 5.5                                                                                                                     | 286 tokens                                | 406 tokens                               |
| Claude Haiku 4.5                                                                                                                     | 496 tokens                                | 588 tokens                               |
| Claude Haiku 3.5 ([retired, except on Google Cloud](https://platform.claude.com/docs/ko/about-claude/model-deprecations))            | 264 tokens                                | 355 tokens                               |

* **auto, none:** The count when tool\_choice is auto or none.
* **any, tool:** The count when tool\_choice is any or tool.
* **Retired:** May still be available on other cloud platforms. See [Model deprecations](https://platform.claude.com/docs/ko/about-claude/model-deprecations) for more.

이러한 토큰 수는 일반 입력 및 출력 토큰에 더해져 요청의 총 비용을 계산하는 데 사용됩니다.

현재 모델별 가격은 [모델 개요](https://platform.claude.com/docs/ko/models/overview#latest-models-comparison) 표를 참조하세요.

도구 사용 프롬프트를 보내면 다른 API 요청과 마찬가지로 응답에는 보고된 `usage` 지표에 입력 및 출력 토큰 수가 모두 포함됩니다.

일부 서버 도구는 토큰 외에 사용량 기반 요금을 추가합니다. 해당 요금은 [웹 검색 도구](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/web-search-tool#usage-and-pricing) 및 [코드 실행 도구](https://platform.claude.com/docs/ko/agents-and-tools/tool-use/code-execution-tool#usage-and-pricing)를 참조하세요.

## 다음 단계

<CardGroup cols={3}>
  <Card href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/how-tool-use-works" title="도구 사용 작동 방식" icon="compass">
    도구 사용 루프, 도구가 실행되는 위치, 산문 대신 도구를 사용해야 하는 경우를 이해하세요.
  </Card>

  <Card href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/build-a-tool-using-agent" title="튜토리얼: 도구를 사용하는 에이전트 구축" icon="graduation-cap">
    단일 도구 호출부터 프로덕션 준비가 된 에이전트 루프까지 안내하는 단계별 가이드입니다.
  </Card>

  <Card href="https://platform.claude.com/docs/ko/agents-and-tools/tool-use/tool-reference" title="도구 레퍼런스" icon="book">
    Anthropic이 제공하는 도구 디렉터리 및 선택적 도구 정의 속성에 대한 레퍼런스입니다.
  </Card>
</CardGroup>
