A simplified framework for building and deploying sophisticated multi-agent AI systems using AWS Bedrock. This project enables seamless orchestration between specialized AI agents through AWS Bedrock Flow, maintaining conversation context and delivering coherent user experiences.
- Specialized Agent Network: Deploy multiple domain-specific agents (HR, general knowledge, etc.)
- Intelligent Orchestration: Route user queries to appropriate agents via Bedrock Flow
- Session Management: Maintain conversation history and context across agent interactions
- Serverless Architecture: Fully serverless implementation using AWS Lambda and Bedrock services
- Infrastructure as Code: Complete CloudFormation templates via Serverless Framework
- Production Ready: Includes logging, error handling, and monitoring capabilities
The system consists of:
- Specialized Bedrock Agents: Domain-specific agents with tailored knowledge and capabilities
- General Agent: Handles broad knowledge queries
- HR/Consulting Agent: Specializes in human resources topics with dedicated knowledge base
- Orchestration Agent: Coordinates between agents via Bedrock Flow
- AWS Bedrock Flow: Manages the conversation flow and agent interactions
- Lambda Functions: Process requests and handle agent communication
- API Gateway: Provides REST endpoints for client applications
- AWS CLI configured with appropriate permissions
- Node.js (v14 or later)
- Serverless Framework installed globally
- Python 3.12
- AWS Account with Bedrock access
- Clone the repository
git clone https://github.com/yourusername/multi-agent-orchestration.git
cd multi-agent-orchestration- Install dependencies
npm install
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt- Configure your environment
Create a params.dev.json file in the project root:
{
"API_NAME": "your-project-name"
}- Create your Bedrock Flow
- Create a Bedrock Flow in the AWS Console
- Update the
YOUR_FLOW_IDandYOUR_FLOW_ALIAS_IDplaceholders inserverless.ymlwith your Flow IDs
- Deploy the application
serverless deploy --stage dev --param-file params.dev.jsonThe project includes three types of agents:
-
General Agent: Handles broad knowledge queries
- Configuration:
infrastructure/ai/general_agent.yml
- Configuration:
-
Consulting/HR Agent: Specializes in human resources topics
- Configuration:
infrastructure/ai/hr_agent.yml - Includes knowledge base integration
- Configuration:
-
Orchestration Agent: Coordinates between agents
- Configuration:
infrastructure/ai/orchestration_agent.yml - Includes action group for invoking Bedrock Flow
- Configuration:
- Create a new Flow in AWS Bedrock Console
- Configure the Flow to connect your specialized agents
- Create a Flow alias
- Update the Flow IDs in
serverless.yml:
environment:
FLOW_ID: your-flow-id
FLOW_ALIAS_ID: your-flow-alias-id- Configure your Prompt Management, based on:
- LLM: amazon.nova-micro-v1:0
- Temperature: 0
- Top P: 0.9
- Maximum output tokens: 50
- Prompt:
<task> Categorize the user's message into one of two categories based on the **overall intention**. </task> <instructions> 1. Carefully read the user's message: <input>{{input}}</input> 2. Analyze the main intention expressed in the message. 3. Classification criteria: - <category>HR</category>: Messages related to human resources, such as: _ Salary _ Benefits \_ Company <category>GENERAL</category>: Messages related to general topics for internet search, which do not fit into the previous categories. 4. Respond with exactly one of the following formats: - If related to human resources: HR - If related to general topics: GENERAL </instructions> <constraints> - Provide **only** the categorized response in the specified format - Do not include explanations, comments, or additional text - Base the classification on the **main intention** of the message in {{input}} - If the message is ambiguous, classify based on the most prominent theme - For messages classified as GENERAL, the system should ask how it can help or request more details about what the user wants to discuss </constraints>- Configure your Bedrock Flow, based on:
{
"connections": [
{
"configuration": {
"data": {
"sourceOutput": "document",
"targetInput": "input"
}
},
"name": "FlowInputNodeFlowInputNode0Toprompt_routerPromptsNode0",
"source": "FlowInputNode",
"target": "prompt_router",
"type": "Data"
},
{
"configuration": {
"data": {
"sourceOutput": "modelCompletion",
"targetInput": "conditionInput"
}
},
"name": "prompt_routerPromptsNode0Tocategory_validateConditionNode0",
"source": "prompt_router",
"target": "category_validate",
"type": "Data"
},
{
"configuration": {
"conditional": {
"condition": "general_router"
}
},
"name": "category_validateConditionNodeHandle0Togeneral_agentgeneral_agentHeaderHandle",
"source": "category_validate",
"target": "general_agent",
"type": "Conditional"
},
{
"configuration": {
"data": {
"sourceOutput": "document",
"targetInput": "agentInputText"
}
},
"name": "FlowInputNodeFlowInputNode0Togeneral_agentAgentsNode0",
"source": "FlowInputNode",
"target": "general_agent",
"type": "Data"
},
{
"configuration": {
"conditional": {
"condition": "hr_router"
}
},
"name": "category_validateConditionNodeHandle1Tohr_agenthr_agentHeaderHandle",
"source": "category_validate",
"target": "hr_agent",
"type": "Conditional"
},
{
"configuration": {
"data": {
"sourceOutput": "document",
"targetInput": "agentInputText"
}
},
"name": "FlowInputNodeFlowInputNode0Tohr_agentAgentsNode0",
"source": "FlowInputNode",
"target": "hr_agent",
"type": "Data"
},
{
"configuration": {
"data": {
"sourceOutput": "agentResponse",
"targetInput": "document"
}
},
"name": "general_agentAgentsNode0Togeneral_agent_outputFlowOutputNode0",
"source": "general_agent",
"target": "general_agent_output",
"type": "Data"
},
{
"configuration": {
"data": {
"sourceOutput": "agentResponse",
"targetInput": "document"
}
},
"name": "hr_agentAgentsNode0Tohr_agent_outputFlowOutputNode0",
"source": "hr_agent",
"target": "hr_agent_output",
"type": "Data"
}
],
"nodes": [
{
"configuration": {
"input": {}
},
"name": "FlowInputNode",
"outputs": [
{
"name": "document",
"type": "String"
}
],
"type": "Input"
},
{
"configuration": {
"prompt": {
"sourceConfiguration": {
"resource": {
"promptArn": "arn:aws:bedrock:YOUR_REGION_NAME:YOUR_ACCOUNT_ID:prompt/YOUR_PROMPT_ID:3"
}
}
}
},
"inputs": [
{
"expression": "$.data",
"name": "input",
"type": "String"
}
],
"name": "prompt_router",
"outputs": [
{
"name": "modelCompletion",
"type": "String"
}
],
"type": "Prompt"
},
{
"configuration": {
"output": {}
},
"inputs": [
{
"expression": "$.data",
"name": "document",
"type": "String"
}
],
"name": "general_agent_output",
"type": "Output"
},
{
"configuration": {
"condition": {
"conditions": [
{
"expression": "conditionInput==\"GENERAL\"",
"name": "general_router"
},
{
"expression": "conditionInput==\"HR\"",
"name": "hr_router"
},
{
"name": "default"
}
]
}
},
"inputs": [
{
"expression": "$.data",
"name": "conditionInput",
"type": "String"
}
],
"name": "category_validate",
"type": "Condition"
},
{
"configuration": {
"agent": {
"agentAliasArn": "arn:aws:bedrock:YOUR_REGION_NAME:YOUR_ACCOUNT_ID:agent-alias/YOUR_AGENT_ID/YOUR_AGENT_ALIAS_ID"
}
},
"inputs": [
{
"expression": "$.data",
"name": "agentInputText",
"type": "String"
}
],
"name": "general_agent",
"outputs": [
{
"name": "agentResponse",
"type": "String"
}
],
"type": "Agent"
},
{
"configuration": {
"agent": {
"agentAliasArn": "arn:aws:bedrock:YOUR_REGION_NAME:YOUR_ACCOUNT_ID:agent-alias/YOUR_AGENT_ID/YOUR_AGENT_ALIAS_ID"
}
},
"inputs": [
{
"expression": "$.data",
"name": "agentInputText",
"type": "String"
}
],
"name": "hr_agent",
"outputs": [
{
"name": "agentResponse",
"type": "String"
}
],
"type": "Agent"
},
{
"configuration": {
"output": {}
},
"inputs": [
{
"expression": "$.data",
"name": "document",
"type": "String"
}
],
"name": "hr_agent_output",
"type": "Output"
}
]
}The deployment creates a Lambda function URL that serves as the entry point for your application:
POST /assistant_response
Request Body:
{
"session_id": "unique-session-identifier",
"prompt": "Your question or request here"
}Response:
{
"response": "Agent's response to the query"
}- User sends a query to the API endpoint
- The orchestration agent analyzes the query
- The orchestration agent invokes Bedrock Flow
- Bedrock Flow routes the query to the appropriate specialized agent
- The specialized agent processes the query and returns a response
- The response is returned to the user with maintained conversation context
- Create a new agent configuration file in
infrastructure/ai/ - Define the agent's IAM role, agent configuration, and alias
- Add the new agent to
serverless.ymlresources section - Update your Bedrock Flow to include the new agent
Modify the agent instructions in the respective YAML files:
Instruction: |
<instruction>
You are virtual AI assistant and your task is to analyze the provided context and generate a relevant response based on it.
</instruction>
<context>
Role: [Define your agent's specialized role here]
</context>
<constraints>
[Define constraints for your agent]
</constraints>
<output_format>
Response: [Insert your response here]
</output_format>The project uses AWS Lambda Powertools for Python to provide structured logging and tracing:
- Logging: Comprehensive logs for all Lambda functions
- Tracing: X-Ray integration for request tracing
- Error Handling: Standardized error responses
- IAM roles with least privilege principle
- Session management for secure user interactions
- AWS Bedrock security best practices
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Gustavo Mainchein β AI Solutions Development Specialist - LinkedIn
This project is licensed under the MIT License.
