AWS bedrock documentation change
Summary
Added detailed Java code example for Bedrock Converse API tool use scenario with weather API integration, including error handling and recursion limits
Security assessment
The changes demonstrate secure coding patterns (input validation, error handling, recursion limits) but don't address specific vulnerabilities. Security documentation is added through the system prompt's instructions about data handling and tool restrictions.
Diff
diff --git a/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_Scenario_ToolUseDemo_AmazonNova_section.md b/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_Scenario_ToolUseDemo_AmazonNova_section.md index eb5c94e5c..1a31c4862 100644 --- a//bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_Scenario_ToolUseDemo_AmazonNova_section.md +++ b//bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_Scenario_ToolUseDemo_AmazonNova_section.md @@ -7 +7 @@ -The following code example shows 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. +The following code examples show 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. @@ -54,0 +55 @@ The primary execution of the scenario flow. This scenario orchestrates the conve + If the user specifies a state, country, or region, infer the locations of cities within that state. @@ -558,0 +560,496 @@ The Converse API action with a tool configuration. +Java + + +**SDK for Java 2.x** + + +###### Note + +There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/bedrock-runtime#code-examples). + +The primary execution of the scenario flow. This scenario orchestrates the conversation between the user, the Amazon Bedrock Converse API, and a weather tool. + + + /* + This demo illustrates a tool use scenario using Amazon Bedrock's Converse API and a weather tool. + The program 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 class BedrockScenario { + public static final String DASHES = new String(new char[80]).replace("\0", "-"); + private static String modelId = "amazon.nova-lite-v1:0"; + private static String defaultPrompt = "What is the weather like in Seattle?"; + private static WeatherTool weatherTool = new WeatherTool(); + + // The maximum number of recursive calls allowed in the tool use function. + // This helps prevent infinite loops and potential performance issues. + private static int maxRecursions = 5; + static BedrockActions bedrockActions = new BedrockActions(); + public static boolean interactive = true; + + private static final String systemPrompt = """ + 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. + """; + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + System.out.println(""" + ================================================= + 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! + """); + System.out.println(DASHES); + + try { + runConversation(scanner); + + } catch (Exception ex) { + System.out.println("There was a problem running the scenario: " + ex.getMessage()); + } + + waitForInputToContinue(scanner); + + System.out.println(DASHES); + System.out.println("Amazon Bedrock Converse API with Tool Use Feature Scenario is complete."); + System.out.println(DASHES); + } + + /** + * Starts the conversation with the user and handles the interaction with Bedrock. + */ + private static List<Message> runConversation(Scanner scanner) { + List<Message> conversation = new ArrayList<>(); + + // Get the first user input + String userInput = getUserInput("Your weather info request:", scanner); + System.out.println(userInput); + + while (userInput != null) { + ContentBlock block = ContentBlock.builder() + .text(userInput) + .build(); + + List<ContentBlock> blockList = new ArrayList<>(); + blockList.add(block); + + Message message = Message.builder() + .role(ConversationRole.USER) + .content(blockList) + .build(); + + conversation.add(message); + + // Send the conversation to Amazon Bedrock. + ConverseResponse bedrockResponse = sendConversationToBedrock(conversation); + + // Recursively handle the model's response until the model has returned its final response or the recursion counter has reached 0. + processModelResponse(bedrockResponse, conversation, maxRecursions); + + // Repeat the loop until the user decides to exit the application. + userInput = getUserInput("Your weather info request:", scanner); + } + printFooter(); + return conversation; + } + + /** + * Processes the response from the model and updates the conversation accordingly. + * + * @param modelResponse the response from the model + * @param conversation the ongoing conversation + * @param maxRecursion the maximum number of recursions allowed + */ + private static void processModelResponse(ConverseResponse modelResponse, List<Message> conversation, int maxRecursion) { + if (maxRecursion <= 0) { + // Stop the process, the number of recursive calls could indicate an infinite loop + System.out.println("\tWarning: Maximum number of recursions reached. Please try again."); + } + + // Append the model's response to the ongoing conversation + conversation.add(modelResponse.output().message()); + + String modelResponseVal = modelResponse.stopReasonAsString(); + if (modelResponseVal.compareTo("tool_use") == 0) { + // If the stop reason is "tool_use", forward everything to the tool use handler + handleToolUse(modelResponse.output(), conversation, maxRecursion - 1); + } + + if (modelResponseVal.compareTo("end_turn") == 0) { + // If the stop reason is "end_turn", print the model's response text, and finish the process + PrintModelResponse(modelResponse.output().message().content().get(0).text()); + if (!interactive) { + defaultPrompt = "x"; + } + } + } + + /** + * Handles the use of a tool by the model in a conversation. + * + * @param modelResponse the response from the model, which may include a tool use request + * @param conversation the current conversation, which will be updated with the tool use results + * @param maxRecursion the maximum number of recursive calls allowed to handle the model's response + */ + private static void handleToolUse(ConverseOutput modelResponse, List<Message> conversation, int maxRecursion) { + List<ContentBlock> toolResults = new ArrayList<>(); + + // The model's response can consist of multiple content blocks + for (ContentBlock contentBlock : modelResponse.message().content()) { + if (contentBlock.text() != null && !contentBlock.text().isEmpty()) { + // If the content block contains text, print it to the console + PrintModelResponse(contentBlock.text()); + } + + if (contentBlock.toolUse() != null) { + ToolResponse toolResponse = invokeTool(contentBlock.toolUse()); + + // Add the tool use ID and the tool's response to the list of results + List<ToolResultContentBlock> contentBlockList = new ArrayList<>(); + ToolResultContentBlock block = ToolResultContentBlock.builder() + .json(toolResponse.getContent()) + .build(); + contentBlockList.add(block); + + ToolResultBlock toolResultBlock = ToolResultBlock.builder() + .toolUseId(toolResponse.getToolUseId()) + .content(contentBlockList) + .build(); + + ContentBlock contentBlock1 = ContentBlock.builder() + .toolResult(toolResultBlock) + .build(); + + toolResults.add(contentBlock1); + }