An extra 30% off every course until Sunday, October 11.Choose your certification →

Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

4.1.1. Amazon Bedrock Agents and Strands Agents

💡 First Principle: Amazon Bedrock Agents manages the reasoning loop, tool orchestration, session memory, and response synthesis as a fully managed service — you define what tools exist and what the agent should accomplish, and Bedrock handles the iterative planning and execution. This eliminates thousands of lines of orchestration code.

Status: Amazon Bedrock Agents is now Amazon Bedrock Agents Classic and has been closed to new customers since July 30, 2026. Existing customers (accounts with Bedrock Agents activity in the previous 12 months) keep using it with no migration deadline or planned end-of-life date, though its model catalog is frozen at that date; other accounts get AccessDeniedException from CreateAgent, and there is no exception process. AWS points new agent builds to Amazon Bedrock AgentCore — a managed harness for config-driven agents, plus Runtime, Memory, Gateway, Identity, and Observability. The concepts below (action groups, knowledge bases, the reasoning loop, tracing) carry over to AgentCore (see 4.1.5).

Bedrock Agents architecture — the key components:
Agent configuration — what you define:
ComponentWhat It IsConfiguration
Foundation ModelThe reasoning engineChoose a supported Bedrock model (the Classic model catalog is frozen as of July 30, 2026)
InstructionsThe agent's operating mandateSystem-prompt-level instructions
Action GroupsTools the agent can callLambda functions + OpenAPI schema describing parameters
Knowledge BasesDocuments the agent can searchAttach existing Bedrock Knowledge Base
MemoryCross-session context persistenceEnable session memory (stored in managed store)
GuardrailsContent safety enforcementAttach Bedrock Guardrails configuration

Action Group definition — the exam-critical pattern: Each action group requires an OpenAPI schema that tells the agent what the tool does, what parameters it accepts, and what it returns. The agent uses this schema to decide when and how to call the tool:

# Lambda function implementing an action group tool
def lambda_handler(event, context):
    action = event['actionGroup']
    api_path = event['apiPath']
    
    if api_path == '/get-customer-orders':
        customer_id = event['requestBody']['content']['application/json']['properties'][0]['value']
        # Query DynamoDB for customer orders
        orders = query_orders(customer_id)
        return {
            'messageVersion': '1.0',
            'response': {
                'actionGroup': action,
                'apiPath': api_path,
                'httpMethod': event['httpMethod'],
                'httpStatusCode': 200,
                'responseBody': {'application/json': {'body': json.dumps(orders)}}
            }
        }
Action group Lambda rules that decide scenarios:
  • Return the action-group response schema. The agent can use a result only when the Lambda returns messageVersion plus a response object (actionGroup, apiPath, httpMethod, httpStatusCode, responseBody, as above). A plain API Gateway-style {'statusCode': 200, 'body': ...} is not a usable observation, so the step fails or the agent keeps calling the same tool until it reaches its iteration limit.
  • Report tool failures as data. When a downstream API fails, return a structured error (status code and message) in the response body so the agent's FM can reason about it: retry, use another tool, or tell the user. An empty body reads as "no data", and an unhandled exception gives the agent nothing to reason with. For function-detail action groups, responseState: REPROMPT hands the response back to the model to try again (invalid input), while FAILURE ends the session with a DependencyFailedException.
  • Keep secrets out of the agent. OAuth client secrets and API keys live in AWS Secrets Manager or Systems Manager Parameter Store SecureString and are fetched at runtime under the function's IAM role, never in the action group schema, the agent instructions, or plaintext environment variables.
  • Enforce authorization in code, not the prompt. Derive the tenant or user from trusted session context and filter every query by it inside the Lambda, with a least-privilege role. A prompt instruction such as "only query company X" can be overridden.
  • Make write tools idempotent. The agent may call the same tool more than once for one request, so pass a request ID and check it (for example, a DynamoDB conditional write) before performing a write.
  • Session context. Every InvokeAgent call carries a sessionId; reusing it keeps the conversation's turns in context. sessionAttributes (kept for the session) and promptSessionAttributes (one turn) are sent to the action group Lambda on every call, which makes them the place to inject exact values such as a user's stored preferences loaded from DynamoDB. Agent memory keeps model-generated session summaries, not exact settings.
  • Grouping. One action group holds up to 11 API operations behind one Lambda function. Group related functions by business domain (for example, search and booking) with clear descriptions, rather than one catch-all group or one group per function.
  • Private and on-premises data. A tool that must reach an on-premises database runs as a Lambda function attached to a VPC that connects to the data center over AWS Direct Connect or Site-to-Site VPN; the agent reaches the data only through the action group.
  • Tool choice. On each turn the agent's FM decides whether to call an action group, search an attached knowledge base (guided by the knowledge base description), or answer directly.

AWS Strands Agents — the open-source, code-first framework launched in 2025. Where Bedrock Agents is configuration-driven (no-code/low-code), Strands is Python-first for developers who need full programmatic control:

from strands import Agent, tool
from strands_tools import use_aws

@tool
def search_orders(customer_id: str) -> dict:
    """Search customer order history by customer ID."""
    return query_dynamodb(customer_id)

@tool  
def update_order_status(order_id: str, status: str) -> str:
    """Update the status of an existing order."""
    return update_dynamodb(order_id, status)

agent = Agent(
    model="us.anthropic.claude-3-5-sonnet-20241022-v2:0",
    tools=[search_orders, update_order_status, use_aws],
    system_prompt="You are an order management assistant..."
)

response = agent("Find all pending orders for customer C-12345 and mark them as processing")

AWS Agent Squad for multi-agent coordination (the supervisor's aggregation step must reconcile, not concatenate: instruct it to detect contradictory sub-agent claims, weigh the evidence and state its resolution, or conflicting findings pass straight into the final answer):

When multi-agent is justified: split into a supervisor and specialists only when subtasks can genuinely run in parallel (for example, research and drafting that currently block each other) or when specialists need separate tools, knowledge bases, or IAM permissions. Low volume with no performance problem, team preference, or wanting a cheaper supervisor model are not reasons on their own. The supervisor's task decomposition is itself an FM decision, so the same request can be split and routed differently between runs, which is a common source of inconsistent multi-agent results.

⚠️ Exam Trap: Every reasoning step in an agent adds at least one model call, so latency grows with the number of steps and multi-step tasks can take tens of seconds end-to-end. For latency-sensitive user-facing applications with SLAs under 5 seconds, simple prompt chaining via Bedrock Prompt Flows or direct InvokeModel calls are more appropriate than an agent.

The concepts in this section (action groups, OpenAPI tool schemas, knowledge base retrieval, the managed reasoning loop) still describe how agents work, and an existing customer may still run them. For a new project, the configuration-based equivalent is the AgentCore managed harness, and the code-first path is Strands Agents on AgentCore Runtime (see 4.1.5).

⚠️ Exam Trap: When a scenario describes a new team or a new account, Bedrock Agents Classic is not the answer, however well its features fit. When a scenario describes an existing Classic deployment, keeping it running is legitimate; the question is usually where new capabilities should be built.

Reflection Question: You need to build a system that answers questions about internal HR documents AND can submit time-off requests to Workday via REST API. Which agent components (knowledge base, action group or Gateway tool) do you configure for each capability, and what Lambda function pattern implements the Workday integration?

See how it connects
Alvin Varughese
Written byAlvin Varughese
Founder•20 professional certifications