AWS Bedrock Knowledge Base

AWS Bedrock Agents Guide

Table of Contents


Overview

AWS Bedrock Agents are autonomous AI systems that can understand user requests, break them down into steps, interact with various tools and data sources, and execute multi-step tasks to achieve goals. They combine foundation models with the ability to take actions in the real world.

Key Capabilities: - Understand complex user requests - Plan and execute multi-step tasks - Call APIs and functions - Access knowledge bases - Use multiple tools dynamically - Maintain conversation context - Provide reasoning traces

What are Bedrock Agents?

The Agent Concept

Simple Definition: An agent is an AI that can think, plan, and act to accomplish tasks, not just answer questions.

Analogy:

Traditional Chatbot (Q&A):
User: "What's the weather?"
Bot: "I don't have access to weather data"
❌ Can only respond with what it knows

Bedrock Agent:
User: "What's the weather?"
Agent: [Thinks] "I need weather data"
      → [Plans] "I'll call the weather API"
      → [Acts] Calls weather API
      → [Responds] "It's 72°F and sunny"
✅ Can take actions to get information

How Agents Work

Agents follow a ReAct pattern (Reasoning + Acting):

1. REASON: Understand what the user wants
   ↓
2. PLAN: Break down into steps
   ↓
3. ACT: Execute actions (call APIs, query data)
   ↓
4. OBSERVE: See results of actions
   ↓
5. REASON: Decide next step
   ↓
6. REPEAT until goal achieved
   ↓
7. RESPOND: Provide final answer

Example Flow:

User: "Book a flight to New York for next Monday and add it to my calendar"

Agent Reasoning:
├─ Step 1: Need to search for flights
│  └─ Action: Call flight_search_api(destination="NYC", date="2024-01-22")
│  └─ Observation: Found flight UA123 at 9:00 AM, $350
│
├─ Step 2: Need to book the flight
│  └─ Action: Call book_flight_api(flight_id="UA123")
│  └─ Observation: Booking confirmed, confirmation #ABC123
│
├─ Step 3: Need to add to calendar
│  └─ Action: Call calendar_api(event="Flight to NYC", date="2024-01-22", time="9:00 AM")
│  └─ Observation: Calendar event created
│
└─ Final Response: "I've booked flight UA123 to New York on Monday at 9:00 AM 
                    ($350) and added it to your calendar. Confirmation: ABC123"

Agent vs Direct Model Invocation

Feature Direct Model Call Bedrock Agent
Capability Answer questions Take actions
Tools None APIs, functions, databases
Planning No Yes, multi-step
Memory Single turn Multi-turn conversations
Autonomy Passive Active
Use Case Q&A, generation Task automation

Example Comparison:

# Direct Model Invocation
response = bedrock.converse(
    modelId="anthropic.claude-3-sonnet-20240229-v1:0",
    messages=[{"role": "user", "content": [{"text": "Book a flight"}]}]
)
# Result: "I cannot book flights. I'm a language model..."

# Bedrock Agent
response = bedrock_agent_runtime.invoke_agent(
    agentId="AGENT123",
    agentAliasId="ALIAS456",
    sessionId="session-1",
    inputText="Book a flight to New York"
)
# Result: Agent searches flights, books one, returns confirmation

Agent Architecture

High-Level Architecture

┌─────────────────────────────────────────────────────────────┐
│                        USER INPUT                            │
│              "Book a flight and update calendar"             │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────┐
│                    BEDROCK AGENT                             │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              AGENT ORCHESTRATION                      │  │
│  │  • Reasoning (Foundation Model)                       │  │
│  │  • Planning (Break down task)                         │  │
│  │  • Decision Making (Choose actions)                   │  │
│  └──────────────────────────────────────────────────────┘  │
│                         │                                    │
│         ┌───────────────┼───────────────┐                   │
│         ▼               ▼               ▼                   │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐               │
│  │ Action   │   │Knowledge │   │  Memory  │               │
│  │ Groups   │   │  Bases   │   │ (Session)│               │
│  └──────────┘   └──────────┘   └──────────┘               │
└─────────────────────────────────────────────────────────────┘
         │               │               │
         ▼               ▼               ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│   Lambda     │ │  OpenSearch  │ │   DynamoDB   │
