다양한 도구 사용 패턴과 기술을 보여주는 몇 가지 코드 예제가 있습니다. 간결성을 위해 도구는 간단한 도구이며, 최상의 성능을 보장하기 위해 이상적인 것보다 도구 설명이 짧습니다. 자세한 내용은 도구 지정을 참조하세요.

단일 도구

이 예제는 get_weather 도구를 사용하는 기본적인 단일 도구 상황을 보여줍니다.

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-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "get_weather",
        "description": "주어진 위치의 현재 날씨 가져오기",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "도시와 주, 예: San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "온도 단위, \"celsius\" 또는 \"fahrenheit\""
                }
            },
            "required": ["location"]
        }
    }],
    "messages": [{"role": "user", "content": "샌프란시스코의 날씨는 어떤가요?"}]
}'

Claude는 다음과 유사한 응답을 반환합니다:

JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-3-opus-20240229",
  "stop_reason": "tool_use",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "<thinking>get_weather 함수를 호출해야 하고, 사용자는 SF를 원하는데, 이는 아마도 San Francisco, CA일 것입니다.</thinking>"
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9", 
      "name": "get_weather",
      "input": {"location": "San Francisco, CA", "unit": "celsius"}
    }
  ]
}

그런 다음 제공된 입력으로 get_weather 함수를 실행하고 새로운 user 메시지에서 결과를 반환해야 합니다:

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-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_weather",
            "description": "주어진 위치의 현재 날씨 가져오기",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "도시와 주, 예: San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "온도 단위, \"celsius\" 또는 \"fahrenheit\""
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [
        {
            "role": "user",
            "content": "샌프란시스코의 날씨는 어떤가요?"
        },
        {
            "role": "assistant",
            "content": [
                {
                    "type": "text",
                    "text": "<thinking>get_weather를 사용해야 하고, 사용자는 SF를 원하는데, 이는 아마도 San Francisco, CA일 것입니다.</thinking>"
                },
                {
                    "type": "tool_use",
                    "id": "toolu_01A09q90qw90lq917835lq9",
                    "name": "get_weather",
                    "input": {
                        "location": "San Francisco, CA",
                        "unit": "celsius"
                    }
                }
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "tool_result",
                    "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
                    "content": "15도"
                }
            ]
        }
    ]
}'

이것은 날씨 데이터를 통합한 Claude의 최종 응답을 출력합니다:

JSON
{
  "id": "msg_01Aq9w938a90dw8q",
  "model": "claude-3-opus-20240229",
  "stop_reason": "stop_sequence",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "현재 샌프란시스코의 날씨는 섭씨 15도(화씨 59도)입니다. 만의 도시에서는 서늘한 날씨입니다!"
    }
  ]
}

누락된 정보

사용자의 프롬프트에 도구의 모든 필수 매개변수를 채우기에 충분한 정보가 포함되어 있지 않은 경우, Claude 3 Opus는 매개변수가 누락되었음을 인식하고 요청할 가능성이 훨씬 높습니다. Claude 3 Sonnet은 도구 요청을 출력하기 전에 생각하라는 메시지가 표시될 때 특히 요청할 수 있습니다. 그러나 합리적인 값을 추론하기 위해 최선을 다할 수도 있습니다.

예를 들어, 위의 get_weather 도구를 사용하여 위치를 지정하지 않고 Claude에게 “날씨가 어떤가요?”라고 묻는 경우, 특히 Claude 3 Sonnet은 도구 입력을 추측할 수 있습니다:

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

이 동작은 보장되지 않으며, 특히 모호한 프롬프트와 Claude 3 Opus보다 지능이 낮은 모델의 경우에는 더욱 그렇습니다. Claude 3 Opus에 필요한 매개변수를 채울 만한 충분한 컨텍스트가 없는 경우, 도구 호출을 하는 대신 명확한 질문으로 응답할 가능성이 훨씬 더 높습니다.


여러 도구

단일 요청에서 Claude에게 선택할 수 있는 여러 도구를 제공할 수 있습니다. 다음은 get_weatherget_time 도구를 모두 사용하고 둘 다 요청하는 사용자 쿼리의 예입니다.

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-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "get_weather",
        "description": "주어진 위치의 현재 날씨 가져오기",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "도시와 주, 예: San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "온도 단위, 'celsius' 또는 'fahrenheit'"
                }
            },
            "required": ["location"]
        }
    },
    {
        "name": "get_time",
        "description": "주어진 시간대의 현재 시간 가져오기",
        "input_schema": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "IANA 시간대 이름, 예: America/Los_Angeles"
                }
            },
            "required": ["timezone"]
        }
    }],
    "messages": [{
        "role": "user",
        "content": "지금 뉴욕의 날씨는 어떤가요? 그리고 거기 시간은 몇 시인가요?"
    }]
}'

