// Copyright (c) Microsoft. All rights reserved. using System.ComponentModel; using Amazon.BedrockAgent; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.Bedrock; namespace GettingStarted.BedrockAgents; /// /// This example demonstrates how to declaratively create instances of . /// public class Step07_BedrockAgent_Declarative : BaseBedrockAgentTest { /// /// Demonstrates creating and using a Bedrock Agent with using configuration settings. /// [Fact] public async Task BedrockAgentWithConfiguration() { var text = """ type: bedrock_agent name: StoryAgent description: Story Telling Agent instructions: Tell a story suitable for children about the topic provided by the user. model: id: ${BedrockAgent:FoundationModel} connection: type: bedrock agent_resource_role_arn: ${BedrockAgent:AgentResourceRoleArn} """; BedrockAgentFactory factory = new(); var agent = await factory.CreateAgentFromYamlAsync(text, configuration: TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "Cats and Dogs"); } /// /// Demonstrates loading an existing Bedrock Agent. /// [Fact] public async Task BedrockAgentWithId() { var text = """ id: ${BedrockAgent:AgentId} type: bedrock_agent """; BedrockAgentFactory factory = new(); var agent = await factory.CreateAgentFromYamlAsync(text, configuration: TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "What is Semantic Kernel?", false); } /// /// Demonstrates creating and using a Bedrock Agent with a code interpreter. /// [Fact] public async Task BedrockAgentWithCodeInterpreter() { var text = """ type: bedrock_agent name: CodeInterpreterAgent instructions: Use the code interpreter tool to answer questions which require code to be generated and executed. description: Agent with code interpreter tool. model: id: ${BedrockAgent:FoundationModel} connection: type: bedrock agent_resource_role_arn: ${BedrockAgent:AgentResourceRoleArn} tools: - type: code_interpreter """; BedrockAgentFactory factory = new(); var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "Use code to determine the values in the Fibonacci sequence that are less then the value of 101?"); } /// /// Demonstrates creating and using a Bedrock Agent with functions. /// [Fact] public async Task BedrockAgentWithFunctions() { var text = """ type: bedrock_agent name: FunctionCallingAgent instructions: Use the provided functions to answer questions about the menu. description: This agent uses the provided functions to answer questions about the menu. model: id: ${BedrockAgent:FoundationModel} connection: type: bedrock agent_resource_role_arn: ${BedrockAgent:AgentResourceRoleArn} tools: - id: Current type: function description: Provides real-time weather information. options: parameters: - name: location type: string required: true description: The location to get the weather for. - id: Forecast type: function description: Forecast weather information. options: parameters: - name: location type: string required: true description: The location to get the weather for. """; BedrockAgentFactory factory = new(); KernelPlugin plugin = KernelPluginFactory.CreateFromType(); this._kernel.Plugins.Add(plugin); var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "What is the current weather in Seattle and what is the weather forecast in Seattle?"); } /// /// Demonstrates creating and using a Bedrock Agent with a knowledge base. /// [Fact] public async Task BedrockAgentWithKnowledgeBase() { var text = """ type: bedrock_agent name: KnowledgeBaseAgent instructions: Use the provided knowledge base to answer questions. description: This agent uses the provided knowledge base to answer questions. model: id: ${BedrockAgent:FoundationModel} connection: type: bedrock agent_resource_role_arn: ${BedrockAgent:AgentResourceRoleArn} tools: - type: knowledge_base description: You will find information here. options: knowledge_base_id: ${BedrockAgent:KnowledgeBaseId} """; BedrockAgentFactory factory = new(); var agent = await factory.CreateAgentFromYamlAsync(text, new() { Kernel = this._kernel }, TestConfiguration.ConfigurationRoot); await InvokeAgentAsync(agent!, "What is Semantic Kernel?"); } public Step07_BedrockAgent_Declarative(ITestOutputHelper output) : base(output) { var builder = Kernel.CreateBuilder(); builder.Services.AddSingleton(this.Client); this._kernel = builder.Build(); } protected override async Task CreateAgentAsync(string agentName) { // Create a new agent on the Bedrock Agent service and prepare it for use var agentModel = await this.Client.CreateAndPrepareAgentAsync(this.GetCreateAgentRequest(agentName)); // Create a new kernel with plugins Kernel kernel = new(); kernel.Plugins.Add(KernelPluginFactory.CreateFromType()); // Create a new BedrockAgent instance with the agent model and the client // so that we can interact with the agent using Semantic Kernel contents. var bedrockAgent = new BedrockAgent(agentModel, this.Client, this.RuntimeClient) { Kernel = kernel, }; // Create the kernel function action group and prepare the agent for interaction await bedrockAgent.CreateKernelFunctionActionGroupAsync(); return bedrockAgent; } #region private private readonly Kernel _kernel; /// /// Invoke the agent with the user input. /// private async Task InvokeAgentAsync(Agent agent, string input, bool deleteAgent = true) { AgentThread? agentThread = null; try { await foreach (AgentResponseItem response in agent.InvokeAsync(input)) { agentThread = response.Thread; WriteAgentChatMessage(response); } } catch (Exception e) { Console.WriteLine($"Error invoking agent: {e.Message}"); } finally { if (deleteAgent) { var bedrockAgent = agent as BedrockAgent; await bedrockAgent!.Client.DeleteAgentAsync(new() { AgentId = bedrockAgent.Id }); } if (agentThread is not null) { await agentThread.DeleteAsync(); } } } private sealed class WeatherPlugin { [KernelFunction, Description("Provides real-time weather information.")] public string Current([Description("The location to get the weather for.")] string location) { return $"The current weather in {location} is 72 degrees."; } [KernelFunction, Description("Forecast weather information.")] public string Forecast([Description("The location to get the weather for.")] string location) { return $"The forecast for {location} is 75 degrees tomorrow."; } } #endregion }