│  Functions   │ │   Vectors    │ │   Sessions   │
└──────────────┘ └──────────────┘ └──────────────┘
         │
         ▼
┌──────────────────────────────────────────────────┐
│         EXTERNAL SYSTEMS                          │
│  • APIs (REST, GraphQL)                          │
│  • Databases (RDS, DynamoDB)                     │
│  • AWS Services (S3, SES, SNS)                   │
│  • Third-party services                          │
└──────────────────────────────────────────────────┘

AgentCore Service

AgentCore is the underlying orchestration engine that powers Bedrock Agents. It handles:

┌─────────────────────────────────────────────────────────────┐
│                      AGENTCORE SERVICE                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │  1. ORCHESTRATION ENGINE                           │    │
│  │     • Task decomposition                           │    │
│  │     • Action selection                             │    │
│  │     • Execution flow control                       │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │  2. REASONING ENGINE                               │    │
│  │     • ReAct pattern implementation                 │    │
│  │     • Chain-of-thought reasoning                   │    │
│  │     • Decision making logic                        │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │  3. TOOL MANAGEMENT                                │    │
│  │     • Tool discovery                               │    │
│  │     • Tool invocation                              │    │
│  │     • Result processing                            │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │  4. CONTEXT MANAGEMENT                             │    │
│  │     • Session state                                │    │
│  │     • Conversation history                         │    │
│  │     • Working memory                               │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │  5. INTEGRATION LAYER                              │    │
│  │     • Foundation Model APIs                        │    │
│  │     • Knowledge Base connectors                    │    │
│  │     • Action Group handlers                        │    │
│  │     • Prompt template engine                       │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
└─────────────────────────────────────────────────────────────┘

AgentCore Responsibilities:

  1. Orchestration

    • Manages the agent's execution loop
    • Coordinates between reasoning and action
    • Handles error recovery and retries
  2. Reasoning

    • Implements ReAct (Reasoning + Acting) pattern
    • Generates plans and strategies
    • Makes decisions about which tools to use
  3. Tool Management

    • Discovers available tools (Action Groups)
    • Formats tool calls
    • Processes tool responses
  4. Context Management

    • Maintains conversation state
    • Tracks what's been done
    • Manages working memory
  5. Integration

    • Connects to Foundation Models
    • Interfaces with Knowledge Bases
    • Executes Action Groups
    • Applies Prompt templates

AgentCore Execution Flow:

User Input
    ↓
┌─────────────────────────────────────┐
│  AgentCore: Pre-Processing          │
│  • Parse input                      │
│  • Load session context             │
│  • Retrieve conversation history    │
└─────────────────────────────────────┘
    ↓
┌─────────────────────────────────────┐
│  AgentCore: Orchestration Loop      │
│  ┌───────────────────────────────┐ │
│  │ 1. Reasoning Step             │ │
│  │    • Call Foundation Model    │ │
│  │    • Get next action          │ │
│  └───────────────────────────────┘ │
│           ↓                         │
│  ┌───────────────────────────────┐ │
│  │ 2. Action Execution           │ │
│  │    • Invoke tool/API          │ │
│  │    • Query Knowledge Base     │ │
│  └───────────────────────────────┘ │
│           ↓                         │
│  ┌───────────────────────────────┐ │
│  │ 3. Observation                │ │
│  │    • Process results          │ │
│  │    • Update context           │ │
│  └───────────────────────────────┘ │
│           ↓                         │
│  ┌───────────────────────────────┐ │
│  │ 4. Decision                   │ │
│  │    • Continue or finish?      │ │
│  │    • Next action?             │ │
│  └───────────────────────────────┘ │
│           ↓                         │
│  Repeat until task complete         │
└─────────────────────────────────────┘
    ↓
┌─────────────────────────────────────┐
│  AgentCore: Post-Processing         │
│  • Format final response            │
│  • Save session state               │
│  • Generate trace logs              │
└─────────────────────────────────────┘
    ↓
Response to User

Agent Components

1. Foundation Model (Brain)

The LLM that powers the agent's reasoning:

