diff --git a/.doc_gen/metadata/bedrock-runtime_metadata.yaml b/.doc_gen/metadata/bedrock-runtime_metadata.yaml index d9433b2dcbd..e0c702bd667 100644 --- a/.doc_gen/metadata/bedrock-runtime_metadata.yaml +++ b/.doc_gen/metadata/bedrock-runtime_metadata.yaml @@ -108,6 +108,10 @@ bedrock-runtime_Converse_AmazonNovaText: - description: Send a text message to Amazon Nova, using Bedrock's Converse API. snippet_tags: - BedrockRuntime.dotnetv3.Converse_AmazonNovaText + - description: Send a conversation of messages to Amazon Nova using Bedrock's Converse API with a tool configuration. + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.SendConverseRequest Python: versions: - sdk_version: 3 @@ -163,6 +167,60 @@ bedrock-runtime_Converse_AmazonTitanText: services: bedrock-runtime: {Converse} +bedrock-runtime_Scenario_ToolUse: + title: "A tool use example illustrating how to connect AI models on &BR; with a custom tool or API" + title_abbrev: "Tool use with the Converse API" + synopsis: "build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input." + category: Scenarios + languages: + .NET: + versions: + - sdk_version: 3 + github: dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario + excerpts: + - description: "The primary execution of the scenario flow. This scenario orchestrates the conversation between the user, the &BR; Converse API, and a weather tool." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.Scenario + - description: "The weather tool used by the demo. This file defines the tool specification and implements the logic to retrieve weather data using from the Open-Meteo API." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.WeatherTool + - description: "The Converse API action with a tool configuration." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.SendConverseRequest + Python: + versions: + - sdk_version: 3 + github: python/example_code/bedrock-runtime + excerpts: + - description: "The primary execution script of the demo. This script orchestrates the conversation between the user, the &BR; Converse API, and a weather tool." + snippet_files: + - python/example_code/bedrock-runtime/cross-model-scenarios/tool_use_demo/tool_use_demo.py + - description: "The weather tool used by the demo. This script defines the tool specification and implements the logic to retrieve weather data using from the Open-Meteo API." + snippet_files: + - python/example_code/bedrock-runtime/cross-model-scenarios/tool_use_demo/weather_tool.py + Rust: + versions: + - sdk_version: 1 + github: rustv1/examples/bedrock-runtime + excerpts: + - description: "The primary scenario and logic for the demo. This orchestrates the conversation between the user, the &BR; Converse API, and a weather tool." + snippet_tags: + - rust.bedrock-runtime.Converse_AnthropicClaude.tool-use + - description: "The weather tool used by the demo. This script defines the tool specification and implements the logic to retrieve weather data using from the Open-Meteo API." + snippet_tags: + - rust.bedrock-runtime.Converse_AnthropicClaude.tool-use.weather-tool + - description: "Utilities to print the Message Content Blocks." + snippet_tags: + - rust.bedrock-runtime.Converse_AnthropicClaude.tool-use.user-interface + - description: "Use statements, Error utility, and constants." + snippet_tags: + - rust.bedrock-runtime.Converse_AnthropicClaude.tool-use.supporting + services: + bedrock-runtime: {Converse} + bedrock-runtime_Converse_AnthropicClaude: title: Invoke Anthropic Claude on &BR; using Bedrock's Converse API title_abbrev: "Converse" @@ -1315,6 +1373,32 @@ bedrock-runtime_InvokeModelWithResponseStream_TitanTextEmbeddings: bedrock-runtime: {InvokeModel} # Tool use scenarios +bedrock-runtime_Scenario_ToolUseDemo_AmazonNova: + title: "A tool use demo illustrating how to connect AI models on &BR; with a custom tool or API" + title_abbrev: "Scenario: Tool use with the Converse API" + synopsis: "build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input." + category: Amazon Nova + languages: + .NET: + versions: + - sdk_version: 3 + github: dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario + excerpts: + - description: "The primary execution of the scenario flow. This scenario orchestrates the conversation between the user, the &BR; Converse API, and a weather tool." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.Scenario + - description: "The weather tool used by the demo. This file defines the tool specification and implements the logic to retrieve weather data using from the Open-Meteo API." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.WeatherTool + - description: "The Converse API action with a tool configuration." + genai: some + snippet_tags: + - Bedrock.ConverseTool.dotnetv3.SendConverseRequest + services: + bedrock-runtime: {Converse} + bedrock-runtime_Scenario_ToolUseDemo_AnthropicClaude: title: "A tool use demo illustrating how to connect AI models on &BR; with a custom tool or API" title_abbrev: "Scenario: Tool use with the Converse API" @@ -1349,7 +1433,6 @@ bedrock-runtime_Scenario_ToolUseDemo_AnthropicClaude: - description: "Use statements, Error utility, and constants." snippet_tags: - rust.bedrock-runtime.Converse_AnthropicClaude.tool-use.supporting - services: bedrock-runtime: {Converse} diff --git a/dotnetv3/Bedrock-runtime/BedrockRuntimeExamples.sln b/dotnetv3/Bedrock-runtime/BedrockRuntimeExamples.sln index d9e5d12e854..dd290cac66d 100644 --- a/dotnetv3/Bedrock-runtime/BedrockRuntimeExamples.sln +++ b/dotnetv3/Bedrock-runtime/BedrockRuntimeExamples.sln @@ -106,6 +106,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AmazonNovaCanvas", "AmazonN EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvokeModel", "Models\AmazonNova\AmazonNovaCanvas\InvokeModel\InvokeModel.csproj", "{2B39D4E2-C6B6-4340-A9AD-5F5C25CA8C1D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{FDC95D1E-41C6-45A5-BF29-F76FCC3DAEF9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockRuntimeActions", "Actions\BedrockRuntimeActions.csproj", "{ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scenarios", "Scenarios", "{045D214B-6181-43B0-ABFE-246675F4D967}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverseToolScenario", "Scenarios\ConverseToolScenario\ConverseToolScenario.csproj", "{C0A5B872-03F5-4865-9349-7A403591C50E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -224,6 +232,14 @@ Global {2B39D4E2-C6B6-4340-A9AD-5F5C25CA8C1D}.Debug|Any CPU.Build.0 = Debug|Any CPU {2B39D4E2-C6B6-4340-A9AD-5F5C25CA8C1D}.Release|Any CPU.ActiveCfg = Release|Any CPU {2B39D4E2-C6B6-4340-A9AD-5F5C25CA8C1D}.Release|Any CPU.Build.0 = Release|Any CPU + {ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC}.Release|Any CPU.Build.0 = Release|Any CPU + {C0A5B872-03F5-4865-9349-7A403591C50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0A5B872-03F5-4865-9349-7A403591C50E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0A5B872-03F5-4865-9349-7A403591C50E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0A5B872-03F5-4865-9349-7A403591C50E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -266,6 +282,8 @@ Global {E144492A-337A-0755-EAB4-DA083C3A2DDB} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {4D3E429C-CCAE-42DE-A062-4717E71D8403} = {3AF63EC9-2EB0-4A0B-8C3B-0CA3595080F6} {2B39D4E2-C6B6-4340-A9AD-5F5C25CA8C1D} = {4D3E429C-CCAE-42DE-A062-4717E71D8403} + {ABA0C307-C7A1-4BBE-A7E2-4BA7163559FC} = {FDC95D1E-41C6-45A5-BF29-F76FCC3DAEF9} + {C0A5B872-03F5-4865-9349-7A403591C50E} = {045D214B-6181-43B0-ABFE-246675F4D967} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E48A5088-1BBB-4A8B-9AB2-CC5CE0482466} diff --git a/dotnetv3/Bedrock-runtime/README.md b/dotnetv3/Bedrock-runtime/README.md index a51ea913fdc..174ab4345b8 100644 --- a/dotnetv3/Bedrock-runtime/README.md +++ b/dotnetv3/Bedrock-runtime/README.md @@ -28,6 +28,13 @@ For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv3 +### Scenarios + +Code examples that show you how to accomplish a specific task by calling multiple +functions within the same service. + +- [Tool use with the Converse API](Scenarios/ConverseToolScenario/ConverseToolScenario.cs) + ### AI21 Labs Jurassic-2 - [Converse](Models/Ai21LabsJurassic2/Converse/Converse.cs#L4) @@ -37,6 +44,7 @@ For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv3 - [Converse](Models/AmazonNova/AmazonNovaText/Converse/Converse.cs#L4) - [ConverseStream](Models/AmazonNova/AmazonNovaText/ConverseStream/ConverseStream.cs#L4) +- [Scenario: Tool use with the Converse API](Scenarios/ConverseToolScenario/ConverseToolScenario.cs#L4) ### Amazon Nova Canvas @@ -110,6 +118,18 @@ Alternatively, you can run the example from within your IDE. +#### Tool use with the Converse API + +This example shows you how to build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input. + + + + + + + + + ### Tests ⚠ Running tests might result in charges to your AWS account. diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/BedrockActionsWrapper.cs b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/BedrockActionsWrapper.cs new file mode 100644 index 00000000000..af2d1859e16 --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/BedrockActionsWrapper.cs @@ -0,0 +1,82 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.BedrockRuntime; +using Amazon.BedrockRuntime.Model; +using Microsoft.Extensions.Logging; + +namespace ConverseToolScenario; + +// snippet-start:[Bedrock.ConverseTool.dotnetv3.SendConverseRequest] + +/// +/// Wrapper class for interacting with the Amazon Bedrock Converse API. +/// +public class BedrockActionsWrapper +{ + private readonly IAmazonBedrockRuntime _bedrockClient; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The Bedrock Converse API client. + /// The logger instance. + public BedrockActionsWrapper(IAmazonBedrockRuntime bedrockClient, ILogger logger) + { + _bedrockClient = bedrockClient; + _logger = logger; + } + + /// + /// Sends a Converse request to the Amazon Bedrock Converse API. + /// + /// The Bedrock Model Id. + /// A system prompt instruction. + /// The array of messages in the conversation. + /// The specification for a tool. + /// The response of the model. + public async Task SendConverseRequestAsync(string modelId, string systemPrompt, List conversation, ToolSpecification toolSpec) + { + try + { + var request = new ConverseRequest() + { + ModelId = modelId, + System = new List() + { + new SystemContentBlock() + { + Text = systemPrompt + } + }, + Messages = conversation, + ToolConfig = new ToolConfiguration() + { + Tools = new List() + { + new Tool() + { + ToolSpec = toolSpec + } + } + } + }; + + var response = await _bedrockClient.ConverseAsync(request); + + return response; + } + catch (ModelNotReadyException ex) + { + _logger.LogError(ex, "Model not ready, please wait and try again."); + throw; + } + catch (AmazonBedrockRuntimeException ex) + { + _logger.LogError(ex, "Error occurred while sending Converse request."); + throw; + } + } +} +// snippet-end:[Bedrock.ConverseTool.dotnetv3.SendConverseRequest] \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.cs b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.cs new file mode 100644 index 00000000000..f220fd4c3d6 --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.cs @@ -0,0 +1,361 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// snippet-start:[Bedrock.ConverseTool.dotnetv3.Scenario] + +using Amazon; +using Amazon.BedrockRuntime; +using Amazon.BedrockRuntime.Model; +using Amazon.Runtime.Documents; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Http; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Console; + +namespace ConverseToolScenario; + +public static class ConverseToolScenario +{ + /* + Before running this .NET code example, set up your development environment, including your credentials. + + This demo illustrates a tool use scenario using Amazon Bedrock's Converse API and a weather tool. + The script interacts with a foundation model on Amazon Bedrock to provide weather information based on user + input. It uses the Open-Meteo API (https://open-meteo.com) to retrieve current weather data for a given location. + */ + + public static BedrockActionsWrapper _bedrockActionsWrapper = null!; + public static WeatherTool _weatherTool = null!; + public static bool _interactive = true; + + // Change this string to use a different model with Converse API. + private static string model_id = "amazon.nova-lite-v1:0"; + + private static string system_prompt = @" + You are a weather assistant that provides current weather data for user-specified locations using only + the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself. + If the user provides coordinates, infer the approximate location and refer to it in your response. + To use the tool, you strictly apply the provided tool specification. + + - Explain your step-by-step process, and give brief updates before each step. + - Only use the Weather_Tool for data. Never guess or make up information. + - Repeat the tool use for subsequent requests if necessary. + - If the tool errors, apologize, explain weather is unavailable, and suggest other options. + - Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use + emojis where appropriate. + - Only respond to weather queries. Remind off-topic users of your purpose. + - Never claim to search online, access external data, or use tools besides Weather_Tool. + - Complete the entire process until you have all required data before sending the complete response. + " + ; + + private static string default_prompt = "What is the weather like in Seattle?"; + + // The maximum number of recursive calls allowed in the tool use function. + // This helps prevent infinite loops and potential performance issues. + private static int max_recursions = 5; + + public static async Task Main(string[] args) + { + // Set up dependency injection for the Amazon service. + using var host = Host.CreateDefaultBuilder(args) + .ConfigureLogging(logging => + logging.AddFilter("System", LogLevel.Error) + .AddFilter("Microsoft", LogLevel.Trace)) + .ConfigureServices((_, services) => + services.AddHttpClient() + .AddSingleton(_ => new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1)) // Specify a region that has access to the chosen model. + .AddTransient() + .AddTransient() + .RemoveAll() + ) + .Build(); + + ServicesSetup(host); + + try + { + await RunConversationAsync(); + + } + catch (Exception ex) + { + Console.WriteLine(new string('-', 80)); + Console.WriteLine($"There was a problem running the scenario: {ex.Message}"); + Console.WriteLine(new string('-', 80)); + } + finally + { + Console.WriteLine( + "Amazon Bedrock Converse API with Tool Use Feature Scenario is complete."); + Console.WriteLine(new string('-', 80)); + } + } + + /// + /// Populate the services for use within the console application. + /// + /// The services host. + private static void ServicesSetup(IHost host) + { + _bedrockActionsWrapper = host.Services.GetRequiredService(); + _weatherTool = host.Services.GetRequiredService(); + } + + /// + /// Starts the conversation with the user and handles the interaction with Bedrock. + /// + /// The conversation array. + public static async Task> RunConversationAsync() + { + // Print the greeting and a short user guide + PrintHeader(); + + // Start with an empty conversation + var conversation = new List(); + + // Get the first user input + var userInput = await GetUserInputAsync(); + + while (userInput != null) + { + // Create a new message with the user input and append it to the conversation + var message = new Message { Role = ConversationRole.User, Content = new List { new ContentBlock { Text = userInput } } }; + conversation.Add(message); + + // Send the conversation to Amazon Bedrock + var bedrockResponse = await SendConversationToBedrock(conversation); + + // Recursively handle the model's response until the model has returned its final response or the recursion counter has reached 0 + await ProcessModelResponseAsync(bedrockResponse, conversation, max_recursions); + + // Repeat the loop until the user decides to exit the application + userInput = await GetUserInputAsync(); + } + + PrintFooter(); + return conversation; + } + + /// + /// Sends the conversation, the system prompt, and the tool spec to Amazon Bedrock, and returns the response. + /// + /// The conversation history including the next message to send. + /// The response from Amazon Bedrock. + private static async Task SendConversationToBedrock(List conversation) + { + Console.WriteLine("\tCalling Bedrock..."); + + // Send the conversation, system prompt, and tool configuration, and return the response + return await _bedrockActionsWrapper.SendConverseRequestAsync(model_id, system_prompt, conversation, _weatherTool.GetToolSpec()); + } + + /// + /// Processes the response received via Amazon Bedrock and performs the necessary actions based on the stop reason. + /// + /// The model's response returned via Amazon Bedrock. + /// The conversation history. + /// The maximum number of recursive calls allowed. + private static async Task ProcessModelResponseAsync(ConverseResponse modelResponse, List conversation, int maxRecursion) + { + if (maxRecursion <= 0) + { + // Stop the process, the number of recursive calls could indicate an infinite loop + Console.WriteLine("\tWarning: Maximum number of recursions reached. Please try again."); + } + + // Append the model's response to the ongoing conversation + conversation.Add(modelResponse.Output.Message); + + if (modelResponse.StopReason == "tool_use") + { + // If the stop reason is "tool_use", forward everything to the tool use handler + await HandleToolUseAsync(modelResponse.Output, conversation, maxRecursion - 1); + } + + if (modelResponse.StopReason == "end_turn") + { + // If the stop reason is "end_turn", print the model's response text, and finish the process + PrintModelResponse(modelResponse.Output.Message.Content[0].Text); + if (!_interactive) + { + default_prompt = "x"; + } + } + } + + /// + /// Handles the tool use case by invoking the specified tool and sending the tool's response back to Bedrock. + /// The tool response is appended to the conversation, and the conversation is sent back to Amazon Bedrock for further processing. + /// + /// The model's response containing the tool use request. + /// The conversation history. + /// The maximum number of recursive calls allowed. + public static async Task HandleToolUseAsync(ConverseOutput modelResponse, List conversation, int maxRecursion) + { + // Initialize an empty list of tool results + var toolResults = new List(); + + // The model's response can consist of multiple content blocks + foreach (var contentBlock in modelResponse.Message.Content) + { + if (!String.IsNullOrEmpty(contentBlock.Text)) + { + // If the content block contains text, print it to the console + PrintModelResponse(contentBlock.Text); + } + + if (contentBlock.ToolUse != null) + { + // If the content block is a tool use request, forward it to the tool + var toolResponse = await InvokeTool(contentBlock.ToolUse); + + // Add the tool use ID and the tool's response to the list of results + toolResults.Add(new ContentBlock + { + ToolResult = new ToolResultBlock() + { + ToolUseId = toolResponse.ToolUseId, + Content = new List() + { new ToolResultContentBlock { Json = toolResponse.Content } } + } + }); + } + } + + // Embed the tool results in a new user message + var message = new Message() { Role = ConversationRole.User, Content = toolResults }; + + // Append the new message to the ongoing conversation + conversation.Add(message); + + // Send the conversation to Amazon Bedrock + var response = await SendConversationToBedrock(conversation); + + // Recursively handle the model's response until the model has returned its final response or the recursion counter has reached 0 + await ProcessModelResponseAsync(response, conversation, maxRecursion); + } + + /// + /// Invokes the specified tool with the given payload and returns the tool's response. + /// If the requested tool does not exist, an error message is returned. + /// + /// The payload containing the tool name and input data. + /// The tool's response or an error message. + public static async Task InvokeTool(ToolUseBlock payload) + { + var toolName = payload.Name; + + if (toolName == "Weather_Tool") + { + var inputData = payload.Input.AsDictionary(); + PrintToolUse(toolName, inputData); + + // Invoke the weather tool with the input data provided + var weatherResponse = await _weatherTool.FetchWeatherDataAsync(inputData["latitude"].ToString(), inputData["longitude"].ToString()); + return new ToolResponse { ToolUseId = payload.ToolUseId, Content = weatherResponse }; + } + else + { + var errorMessage = $"\tThe requested tool with name '{toolName}' does not exist."; + return new ToolResponse { ToolUseId = payload.ToolUseId, Content = new { error = true, message = errorMessage } }; + } + } + + + /// + /// Prompts the user for input and returns the user's response. + /// Returns null if the user enters 'x' to exit. + /// + /// The prompt to display to the user. + /// The user's input or null if the user chooses to exit. + private static async Task GetUserInputAsync(string prompt = "\tYour weather info request:") + { + var userInput = default_prompt; + if (_interactive) + { + Console.WriteLine(new string('*', 80)); + Console.WriteLine($"{prompt} (x to exit): \n\t"); + userInput = Console.ReadLine(); + } + + if (string.IsNullOrWhiteSpace(userInput)) + { + prompt = "\tPlease enter your weather info request, e.g. the name of a city"; + return await GetUserInputAsync(prompt); + } + + if (userInput.ToLowerInvariant() == "x") + { + return null; + } + + return userInput; + } + + /// + /// Logs the welcome message and usage guide for the tool use demo. + /// + public static void PrintHeader() + { + Console.WriteLine(@" + ================================================= + Welcome to the Amazon Bedrock Tool Use demo! + ================================================= + + This assistant provides current weather information for user-specified locations. + You can ask for weather details by providing the location name or coordinates. Weather information + will be provided using a custom Tool and open-meteo API. + + Example queries: + - What's the weather like in New York? + - Current weather for latitude 40.70, longitude -74.01 + - Is it warmer in Rome or Barcelona today? + + To exit the program, simply type 'x' and press Enter. + + P.S.: You're not limited to single locations, or even to using English! + Have fun and experiment with the app! + "); + } + + /// + /// Logs the footer information for the tool use demo. + /// + public static void PrintFooter() + { + Console.WriteLine(@" + ================================================= + Thank you for checking out the Amazon Bedrock Tool Use demo. We hope you + learned something new, or got some inspiration for your own apps today! + + For more Bedrock examples in different programming languages, have a look at: + https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html + ================================================= + "); + } + + /// + /// Logs information about the tool use. + /// + /// The name of the tool being used. + /// The input data for the tool. + public static void PrintToolUse(string toolName, Dictionary inputData) + { + Console.WriteLine($"\n\tInvoking tool: {toolName} with input: {inputData["latitude"].ToString()}, {inputData["longitude"].ToString()}...\n"); + } + + /// + /// Logs the model's response. + /// + /// The model's response message. + public static void PrintModelResponse(string message) + { + Console.WriteLine("\tThe model's response:\n"); + Console.WriteLine(message); + Console.WriteLine(); + } +} +// snippet-end:[Bedrock.ConverseTool.dotnetv3.Scenario] \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.csproj b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.csproj new file mode 100644 index 00000000000..6d77e9066e9 --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ConverseToolScenario.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/README.md b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/README.md new file mode 100644 index 00000000000..0c052ac1e45 --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/README.md @@ -0,0 +1,59 @@ +# Bedrock Runtime Converse API with Tool Feature Scenario + +## Overview + +This example shows how to use AWS SDKs and the Amazon Bedrock Converse API to call a custom tool from a large language model (LLM) as part of a multistep conversation. The example creates a weather tool that leverages the Open-Meteo API to retrieve current weather information based on user input. + +[Bedrock Converse API with Tool Definition](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use-inference-call.html). + +## ⚠ Important + +* Running this code might result in charges to your AWS account. +* Running the tests might result in charges to your AWS account. +* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). +* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). + +## Scenario + +This example illustrates a typical interaction between a generative AI model, an application, and connected tools or APIs to solve a problem or achieve a specific goal. The scenario follows these steps: + +1. Set up the system prompt and tool configuration. +2. Specify the AI model to be used (e.g., Anthropic Claude 3 Sonnet). +3. Create a client to interact with Amazon Bedrock. +4. Prompt the user for their weather request. +5. Send the user input including the conversation history to the model. +6. The model processes the input and determines if a connected tool or API needs to be used. If this is the case, the model returns a tool use request with specific parameters needed to invoke the tool, and a unique tool use ID to correlate tool responses to the request. +7. The scenario application invokes the tool to fetch weather data, and append the response and tool use ID to the conversation. +8. The model uses the tool response to generate a final response. If additional tool requests are needed, the process is repeated. +9. Once the final response is received and printed, the application returns to the prompt. + +### Prerequisites + +For general prerequisites, see the [README](../../../README.md) in the `dotnetv3` folder. + +### Resources + +No additional resources are needed for this scenario. + +### Instructions + +After the example compiles, you can run it from the command line. To do so, navigate to +the folder that contains the .sln file and run the following command: + +``` +dotnet run +``` + +Alternatively, you can run the example from within your IDE. + +This starts an interactive scenario that walks you through exploring conditional requests for read, write, and copy operations. + +## Additional resources + +- [Documentation: The Amazon Bedrock User Guide](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html) +- [Tutorials: A developer's guide to Bedrock's new Converse API](https://community.aws/content/2dtauBCeDa703x7fDS9Q30MJoBA/amazon-bedrock-converse-api-developer-guide) +- [More examples: Amazon Bedrock code examples and scenarios in multiple programming languages](https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html) + +--- + +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ToolResponse.cs b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ToolResponse.cs new file mode 100644 index 00000000000..95dbb986fa1 --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/ToolResponse.cs @@ -0,0 +1,16 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// snippet-start:[Bedrock.ConverseTool.dotnetv3.ToolResponse] + +namespace ConverseToolScenario; + +/// +/// Response object for the tool results. +/// +public class ToolResponse +{ + public string ToolUseId { get; set; } = null!; + public dynamic Content { get; set; } = null!; +} +// snippet-end:[Bedrock.ConverseTool.dotnetv3.ToolResponse] \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/WeatherTool.cs b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/WeatherTool.cs new file mode 100644 index 00000000000..1e87b25927b --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/WeatherTool.cs @@ -0,0 +1,98 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// snippet-start:[Bedrock.ConverseTool.dotnetv3.WeatherTool] + +using Amazon.BedrockRuntime.Model; +using Amazon.Runtime.Documents; +using Microsoft.Extensions.Logging; + +namespace ConverseToolScenario; + +/// +/// Weather tool that will be invoked when requested by the Bedrock response. +/// +public class WeatherTool +{ + private readonly ILogger _logger; + private readonly IHttpClientFactory _httpClientFactory; + + public WeatherTool(ILogger logger, IHttpClientFactory httpClientFactory) + { + _logger = logger; + _httpClientFactory = httpClientFactory; + } + + /// + /// Returns the JSON Schema specification for the Weather tool. The tool specification + /// defines the input schema and describes the tool's functionality. + /// For more information, see https://json-schema.org/understanding-json-schema/reference. + /// + /// The tool specification for the Weather tool. + public ToolSpecification GetToolSpec() + { + ToolSpecification toolSpecification = new ToolSpecification(); + + toolSpecification.Name = "Weather_Tool"; + toolSpecification.Description = "Get the current weather for a given location, based on its WGS84 coordinates."; + + Document toolSpecDocument = Document.FromObject( + new + { + type = "object", + properties = new + { + latitude = new + { + type = "string", + description = "Geographical WGS84 latitude of the location." + }, + longitude = new + { + type = "string", + description = "Geographical WGS84 longitude of the location." + } + }, + required = new[] { "latitude", "longitude" } + }); + + toolSpecification.InputSchema = new ToolInputSchema() { Json = toolSpecDocument }; + return toolSpecification; + } + + /// + /// Fetches weather data for the given latitude and longitude using the Open-Meteo API. + /// Returns the weather data or an error message if the request fails. + /// + /// The latitude of the location. + /// The longitude of the location. + /// The weather data or an error message. + public async Task FetchWeatherDataAsync(string latitude, string longitude) + { + string endpoint = "https://api.open-meteo.com/v1/forecast"; + + try + { + var httpClient = _httpClientFactory.CreateClient(); + var response = await httpClient.GetAsync($"{endpoint}?latitude={latitude}&longitude={longitude}¤t_weather=True"); + response.EnsureSuccessStatusCode(); + var weatherData = await response.Content.ReadAsStringAsync(); + + Document weatherDocument = Document.FromObject( + new { weather_data = weatherData }); + + return weatherDocument; + } + catch (HttpRequestException e) + { + _logger.LogError(e, "Error fetching weather data: {Message}", e.Message); + throw; + } + catch (Exception e) + { + _logger.LogError(e, "Unexpected error fetching weather data: {Message}", e.Message); + throw; + } + } +} +// snippet-end:[Bedrock.ConverseTool.dotnetv3.WeatherTool] \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Tests/BedrockRuntimeTests.csproj b/dotnetv3/Bedrock-runtime/Tests/BedrockRuntimeTests.csproj index ef74e91feaf..6c0e8620b3e 100644 --- a/dotnetv3/Bedrock-runtime/Tests/BedrockRuntimeTests.csproj +++ b/dotnetv3/Bedrock-runtime/Tests/BedrockRuntimeTests.csproj @@ -13,9 +13,9 @@ + - runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -55,6 +55,7 @@ + \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Tests/ConverseToolScenarioTests.cs b/dotnetv3/Bedrock-runtime/Tests/ConverseToolScenarioTests.cs new file mode 100644 index 00000000000..f5660a3774b --- /dev/null +++ b/dotnetv3/Bedrock-runtime/Tests/ConverseToolScenarioTests.cs @@ -0,0 +1,65 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +using Amazon; +using Amazon.BedrockRuntime; +using ConverseToolScenario; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace BedrockRuntimeTests; + +/// +/// Tests for the Converse Tool Use example. +/// +public class ConverseToolScenarioTests +{ + private readonly BedrockActionsWrapper _bedrockActionsWrapper = null!; + private readonly WeatherTool _weatherTool = null!; + private readonly ILoggerFactory _loggerFactory; + + /// + /// Constructor for the test class. + /// + public ConverseToolScenarioTests() + { + + _loggerFactory = LoggerFactory.Create(builder => + { + builder.AddConsole(); + }); + + IServiceCollection services = new ServiceCollection(); // [1] + + services.AddHttpClient(); + + IHttpClientFactory _httpClientFactory = services + .BuildServiceProvider() + .GetRequiredService(); + + _bedrockActionsWrapper = new BedrockActionsWrapper( + new AmazonBedrockRuntimeClient(RegionEndpoint.USEast1), new Logger(_loggerFactory)); + _weatherTool = new WeatherTool(new Logger(_loggerFactory), + _httpClientFactory); + ConverseToolScenario.ConverseToolScenario._bedrockActionsWrapper = _bedrockActionsWrapper; + ConverseToolScenario.ConverseToolScenario._weatherTool = _weatherTool; + } + + /// + /// Run the non-interactive scenario. Should return a non-empty conversation. + /// + /// Async task. + [Fact] + [Trait("Category", "Integration")] + public async Task TestScenario() + { + // Arrange. + ConverseToolScenario.ConverseToolScenario._interactive = false; + + // Act. + var conversation = await ConverseToolScenario.ConverseToolScenario.RunConversationAsync(); + + // Assert. + Assert.NotEmpty(conversation); + } +} \ No newline at end of file diff --git a/dotnetv3/Bedrock-runtime/Tests/GlobalUsings.cs b/dotnetv3/Bedrock-runtime/Tests/GlobalUsings.cs index ef5ce323ba9..0f64a5599c7 100644 --- a/dotnetv3/Bedrock-runtime/Tests/GlobalUsings.cs +++ b/dotnetv3/Bedrock-runtime/Tests/GlobalUsings.cs @@ -2,11 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 global using Xunit; -global using Xunit.Extensions.Ordering; // Optional. -[assembly: CollectionBehavior(DisableTestParallelization = true)] -// Optional. -[assembly: TestCaseOrderer("Xunit.Extensions.Ordering.TestCaseOrderer", "Xunit.Extensions.Ordering")] -// Optional. -[assembly: TestCollectionOrderer("Xunit.Extensions.Ordering.CollectionOrderer", "Xunit.Extensions.Ordering")] \ No newline at end of file +[assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file diff --git a/dotnetv3/DotNetV3Examples.sln b/dotnetv3/DotNetV3Examples.sln index 54a02263eb2..c6f351d608b 100644 --- a/dotnetv3/DotNetV3Examples.sln +++ b/dotnetv3/DotNetV3Examples.sln @@ -837,6 +837,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S3ObjectLockScenario", "S3\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S3ObjectLockTests", "S3\scenarios\S3ObjectLockScenario\S3ObjectLockTests\S3ObjectLockTests.csproj", "{BCCFBED0-E800-46C5-975B-7D404486F00F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverseToolScenario", "Bedrock-runtime\Scenarios\ConverseToolScenario\ConverseToolScenario.csproj", "{83ED7BBE-5C9A-47AC-805B-351270069570}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1915,6 +1917,10 @@ Global {BCCFBED0-E800-46C5-975B-7D404486F00F}.Debug|Any CPU.Build.0 = Debug|Any CPU {BCCFBED0-E800-46C5-975B-7D404486F00F}.Release|Any CPU.ActiveCfg = Release|Any CPU {BCCFBED0-E800-46C5-975B-7D404486F00F}.Release|Any CPU.Build.0 = Release|Any CPU + {83ED7BBE-5C9A-47AC-805B-351270069570}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83ED7BBE-5C9A-47AC-805B-351270069570}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83ED7BBE-5C9A-47AC-805B-351270069570}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83ED7BBE-5C9A-47AC-805B-351270069570}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2296,6 +2302,7 @@ Global {7EC94891-9A5F-47EF-9C97-8A280754525C} = {0169CEB9-B6A7-447D-921D-C79358DDCCE6} {93588ED1-A248-4F6C-85A4-27E9E65D8AC7} = {7EC94891-9A5F-47EF-9C97-8A280754525C} {BCCFBED0-E800-46C5-975B-7D404486F00F} = {7EC94891-9A5F-47EF-9C97-8A280754525C} + {83ED7BBE-5C9A-47AC-805B-351270069570} = {BA23BB28-EC63-4330-8CA7-DEB1B6489580} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {08502818-E8E1-4A91-A51C-4C8C8D4FF9CA} diff --git a/dotnetv4/Bedrock/Actions/BedrockActions.csproj b/dotnetv4/Bedrock/Actions/BedrockActions.csproj index 9f12aa3e3f2..ffee5ec19c7 100644 --- a/dotnetv4/Bedrock/Actions/BedrockActions.csproj +++ b/dotnetv4/Bedrock/Actions/BedrockActions.csproj @@ -9,6 +9,7 @@ + diff --git a/python/example_code/bedrock-runtime/README.md b/python/example_code/bedrock-runtime/README.md index 91bca8633dc..68a71a78623 100644 --- a/python/example_code/bedrock-runtime/README.md +++ b/python/example_code/bedrock-runtime/README.md @@ -43,6 +43,13 @@ python -m pip install -r requirements.txt - [Hello Amazon Bedrock Runtime](hello/hello_bedrock_runtime_invoke.py#L5) (`InvokeModel`) +### Scenarios + +Code examples that show you how to accomplish a specific task by calling multiple +functions within the same service. + +- [Tool use with the Converse API](cross-model-scenarios/tool_use_demo/tool_use_demo.py) + ### AI21 Labs Jurassic-2 - [Converse](models/ai21_labs_jurassic2/converse.py#L4) @@ -143,6 +150,24 @@ python hello/hello_bedrock_runtime_invoke.py ``` +#### Tool use with the Converse API + +This example shows you how to build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input. + + + + + +Start the example by running the following at a command prompt: + +``` +python cross-model-scenarios/tool_use_demo/tool_use_demo.py +``` + + + + + ### Tests ⚠ Running tests might result in charges to your AWS account. diff --git a/rustv1/examples/bedrock-runtime/README.md b/rustv1/examples/bedrock-runtime/README.md index ae64bcc7542..abb0df99ce4 100644 --- a/rustv1/examples/bedrock-runtime/README.md +++ b/rustv1/examples/bedrock-runtime/README.md @@ -28,6 +28,13 @@ For prerequisites, see the [README](../../README.md#Prerequisites) in the `rustv +### Scenarios + +Code examples that show you how to accomplish a specific task by calling multiple +functions within the same service. + +- [Tool use with the Converse API](src/bin/tool-use.rs) + ### Anthropic Claude - [Converse](src/bin/converse.rs#L43) @@ -48,6 +55,18 @@ For prerequisites, see the [README](../../README.md#Prerequisites) in the `rustv +#### Tool use with the Converse API + +This example shows you how to build a typical interaction between an application, a generative AI model, and connected tools or APIs to mediate interactions between the AI and the outside world. It uses the example of connecting an external weather API to the AI model so it can provide real-time weather information based on user input. + + + + + + + + + ### Tests ⚠ Running tests might result in charges to your AWS account. @@ -74,4 +93,4 @@ in the `rustv1` folder. Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0 \ No newline at end of file +SPDX-License-Identifier: Apache-2.0 diff --git a/scenarios/features/bedrock_converse_tool/README.md b/scenarios/features/bedrock_converse_tool/README.md new file mode 100644 index 00000000000..3e8cb087dcf --- /dev/null +++ b/scenarios/features/bedrock_converse_tool/README.md @@ -0,0 +1,42 @@ +# Bedrock Runtime Converse API with Tool Feature Scenario + +## Overview + +This example shows how to use AWS SDKs and the Amazon Bedrock Converse API to call a custom tool from a large language model (LLM) as part of a multistep conversation. The example creates a weather tool that leverages the Open-Meteo API to retrieve current weather information based on user input. + +[Bedrock Converse API with Tool Definition](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use-inference-call.html). + +This example illustrates a typical interaction between a generative AI model, an application, and connected tools or APIs to solve a problem or achieve a specific goal. The scenario follows these steps: + +1. Set up the system prompt and tool configuration. +2. Create a client to interact with Amazon Bedrock. +3. Prompt the user for their weather request. +4. Send the user input including the conversation history to the model. +5. The model processes the input and determines if a connected tool or API needs to be used. If this is the case, the model returns a tool use request with specific parameters needed to invoke the tool, and a unique tool use ID to correlate tool responses to the request. +6. The scenario application invokes the tool to fetch weather data, and append the response and tool use ID to the conversation. +7. The model uses the tool response to generate a final response. If additional tool requests are needed, the process is repeated. If the max recursion is reached, the conversation is ended. +8. Once the final response is received and printed, the application returns to the prompt. + +![img.png](toolscenario.png) + +![img.png](toolscenario.png) + +### Resources + +No additional resources are needed for this scenario. + +## Implementations + +This example is implemented in the following languages: + +- [.NET](../../../dotnetv3/Bedrock-runtime/Scenarios/ConverseToolScenario/README.md) + +## Additional resources + +- [Documentation: The Amazon Bedrock User Guide](https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html) +- [Tutorials: A developer's guide to Bedrock's new Converse API](https://community.aws/content/2dtauBCeDa703x7fDS9Q30MJoBA/amazon-bedrock-converse-api-developer-guide) +- [More examples: Amazon Bedrock code examples and scenarios in multiple programming languages](https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html) + +--- + +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 diff --git a/scenarios/features/bedrock_converse_tool/SPECIFICATION.md b/scenarios/features/bedrock_converse_tool/SPECIFICATION.md new file mode 100644 index 00000000000..474980999a9 --- /dev/null +++ b/scenarios/features/bedrock_converse_tool/SPECIFICATION.md @@ -0,0 +1,246 @@ +# Bedrock Runtime Converse API with Tool Feature Scenario - Technical specification + +This document contains the technical specifications for _Bedrock Runtime Converse API with Tool Feature Scenario_, a feature scenario that showcases AWS services and SDKs. It is primarily intended for the AWS code examples team to use while developing this example in additional languages. + +This document explains the following: + +- Architecture and features of the example scenario. +- Metadata information for the scenario. +- Sample reference output. + +For an introduction, see the [README.md](README.md). + +--- + +### Table of contents + +- [User Input](#user-input) +- [Example Output](#example-output) +- [Errors](#errors) +- [Metadata](#metadata) + +## User Input + +The user's input is used as the starting point for the Bedrock Runtime conversation, and each response is added to an array of messages. +The model should respond when it needs to invoke the tool, and the application should run the tool and append the response to the conversation. +This process can be repeated as needed until a maximum number of recursions (5). See the .NET implementation for an example of the processing of the messages. Following is an example of how the conversation could go: + +1. Greet the user and provide an overview of the application. +1. Handle the user's weather information request: + 1. The user requests weather information. This request is sent to the Bedrock model. + 2. The model response includes a tool request, with a latitude and longitude to provide to the tool. + 3. The application then uses the Weather_Tool to retrieve the current weather data for those coordinates, and appends that response as a tool response to the conversation. The conversation is sent back to the model. + 4. The model responds with either a final response, or a request for more information. The process repeats. + 5. The application prints the final response. +1. Any off topic requests should be handled according to the system prompt. This prompt is provided below. +1. The user can type 'x' to exit the application. + +#### System prompt +``` +You are a weather assistant that provides current weather data for user-specified locations using only +the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself. +If the user provides coordinates, infer the approximate location and refer to it in your response. +To use the tool, you strictly apply the provided tool specification. + +- Explain your step-by-step process, and give brief updates before each step. +- Only use the Weather_Tool for data. Never guess or make up information. +- Repeat the tool use for subsequent requests if necessary. +- If the tool errors, apologize, explain weather is unavailable, and suggest other options. +- Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use + emojis where appropriate. +- Only respond to weather queries. Remind off-topic users of your purpose. +- Never claim to search online, access external data, or use tools besides Weather_Tool. +- Complete the entire process until you have all required data before sending the complete response. +``` + +#### Weather tool specification +For strongly typed languages, you will need to use the Bedrock classes provided for tool specification. + +``` +"toolSpec": { + "name": "Weather_Tool", + "description": "Get the current weather for a given location, based on its WGS84 coordinates.", + "inputSchema": { + "json": { + "type": "object", + "properties": { + "latitude": { + "type": "string", + "description": "Geographical WGS84 latitude of the location.", + }, + "longitude": { + "type": "string", + "description": "Geographical WGS84 longitude of the location.", + }, + }, + "required": ["latitude", "longitude"], + } + }, + } +``` + + +## Example Output +``` +******************************************************************************** + Welcome to the Amazon Bedrock Tool Use demo! +******************************************************************************** + + This assistant provides current weather information for user-specified locations. + You can ask for weather details by providing the location name or coordinates. + + Example queries: + - What's the weather like in New York? + - Current weather for latitude 40.70, longitude -74.01 + - Is it warmer in Rome or Barcelona today? + + To exit the program, simply type 'x' and press Enter. + + P.S.: You're not limited to single locations, or even to using English! + Have fun and experiment with the app! + +******************************************************************************** + Your weather info request: (x to exit): + +>What's the weather like in Oklahoma City? + Calling Bedrock... + The model's response: + +Okay, let me get the current weather information for Oklahoma City: + +1) I will look up the latitude and longitude coordinates for Oklahoma City. +2) Then I will use the Weather_Tool to get the weather data for those coordinates. + + + Invoking tool: Weather_Tool with input: 35.4676, -97.5164... + + Calling Bedrock... + The model's response: + +According to the weather data, the current conditions in Oklahoma City are: + +??? Partly cloudy +Temperature: 2.7°C (36.9°F) +Wind: 22.3 km/h (13.9 mph) from the North + +The wind is breezy and it's a bit cool for this time of year in Oklahoma City. I'd recommend wearing a jacket if going outside for extended periods. + +******************************************************************************** + Your weather info request: (x to exit): + +>What's the best kind of cat? + Calling Bedrock... + The model's response: + +I'm an AI assistant focused on providing current weather information using the available Weather_Tool. I don't have any data or capabilities related to discussing different types of cats. Perhaps we could return to discussing weather conditions for a particular location? I'd be happy to look up the latest forecast if you provide a city or geographic coordinates. + +******************************************************************************** + Your weather info request: (x to exit): + +>Where is the warmest city in Oklahoma right now? + Calling Bedrock... + The model's response: + +Okay, let me see if I can find the warmest city in Oklahoma right now using the Weather_Tool: + +1) I will look up the coordinates for some major cities in Oklahoma. +2) Then I will use the Weather_Tool to get the current temperature for each city. +3) I will compare the temperatures to determine the warmest city. + + + Invoking tool: Weather_Tool with input: 35.4676, -97.5164... + + Calling Bedrock... + The model's response: + +Oklahoma City: 2.7°C + + + Invoking tool: Weather_Tool with input: 36.1539, -95.9925... + + Calling Bedrock... + The model's response: + +Tulsa: 5.5°C + +Based on the data from the Weather_Tool, the warmest major city in Oklahoma right now is Tulsa at 5.5°C (41.9°F). + +******************************************************************************** + Your weather info request: (x to exit): + +>What's the warmest city in California right now? + Calling Bedrock... + The model's response: + +OK, let me check the current temperatures in some major cities in California to find the warmest one: + + + Invoking tool: Weather_Tool with input: 34.0522, -118.2437... + + Calling Bedrock... + The model's response: + +Los Angeles: 10.6°C (51.1°F) + + + Invoking tool: Weather_Tool with input: 37.7749, -122.4194... + + Calling Bedrock... + The model's response: + + + +San Francisco: 11.6°C (52.9°F) + + + Invoking tool: Weather_Tool with input: 32.7157, -117.1611... + + Calling Bedrock... + Warning: Maximum number of recursions reached. Please try again. + The model's response: + +San Diego: 12.9°C (55.2°F) + +Based on the data from the Weather_Tool, the warmest major city in California right now appears to be San Diego at 12.9°C (55.2°F). + +******************************************************************************** + Your weather info request: (x to exit): +>x +******************************************************************************** + Thank you for checking out the Amazon Bedrock Tool Use demo. We hope you + learned something new, or got some inspiration for your own apps today! + + For more Bedrock examples in different programming languages, have a look at: + https://docs.aws.amazon.com/bedrock/latest/userguide/service_code_examples.html +******************************************************************************** + +Amazon Bedrock Converse API with Tool Use Feature Scenario is complete. +-------------------------------------------------------------------------------- + +``` +- Cleanup + - There are no resources needing cleanup in this scenario. + +--- + +## Errors +In addition to handling Bedrock Runtime errors on the Converse action, the scenario should also +handle errors related to the tool itself, such as an HTTP Request failure. + +| action | Error | Handling | +|----------------|------------------------|------------------------------------------------------| +| `Converse` | ModelNotReady | Notify the user to try again, and stop the scenario. | +| `HTTP Request` | HttpRequestException | Notify the user and stop the scenario. | + +--- + +## Metadata +For languages which already have an entry for the action, add a description for the snippet describing the scenario or action. + +| action / scenario | metadata file | metadata key | +|--------------------------------------------|--------------------------------|------------------------------------------------------| +| `Converse` | bedrock-runtime_metadata.yaml | bedrock-runtime_Converse_AmazonNovaText | +| `Tool use with the Converse API` | bedrock-runtime_metadata.yaml | bedrock-runtime_Scenario_ToolUse | +| `Scenario: Tool use with the Converse API` | bedrock-runtime_metadata.yaml | bedrock-runtime_Scenario_ToolUseDemo_AmazonNova | + + diff --git a/scenarios/features/bedrock_converse_tool/toolscenario.png b/scenarios/features/bedrock_converse_tool/toolscenario.png new file mode 100644 index 00000000000..45defe47143 Binary files /dev/null and b/scenarios/features/bedrock_converse_tool/toolscenario.png differ