Automate Prompt Flow Creation in Amazon Bedrock Using .NET

Introduction

Amazon Bedrock Flows enables you to build and orchestrate AI workflows using a visual builder, seamlessly integrating with Amazon Bedrock services like foundational models, knowledge bases, and prompt management. It also connects with other AWS services, such as AWS Lambda and Amazon S3. In this article, you’ll learn how to automate the creation of a flow with a single prompt in Amazon Bedrock using the .NET console application. Specifically, we’ll generate a music playlist based on genre and the number of songs requested.

Amazon Bedrock

Prerequisites

  1. AWS account and the required permissions to access Amazon Bedrock.
  2. Access to Amazon Bedrock foundation model to validate the prompt flow.
  3. Install or update to the latest version of the AWS CLI.
  4. Get credentials to grant programmatic access.
  5. Visual Studio 2022.
  6. Install and set up the AWS Toolkit for Visual Studio.
  7. A service role to create and manage a flow in Amazon Bedrock

Steps Involved

Perform the following steps to create a flow in Amazon Bedrock flow using the .NET console application.

  1. Open Visual Studio 2022.
  2. Click File -> New -> Project.
  3. Select the Console App template. Click Next.
  4. Enter the project name and click Next.
  5. Select the .NET 8.0 framework. Click Create.
  6. Add the following NuGet packages.
    AWSSDK.BedrockAgent
  7. Open Program.cs and replace the code with the following.
    using Amazon;
    using Amazon.BedrockAgent;
    using Amazon.BedrockAgent.Model;
    using Amazon.BedrockRuntime;
    
    namespace AmazonBedrockCreateFlow
    {
        internal class Program
        {        
            static async Task Main(string[] args)
            {
                try
                {
                    // Initialize Bedrock client for flow creation
                    using var client = new AmazonBedrockAgentClient(RegionEndpoint.USEast1);
    
                    // Create a flow definition
                    FlowDefinition flowDefinition = CreateFlowDefinition();
    
                    // Create a request to create the flow with the provided definition
                    var request = new CreateFlowRequest
                    {
                        Name = "MakePlaylist5", // Set the name for the flow
                        Description = "Make a playlist5", // Add description
                        Definition = flowDefinition, // Assign the flow definition created above
                        ExecutionRoleArn = "arn:aws:iam::654654320368:role/AmazonBedrockFlowServiceRole" // Role with the necessary permissions
                    };
    
                    // Create the flow and capture the response
                    var response = await client.CreateFlowAsync(request);
    
                    if (response.Status == FlowStatus.NotPrepared)
                    {
                        Console.WriteLine("Flow created successfully!");
                        Console.WriteLine($"Flow Arn: {response.Arn}");
    
                        // Prepare the flow for execution (DRAFT version)
                        await PrepareFlow(client, response);
    
                        // Create a new version for the flow
                        CreateFlowVersionResponse createFlowVersionResponse = await CreateFlowVersion(client, response);
    
                        // Create an alias for the created version (e.g., for dev environment)
                        await CreateFlowAlias(client, response, createFlowVersionResponse);
                    }
                    else
                    {
                        // Output error if flow creation fails
                        Console.WriteLine($"Flow creation failed with status: {response.Status}");
                    }
                }
                catch (Exception ex)
                {
                    // Catch and log any exception that occurs during the process
                    Console.WriteLine($"An error occurred: {ex.Message}");
                }
            }
    
            // Method to create a flow alias after a version is created
            private static async Task CreateFlowAlias(AmazonBedrockAgentClient client, CreateFlowResponse response, CreateFlowVersionResponse createFlowVersionResponse)
            {
                try
                {
                    // Creating a flow alias pointing to the specified version
                    await client.CreateFlowAliasAsync(new CreateFlowAliasRequest
                    {
                        FlowIdentifier = response.Id, // Flow ID
                        Name = "dev", // Alias name (e.g., dev, prod)
                        RoutingConfiguration = new List<FlowAliasRoutingConfigurationListItem>
                        {
                            new FlowAliasRoutingConfigurationListItem
                            {
                                FlowVersion = createFlowVersionResponse.Version // Associate the version with the alias
                            }
                        }
                    });
    
                    Console.WriteLine("Flow alias created successfully!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error creating flow alias: {ex.Message}");
                }
            }
    
            // Method to create a new version of the flow
            private static async Task<CreateFlowVersionResponse> CreateFlowVersion(AmazonBedrockAgentClient client, CreateFlowResponse response)
            {
                try
                {
                    // Create a new version of the flow
                    return await client.CreateFlowVersionAsync(new CreateFlowVersionRequest()
                    {
                        FlowIdentifier = response.Id,
                        Description = "Create Flow Version"
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error creating flow version: {ex.Message}");
                    throw;
                }
            }
    
            // Method to prepare the flow (required before invoking the flow for testing)
            private static async Task PrepareFlow(AmazonBedrockAgentClient client, CreateFlowResponse response)
            {
                try
                {
                    // Prepare the flow so that it can be invoked for testing (DRAFT version)
                    await client.PrepareFlowAsync(new PrepareFlowRequest { FlowIdentifier = response.Id });
                    Console.WriteLine("Flow prepared for execution.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error preparing flow: {ex.Message}");
                    throw;
                }
            }
    
            // Method to define and create a flow definition with nodes and connections
            private static FlowDefinition CreateFlowDefinition()
            {
                // Define the flow structure including nodes and their configurations
                var flowDefinition = new FlowDefinition()
                {
                    Nodes = new List<FlowNode>
                    {
                        // Input node for taking data
                        new FlowNode
                        {
                            Name = "FlowInput",
                            Type = FlowNodeType.Input,
                            Configuration = new FlowNodeConfiguration
                            {
                                Input = new InputFlowNodeConfiguration()
                            },
                            Outputs = new List<FlowNodeOutput>
                            {
                                new FlowNodeOutput { Name = "document", Type = FlowNodeIODataType.Object }
                            }
                        },
                        // Prompt node for generating playlist
                        new FlowNode
                        {
                            Name = "MakePlaylist",
                            Type = FlowNodeType.Prompt,
                            Configuration = new FlowNodeConfiguration
                            {
                                Prompt = new PromptFlowNodeConfiguration
                                {
                                    SourceConfiguration = new PromptFlowNodeSourceConfiguration
                                    {
                                        Inline = new PromptFlowNodeInlineConfiguration
                                        {
                                            ModelId = "anthropic.claude-3-5-sonnet-20240620-v1:0",
                                            TemplateConfiguration = new PromptTemplateConfiguration()
                                            {
                                                Text = new TextPromptTemplateConfiguration()
                                                {
                                                    Text = "Make me a {{genre}} playlist consisting of the following number of songs: {{number}}.",
                                                    InputVariables = new List<PromptInputVariable>()
                                                    {
                                                        new PromptInputVariable() { Name = "genre" },
                                                        new PromptInputVariable() { Name = "number" }
                                                    }
                                                }
                                            },
                                            TemplateType = "TEXT",
                                            InferenceConfiguration = new PromptInferenceConfiguration()
                                            {
                                                Text = new PromptModelInferenceConfiguration()
                                                {
                                                    MaxTokens = 2000,
                                                    Temperature = 0.5F,
                                                    TopP = 0.5F
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                            Inputs = new List<FlowNodeInput>
                            {
                                new FlowNodeInput { Name = "genre", Type = FlowNodeIODataType.String, Expression = "$.data.genre" },
                                new FlowNodeInput { Name = "number", Type = FlowNodeIODataType.Number, Expression = "$.data.number" }
                            },
                            Outputs = new List<FlowNodeOutput>
                            {
                                new FlowNodeOutput { Name = "modelCompletion", Type = FlowNodeIODataType.String }
                            }
                        },
                        // Output node for returning results
                        new FlowNode
                        {
                            Name = "FlowOutputNode",
                            Type = FlowNodeType.Output,
                            Configuration = new FlowNodeConfiguration
                            {
                                Output = new OutputFlowNodeConfiguration()
                            },
                            Inputs = new List<FlowNodeInput>
                            {
                                new FlowNodeInput { Name = "document", Type = FlowNodeIODataType.String, Expression = "$.data" }
                            }
                        }
                    },
                    Connections = new List<FlowConnection>
                    {
                        // Connect the input to the prompt (genre)
                        new FlowConnection
                        {
                            Name = "input1ToPrompt",
                            Source = "FlowInput",
                            Target = "MakePlaylist",
                            Type = FlowConnectionType.Data,
                            Configuration = new FlowConnectionConfiguration
                            {
                                Data = new FlowDataConnectionConfiguration
                                {
                                    SourceOutput = "document",
                                    TargetInput = "genre"
                                }
                            }
                        },
                        // Connect the input to the prompt (number)
                        new FlowConnection
                        {
                            Name = "input2ToPrompt",
                            Source = "FlowInput",
                            Target = "MakePlaylist",
                            Type = FlowConnectionType.Data,
                            Configuration = new FlowConnectionConfiguration
                            {
                                Data = new FlowDataConnectionConfiguration
                                {
                                    SourceOutput = "document",
                                    TargetInput = "number"
                                }
                            }
                        },
                        // Connect the prompt to the output
                        new FlowConnection
                        {
                            Name = "promptToOutput",
                            Source = "MakePlaylist",
                            Target = "FlowOutputNode",
                            Type = FlowConnectionType.Data,
                            Configuration = new FlowConnectionConfiguration
                            {
                                Data = new FlowDataConnectionConfiguration
                                {
                                    SourceOutput = "modelCompletion",
                                    TargetInput = "document"
                                }
                            }
                        }
                    }
                };
                return flowDefinition;
            }
        }
    }
  8. Run the application.

Validate the flow

Navigate to the Amazon Bedrock service in the AWS Console. In the left-hand navigation pane, under the Builder Tools section, click Flows and select the newly created flow. Click Edit in Flow Builder. In the Test flow section, enter the following JSON to view the response and the trace.

{
    "genre": "pop",
    "number": 3
}

References

Summary

This article describes how to automate the creation of a flow with a single prompt in Amazon Bedrock using the .NET console application.

Up Next
    Ebook Download
    View all
    Learn
    View all