agent_config = {
    'foundationModel': 'anthropic.claude-3-sonnet-20240229-v1:0',
    'instruction': '''You are a helpful travel assistant.

    Your capabilities:
    - Search for flights
    - Book hotels
    - Check weather
    - Provide travel recommendations

    Always be helpful and confirm actions before executing them.'''
}

Supported Models: - Anthropic Claude 3 (Opus, Sonnet, Haiku) - Anthropic Claude 2.x - Amazon Titan models

2. Instructions (Agent Prompt)

The system prompt that defines the agent's behavior:

instructions = '''You are a customer service agent for TechCorp.

Your role:
- Help customers with product questions
- Process returns and refunds
- Escalate complex issues to human agents

Guidelines:
- Always be polite and professional
- Verify customer identity before accessing account info
- Provide order numbers in responses
- If unsure, ask clarifying questions

Available tools:
- search_orders: Find customer orders
- process_refund: Issue refunds
- check_inventory: Check product availability
- create_ticket: Escalate to support team'''

3. Action Groups (Tools/Functions)

Functions the agent can call to take actions:

action_group = {
    'actionGroupName': 'OrderManagement',
    'description': 'Manage customer orders',
    'actionGroupExecutor': {
        'lambda': 'arn:aws:lambda:us-east-1:ACCOUNT:function:order-handler'
    },
    'apiSchema': {
        's3': {
            's3BucketName': 'my-api-schemas',
            's3ObjectKey': 'order-api-schema.json'
        }
    }
}

4. Knowledge Bases (Memory/Context)

Access to company documents and data:

knowledge_base_config = {
    'knowledgeBaseId': 'KB123456',
    'description': 'Product documentation and FAQs',
    'knowledgeBaseState': 'ENABLED'
}

5. Guardrails (Safety)

Content filtering and safety controls:

guardrail_config = {
    'guardrailIdentifier': 'GUARDRAIL123',
    'guardrailVersion': '1'
}

How Agents Work with Bedrock APIs

Agents with Invoke API

Agents use the Invoke API internally to call foundation models for reasoning:

User Request
    ↓
AgentCore receives input
    ↓
┌─────────────────────────────────────┐
│  AgentCore calls Invoke API         │
│                                     │
│  bedrock.invoke_model(              │
│      modelId="claude-3-sonnet",     │
│      body={                         │
│          "messages": [              │
│              {                      │
│                  "role": "user",    │
│                  "content": prompt  │
│              }                      │
│          ],                         │
│          "tools": [                 │
│              {tool definitions}     │
│          ]                          │
│      }                              │
│  )                                  │
└─────────────────────────────────────┘
    ↓
Model returns: "I should call search_flights tool"
    ↓
AgentCore executes tool
    ↓
AgentCore calls Invoke API again with results
    ↓
Model returns: "Here's the flight information..."

How it works:

# AgentCore internal flow (simplified)
class AgentCore:
    def execute_agent(self, user_input):
        context = self.load_session_context()

        # Reasoning loop
        while not task_complete:
            # 1. Call Invoke API for reasoning
            prompt = self.build_prompt(user_input, context, available_tools)

            model_response = bedrock_runtime.invoke_model(
                modelId=self.agent.foundation_model,
                body=json.dumps({
                    "anthropic_version": "bedrock-2023-05-31",
                    "messages": prompt,
                    "tools": self.get_tool_definitions(),
                    "max_tokens": 4096
                })
            )

            # 2. Parse model response
            response = json.loads(model_response['body'].read())

            # 3. Check if model wants to use a tool
            if response.get('stop_reason') == 'tool_use':
                tool_call = response['content'][0]

                # 4. Execute the tool
                tool_result = self.execute_tool(
                    tool_call['name'],
                    tool_call['input']
                )

                # 5. Add result to context
                context.append({
                    'role': 'user',
                    'content': [{
                        'type': 'tool_result',
                        'tool_use_id': tool_call['id'],
                        'content': tool_result
                    }]
                })

                # Loop continues with tool result
            else:
                # Task complete
                task_complete = True
                final_response = response['content'][0]['text']

        return final_response

Agents with Converse API

