DEV Community

sea-turt1e
sea-turt1e

Posted on • Originally published at zenn.dev

[Sample Code] Using Amazon Bedrock Claude's ToolUse with AWS SDK for Go v2

This time, I will introduce an implementation example of Claude's ToolUse via Amazon Bedrock in Go.

When I searched for sample code online or read AWS documentation, I only found code in Python or Rust, and barely any in Go, which was quite challenging. I hope this helps others facing the same difficulty.

AWS SDK for Go v2

I will use AWS SDK for Go v2 for this tutorial.

Performing this with v1 is quite difficult (probably due to halted development), so I don't recommend it. I initially struggled with v1 due to other constraints, but it didn't work out.

What is ToolUse?

Claude's ToolUse is a feature that allows you to define and call external tools or functions (APIs), thereby extending Claude's capabilities. It is similar to "Function Calling" in GPT. In this sample code, we perform a simple math calculation and return the result in JSON format.

Code

Full Code

The complete code is available here

Code Explanation

Setting Environment Variables

First, set the necessary environment variables in a .env file when using the AWS SDK.

AWS_ACCESS_KEY_ID=your_aws_access_key_id
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key
AWS_REGION=your_aws_region
MODEL_ID=your_model_id
Enter fullscreen mode Exit fullscreen mode

MODEL_ID is the model ID used in the API request, such as "anthropic.claude-3-haiku-20240307-v1:0".

However, you need to allow model access on the AWS console for the model you want to use.

As of 2025/03/15, the claude-3.5-haiku model is only available Cross-Region. To use claude-3.5-haiku, you need to specify "us.anthropic.claude-3-5-haiku-20241022-v1:0".

Loading Environment Variables

The following code is from main.go, which loads the environment variables from the .env file.

func init() {
    if err := godotenv.Load("../../.env"); err != nil {
        log.Fatal("Error loading .env file")
    }
}
Enter fullscreen mode Exit fullscreen mode

Defining Tool Name and Input Schema

Next, set the tool name and input schema to define what data the tool will accept.

var toolName = "math_tool"

var itemProperties = map[string]interface{}{
    "formula": map[string]interface{}{
        "description": "Formula to be calculated",
        "type":        "string",
    },
    "answer": map[string]interface{}{
        "description": "the answer to the formula",
        "type":        "string",
    },
}

var toolProperties = map[string]interface{}{
    "item": map[string]interface{}{
        "type":       "array",
        "properties": itemProperties,
    },
}

var inputSchema = map[string]interface{}{
    "type": "object",
    "properties": map[string]interface{}{
        "tool": toolProperties,
    },
}
Enter fullscreen mode Exit fullscreen mode

Setting System Instructions and User Message

Next, define the system instructions and user message to specify what task the AI model should perform.

systemInstruction := fmt.Sprintf("Use %s to get the sum of two numbers.", toolName)
system := []types.SystemContentBlock{
    &types.SystemContentBlockMemberText{
        Value: systemInstruction,
    },
}

input := "1 + 2"
userMsg := types.Message{
    Role: types.ConversationRoleUser,
    Content: []types.ContentBlock{
        &types.ContentBlockMemberText{
            Value: input,
        },
    },
}
Enter fullscreen mode Exit fullscreen mode

Defining Tool Configuration

Specify which tool to use.

toolConfig := types.ToolConfiguration{
    Tools: []types.Tool{
        &types.ToolMemberToolSpec{
            Value: types.ToolSpecification{
                InputSchema: &types.ToolInputSchemaMemberJson{
                    Value: document.NewLazyDocument(inputSchema),
                },
                Name: &toolName,
            },
        },
    },
}
Enter fullscreen mode Exit fullscreen mode

Request to Claude

Send the request to Claude using Bedrock Runtime.

output, err := bedrockRuntime.Converse(context.Background(), &bedrockruntime.ConverseInput{
    ModelId:    &modelId,
    Messages:   []types.Message{userMsg},
    System:     system,
    ToolConfig: &toolConfig,
})
Enter fullscreen mode Exit fullscreen mode

Handling the Response

Extract the necessary information from the response.

response, _ := output.Output.(*types.ConverseOutputMemberMessage)
responseContentBlock := response.Value.Content[0]
text, _ := responseContentBlock.(*types.ContentBlockMemberText)
fmt.Printf("Response: %s\n", text.Value)

contentBlock := response.Value.Content[1]
toolUseOutput, _ := contentBlock.(*types.ContentBlockMemberToolUse)
toolUseOutputJson, err := toolUseOutput.Value.Input.MarshalSmithyDocument()
if err != nil {
    log.Fatalf("unable to marshal tool use output, %v", err)
}
fmt.Printf("Tool Use Output: %s\n", toolUseOutputJson)
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, I introduced how to use Claude's ToolUse via Amazon Bedrock with AWS SDK for Go v2. Since I'm not an expert in Go, I would appreciate any feedback on improving the code.

Top comments (0)