

# Amazon Nova에서 도구 사용(함수 직접 호출)
<a name="tool-use"></a>

**참고**  
이 설명서는 Amazon Nova 버전 1용입니다. Amazon Nova 2에서 도구 사용에 대한 자세한 내용은 [도구 사용(함수 호출)](https://docs.aws.amazon.com/nova/latest/nova2-userguide/using-tools.html)을 참조하세요.

도구는 Amazon Nova에 API 직접 호출, 코드 함수 등의 외부 기능을 제공하는 방법입니다. 이 섹션에서는 Amazon Nova 모델로 작업할 때 도구를 정의하고 통합하는 방법을 다룹니다.

도구 사용에는 세 가지 주요 단계가 포함됩니다.
+ **사용자 쿼리** - 각 도구의 기능과 입력 요구 사항을 설명하는 JSON 스키마를 제공하여 Amazon Nova에서 사용할 수 있는 도구를 정의합니다.
+ **도구 선택** - 사용자가 메시지를 전송하면 Amazon Nova가 이를 분석하여 응답을 생성하는 데 도구가 필요한지 결정합니다. 이를 `Auto` 도구 선택이라고 합니다. 자세한 내용은 [도구 선택](https://docs.aws.amazon.com/nova/latest/userguide/tool-choice.html)을 참조하세요. Amazon Nova가 적합한 도구를 식별하면 ‘도구를 직접적으로 호출’하고 도구 이름과 사용할 파라미터를 반환합니다.

  개발자는 모델의 요청에 따라 도구를 실행할 책임이 있습니다. 즉, 도구의 기능을 간접적으로 호출하고 모델에서 제공하는 입력 파라미터를 처리하는 코드를 작성해야 합니다.
**참고**  
모든 LLM 응답과 마찬가지로 Amazon Nova는 도구 직접 호출을 할루시네이션할 수 있습니다. 도구가 있는지, 입력 형식이 올바르게 지정되어 있는지, 적절한 권한이 이미 부여되어 있는지 확인하는 것은 개발자의 책임입니다.
+ **결과 반환** - 도구를 실행한 후 결과를 구조화된 형식으로 Amazon Nova에 다시 전송해야 합니다. 유효한 형식에는 JSON 또는 텍스트와 이미지의 조합이 포함됩니다. 이를 통해 Amazon Nova는 도구의 출력을 사용자에게 보내는 최종 응답에 통합할 수 있습니다.

  도구 실행 중에 오류가 발생하는 경우 Amazon Nova에 대한 도구 응답에 이를 표시하여 Amazon Nova가 그에 따라 응답을 조정하도록 할 수 있습니다.

계산기 도구의 간단한 예제를 생각해 보세요.

------
#### [ User query ]

도구 직접 호출 워크플로의 첫 번째 단계는 사용자가 Amazon Nova에 수학 방정식의 결과(10 x 5)를 쿼리하는 것입니다. 이 쿼리는 계산기를 나타내는 도구 사양과 함께 Amazon Nova에 프롬프트로 전송됩니다.

```
user_query = "10*5"

messages = [{
    "role": "user",
    "content": [{"text": user_query}]
}]

tool_config = {
    "tools": [
        {
            "toolSpec": {
                "name": "calculator", # Name of the tool
                "description": "A calculator tool that can execute a math equation", # Concise description of the tool
                "inputSchema": {
                    "json": { 
                        "type": "object",
                        "properties": {
                            "equation": { # The name of the parameter
                                "type": "string", # parameter type: string/int/etc
                                "description": "The full equation to evaluate" # Helpful description of the parameter
                            }
                        },
                        "required": [ # List of all required parameters
                            "equation"
                        ]
                    }
                }
            }
        }
    ]
}
```

------
#### [ Tool selection ]

Amazon Nova는 사용자 프롬프트와 함께 도구의 컨텍스트를 사용하여 사용할 필수 도구와 필요한 구성을 결정합니다. 이는 API 응답의 일부로 반환됩니다.

```
{
    "toolUse": {
        "toolUseId": "tooluse_u7XTryCSReawd9lXwljzHQ", 
        "name": "calculator", 
        "input": {
            "equation": "10*5"
         }
    }
}
```

애플리케이션은 도구를 실행하고 결과를 저장하는 역할을 합니다.

```
def calculator(equation: str):
    return eval(equation)
    
tool_result = calculator("10*5")
```

------
#### [ Return results ]

Amazon Nova에 도구 결과를 반환하기 위해 도구 결과가 새 API 요청에 포함됩니다. 도구 사용 ID는 이전 응답에서 Amazon Nova에서 반환된 ID와 일치합니다.

```
{ 
    "toolResult": {
        "toolUseId": "tooluse_u7XTryCSReawd9lXwljzHQ",
        "content": [
            {
                "json": {
                    "result": "50"
                }
            }
        ],
        "status": "success"
    }
}
```
+ Amazon Nova는 초기 사용자 쿼리, 도구 사용 및 도구 결과를 포함한 메시지의 전체 컨텍스트를 사용하여 사용자에 대한 최종 응답을 결정합니다. 이 경우 Amazon Nova는 사용자에게 ‘10 곱하기 5는 50입니다.’라고 응답합니다.

------

Amazon Nova는 Invoke API와 Converse API 모두에서 도구 사용을 허용하지만, 모든 기능을 사용하려면 [Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use-inference-call.html)를 사용하는 것이 좋으며, 앞으로도 이 API의 예제를 사용할 것입니다.

**Topics**
+ [도구 정의](tool-use-definition.md)
+ [도구 간접 호출](tool-use-invocation.md)
+ [도구 선택](tool-choice.md)
+ [도구 결과 반환](tool-use-results.md)
+ [기본 제공 도구 사용](tool-built-in.md)
+ [오류 보고](tool-use-error.md)
+ [추가 참조](#tool-use-resources)

# 도구 정의
<a name="tool-use-definition"></a>

도구 직접 호출 워크플로에서 중요한 단계는 도구를 정의하는 것입니다. 도구 정의에는 모델이 도구를 간접적으로 호출하기에 적절한 경우를 안내하는 데 필요한 모든 컨텍스트가 포함되어야 합니다.

도구를 정의하려면 도구 구성을 생성하고 사용자 메시지와 함께 API에 전달합니다. [도구 구성](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolConfiguration.html) 스키마에는 도구 배열과 도구 선택 파라미터(선택 사항)가 필요합니다.

**참고**  
Amazon Nova는 `toolChoice`에 대해 `auto`, `any`, `tool` 옵션을 지원합니다. 자세한 내용은 Amazon Bedrock API 설명서의 [ToolChoice](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolChoice.html)와 [Use a tool to complete an Amazon Bedrock model response](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html)를 참조하세요.

다음은 도구를 정의하는 방법의 예제입니다.

```
tool_config = {
    "tools": [
        {
            "toolSpec": {
                "name": "top_song",
                "description": "Get the most popular song played on a radio station.",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "sign": {
                                "type": "string",
                                "description": "The call sign for the radio station for which you want the most popular song. Example calls signs are WZPZ, and WKRP."
                            }
                        },
                        "required": [
                            "sign"
                        ]
                    }
                }
            }
        }
    ],
}
```

이름, 설명 및 입력 스키마는 도구의 정확한 기능과 함께 명시적이어야 합니다. 도구 사용 시기에 대한 주요 차별화 요소가 도구 구성에 반영되어 있는지 확인하세요.

**참고**  
Amazon Nova 이해 모델은 현재 Converse API에서 [ToolInputSchema](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolInputSchema.html)를 정의하는 데 사용될 때 JsonSchema 기능의 하위 집합만 지원합니다.  
최상위 스키마는 [객체](https://json-schema.org/understanding-json-schema/reference/object) 유형이어야 합니다.
최상위 객체에서는 유형(‘object’로 설정해야 함), [https://json-schema.org/understanding-json-schema/reference/object#properties](https://json-schema.org/understanding-json-schema/reference/object#properties), [https://json-schema.org/understanding-json-schema/reference/object#required](https://json-schema.org/understanding-json-schema/reference/object#required)의 세 가지 필드만 지원됩니다.

도구 직접 호출의 경우, 온도를 0으로 설정하여 그리디 디코딩을 사용하는 것이 좋습니다.

다음은 Converse API를 사용하여 도구를 직접적으로 호출하는 예제입니다.

```
import json
import boto3

client = boto3.client("bedrock-runtime", region_name="us-east-1")

input_text = "What is the most popular song on WZPZ?"

messages = [{
    "role": "user",
    "content": [{"text": input_text}]
}]

inf_params = {"maxTokens": 1000, "temperature": 0}

response = client.converse(
    modelId="us.amazon.nova-lite-v1:0",
    messages=messages,
    toolConfig=tool_config,
    inferenceConfig=inf_params
)

messages.append(response["output"]["message"])

# Pretty print the response JSON.
print("[Full Response]")
print(json.dumps(response, indent=2))

# Print the tool content for easy readability.
tool = next(
    block["toolUse"]
    for block in response["output"]["message"]["content"]
    if "toolUse" in block
)
print("\n[Tool Response]")
print(tool)
```

# 도구 간접 호출
<a name="tool-use-invocation"></a>

Amazon Nova가 도구를 직접적으로 호출하기로 결정하면 도구 사용 블록이 어시스턴트 메시지의 일부로 반환되며 중지 이유는 ‘tool\$1use’가 됩니다. 도구 블록에는 도구의 이름과 입력 내용이 포함됩니다.

**참고**  
도구 직접 호출의 정확도를 높이기 위해 Amazon Nova 모델의 기본 동작은 도구 직접 호출에 생각의 사슬 추론을 사용하는 것입니다. 생각 프로세스는 어시스턴트 메시지를 통해 제공되며 <thinking> 태그에 포함됩니다. 응답에 여러 도구 직접 호출과 생각 블록이 있을 수 있으므로 애플리케이션에서 이를 고려해야 합니다.  
도구 선택이 `any` 또는 `tool`로 구성된 경우 이는 생각의 사슬 동작을 재정의하고 응답에는 필요한 도구 직접 호출만 포함됩니다.

```
{
   "toolUse": 
    {
        "toolUseId": "tooluse_20Z9zl0BQWSXjFuLKdTJcA", 
        "name": "top_song", 
        "input": {
            "sign": "WZPZ"
        }
    }
}
```

실제로 도구를 직접적으로 호출하려면 메시지에서 도구 이름과 인수를 추출한 다음 애플리케이션에서 도구를 간접적으로 호출합니다.

다음은 도구 직접 호출을 처리하는 방법의 예제입니다.

```
def get_top_song(sign):
    print(f"Getting the top song at {sign}")
    return ("Espresso", "Sabrina Carpenter")

stop_reason = response["stopReason"]

tool, song, artist = None, None, None
if stop_reason == "tool_use":
    thought_process = next(
        block["text"]
        for block in response["output"]["message"]["content"]
        if "text" in block
    )

    print(thought_process)

    tool = next(
        block["toolUse"]
        for block in response["output"]["message"]["content"]
        if "toolUse" in block
    )

    if tool["name"] == "top_song":
        song, artist = get_top_song(tool["input"]["sign"])
```

도구를 정의하고 간접적으로 호출할 때 보안을 염두에 두는 것이 중요합니다. Amazon Nova와 같은 LLM은 세션 세부 정보에 액세스할 수 없으므로 도구를 간접적으로 호출하기 전에 필요한 경우 권한을 검증해야 합니다. 프롬프트를 보강하고 Amazon Nova가 도구 직접 호출에 주입하도록 허용하는 대신 세션의 사용자 세부 정보를 사용합니다.

# 도구 선택
<a name="tool-choice"></a>

Amazon Nova 모델은 *도구 선택* 기능을 지원합니다. 도구 선택을 통해 개발자는 도구가 직접적으로 호출되는 방식을 제어할 수 있습니다. 도구 선택에 지원되는 파라미터 옵션은 `tool`, `any`, `auto`의 세 가지입니다.
+ **도구** - 지정된 도구가 한 번 직접적으로 호출됩니다.
+ **모두** - 제공된 도구 중 하나가 한 번 이상 직접적으로 호출됩니다.
+ **자동** - 모델이 도구를 직접적으로 호출할지 결정하고 필요한 경우 여러 도구가 직접적으로 호출됩니다.

------
#### [ Tool ]

도구 선택으로 `tool`을 사용하면 모델이 직접적으로 호출하는 특정 도구를 제어할 수 있습니다. 아래 예제에서는 응답의 형식을 일관된 방식으로 지정해야 하는 구조화된 출력 사용 사례를 통해 이를 보여줍니다.

```
tool_config = {
    "toolChoice": {
        "tool": { "name" : "extract_recipe"}
    },
    "tools": [
        {
            "toolSpec": {
                "name": "extract_recipe",
                "description": "Extract recipe for cooking instructions",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "description": "Name of the recipe"
                            },
                            "description": {
                                "type": "string",
                                "description": "Brief description of the dish"
                            },
                            "ingredients": {
                                "type": "array",
                                "items": {
                                    "type": "string",
                                    "description": "Name of ingredient"
                                }
                            }
                        },
                        "required": ["name", "description", "ingredients"]
                    }
                }
            }
        }
    ]
}
```

------
#### [ Any ]

도구 선택으로 `any`를 사용하면 매번 최소 하나의 도구가 직접적으로 호출되도록 할 수 있습니다. 어떤 도구를 직접적으로 호출할지 결정하는 것은 모델에 달려 있지만, 항상 반환되는 도구가 있습니다. 아래 예제에서는 API 선택 엔드포인트 사용 사례에 도구 선택으로 any를 사용하는 것을 보여줍니다. 이는 모델이 특정 도구를 반환하도록 요구하는 것이 유용한 한 가지 예제입니다.

```
tool_config = {
    "toolChoice": {
        "any": {}
    },
    "tools": [
         {
            "toolSpec": {
                "name": "get_all_products",
                "description": "API to retrieve multiple products with filtering and pagination options",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "sort_by": {
                                "type": "string",
                                "description": "Field to sort results by. One of: price, name, created_date, popularity",
                                "default": "created_date"
                            },
                            "sort_order": {
                                "type": "string",
                                "description": "Order of sorting (ascending or descending). One of: asc, desc",
                                "default": "desc"
                            },
                        },
                        "required": []
                    }
                }
            }
        },
        {
            "toolSpec": {
                "name": "get_products_by_id",
                "description": "API to retrieve retail products based on search criteria",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "product_id": {
                                "type": "string",
                                "description": "Unique identifier of the product"
                            },
                        },
                        "required": ["product_id"]
                    }
                }
            }
        }
    ]
}
```

------
#### [ Auto ]

도구 선택으로 `auto`를 사용하는 것은 도구 지원의 기본 기능으로, 모델이 도구를 직접적으로 호출할 시기와 직접적으로 호출할 도구의 수를 결정할 수 있습니다. 이는 요청에 도구 선택을 포함하지 않는 경우의 동작입니다.

**참고**  
Amazon Nova 도구 직접 호출의 기본 동작은 도구 선택에 생각의 사슬을 사용하는 것입니다. 기본 동작이나 도구 선택 `auto`를 사용하는 경우 <thinking> 태그에 생각 프로세스 출력도 표시됩니다.

다음 예제에서는 모델이 인터넷에서 최신 정보를 검색하거나 사용자에게 직접 응답하도록 허용하려는 챗봇 사용 사례를 강조합니다. 이 도구 선택은 유연성을 제공하며 추론은 모델에 맡깁니다.

```
tool_config = {
    "toolChoice": {
        "auto": {}
    },
    "tools": [
         {
            "toolSpec": {
                "name": "search",
                "description": "API that provides access to the internet",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "query": {
                                "type": "string",
                                "description": "Query to search by",
                            },
                        },
                        "required": ["query"]
                    }
                }
            }
        }
    ]
}
```

------

**참고**  
도구 선택 파라미터를 설정할 때 모델 출력 텍스트가 계속 표시되거나 원래 도구 선택 후에 순차적 도구 호출을 수행할 수 있습니다. 여기에서 중지 시퀀스를 설정하여 출력을 도구로만 제한하는 것이 좋습니다.  

```
“stopSequences”: [“</tool>”]
```
자세한 내용은 Amazon Bedrock API 가이드의 [InferenceConfiguration](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_InferenceConfiguration.html)을 참조하세요.

# 도구 결과 반환
<a name="tool-use-results"></a>

애플리케이션에서 도구를 간접적으로 호출한 후 마지막 단계는 모델에 도구 결과를 제공하는 것입니다. 이는 도구 직접 호출의 ID와 응답 콘텐츠가 포함된 도구 결과를 반환하는 방식으로 이루어집니다. 이 콘텐츠는 [ToolResultBlock](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolResultBlock.html) 스키마를 따릅니다.

```
{
    "toolResult": {
        "toolUseId": tool['toolUseId'],
        "content": [{"json": {"song": song, "artist": artist}}],
        "status": "success"
    }
}
```

`ToolResultBlock`의 콘텐츠는 단일 JSON이거나 텍스트와 이미지를 혼합한 것이어야 합니다.

상태 필드는 모델에 도구 실행 상태를 표시하는 데 사용할 수 있습니다. 도구 실행이 실패한 경우 실패를 표시하면 Amazon Nova가 원래 도구 직접 호출을 수정하려고 시도합니다.

스키마에 대한 자세한 내용은 [ToolResultContentBlock](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ToolResultContentBlock.html) 설명서를 참조하세요.

다음은 Converse API를 사용하여 도구 결과를 반환하는 방법의 예제입니다.

```
messages.append({
    "role": "user",
    "content": [
        {
            "toolResult": {
                "toolUseId": tool['toolUseId'],
                "content": [{"json": {"song": song, "artist": artist}}],
                "status": "success"
            }
        }
    ]
})

inf_params = {"maxTokens": 1000, "temperature": 0}

# Send the tool result to the model.
response = client.converse(
    modelId="us.amazon.nova-lite-v1:0",
    messages=messages,
    toolConfig=tool_config,
    inferenceConfig=inf_params
)

print(response['output']['message'])
```

도구를 활용하는 방법에 대한 자세한 내용은 [Amazon Bedrock Tool Use](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html) 설명서나 Amazon Nova 샘플 리포지토리의 [도구 사용 샘플](https://github.com/aws-samples/amazon-nova-samples/blob/main/multimodal-understanding/repeatable-patterns/10-tool-calling-with-converse/10_tool_calling_with_converse.ipynb)을 참조하세요.

# 기본 제공 도구 사용
<a name="tool-built-in"></a>

기본 제공 도구는 사용자 지정 구현 없이 즉시 사용할 수 있는 완전 관리형 도구입니다. 토글로 간단하게 Converse API에서 활성화할 수 있습니다.

## 코드 인터프리터
<a name="code-interpreter"></a>

코드 인터프리터를 사용하면 Nova가 격리된 샌드박스 환경에서 Python 코드를 안전하게 실행할 수 있습니다. 이를 통해 코드를 작성 및 실행하고, 데이터를 분석하고, 시각화를 생성하고, 수학적 문제를 해결할 수 있습니다. 예를 들어 코드 인터프리터를 사용하여 다음을 수행할 수 있습니다.
+ 업로드된 데이터를 기반으로 재무 보고서 생성
+ 전체 통계 분석 또는 알고리즘 시뮬레이션
+ 격리된 환경에서 데이터베이스 마이그레이션 스크립트 실행
+ 새로 생성된 코드에 대한 유닛 테스트 실행

다음은 Converse API를 사용하여 코드 인터프리터를 활성화하는 방법의 예입니다.

```
{
  "messages": [
    {
      "role": "user",
      "content": [{"text":  "What is the average of 10, 24, 2, 3, 43, 52, 13, 68, 6, 7, 902, 82")}]
    }
  ],

"toolConfig": {
    "tools": [
        {
            "systemTool": {
                "name": "nova_code_interpreter"
            }
        }
    ]
},
```

이 경우 모델은 요청에 계산이 필요하다고 판단하여 필요한 Python 코드를 생성하고 코드 인터프리터 도구를 호출합니다.

```
{
    "toolUse": {
        "input": {
            "code": "'''Calculate the average of the given numbers.'''\nnumbers = [10, 24, 2, 3, 43, 52, 13, 68, 6, 7, 902, 82]\nsum_numbers = sum(numbers)\ncount = len(numbers)\naverage = sum_numbers / count\n(sum_numbers, count, average)"
        },
        "name": "nova_code_interpreter",
        "toolUseId": "tooluse_WytfF0g1S5qUeEPm0ptOdQ",
        "type": "server_tool_use"
    }
},
```

인터프리터는 샌드박스에서 이 코드를 실행하고 표준 스키마에서 결과, 출력을 캡처합니다.

```
{
  "stdOut": String,
  "stdErr": String,
  "exitCode": int,
  "isError": boolean
}
```

이 경우 다음을 다시 수신하게 됩니다.

```
{
    "toolResult": {
        "content": [
            {
                "text": "{\"stdOut\":\"(1212, 12, 101.0)\",\"stdErr\":\"\",\"exitCode\":0,\"isError\":false}"
            }
        ],
        "status": "success",
        "toolUseId": "tooluse_WytfF0g1S5qUeEPm0ptOdQ",
        "type": "nova_code_interpreter_result"
    }
}
```

## Model Context Protocol(MCP)
<a name="w2aac51c28b7"></a>

Model Context Protocol(MCP)은 개발자가 데이터 소스와 AI 기반 도구 간에 안전한 양방향 연결을 구축할 수 있는 개방형 표준입니다. 각 API 또는 서비스에 대한 사용자 지정 어댑터를 작성하는 대신 MCP 서버를 실행하고 Nova가 클라이언트 브리지를 통해 도구를 자동으로 검색하도록 할 수 있습니다. 연결되면 Nova는 이러한 도구를 다른 외부 통합처럼 취급합니다. 즉, 호출 시기를 결정하고, 필요한 파라미터를 전송하고, 결과를 응답에 통합합니다.

# 오류 보고
<a name="tool-use-error"></a>

Amazon Nova에서 선택한 파라미터로 인해 외부 오류가 발생하는 경우가 있습니다. 그러면 요청을 수정하고 재시도할 수 있게 Amazon Nova에 이를 다시 전달하는 것이 도움이 될 수 있습니다. 오류에 대해 알리려면 도구 결과를 반환하되 오류를 보고하고 예외 메시지를 공유하도록 상태를 수정합니다.

다음은 오류 상태 메시지를 보고하는 예제입니다.

```
tool_result_message = {
    "role": "user",
    "content": [
        { 
            "toolResult": {
                "toolUseId": tool["toolUseId"],
                "content": [{"text": "A validation exception occured on field: sample.field"}],
                "status": "error"
            }
        }
    ]
}
```

## 추가 참조
<a name="tool-use-resources"></a>

1. [도구를 사용하여 모델 응답 완성](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html)

1. [Amazon Nova로 AI 에이전트 구축](agents.md)

1. [텍스트 이해 프롬프팅 모범 사례](prompting-text-understanding.md)

1. [도구 직접 호출 문제 해결](prompting-tool-troubleshooting.md)