Agents can also use the Converse API for standardized model interaction:

# AgentCore using Converse API
class AgentCoreWithConverse:
    def reasoning_step(self, messages, tools):
        """
        Use Converse API for reasoning
        """
        response = bedrock_runtime.converse(
            modelId=self.agent.foundation_model,
            messages=messages,
            toolConfig={
                'tools': tools,
                'toolChoice': {'auto': {}}  # Let model decide
            },
            inferenceConfig={
                'temperature': 0.7,
                'maxTokens': 4096
            }
        )

        return response

    def execute_agent_with_converse(self, user_input):
        """
        Agent execution using Converse API
        """
        messages = [
            {
                'role': 'user',
                'content': [{'text': user_input}]
            }
        ]

        # Define available tools
        tools = [
            {
                'toolSpec': {
                    'name': 'search_flights',
                    'description': 'Search for available flights',
                    'inputSchema': {
                        'json': {
                            'type': 'object',
                            'properties': {
                                'origin': {'type': 'string'},
                                'destination': {'type': 'string'},
                                'date': {'type': 'string'}
                            },
                            'required': ['origin', 'destination', 'date']
                        }
                    }
                }
            }
        ]

        # Reasoning loop
        while True:
            # Call Converse API
            response = self.reasoning_step(messages, tools)

            # Check stop reason
            stop_reason = response['stopReason']

            if stop_reason == 'tool_use':
                # Model wants to use a tool
                for content in response['output']['message']['content']:
                    if 'toolUse' in content:
                        tool_use = content['toolUse']

                        # Execute tool
                        tool_result = self.execute_tool(
                            tool_use['name'],
                            tool_use['input']
                        )

                        # Add assistant message
                        messages.append(response['output']['message'])

                        # Add tool result
                        messages.append({
                            'role': 'user',
                            'content': [{
                                'toolResult': {
                                    'toolUseId': tool_use['toolUseId'],
                                    'content': [{'text': json.dumps(tool_result)}]
                                }
                            }]
                        })

            elif stop_reason == 'end_turn':
                # Task complete
                final_text = response['output']['message']['content'][0]['text']
                return final_text

Benefits of Converse API for Agents: - ✅ Standardized interface across models - ✅ Built-in tool calling support - ✅ Cleaner message format - ✅ Better error handling - ✅ Easier to switch models

Agents with Knowledge Bases

Agents integrate with Knowledge Bases for RAG (Retrieval-Augmented Generation):

User: "What's our return policy?"
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Reasoning                       │
│  "I need to check company policies"         │
└─────────────────────────────────────────────┘
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Query Knowledge Base            │
│                                             │
│  kb_results = retrieve(                     │
│      knowledgeBaseId="KB123",               │
│      query="return policy"                  │
│  )                                          │
└─────────────────────────────────────────────┘
    ↓
Retrieved: "Customers can return items within 30 days..."
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Reasoning with Context          │
│  "Based on the policy document..."          │
└─────────────────────────────────────────────┘
    ↓
Response: "According to our policy, you can return 
          items within 30 days with receipt..."

Configuration:

# Create agent with Knowledge Base
agent_config = {
    'agentName': 'customer-support-agent',
    'foundationModel': 'anthropic.claude-3-sonnet-20240229-v1:0',
    'instruction': 'You are a customer support agent. Use the knowledge base to answer questions.',
    'knowledgeBases': [
        {
            'knowledgeBaseId': 'KB123456',
            'description': 'Company policies and product documentation',
            'knowledgeBaseState': 'ENABLED'
        }
    ]
}

# Agent automatically queries KB when needed
response = bedrock_agent_runtime.invoke_agent(
    agentId='AGENT123',
    agentAliasId='ALIAS456',
    sessionId='session-1',
    inputText='What is the warranty period?'
)

# Agent will:
# 1. Recognize it needs product information
# 2. Query the Knowledge Base
# 3. Use retrieved context to answer
# 4. Cite sources

How AgentCore Uses Knowledge Bases:

class AgentCoreKBIntegration:
    def should_query_kb(self, user_query, agent_reasoning):
        """
        AgentCore decides if KB query is needed
        """
        # Model indicates it needs information
        if "I need to check" in agent_reasoning or \
           "Let me look up" in agent_reasoning:
            return True
        return False

    def query_knowledge_base(self, kb_id, query):
        """
        AgentCore queries KB
        """
        response = bedrock_agent_runtime.retrieve(
            knowledgeBaseId=kb_id,
            retrievalQuery={'text': query},
            retrievalConfiguration={
                'vectorSearchConfiguration': {
                    'numberOfResults': 5
                }
            }
        )

        # Extract relevant context
        context = []
        for result in response['retrievalResults']:
            context.append({
                'content': result['content']['text'],
                'source': result['location']['s3Location']['uri'],
                'score': result['score']
            })

        return context

    def agent_with_kb(self, user_input):
        """
        Agent execution with KB integration
        """
        # Initial reasoning
        reasoning = self.call_model(user_input)

        # Check if KB query needed
        if self.should_query_kb(user_input, reasoning):
            # Query KB
            kb_context = self.query_knowledge_base(
                self.agent.knowledge_base_id,
                user_input
            )

            # Add context to prompt
            enhanced_prompt = f"""
            Based on this information from our knowledge base:

            {json.dumps(kb_context, indent=2)}

            User question: {user_input}

            Provide an accurate answer and cite your sources.
            """

            # Reason with context
            final_response = self.call_model(enhanced_prompt)

            return final_response
        else:
            return reasoning

Automatic KB Integration:

When you add a Knowledge Base to an agent, AgentCore automatically:

  1. Detects when KB is needed

    • Analyzes user query
    • Checks if information is in agent's instructions
    • Decides to query KB
  2. Retrieves relevant information

    • Converts query to embeddings
    • Searches vector store
    • Ranks results by relevance
  3. Augments the prompt

    • Adds retrieved context
    • Maintains source attribution
    • Formats for model consumption
  4. Generates response

    • Model uses KB context
    • Cites sources
    • Provides accurate information

Agents with Flows

Agents can invoke Bedrock Flows for complex, multi-step workflows:

User: "Generate a marketing report for Q4"
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Reasoning                       │
│  "This requires a multi-step workflow"      │
└─────────────────────────────────────────────┘
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Invoke Flow                     │
│                                             │
│  flow_result = invoke_flow(                 │
│      flowId="FLOW123",                      │
│      inputs={                               │
│          "quarter": "Q4",                   │
│          "year": "2024"                     │
│      }                                      │
│  )                                          │
└─────────────────────────────────────────────┘
    ↓
Flow executes:
  1. Retrieve sales data
  2. Analyze trends
  3. Generate charts
  4. Create summary
    ↓
┌─────────────────────────────────────────────┐
│  AgentCore: Process Flow Results           │
│  "Flow completed successfully"              │
└─────────────────────────────────────────────┘
    ↓
Response: "Here's your Q4 marketing report..."

Integration Pattern:

# Define Flow as an Action Group
action_group_with_flow = {
    'actionGroupName': 'ReportGeneration',
    'description': 'Generate various reports using flows',
    'actionGroupExecutor': {
        'lambda': 'arn:aws:lambda:us-east-1:ACCOUNT:function:flow-invoker'
    },
    'apiSchema': {
        's3': {
            's3BucketName': 'my-schemas',
            's3ObjectKey': 'report-flow-schema.json'
        }
    }
}

# Lambda function that invokes Flow
def lambda_handler(event, context):
    """
    Lambda that bridges Agent and Flow
    """
    action = event['actionGroup']
    function = event['function']
    parameters = event.get('parameters', [])

    if function == 'generate_report':
        # Extract parameters
        report_type = next(p['value'] for p in parameters if p['name'] == 'report_type')
        period = next(p['value'] for p in parameters if p['name'] == 'period')

        # Invoke Bedrock Flow
        bedrock_agent_runtime = boto3.client('bedrock-agent-runtime')

        flow_response = bedrock_agent_runtime.invoke_flow(
            flowIdentifier='FLOW123',
            flowAliasIdentifier='ALIAS456',
            inputs=[
                {
                    'content': {
                        'document': {
                            'report_type': report_type,
                            'period': period
                        }
                    },
                    'nodeName': 'FlowInput',
                    'nodeOutputName': 'document'
                }
            ]
        )

        # Process flow results
        results = []
        for event in flow_response['responseStream']:
            if 'flowOutputEvent' in event:
                results.append(event['flowOutputEvent'])

        return {
            'messageVersion': '1.0',
            'response': {
                'actionGroup': action,
                'function': function,
                'functionResponse': {
                    'responseBody': {
                        'TEXT': {
                            'body': json.dumps(results)
                        }
                    }
                }
            }
        }