이 경우 Claude는 사용자의 질문에 완전히 답하기 위해 get_weatherget_time이라는 두 개의 별도 도구를 한 번에 하나씩 사용하려고 할 가능성이 높습니다. 그러나 특히 서로 의존하지 않는 경우에는 두 개의 tool_use 블록을 한 번에 출력하기도 합니다. 각 도구를 실행하고 단일 user 메시지 내에서 별도의 tool_result 블록에 결과를 반환해야 합니다.


순차적 도구

일부 작업은 한 도구의 출력을 다른 도구의 입력으로 사용하여 여러 도구를 순차적으로 호출해야 할 수 있습니다. 이런 경우 Claude는 한 번에 하나의 도구를 호출합니다. 모든 도구를 한 번에 호출하라는 메시지가 표시되면 Claude는 업스트림에 있는 도구의 도구 결과에 의존하는 다운스트림에 있는 도구의 매개변수를 추측할 가능성이 높습니다.

다음은 get_location 도구를 사용하여 사용자의 위치를 가져온 다음 해당 위치를 get_weather 도구에 전달하는 예입니다:

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-3-opus-20240229",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_location",
            "description": "IP 주소를 기반으로 현재 사용자 위치를 가져옵니다. 이 도구에는 매개변수나 인수가 없습니다.",
            "input_schema": {
                "type": "object",
                "properties": {}
            }
        },
        {
            "name": "get_weather",
            "description": "주어진 위치의 현재 날씨 가져오기",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "도시와 주, 예: San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "온도 단위, 'celsius' 또는 'fahrenheit'"
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [{
        "role": "user",
        "content": "내가 있는 곳의 날씨는 어떤가요?"
    }]
}'

이 경우 Claude는 먼저 get_location 도구를 호출하여 사용자의 위치를 가져옵니다. tool_result에서 위치를 반환한 후 Claude는 해당 위치로 get_weather를 호출하여 최종 답변을 얻습니다.

전체 대화는 다음과 같을 수 있습니다:

역할내용
사용자내가 있는 곳의 날씨는 어떤가요?
어시스턴트<thinking>이 질문에 답하려면 먼저 get_location 도구를 사용하여 사용자의 위치를 확인해야 합니다. 그런 다음 해당 위치를 get_weather 도구에 전달하여 현재 날씨를 찾을 수 있습니다.</thinking>[get_location에 대한 도구 사용]
사용자[일치하는 ID와 San Francisco, CA 결과가 있는 get_location에 대한 도구 결과]
어시스턴트[다음 입력으로 get_weather에 대한 도구 사용]{ “location”: “San Francisco, CA”, “unit”: “fahrenheit” }
사용자[일치하는 ID와 “화씨 59도(섭씨 15도), 대체로 흐림”이라는 결과가 있는 get_weather에 대한 도구 결과]
어시스턴트현재 샌프란시스코에 있는 귀하의 위치를 기준으로 현재 날씨는 화씨 59도(섭씨 15도)이며 대체로 흐립니다. 도시에서는 꽤 서늘하고 흐린 날씨입니다. 외출할 때는 가벼운 재킷을 가져가는 것이 좋습니다.

이 예제는 Claude가 여러 출처에서 데이터를 수집해야 하는 질문에 답하기 위해 여러 도구 호출을 연결하는 방법을 보여줍니다. 주요 단계는 다음과 같습니다:

  1. Claude는 먼저 날씨 질문에 답하려면 사용자의 위치가 필요하다는 것을 깨닫고 get_location 도구를 호출합니다.
  2. 사용자(즉, 클라이언트 코드)는 실제 get_location 함수를 실행하고 tool_result 블록에서 “San Francisco, CA” 결과를 반환합니다.
  3. 이제 위치를 알게 된 Claude는 location 매개변수로 “San Francisco, CA”를 전달하여 get_weather 도구를 호출합니다(unit은 필수 매개변수가 아니므로 unit 매개변수도 추측합니다).
  4. 사용자는 다시 제공된 인수로 실제 get_weather 함수를 실행하고 다른 tool_result 블록에서 날씨 데이터를 반환합니다.
  5. 마지막으로 Claude는 날씨 데이터를 원래 질문에 대한 자연어 응답에 통합합니다.

사고 연쇄 도구 사용