Use Cases for Agent + Flow:

  1. Complex Document Processing

    Agent receives document → Invokes processing flow
    Flow: Extract → Analyze → Summarize → Format
    Agent returns processed document
    
  2. Multi-Step Data Analysis

    Agent receives query → Invokes analysis flow
    Flow: Fetch data → Clean → Analyze → Visualize
    Agent presents insights
    
  3. Content Generation Pipeline

    Agent receives request → Invokes content flow
    Flow: Research → Outline → Draft → Review → Polish
    Agent delivers final content
    

Agents with Prompts

Agents use Managed Prompts for consistent, versioned instructions:

┌─────────────────────────────────────────────┐
│  Agent Configuration                        │
│                                             │
│  promptOverrideConfiguration: {             │
│      promptConfigurations: [                │
│          {                                  │
│              promptType: "PRE_PROCESSING",  │
│              promptIdentifier: "PROMPT123", │
│              promptVersion: "1"             │
│          },                                 │
│          {                                  │
│              promptType: "ORCHESTRATION",   │
│              promptIdentifier: "PROMPT456", │
│              promptVersion: "2"             │
│          }                                  │
│      ]                                      │
│  }                                          │
└─────────────────────────────────────────────┘

Prompt Types in Agents:

  1. Pre-Processing Prompt

    • Runs before agent reasoning
    • Cleans and formats user input
    • Extracts intent
  2. Orchestration Prompt

    • Main reasoning prompt
    • Guides agent decision-making
    • Defines tool usage patterns
  3. Knowledge Base Response Generation Prompt

    • Used when generating responses from KB results
    • Formats citations
    • Structures answers
  4. Post-Processing Prompt

    • Runs after agent reasoning
    • Formats final response
    • Adds disclaimers or context

Example Configuration:

# Create managed prompts for agent
pre_processing_prompt = bedrock_agent.create_prompt(
    name='agent-pre-processing',
    variants=[{
        'name': 'default',
        'templateType': 'TEXT',
        'templateConfiguration': {
            'text': {
                'text': '''Clean and structure the user input.

User input: {{user_input}}

Extract:
- Intent: What does the user want?
- Entities: Key information (dates, names, etc.)
- Context: Any relevant background

Structured input:'''
            }
        },
        'modelId': 'anthropic.claude-3-sonnet-20240229-v1:0'
    }]
)

orchestration_prompt = bedrock_agent.create_prompt(
    name='agent-orchestration',
    variants=[{
        'name': 'default',
        'templateType': 'TEXT',
        'templateConfiguration': {
            'text': {
                'text': '''You are a helpful agent with access to tools.

Available tools:
{{tools}}

User request: {{user_request}}

Think step by step:
1. What information do I need?
2. Which tools should I use?
3. In what order?

Decide your next action:'''
            }
        },
        'modelId': 'anthropic.claude-3-sonnet-20240229-v1:0'
    }]
)

# Use in agent
agent_config = {
    'agentName': 'my-agent',
    'foundationModel': 'anthropic.claude-3-sonnet-20240229-v1:0',
    'promptOverrideConfiguration': {
        'promptConfigurations': [
            {
                'promptType': 'PRE_PROCESSING',
                'promptIdentifier': pre_processing_prompt['id'],
                'promptVersion': '1',
                'inferenceConfiguration': {
                    'temperature': 0.3,
                    'maxTokens': 500
                }
            },
            {
                'promptType': 'ORCHESTRATION',
                'promptIdentifier': orchestration_prompt['id'],
                'promptVersion': '1',
                'inferenceConfiguration': {
                    'temperature': 0.7,
                    'maxTokens': 2000
                }
            }
        ]
    }
}

Benefits of Managed Prompts with Agents:

Creating Your First Agent

Step 1: Define Agent Configuration

import boto3
import json

bedrock_agent = boto3.client('bedrock-agent', region_name='us-east-1')

# Create agent
agent_response = bedrock_agent.create_agent(
    agentName='customer-support-agent',
    description='Handles customer inquiries and support requests',
    foundationModel='anthropic.claude-3-sonnet-20240229-v1:0',
    instruction='''You are a helpful customer support agent for TechCorp.

Your responsibilities:
- Answer product questions
- Help with order tracking
- Process returns and refunds
- Escalate complex issues

Guidelines:
- Always be polite and professional
- Verify customer information before accessing accounts
- Provide clear, step-by-step instructions
- If unsure, ask clarifying questions

When you need information:
- Use search_orders to find order details
- Use check_inventory for product availability
- Use process_refund to issue refunds
- Use create_ticket to escalate issues''',
    idleSessionTTLInSeconds=600
)

agent_id = agent_response['agent']['agentId']
print(f"Agent created: {agent_id}")

Step 2: Create Action Groups

# Define API schema
api_schema = {
    "openapi": "3.0.0",
    "info": {
        "title": "Customer Support API",
        "version": "1.0.0"
    },
    "paths": {
        "/search_orders": {
            "post": {
                "summary": "Search customer orders",
                "description": "Find orders by customer email or order number",
                "operationId": "search_orders",
                "requestBody": {
                    "required": True,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "customer_email": {
                                        "type": "string",
                                        "description": "Customer email address"
                                    },
                                    "order_number": {
                                        "type": "string",
                                        "description": "Order number"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Order details",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "orders": {
                                            "type": "array",
                                            "items": {
                                                "type": "object"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/process_refund": {
            "post": {
                "summary": "Process a refund",
                "description": "Issue a refund for an order",
                "operationId": "process_refund",
                "requestBody": {
                    "required": True,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "order_number": {
                                        "type": "string",
                                        "description": "Order number to refund"
                                    },
                                    "amount": {
                                        "type": "number",
                                        "description": "Refund amount"
                                    },
                                    "reason": {
                                        "type": "string",
                                        "description": "Reason for refund"
                                    }
                                },
                                "required": ["order_number", "amount"]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Refund processed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "refund_id": {"type": "string"},
                                        "status": {"type": "string"}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

# Upload schema to S3
s3 = boto3.client('s3')
s3.put_object(
    Bucket='my-agent-schemas',
    Key='customer-support-api.json',
    Body=json.dumps(api_schema)
)

# Create action group
action_group_response = bedrock_agent.create_agent_action_group(
    agentId=agent_id,
    agentVersion='DRAFT',
    actionGroupName='CustomerSupportActions',
    description='Actions for customer support operations',
    actionGroupExecutor={
        'lambda': 'arn:aws:lambda:us-east-1:ACCOUNT:function:customer-support-handler'
    },
    apiSchema={
        's3': {
            's3BucketName': 'my-agent-schemas',
            's3ObjectKey': 'customer-support-api.json'
        }
    }
)

print(f"Action group created: {action_group_response['agentActionGroup']['actionGroupId']}")

Step 3: Create Lambda Function for Actions

# Lambda function: customer-support-handler
import json
import boto3

dynamodb = boto3.resource('dynamodb')
orders_table = dynamodb.Table('Orders')

def lambda_handler(event, context):
    """
    Handle agent action requests
    """
    agent = event['agent']
    action_group = event['actionGroup']
    function = event['function']
    parameters = event.get('parameters', [])

    print(f"Agent: {agent}, Action: {action_group}, Function: {function}")

    # Route to appropriate function
    if function == 'search_orders':
        return search_orders(parameters)
    elif function == 'process_refund':
        return process_refund(parameters)
    else:
        return {
            'messageVersion': '1.0',
            'response': {
                'actionGroup': action_group,
                'function': function,
                'functionResponse': {
                    'responseBody': {
                        'TEXT': {
                            'body': json.dumps({'error': 'Unknown function'})
                        }
                    }
                }
            }
        }

def search_orders(parameters):
    """
    Search for customer orders
    """
    # Extract parameters
    customer_email = next((p['value'] for p in parameters if p['name'] == 'customer_email'), None)
    order_number = next((p['value'] for p in parameters if p['name'] == 'order_number'), None)

    # Query DynamoDB
    if order_number:
        response = orders_table.get_item(Key={'order_number': order_number})
        orders = [response.get('Item', {})] if 'Item' in response else []
    elif customer_email:
        response = orders_table.query(
            IndexName='CustomerEmailIndex',
            KeyConditionExpression='customer_email = :email',
            ExpressionAttributeValues={':email': customer_email}
        )
        orders = response.get('Items', [])
    else:
        orders = []

    # Return response
    return {
        'messageVersion': '1.0',
        'response': {
            'actionGroup': 'CustomerSupportActions',
            'function': 'search_orders',
            'functionResponse': {
                'responseBody': {
                    'TEXT': {
                        'body': json.dumps({
                            'orders': orders,
                            'count': len(orders)
                        })
                    }
                }
            }
        }
    }

def process_refund(parameters):
    """
    Process a refund
    """
    order_number = next(p['value'] for p in parameters if p['name'] == 'order_number')
    amount = float(next(p['value'] for p in parameters if p['name'] == 'amount'))
    reason = next((p['value'] for p in parameters if p['name'] == 'reason'), 'Customer request')

    # Process refund (simplified)
    refund_id = f"REF-{order_number}-{int(time.time())}"

    # Update order in DynamoDB
    orders_table.update_item(
        Key={'order_number': order_number},
        UpdateExpression='SET refund_status = :status, refund_id = :refund_id, refund_amount = :amount',
        ExpressionAttributeValues={
            ':status': 'REFUNDED',
            ':refund_id': refund_id,
            ':amount': amount
        }
    )

    return {
        'messageVersion': '1.0',
        'response': {
            'actionGroup': 'CustomerSupportActions',
            'function': 'process_refund',
            'functionResponse': {
                'responseBody': {
                    'TEXT': {
                        'body': json.dumps({
                            'refund_id': refund_id,
                            'status': 'PROCESSED',
                            'amount': amount,
                            'order_number': order_number
                        })
                    }
                }
            }
        }
    }

Step 4: Add Knowledge Base (Optional)

# Associate knowledge base with agent
kb_response = bedrock_agent.associate_agent_knowledge_base(
    agentId=agent_id,
    agentVersion='DRAFT',
    knowledgeBaseId='KB123456',
    description='Product documentation and FAQs',
    knowledgeBaseState='ENABLED'
)

print("Knowledge base associated")

Step 5: Prepare Agent

# Prepare agent (validates configuration)
prepare_response = bedrock_agent.prepare_agent(
    agentId=agent_id
)

print(f"Agent status: {prepare_response['agentStatus']}")

Step 6: Create Agent Alias

# Create alias for deployment
alias_response = bedrock_agent.create_agent_alias(
    agentId=agent_id,
    agentAliasName='production',
    description='Production version of customer support agent'
)

agent_alias_id = alias_response['agentAlias']['agentAliasId']
print(f"Agent alias created: {agent_alias_id}")

Step 7: Invoke Agent

bedrock_agent_runtime = boto3.client('bedrock-agent-runtime', region_name='us-east-1')

def invoke_agent(agent_id, alias_id, session_id, user_input):
    """
    Invoke the agent
    """
    response = bedrock_agent_runtime.invoke_agent(
        agentId=agent_id,
        agentAliasId=alias_id,
        sessionId=session_id,
        inputText=user_input
    )

    # Process response stream
    full_response = ""
    for event in response['completion']:
        if 'chunk' in event:
            chunk = event['chunk']
            if 'bytes' in chunk:
                full_response += chunk['bytes'].decode('utf-8')

    return full_response

# Test the agent
response = invoke_agent(
    agent_id=agent_id,
    alias_id=agent_alias_id,
    session_id='test-session-1',
    user_input='I need to check the status of order #12345'
)

print(f"Agent response: {response}")