기본적으로 Claude 3 Opus는 도구가 필요한지, 어떤 도구를 사용할지, 적절한 매개변수는 무엇인지 가장 잘 판단하기 위해 도구 사용 쿼리에 답하기 전에 생각하도록 프롬프트됩니다. Claude 3 Sonnet과 Claude 3 Haiku는 가능한 한 많은 도구를 사용하도록 프롬프트되며 불필요한 도구를 호출하거나 누락된 매개변수를 추론할 가능성이 더 높습니다. Sonnet 또는 Haiku가 도구 호출을 하기 전에 사용자 쿼리를 더 잘 평가하도록 프롬프트하려면 다음 프롬프트를 사용할 수 있습니다:

사고 연쇄 프롬프트

관련 도구(사용 가능한 경우)를 사용하여 사용자의 요청에 답하세요. 도구를 호출하기 전에 \<thinking>\</thinking> 태그 내에서 분석을 수행하세요. 먼저 제공된 도구 중 사용자의 요청에 답하는 데 관련된 도구가 무엇인지 생각해 보세요. 둘째, 관련 도구의 필수 매개변수를 하나씩 살펴보고 사용자가 직접 제공했거나 값을 추론할 수 있는 충분한 정보를 제공했는지 확인하세요. 매개변수를 추론할 수 있는지 결정할 때는 특정 값을 지원하는지 모든 컨텍스트를 신중하게 고려하세요. 모든 필수 매개변수가 있거나 합리적으로 추론할 수 있는 경우 생각 태그를 닫고 도구 호출을 진행하세요. 그러나 필수 매개변수 중 하나의 값이 누락된 경우 함수를 호출하지 마세요(누락된 매개변수에 대한 필러도 사용하지 마세요). 대신 사용자에게 누락된 매개변수를 제공하도록 요청하세요. 제공되지 않은 경우 선택적 매개변수에 대한 추가 정보를 요청하지 마세요.


JSON 모드

도구를 실행하거나 함수를 통해 출력을 실행할 의도가 없더라도 도구를 사용하여 Claude가 스키마를 따르는 JSON 출력을 생성하도록 할 수 있습니다.

이런 식으로 도구를 사용할 때:

  • 일반적으로 단일 도구를 제공하려고 합니다
  • tool_choice를 설정하여(도구 사용 강제 참조) 모델이 해당 도구를 명시적으로 사용하도록 지시해야 합니다
  • 모델이 input을 도구에 전달할 것이므로 도구의 이름과 설명은 모델의 관점에서 작성되어야 합니다.

다음은 특정 형식을 따르는 이미지를 설명하기 위해 record_summary 도구를 사용합니다.

#!/bin/bash
IMAGE_URL="https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg"
IMAGE_MEDIA_TYPE="image/jpeg"
IMAGE_BASE64=$(curl "$IMAGE_URL" | base64)

curl https://api.anthropic.com/v1/messages \
     --header "content-type: application/json" \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --data \
'{
    "model": "claude-3-sonnet-20240229",
    "max_tokens": 1024,
    "tools": [{
        "name": "record_summary",
        "description": "잘 구조화된 JSON을 사용하여 이미지 요약 기록",
        "input_schema": {
            "type": "object",
            "properties": {
                "key_colors": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
"r": { "type": "number", "description": "빨간색 값 [0.0, 1.0]" },
"g": { "type": "number", "description": "녹색 값 [0.0, 1.0]" },
"b": { "type": "number", "description": "파란색 값 [0.0, 1.0]" },
"name": { "type": "string", "description": "snake_case로 된 사람이 읽을 수 있는 색상 이름, 예: \"olive_green\" 또는 \"turquoise\"" }
                        },
                        "required": [ "r", "g", "b", "name" ]
                    },
                    "description": "이미지의 주요 색상. 4개 미만으로 제한."
                },
                "description": {
                    "type": "string",
                    "description": "이미지 설명. 최대 1~2문장."
                },
                "estimated_year": {
                    "type": "integer",
                    "description": "사진인 경우 이미지가 촬영된 추정 연도. 이미지가 비허구적인 것으로 보이는 경우에만 이 값을 설정하세요. 대략적인 추정도 괜찮습니다!"
                }
            },
            "required": [ "key_colors", "description" ]
        }
    }],
    "tool_choice": {"type": "tool", "name": "record_summary"},
    "messages": [
        {"role": "user", "content": [
            {"type": "image", "source": {
                "type": "base64",
                "media_type": "'$IMAGE_MEDIA_TYPE'",
                "data": "'$IMAGE_BASE64'"
            }},
            {"type": "text", "text": "이 이미지를 설명하세요."}
        ]}
    ]
}'