0 of 0

Module 01 โ€” AgentCore Architecture & Concepts

  • Explain what Amazon Bedrock AgentCore is and the problem it solves
  • Describe the core service components and how they relate
  • Understand the flat resource model and project structure
  • Explain why AgentCore exists alongside other AWS agent offerings
Install the AgentCore CLI The CLI requires Node.js 18+. Install the preview version โ€” do not use @latest, which points to an older incompatible release:
npm install -g @aws/agentcore@preview

# Verify installation
agentcore --version

# Bootstrap your AWS account (one-time setup per region)
agentcore bootstrap
You'll need AWS credentials configured (aws configure or an active SSO session) and sufficient IAM permissions to create CloudFormation stacks, Lambda functions, and ECR repositories.
๐Ÿ”ง Workshop Setup โ€” Do This First Before starting labs, create your training project. Use myagentcore throughout all 11 modules:
agentcore create \
  --name myagentcore \
  --framework Strands \
  --model-provider Bedrock \
  --memory none

cd myagentcore
Harness vs Agent: Running agentcore create --defaults creates a harness project (config-driven, no Python code). This curriculum teaches agent projects. Use the command above, not --defaults.
SRE Context: Why AgentCore? Without AgentCore, deploying AI agents on AWS requires wiring together ECS/Fargate for execution, DynamoDB for session state, Secrets Manager for credentials, CloudWatch for logs, and X-Ray for traces โ€” all custom. AgentCore provides this as managed infrastructure so your team writes agent logic, not plumbing. Estimated 60โ€“70% reduction in undifferentiated infrastructure work.

What is Amazon Bedrock AgentCore?

AgentCore is AWS's managed infrastructure platform for deploying AI agents at scale. It sits above raw Lambda/ECS and below higher-level products like Bedrock Agents, giving you a "runtime for agents" that handles:

  • Scalable execution โ€” containerized agent processes that scale on demand
  • Session management โ€” multi-turn conversation context, user/session IDs
  • Persistent memory โ€” cross-conversation recall with configurable strategies
  • Tool connectivity โ€” the Gateway layer, an MCP-compatible proxy to external tools
  • Identity & credentials โ€” secure API key and OAuth storage, no secrets in code
  • Observability โ€” traces, logs, and evaluation pipelines built in
  • Policy enforcement โ€” Cedar-based fine-grained authorization on tool calls

Key insight: AgentCore lets you bring any framework (Strands, LangGraph, OpenAI Agents, Google ADK) and any model (Bedrock, Anthropic, OpenAI, Gemini) and deploys it consistently.

Where AgentCore Fits

Your Agent FrameworkStrands / LangGraph / OpenAI Agents / Google ADK AgentCore RuntimeSession management ยท Scaling ยท Memory integration ยท Traces + Logs AgentCore Memory AgentCore Identity AgentCore GatewayMCP-compatible proxy โ†’ MCP Servers, API Gateway, Lambda, OpenAPI AWS Bedrock / Anthropic / OpenAI / Google Gemini

The Six Core Service Areas

Service AreaWhat It Doesproject.json Key
RuntimeManaged execution environment for agent coderuntimes
MemoryPersistent, multi-strategy context storagememories
GatewayMCP-compatible proxy to external toolsagentCoreGateways
IdentitySecure credential storage (API keys, OAuth)credentials
EvaluationsLLM-as-a-Judge quality monitoringevaluators
PolicyCedar-based authorization on tool callspolicyEngines

Resource Limits Reference

ResourceDefault / Limit
Session idle timeout300s (configurable with --idle-timeout)
Session max lifetime3600s (configurable with --max-lifetime)
CodeZip max size250 MB
Agent name max length48 characters
Project name max length23 characters (alphanumeric, starts with letter)
Memory event expiry7โ€“365 days

The Flat Resource Model

AgentCore uses a flat resource model โ€” all resources (agents, memories, gateways, credentials) are independent top-level items defined in project.json. They are NOT nested inside each other.

An agent discovers its memory through an environment variable injected at runtime:

MEMORY_MYMEMORYNAME_ID=<memory-id>
AGENTCORE_GATEWAY_MYGATEWAY_URL=https://...

This decoupling means you can share a memory across multiple agents, swap gateways without changing agent code, and redeploy resources independently.

project.jsonsource of truth Runtime (Agent) Memory Gateway Credentials MEMORY_<NAME>_ID GATEWAY_<NAME>_URL

Project Structure

myagentcore/
โ”œโ”€โ”€ agentcore/
โ”‚   โ”œโ”€โ”€ project.json         # Source of truth โ€” all resource specs
โ”‚   โ”‚                        # (older projects may use agentcore.json)
โ”‚   โ”œโ”€โ”€ aws-targets.json     # Deployment targets (account + region)
โ”‚   โ”œโ”€โ”€ .env.local           # Secrets for local dev (gitignored)
โ”‚   โ””โ”€โ”€ .llm-context/        # TypeScript type defs (added after first deploy)
โ”œโ”€โ”€ cdk/                     # Generated CDK app โ€” at project ROOT, not inside agentcore/
โ”œโ”€โ”€ app/
โ”‚   โ””โ”€โ”€ myagentcore/         # Agent source code
โ”‚       โ”œโ”€โ”€ main.py          # Agent entry point
โ”‚       โ””โ”€โ”€ pyproject.toml   # Python deps
โ””โ”€โ”€ evaluators/              # Custom evaluator code (optional)
Critical Rule project.json is the single source of truth. The CDK code in cdk/ is generated from it โ€” never edit CDK directly. Renaming a resource in project.json = destroy + recreate in CloudFormation.

project.json Anatomy

{
  "name": "myagentcore",
  "version": 1,
  "tags": { "agentcore:project-name": "myagentcore" },
  "runtimes": [],         // agents
  "memories": [],         // memory resources
  "credentials": [],      // API keys, OAuth providers
  "evaluators": [],       // LLM-as-a-Judge definitions
  "onlineEvalConfigs": [], // continuous eval configs
  "agentCoreGateways": [], // gateways + targets
  "policyEngines": []     // Cedar policy engines
}

Supported Frameworks & Models

FrameworkBest For
Strands AgentsAWS-native, streaming, recommended for Bedrock
LangChain/LangGraphGraph-based workflows, complex reasoning chains
Google ADKGemini models
OpenAI AgentsOpenAI models
Model ProviderAuth Method
Amazon BedrockAWS credentials (no API key needed)
AnthropicAPI key
OpenAIAPI key
Google GeminiAPI key

Deployment Model

AgentCore uses AWS CDK under the hood. When you run agentcore deploy, the CLI reads project.json, synthesizes CDK CloudFormation, and deploys via CDK toolkit. All resources are tracked as CloudFormation stacks โ€” you get drift detection, rollback, and change sets for free.

Hands-On Labs

โ–ผ
cd ~/myagentcore

# View the source of truth config
cat agentcore/project.json

# Check the deployment target
cat agentcore/aws-targets.json

Questions to answer:

  • What is the name of the agent runtime in your project?
  • What memory strategies are configured (if any)?
  • Which region and account is the deployment target?
  • Where is the cdk/ directory โ€” inside agentcore/ or at the project root?
โ–ผ

Based on what you found in Lab 1.1, describe the architecture of your myagentcore project:

  • Agent โ†’ uses what memory?
  • Agent โ†’ connects to what gateway?
  • What model/framework does the agent use?
  • What would need to change in project.json to add memory?

Knowledge Check

Q1: In the flat resource model, how does an agent know which memory ID to use at runtime?
a) It's hardcoded in the agent source code
b) Through an environment variable injected by the runtime: MEMORY_<NAME>_ID
c) Through a direct API call to the AgentCore control plane
d) Through a config file in the CDK stack
Answer: B โ€” The runtime injects MEMORY_<NAME>_ID as an environment variable. The agent code reads os.getenv("MEMORY_MYMEMORY_ID"). This is the flat resource model โ€” the agent code doesn't need to know the physical memory ARN at dev time.
Q2: You rename a memory resource from MyMemory to ProdMemory in project.json and run agentcore deploy. What happens?
a) The existing memory is renamed in-place, no data loss
b) The existing memory is destroyed and a new one is created (all stored memories are lost)
c) The deploy fails with a validation error
d) Nothing โ€” rename is ignored, the old name is preserved
Answer: B โ€” Resource name maps to the CloudFormation logical ID. Rename = CloudFormation delete + create. For memory this means all stored data is lost. This is why renaming is considered destructive.
Q3: Which file should you NEVER edit directly in an AgentCore project?
a) project.json
b) aws-targets.json
c) cdk/ (the generated CDK app, at project root)
d) app/MyAgent/main.py
Answer: C โ€” The CDK code in cdk/ (project root) is generated from project.json. Manual edits will be overwritten on the next agentcore deploy. Always modify resources through project.json or CLI commands.
Q4: AgentCore supports which agent frameworks? (Multiple correct answers)
a) Strands Agents
b) LangChain/LangGraph
c) AWS Step Functions
d) Google ADK
e) OpenAI Agents SDK
Answer: A, B, D, E โ€” Strands, LangGraph, Google ADK, and OpenAI Agents are all supported. Step Functions is an orchestration service, not an agent framework.
Q5: What is the underlying deployment mechanism AgentCore uses to provision resources in AWS?
a) AWS SAM (Serverless Application Model)
b) Terraform
c) AWS CDK (Cloud Development Kit)
d) Direct API calls to each service
Answer: C โ€” AgentCore CLI synthesizes CDK stacks from project.json and deploys them using the CDK toolkit. This gives you CloudFormation drift detection, rollback, and change previews.

Key Takeaways

  • AgentCore = managed runtime for AI agents (bring your own framework + model)
  • The flat resource model decouples agents from their memory/gateways via env vars
  • project.json is the single source of truth โ€” never edit the generated CDK
  • Renaming resources is a destructive operation (destroy + recreate)
  • Six service areas: Runtime, Memory, Gateway, Identity, Evaluations, Policy
  • CDK is the deployment engine โ€” all resources are CloudFormation stacks
  • Config file is project.json (inside agentcore/); cdk/ is at the project root
  • --defaults creates a harness project; use --framework Strands --model-provider Bedrock --memory none for an agent project

Module 02 โ€” CLI Fundamentals

  • Install and verify the AgentCore CLI
  • Navigate both TUI (interactive) and non-interactive CLI modes
  • Use --json output effectively for scripting and automation
  • Understand command aliases and global flags

Installation

Always install the @preview tag โ€” it's the active development line. @latest points to 0.13.1 (old, missing many commands). @preview is 1.0.0-preview.x with all current commands.
# Always install the @preview tag
npm install -g @aws/agentcore@preview
agentcore --version   # should show 1.0.0-preview.x

# Prerequisites
# Node.js 20.x or later
# uv for Python agents: brew install uv
# AWS credentials: aws configure

# Upgrading from old Python toolkit
pip uninstall bedrock-agentcore-starter-toolkit

# Check for updates
agentcore update          # Check and install
agentcore update --check  # Check only

Two Modes: TUI vs Non-Interactive

TUI (Terminal UI) โ€” launch with no arguments: agentcore. A full terminal UI with menus, wizards, and live dashboards. Use when learning, exploring, or wanting guided setup wizards.

TUI vs --help discrepancy: The TUI menu shows a filtered subset of commands (workflow-stage commands like add, deploy, invoke). One-time commands like create don't appear in the TUI but ARE available from the CLI. Always use agentcore --help for the full command list.

Non-interactive (CLI) mode โ€” triggered by passing any flag or argument. Use in CI/CD pipelines, scripting, or when you know exactly what you want.

agentcore deploy -y
agentcore status --json
agentcore invoke "Hello"
agentcore help modes   # Explains both modes in detail

Command Aliases

Full CommandAlias
deploydp
devd
invokei
statuss
logsl
tracest
packagepkg

Global Flags

FlagWhat It Does
-h, --helpShow help for any command
--versionPrint CLI version (root only)
--jsonMachine-readable JSON output
-y, --yesAuto-confirm prompts (deploy, remove)
--dry-runPreview without taking action

The --json Flag

# Human-readable status
agentcore status

# Machine-readable JSON
agentcore status --json

# Pipe through jq to extract specific fields
agentcore status --json | jq '.resources[] | select(.resourceType == "agent")'

# Invoke and extract just the response text
agentcore invoke "Hello" --json | jq -r '.response'

# Use in CI โ€” check deployment success
agentcore deploy -y --json | jq '.success'
CI/CD Pattern: Chain validate and deploy with exit code handling:
agentcore validate && agentcore deploy -y --json | tee deploy-output.json
# jq '.success' deploy-output.json

The --dry-run Flag

agentcore deploy --dry-run     # Show what CDK would deploy
agentcore deploy --diff        # Show CDK diff (what changes)
agentcore remove all --dry-run # Preview what would be removed
agentcore create --name Foo --defaults --dry-run  # Preview project creation
Always use --dry-run before destructive operations in production.

The validate Command

agentcore validate           # Validate project.json in current dir
agentcore validate -d ./path # Validate a specific project directory

The status Command

agentcore status              # All resources in default target
agentcore status --json       # JSON output
agentcore status --runtime MyAgent     # Filter to one agent
agentcore status --type memory         # Filter by resource type
agentcore status --state deployed      # Filter by state

# Resource types: agent, harness, runtime-endpoint, memory, credential,
#                 gateway, evaluator, online-eval, policy-engine, policy,
#                 config-bundle, ab-test

Hands-On Labs

โ–ผ
agentcore --version
agentcore update --check
โ–ผ
agentcore --help
agentcore add --help
agentcore deploy --help
agentcore logs --help

Challenge: Without looking at the docs, find the flag that lets you stream the response when invoking an agent. (Hint: agentcore invoke --help)

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab โ€” it provisions AWS resources (~5โ€“10 min on first run).
cd ~/myagentcore

# Check status โ€” human readable
agentcore status

# Check status โ€” JSON (pipe through jq)
agentcore status --json | jq '.resources | length'
agentcore status --json | jq '.resources[] | {name: .name, type: .resourceType, state: .state}'

# Filter to just the agent
agentcore status --type agent

Answer: How many total resources are deployed? What is the state of each resource? What ARN is shown for the agent runtime?

โ–ผ
cd ~/myagentcore

agentcore status --json | jq '.resources[0]'
agentcore status --json | jq '[.resources[] | {name, type: .resourceType}]'
agentcore validate

Knowledge Check

Q1: You're in a CI/CD pipeline and need to run agentcore deploy without any human interaction. Which flags do you need?
a) --silent --auto
b) -y --json
c) --no-prompt
d) --batch
Answer: B โ€” -y suppresses confirmation prompts, --json provides machine-readable output. These are the standard CI/CD flags.
Q2: What is the alias for agentcore invoke?
a) agentcore in
b) agentcore inv
c) agentcore i
d) agentcore run
Answer: C โ€” agentcore i is the alias for invoke. Learn all aliases: d=dev, dp=deploy, i=invoke, s=status, l=logs, t=traces, pkg=package.
Q3: You want to see what CDK changes would happen if you deploy, without actually deploying. Which command do you use?
a) agentcore deploy --preview
b) agentcore deploy --dry-run
c) agentcore deploy --diff
d) agentcore status --pending
Answer: C โ€” --diff shows the CDK diff (what would change in CloudFormation) without deploying. --dry-run runs the synthesis but also skips deploy. Both are useful; --diff is more targeted for reviewing changes.
Q4: agentcore validate checks which file?
a) agentcore/cdk/cdk.json
b) agentcore/aws-targets.json
c) agentcore/project.json
d) app/main.py
Answer: C โ€” validate checks project.json against the schema. It runs before deploy internally, but you should run it manually before committing config changes.
Q5: How do you get help for the agentcore logs command specifically?
a) agentcore help logs
b) agentcore logs -h
c) agentcore logs --help
d) Both b and c work
Answer: D โ€” Both -h and --help work on any command. -h is shorter; --help is the long form. Both are valid.

Key Takeaways

  • Two modes: TUI (interactive) and CLI (non-interactive) โ€” flags trigger CLI mode
  • --json turns any command into an automation building block
  • --dry-run and --diff are your safety net before destructive operations
  • Learn the aliases: d, dp, i, s, l, t, pkg
  • Always agentcore validate before agentcore deploy
  • agentcore status is your primary diagnostic tool
  • TUI menu is a subset of commands โ€” use --help for the full list

Module 03 โ€” Project Lifecycle

  • Create an AgentCore project from scratch with the full range of options
  • Understand the complete project lifecycle: create โ†’ validate โ†’ deploy โ†’ iterate โ†’ teardown
  • Use deploy, status, validate, and package fluently
  • Understand deployment targets and how to manage multiple environments

The Full Lifecycle

create dev validate deploy status/invoke/logs/traces iterate remove all(teardown)

agentcore create

# Minimal โ€” wizard fills the rest
agentcore create

# Fully non-interactive agent project (requires ALL THREE: --framework, --model-provider, --memory)
agentcore create \
  --name MyProject \
  --framework Strands \
  --model-provider Bedrock \
  --memory shortTerm

# With long-and-short-term memory
agentcore create \
  --name MyProject \
  --framework Strands \
  --model-provider Bedrock \
  --memory longAndShortTerm

# VPC networking (for private environments)
agentcore create \
  --name MyProject \
  --defaults \
  --network-mode VPC \
  --subnets subnet-abc,subnet-def \
  --security-groups sg-123

# Preview without creating
agentcore create --name MyProject --defaults --dry-run

# Note: --defaults creates a HARNESS project. For an agent project, use --framework instead.
agentcore create \
  --name MyProject \
  --framework Strands \
  --model-provider Bedrock \
  --memory none
FlagDescription
--nameProject name (alphanumeric, max 23 chars, starts with letter)
--defaultsUse defaults โ€” creates a harness project (not agent)
--frameworkStrands, LangChain_LangGraph, GoogleADK, OpenAIAgents
--model-providerBedrock, Anthropic, OpenAI, Gemini
--memorynone, shortTerm, longAndShortTerm
--buildCodeZip (default) or Container
--protocolHTTP (default), MCP, or A2A
--network-modePUBLIC (default) or VPC
--dry-runPreview without creating

What create Generates

MyProject/
โ”œโ”€โ”€ agentcore/
โ”‚   โ”œโ”€โ”€ project.json            # Resource config (one agent already defined)
โ”‚   โ”œโ”€โ”€ aws-targets.json        # Default target (your account + region)
โ”‚   โ””โ”€โ”€ .env.local              # Gitignored secrets placeholder
โ”œโ”€โ”€ cdk/                        # Generated CDK app (at project ROOT)
โ””โ”€โ”€ app/
    โ””โ”€โ”€ MyAgent/                # Agent source code
        โ”œโ”€โ”€ main.py             # Entry point with @app.entrypoint decorator
        โ””โ”€โ”€ pyproject.toml      # Python deps

agentcore validate

Validates project.json against the schema. Run this before every deploy:

agentcore validate           # Validates current directory
agentcore validate -d ./path # Validate a specific project

Catches: missing required fields, invalid names, invalid cross-references, schema version mismatches.

agentcore deploy

agentcore validate && agentcore deploy -y

# Preview before deploying
agentcore deploy --diff        # Show what changes in CloudFormation
agentcore deploy --dry-run     # Full synthesis without deploying

# Deploy with verbose output
agentcore deploy -y -v

# Deploy to a named target
agentcore deploy --target staging -y

# JSON output for CI/CD
agentcore deploy -y --json

What deploy does under the hood:

  1. Reads project.json + aws-targets.json
  2. Runs the CDK synthesizer to produce CloudFormation
  3. Calls CDK deploy (which calls CloudFormation)
  4. Updates agentcore/.cli/deployed-state.json with the resulting ARNs
On first deploy: CDK bootstraps the account if not already done (creates an S3 bucket and ECR repo for CDK assets).

agentcore status

agentcore status              # All resources
agentcore status --json       # JSON output
agentcore status --type agent
agentcore status --type memory
agentcore status --runtime MyAgent
agentcore status --state deployed
agentcore status --state pending-removal

States: deployed (in AWS, matching config), local-only (in project.json, not yet deployed), pending-removal (removed from config but still in AWS โ€” deploy to clean up).

agentcore package

agentcore package                      # Package all runtimes
agentcore package --runtime MyAgent    # Package one runtime
agentcore package -d ./my-project      # Specify project directory

Deployment Targets

# aws-targets.json
[
  { "name": "default", "description": "Development", "account": "123456789012", "region": "us-east-1" },
  { "name": "staging", "description": "Staging", "account": "987654321098", "region": "us-east-1" }
]

# Deploy to a specific environment
agentcore deploy --target staging -y
agentcore status --target staging
agentcore invoke "Hello" --target staging

agentcore remove

agentcore remove agent --name MyAgent -y
agentcore remove memory --name SharedMemory -y
agentcore remove credential --name OpenAI
agentcore remove gateway --name MyGateway

# Nuclear option โ€” remove everything
agentcore remove all -y
agentcore remove all --dry-run  # Preview first
Important: agentcore remove removes from project.json and marks resources for deletion. Resources stay in AWS until the next agentcore deploy.

The Config Lifecycle

# Add to project.json โ†’ deploy โ†’ deployed-state.json updated with ARNs
# Remove from project.json โ†’ deploy โ†’ resource deleted from AWS

# deployed-state.json is auto-managed โ€” NEVER edit it manually
# It tracks: ARNs, endpoint URLs, last deploy timestamps

Hands-On Labs

โ–ผ
cd ~/myagentcore

# Read the full config
cat agentcore/project.json

# Read deployment targets
cat agentcore/aws-targets.json

# Check deployed state (exists after first deploy)
cat agentcore/.cli/deployed-state.json 2>/dev/null || echo "No deployed state yet"

Identify: What resources are in the config? What account/region is the default target? After deploying, what ARNs appear in deployed-state.json?

โ–ผ
cd ~/myagentcore
agentcore validate

Is it valid? What does the output tell you?

โ–ผ
cd ~/myagentcore
agentcore deploy --diff

This shows what CloudFormation would change if you ran deploy. On a fresh project, it will show all new resources to be created.

โ–ผ
# Preview creating a project with memory โ€” no files written
agentcore create \
  --name TrainingTest \
  --framework Strands \
  --model-provider Bedrock \
  --memory longAndShortTerm \
  --dry-run

Observe what files would be generated. Notice that cdk/ is at the project root and the config is named project.json.

Knowledge Check

Q1: You run agentcore remove agent --name MyAgent. What happens to the agent in AWS immediately after this command?
a) The agent is deleted from AWS immediately
b) The agent is removed from project.json but still exists in AWS until the next agentcore deploy
c) The agent is put into a pending-removal state and deleted after 24 hours
d) Nothing โ€” you need to run agentcore deploy first before you can remove
Answer: B โ€” remove removes from project.json (sets state to pending-removal). The resource stays in AWS until the next agentcore deploy, which synthesizes the CDK without that resource and CloudFormation deletes it.
Q2: Which file tracks the ARNs of deployed resources and is managed automatically by the CLI?
a) agentcore/project.json
b) agentcore/aws-targets.json
c) agentcore/.cli/deployed-state.json
d) agentcore/cdk/cdk.out/
Answer: C โ€” agentcore/.cli/deployed-state.json is the auto-managed runtime state file. Never edit it manually. It tracks ARNs, endpoint URLs, and is updated after every deploy.
Q3: You have aws-targets.json with two targets: default and staging. How do you deploy specifically to staging?
a) agentcore deploy --env staging
b) agentcore deploy --target staging
c) agentcore deploy --profile staging
d) Edit the default target to point to staging, then deploy
Answer: B โ€” --target <name> selects a named target from aws-targets.json. This is how you manage dev/staging/prod with a single codebase.
Q4: What does agentcore deploy --diff do?
a) Shows Git diff of changed files
b) Shows CloudFormation diff of what would change, without deploying
c) Shows differences between two deployment targets
d) Shows the diff between project.json and deployed-state.json
Answer: B โ€” --diff runs CDK synthesis and shows the CloudFormation change set โ€” a diff of what resources would be added, modified, or deleted. No changes are made.
Q5: What is the maximum character length for a project --name?
a) 48 characters
b) 64 characters
c) 23 characters
d) 100 characters
Answer: C โ€” Project names are limited to 23 characters (alphanumeric, starts with a letter). Agent names within a project can be up to 48 characters.

Key Takeaways

  • Lifecycle: create โ†’ validate โ†’ deploy โ†’ iterate (add/remove resources + redeploy) โ†’ teardown
  • project.json drives everything; CDK synthesizes from it
  • Always validate before deploy โ€” catches schema errors before CDK fails
  • Use --diff and --dry-run before destructive operations
  • deployed-state.json is auto-managed โ€” never edit it
  • Multiple targets (aws-targets.json) enable dev/staging/prod workflows
  • Resource removal is two-step: remove from config โ†’ deploy to delete from AWS
  • --framework requires all three: --framework, --model-provider, --memory

Module 04 โ€” Agent Types & Frameworks

  • Distinguish the three agent creation types: template, BYO, and import
  • Understand the two build types: CodeZip vs Container
  • Know the supported frameworks and model providers
  • Add agents to an existing project and configure advanced options

Three Ways to Create an Agent

1. Template Agent (default --type create)

The CLI scaffolds a complete working agent from a framework template. Best for new agents.

agentcore add agent \
  --name MyAgent \
  --framework Strands \
  --model-provider Bedrock \
  --memory shortTerm

2. BYO โ€” Bring Your Own Code (--type byo)

You already have agent code and want to register it with AgentCore without changing its structure.

agentcore add agent \
  --name MyAgent \
  --type byo \
  --code-location ./my-existing-agent \
  --entrypoint main.py \
  --language Python

BYO supports Python, TypeScript, and "Other" (any binary/script). Your entry point must implement the AgentCore HTTP/MCP/A2A protocol using the @app.entrypoint decorator.

3. Import from Bedrock Agents (--type import)

agentcore add agent \
  --name MyAgent \
  --type import \
  --agent-id AGENT123 \
  --agent-alias-id ALIAS456 \
  --region us-east-1 \
  --framework Strands \
  --memory none

Two Build Types

CodeZip (default)

Python source code is zipped and deployed directly to AgentCore's managed Python runtime. No Docker required, faster build and deploy. Best for pure Python agents without custom system dependencies.

Container

Agent is packaged as a Docker container image, built via AWS CodeBuild (ARM64), pushed to ECR, and deployed to AgentCore runtime. Full control over the runtime environment, supports any language, requires a Dockerfile.

Supported Frameworks

FrameworkFlag ValueBest For
Strands AgentsStrandsAWS-native, streaming, Bedrock integration
LangChain/LangGraphLangChain_LangGraphGraph-based workflows
Google ADKGoogleADKGemini models
OpenAI Agents SDKOpenAIAgentsOpenAI models
Framework Decision Matrix
Your SituationRecommended
Bedrock-native, streaming responsesStrands Agents
Complex branching / DAG workflowsLangChain/LangGraph
Using Gemini modelsGoogle ADK
Using OpenAI modelsOpenAI Agents SDK

Supported Model Providers

ProviderFlag ValueDefault ModelNeeds API Key?
Amazon BedrockBedrockus.anthropic.claude-sonnet-4-5...No
AnthropicAnthropicclaude-sonnet-4-5...Yes
OpenAIOpenAIgpt-4.1Yes
Google GeminiGeminigemini-2.5-flashYes

Agent Protocols

ProtocolFlagUse Case
HTTPHTTPStandard REST invocation โ€” most common
MCPMCPAgent acts as an MCP tool server (agents-as-tools)
A2AA2AAgent-to-Agent protocol for multi-agent orchestration

Full add agent Flag Reference

agentcore add agent \
  --name <name>               # Agent name (max 48 chars)
  --type create|byo|import    # How to create the agent
  --framework <fw>            # Strands, LangChain_LangGraph, etc.
  --model-provider <p>        # Bedrock, Anthropic, OpenAI, Gemini
  --api-key <key>             # For non-Bedrock providers
  --memory none|shortTerm|longAndShortTerm
  --build CodeZip|Container
  --protocol HTTP|MCP|A2A
  --network-mode PUBLIC|VPC
  --authorizer-type AWS_IAM|CUSTOM_JWT
  --idle-timeout <seconds>    # Kill session after N seconds idle
  --max-lifetime <seconds>    # Max session lifetime
  --code-location <path>      # BYO only
  --entrypoint <file>         # BYO only, default: main.py
  --agent-id <id>             # Import only
  --agent-alias-id <id>       # Import only

Generated main.py (Strands)

from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from strands.models import BedrockModel

app = BedrockAgentCoreApp()

@app.entrypoint
async def invoke(payload, context):
    session_id = getattr(context, 'session_id', 'default-session')
    user_id = getattr(context, 'user_id', 'default-user')

    agent = Agent(
        model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250514-v1:0"),
        system_prompt="You are a helpful assistant.",
    )

    response = await agent.invoke_async(payload)
    return {"response": str(response)}

Hands-On Labs

โ–ผ
cd ~/myagentcore
ls app/
cat app/myagentcore/main.py
cat app/myagentcore/pyproject.toml

Questions: What framework does the generated agent use? What model is configured? What does the @app.entrypoint decorator do?

โ–ผ
cd ~/myagentcore
cat agentcore/project.json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d['runtimes'], indent=2))"

Identify: build type, protocol, networkMode, any authorizerType.

โ–ผ
agentcore add agent --help

Questions: What is the --type flag's default value? What protocols are supported? What languages are supported for BYO agents?

โ–ผ
cd ~/myagentcore
agentcore add agent --help

# Optional experiment (modifies project.json):
# agentcore add agent \
#   --name SecondAgent \
#   --framework LangChain_LangGraph \
#   --model-provider Bedrock \
#   --memory none

Knowledge Check

Q1: You have existing Python agent code in ./my-bot/. How do you add it to your project without regenerating from a template?
a) agentcore add agent --type existing --code-location ./my-bot
b) agentcore add agent --type byo --code-location ./my-bot --entrypoint main.py
c) Copy the files manually to app/ and edit project.json
d) agentcore add agent --import ./my-bot
Answer: B โ€” --type byo is the "Bring Your Own Code" option. Point to your existing code directory with --code-location and specify the entry file with --entrypoint.
Q2: Which build type requires a Dockerfile in the agent directory?
a) CodeZip
b) Container
c) Both
d) Neither โ€” Dockerfile is optional for both
Answer: B โ€” Container build requires a Dockerfile. The CLI uses CodeBuild to build the image, pushes to ECR. CodeZip has no Docker requirement.
Q3: An agent with --protocol MCP means what?
a) The agent calls MCP servers as tools
b) The agent exposes itself as an MCP tool server (other agents can use it as a tool)
c) The agent uses the Model Context Protocol for memory retrieval
d) MCP is required for gateway-connected agents
Answer: B โ€” When an agent is built with --protocol MCP, it exposes itself as an MCP tool server. Other agents, Claude, or MCP clients can invoke it as a tool. Different from an agent that uses MCP tools via a gateway.
Q4: You want to build an agent using LangGraph with OpenAI's GPT-4.1. Which flags are correct?
a) --framework LangGraph --model gpt-4.1
b) --framework LangChain_LangGraph --model-provider OpenAI --api-key sk-...
c) --framework LangChain --model-provider OpenAI
d) --framework LangGraph --provider OpenAI
Answer: B โ€” The framework flag value is LangChain_LangGraph (the full enum value, not just "LangGraph"). The --model-provider OpenAI flag tells AgentCore to use OpenAI, and --api-key provides the credential.
Q5: What does the --idle-timeout flag control?
a) How long the CLI waits for a deploy to complete
b) How long an agent runtime session stays alive after the last request
c) How long until unused API credentials expire
d) The HTTP timeout for agent invocations
Answer: B โ€” --idle-timeout (in seconds) controls when the runtime kills a session that hasn't received requests. Short-lived agents for one-shot tasks, longer sessions for conversational agents.

Key Takeaways

  • Three creation types: template (scaffold), BYO (bring existing code), import (from Bedrock Agents)
  • Two build types: CodeZip (zip + managed Python runtime) vs Container (Docker + ECR + CodeBuild)
  • Four frameworks: Strands, LangChain/LangGraph, Google ADK, OpenAI Agents
  • Four model providers: Bedrock (no API key), Anthropic, OpenAI, Gemini (last three need API key)
  • Three protocols: HTTP (default), MCP (expose as tool server), A2A (multi-agent)
  • --authorizer-type controls inbound auth: AWS_IAM (default) or CUSTOM_JWT
  • The @app.entrypoint decorator is the integration point between your code and the runtime

Module 05 โ€” Local Development

  • Run an agent locally with hot-reload using agentcore dev
  • Invoke both local and deployed agents with agentcore invoke
  • Use MCP protocol-specific dev commands
  • Debug local agents using exec and logs

agentcore dev โ€” the Local Dev Server

Browser UI (v1.0.0-preview.8+): agentcore dev opens a web browser chat interface by default. To use the terminal TUI, add the --no-browser flag.
# Start dev server (opens browser chat UI by default)
agentcore dev

# Use terminal TUI instead of browser
agentcore dev --no-browser

# Non-interactive โ€” logs to stdout (useful in one terminal, invoke in another)
agentcore dev --logs

# Target a specific runtime (required when multiple agents in project)
agentcore dev --runtime MyAgent

# Use a different port
agentcore dev --port 3000

CodeZip agents: Dev runs via uvicorn with a file watcher โ€” changes to Python files restart automatically.

Container agents: Dev builds the Docker image and runs it with a volume mount so code changes are reflected immediately.

Invoking the Local Dev Server

# While agentcore dev is running in one terminal, invoke from another:
agentcore dev "What can you do?"
agentcore dev "Tell me a long story" --stream
agentcore dev "Hello" --runtime MyAgent

# MCP protocol dev commands
agentcore dev list-tools
agentcore dev call-tool --tool myTool --input '{"arg": "value"}'

agentcore invoke โ€” Invoke Deployed Agents

# Basic invocation
agentcore invoke "What can you do?"

# Stream the response in real-time
agentcore invoke "Explain quantum computing" --stream

# Continue an existing session (multi-turn conversation)
agentcore invoke "What did I ask before?" --session-id abc123

# Invoke a specific runtime
agentcore invoke --runtime MyAgent "Hello"

# Invoke against a specific deployment target
agentcore invoke "Hello" --target staging

# JSON output
agentcore invoke "Hello" --json

# Set a user ID (for memory namespacing)
agentcore invoke "Hello" --user-id alice

Prompt Sources (priority order)

  1. --prompt <text> (highest priority)
  2. Positional argument: agentcore invoke "Hello"
  3. --prompt-file <path>: read from a file
  4. Piped stdin: cat prompt.txt | agentcore invoke
# Long structured prompt from file
agentcore invoke --prompt-file ./test-prompt.json --json

# MCP protocol agents
agentcore invoke call-tool --tool myTool --input '{"key": "value"}'

# JWT auth agents
agentcore invoke "Hello" --bearer-token <your-jwt-token>

Remote Exec โ€” Debug Inside the Runtime Container

# List files in the agent directory
agentcore invoke --exec "ls -la /app"

# Check environment variables
agentcore invoke --exec "env | grep MEMORY"

# Check OS/environment
agentcore invoke --exec "cat /etc/os-release"

# Run a Python script inside the runtime
agentcore invoke --exec "python script.py"

# With timeout (default: 60s)
agentcore invoke --exec "python long-script.py" --timeout 120

# Also works locally
agentcore dev --exec "pip list"

Use cases: inspect installed packages, check env vars, run data migration scripts, debug file permissions. This is your "remote shell" into a running AgentCore runtime.

Gateway Environment Variables in Local Dev

Requires prior deploy: Gateway URLs are only known after deployment. agentcore dev reads URLs from deployed-state.json. You must deploy at least once before local dev can inject gateway URLs.
# After deploying, these are auto-injected into agentcore dev:
AGENTCORE_GATEWAY_MYGATEWAY_URL=https://bedrock-agentcore.us-east-1.amazonaws.com/...
AGENTCORE_GATEWAY_MYGATEWAY_MANAGED_OAUTH_TOKEN=...

Hands-On Labs

โ–ผ
cd ~/myagentcore
cat agentcore/project.json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d['runtimes'][0], indent=2))"

Find: What is the entrypoint? What is the codeLocation? What build type is it?

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore
agentcore invoke "What can you do?"
agentcore invoke "Tell me about Amazon Bedrock AgentCore" --stream
agentcore invoke "Hello" --json
โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore
agentcore invoke --exec "env" | grep -E "MEMORY|GATEWAY|AWS"
agentcore invoke --exec "pip list 2>/dev/null || uv pip list"
agentcore invoke --exec "ls -la /app"
โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore
RESPONSE=$(agentcore invoke "My name is Alex and I'm learning AgentCore" --json)
SESSION_ID=$(echo $RESPONSE | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('sessionId',''))")
echo "Session ID: $SESSION_ID"
agentcore invoke "What did I just tell you?" --session-id "$SESSION_ID"

Knowledge Check

Q1: You have two agents: AnalysisAgent and SummaryAgent. How do you start the dev server for just SummaryAgent?
a) agentcore dev SummaryAgent
b) agentcore dev --agent SummaryAgent
c) agentcore dev --runtime SummaryAgent
d) agentcore dev --name SummaryAgent
Answer: C โ€” --runtime <name> is the flag to select a specific runtime. Consistent across dev, invoke, logs, traces, and status.
Q2: You want to read a very long prompt from a file. Which flag do you use with agentcore invoke?
a) --input <file>
b) --from-file <file>
c) --prompt-file <file>
d) --file <file>
Answer: C โ€” --prompt-file <path> reads the prompt from a file. Useful for long structured prompts (JSON, multi-paragraph instructions).
Q3: You run agentcore dev on a project with a deployed gateway. What prerequisite must be true for gateway env vars to be injected?
a) The gateway must be defined in project.json
b) The gateway must have been deployed at least once (agentcore deploy must have run)
c) You must manually set AGENTCORE_GATEWAY_URL in .env.local
d) No prerequisite โ€” the CLI fetches the URL dynamically
Answer: B โ€” Gateway URLs are only known after deployment. agentcore dev reads the URLs from deployed-state.json which is populated by agentcore deploy.
Q4: Which command lets you run a shell command inside the deployed agent's container to debug its environment?
a) agentcore ssh --runtime MyAgent
b) agentcore invoke --exec "ls /app"
c) agentcore debug --runtime MyAgent "ls /app"
d) agentcore exec "ls /app"
Answer: B โ€” agentcore invoke --exec "command" executes a shell command inside the running agent container. This is the only way to "shell into" a running AgentCore runtime โ€” there's no SSH.
Q5: You want to continue a previously started conversation so the agent remembers what was said. Which flag do you use?
a) --conversation-id <id>
b) --context-id <id>
c) --session-id <id>
d) --thread-id <id>
Answer: C โ€” --session-id <id> continues a specific session. The session ID is returned in the JSON response from the first invocation.

Key Takeaways

  • agentcore dev = hot-reload local server (opens browser UI by default; use --no-browser for TUI)
  • agentcore invoke = call the deployed endpoint (add --stream for real-time)
  • Four prompt sources in priority order: --prompt > positional > --prompt-file > stdin
  • --session-id enables multi-turn conversations
  • --exec is your remote shell into the container โ€” use it for debugging
  • Gateway env vars in local dev require a prior agentcore deploy
  • --runtime <name> is the consistent flag for targeting specific agents across all commands

Module 06 โ€” Memory Deep Dive

  • Understand short-term vs long-and-short-term memory
  • Know all four memory strategies and when to use each
  • Add memory to a project and configure it in agent code
  • Understand namespaces, event expiry, and memory record streaming

Why Memory?

Without memory, every conversation with an agent starts from zero. AgentCore Memory provides cross-session recall, within-session context, and semantic search over past interactions. Memory is a managed service โ€” you don't host it, it scales automatically.

The Three --memory Shorthands

ShorthandWhat Gets CreatedUse Case
noneNo memory resourceStateless agents
shortTermMemory with no strategies (event expiry only)Session context within a window
longAndShortTermMemory with all four strategiesFull persistent memory

The Four Memory Strategies

StrategyWhat It DoesBest For
SEMANTICVector-based similarity search over stored factsRetrieving relevant past context by meaning
SUMMARIZATIONCompresses conversation history into summariesLong conversations, token efficiency
USER_PREFERENCEStores explicit user preferencesPersonalization ("I prefer dark mode")
EPISODICCaptures meaningful interaction episodes + reflectionsLong-term relationship building
Memory Trade-offs: SEMANTIC uses a vector store (higher cost, best recall). SUMMARIZATION compresses tokens (saves cost on long conversations). USER_PREFERENCE is low-volume but high-value. EPISODIC provides rich long-term context at moderate cost. Start with shortTerm (no strategies), then add SEMANTIC + SUMMARIZATION as needed.

Long-and-short-term namespaces:

SEMANTIC     โ†’ /users/{actorId}/facts
USER_PREFERENCE โ†’ /users/{actorId}/preferences
SUMMARIZATION โ†’ /summaries/{actorId}/{sessionId}
EPISODIC     โ†’ /episodes/{actorId}/{sessionId}
             โ†’ /episodes/{actorId} (reflections)

Adding Memory via CLI

agentcore add memory \
  --name SharedMemory \
  --strategies SEMANTIC,SUMMARIZATION,USER_PREFERENCE,EPISODIC \
  --expiry 30           # Days until events expire (7-365, default 30)

# With Kinesis streaming
agentcore add memory \
  --name MyMemory \
  --strategies SEMANTIC \
  --data-stream-arn arn:aws:kinesis:us-east-1:123456789012:stream/my-stream \
  --stream-content-level FULL_CONTENT

Memory Configuration in project.json

{
  "memories": [
    {
      "name": "MyMemory",
      "eventExpiryDuration": 30,
      "strategies": [
        { "type": "SEMANTIC" },
        { "type": "SUMMARIZATION" },
        { "type": "USER_PREFERENCE" },
        { "type": "EPISODIC", "reflectionNamespaces": ["/episodes/{actorId}"] }
      ]
    }
  ]
}

How Agents Discover Memory

Each memory gets an environment variable: MEMORY_<UPPERCASENAME>_ID

  • MyMemory โ†’ MEMORY_MYMEMORY_ID
  • SharedMemory โ†’ MEMORY_SHAREDMEMORY_ID
  • prod_memory โ†’ MEMORY_PROD_MEMORY_ID
import os
memory_id = os.getenv("MEMORY_MYMEMORY_ID")

Memory Integration in Strands Agents

import os
from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig, RetrievalConfig
from bedrock_agentcore.memory.integrations.strands.session_manager import AgentCoreMemorySessionManager

MEMORY_ID = os.getenv("MEMORY_MYMEMORY_ID")
REGION = os.getenv("AWS_REGION")

def get_memory_session_manager(session_id: str, actor_id: str):
    if not MEMORY_ID:
        return None
    retrieval_config = {
        f"/users/{actor_id}/facts": RetrievalConfig(top_k=3, relevance_score=0.5),
        f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5)
    }
    return AgentCoreMemorySessionManager(
        AgentCoreMemoryConfig(
            memory_id=MEMORY_ID, session_id=session_id,
            actor_id=actor_id, retrieval_config=retrieval_config,
        ), REGION
    )

Adding Memory to an Existing Agent

# 1. Add memory resource
agentcore add memory --name MyMemory --strategies SEMANTIC,SUMMARIZATION

# 2. Create memory directory
mkdir -p app/MyAgent/memory

# 3. Create app/MyAgent/memory/session.py with session manager code (see above)

# 4. Update main.py to import and use it:
# from memory.session import get_memory_session_manager
# session_manager = get_memory_session_manager(session_id, user_id)
# agent = Agent(model=..., session_manager=session_manager)

# 5. Deploy
agentcore deploy
Sharing Memory Across Agents: Memory is a flat top-level resource. Multiple agents can share the same memory by reading the same MEMORY_SHAREDMEMORY_ID env var. Useful for multi-agent workflows where agents need shared context.

Hands-On Labs

โ–ผ
cd ~/myagentcore
agentcore add memory --name SharedMemory --strategies SEMANTIC,SUMMARIZATION --expiry 30
cat agentcore/project.json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d['memories'], indent=2))"

Questions: What env var does the agent use to find this memory? What strategies are configured? What is the expiry?

โ–ผ
cd ~/myagentcore
ls app/myagentcore/ 2>/dev/null

# Preview what memory integration code would be generated:
agentcore create \
  --name memorytest \
  --framework Strands \
  --model-provider Bedrock \
  --memory longAndShortTerm \
  --dry-run
โ–ผ
cd ~/myagentcore
agentcore status --type memory
agentcore add memory --help
โ–ผ
agentcore add memory --help

Which strategy would you use for a customer support agent that needs to remember user preferences across sessions?

Knowledge Check

Q1: You create a memory named CustomerData. What environment variable does the agent use to get its ID?
a) AGENTCORE_MEMORY_CustomerData
b) MEMORY_ID_CUSTOMERDATA
c) MEMORY_CUSTOMERDATA_ID
d) AGENTCORE_MEMORY_ID
Answer: C โ€” The pattern is MEMORY_<UPPERCASENAME>_ID. CustomerData โ†’ MEMORY_CUSTOMERDATA_ID.
Q2: Which memory strategy extracts and stores explicit user preferences like "I prefer email notifications"?
a) SEMANTIC
b) SUMMARIZATION
c) USER_PREFERENCE
d) EPISODIC
Answer: C โ€” USER_PREFERENCE is specifically for storing explicit preferences expressed by users.
Q3: Memory named SharedMemory is referenced by Agent A and Agent B. Which statement is true?
a) Each agent gets its own isolated copy of SharedMemory
b) Both agents read from and write to the same memory store
c) Only the first agent to deploy gets access
d) Sharing memory requires a special --shared flag on both agents
Answer: B โ€” Memory is a flat top-level resource, not owned by any agent. Both read from and write to the same store โ€” there's no per-agent isolation unless you use different namespaces.
Q4: What does eventExpiryDuration: 30 mean in a memory config?
a) Memory records are automatically deleted after 30 days
b) Raw conversation events expire after 30 days (extracted facts/summaries persist)
c) The memory strategy runs every 30 days
d) Sessions expire after 30 days of inactivity
Answer: B โ€” eventExpiryDuration controls the raw event log retention. Extracted memories (facts, summaries, preferences) are stored separately and persist beyond this window.
Q5: After adding memory and memory/session.py to an existing agent, what else must you do?
a) Nothing โ€” the runtime auto-detects memory files
b) Update project.json to link the memory to the agent
c) Update main.py to import and pass the session manager to the Agent constructor, then redeploy
d) Run agentcore add memory --attach MyAgent
Answer: C โ€” You must update main.py to import get_memory_session_manager, call it with session_id and user_id, and pass the result to Agent(...). Then agentcore deploy.

Key Takeaways

  • Three shorthands: none, shortTerm (events only), longAndShortTerm (all 4 strategies)
  • Four strategies: SEMANTIC (vector search), SUMMARIZATION (compress history), USER_PREFERENCE (prefs), EPISODIC (episodes)
  • Memory is discovered via env var: MEMORY_<UPPERCASENAME>_ID
  • Memory is a flat resource โ€” easily shared across multiple agents
  • Namespaces scope retrieval by user (actorId) and session (sessionId)
  • eventExpiryDuration controls raw event log (not extracted memories)
  • Stream memory changes to Kinesis for event-driven architectures

Module 07 โ€” Gateway & Gateway Targets

  • Explain what an AgentCore Gateway is and why it exists
  • Add gateways and gateway targets using the CLI
  • Configure all five target types correctly
  • Understand inbound and outbound authentication options

What Is a Gateway?

An AgentCore Gateway is an MCP-compatible proxy that sits between your agent and its tools. Instead of your agent calling APIs directly, it calls the gateway, which discovers available tools from all configured targets, routes tool calls to the correct backend, handles authentication, and optionally enforces Cedar policies.

Analogy: A gateway is like an API gateway that speaks MCP. Your agent only needs to know the gateway URL.

Agent GatewayMCP proxy mcp-server api-gateway open-api-schema smithy-model lambda-function-arn
Security Note: Always set --authorizer-type AWS_IAM or CUSTOM_JWT in production. NONE auth (the default) leaves the gateway endpoint open to anyone with the URL within your AWS account boundary. For external-facing gateways, CUSTOM_JWT with an OIDC provider is recommended.

Quick Start Pattern

# Recommended order: gateway BEFORE agent (new agents auto-wire gateway client code)
# 1. Create project
agentcore create --name MyProject --framework Strands --model-provider Bedrock --memory none
cd MyProject

# 2. Add gateway
agentcore add gateway --name my-gateway

# 3. Add target(s)
agentcore add gateway-target \
  --type mcp-server \
  --name weather-tools \
  --endpoint https://mcp.example.com/mcp \
  --gateway my-gateway

# 4. Create agent (automatically gets gateway client code)
agentcore add agent --name MyAgent --framework Strands --model-provider Bedrock --memory none

# 5. Deploy
agentcore deploy -y

agentcore add gateway

# Simplest (no auth โ€” dev/testing)
agentcore add gateway --name my-gateway

# Production with CUSTOM_JWT
agentcore add gateway \
  --name my-gateway \
  --authorizer-type CUSTOM_JWT \
  --discovery-url https://idp.example.com/.well-known/openid-configuration \
  --allowed-audience my-api \
  --allowed-clients my-client-id \
  --client-id agent-client-id \
  --client-secret agent-client-secret
FlagDescription
--nameGateway name (alphanumeric + hyphens, 1-100 chars)
--authorizer-typeNONE (default), AWS_IAM, CUSTOM_JWT
--no-semantic-searchDisable semantic tool discovery
--exception-levelNONE (default) or ALL (returns full error detail)
--policy-engineAttach a Cedar policy engine

Five Gateway Target Types

1. mcp-server

agentcore add gateway-target \
  --type mcp-server \
  --name weather-tools \
  --endpoint https://mcp.example.com/mcp \
  --gateway my-gateway \
  --outbound-auth oauth \
  --oauth-client-id my-client \
  --oauth-client-secret my-secret \
  --oauth-discovery-url https://auth.example.com/.well-known/openid-configuration

2. api-gateway

agentcore add gateway-target \
  --type api-gateway \
  --name PetStore \
  --rest-api-id abc123 \
  --stage prod \
  --tool-filter-path '/pets/*' \
  --tool-filter-methods GET,POST \
  --gateway my-gateway

3. open-api-schema

# Requires outbound auth (oauth or api-key)
agentcore add gateway-target \
  --type open-api-schema \
  --name PetStoreAPI \
  --schema specs/petstore.json \
  --gateway my-gateway \
  --outbound-auth oauth \
  --credential-name MyOAuth

4. smithy-model

# IAM role auth exclusively โ€” no outbound auth flags needed
agentcore add gateway-target \
  --type smithy-model \
  --name MyService \
  --schema models/service.json \
  --gateway my-gateway

5. lambda-function-arn

# IAM role auth exclusively
agentcore add gateway-target \
  --type lambda-function-arn \
  --name MyLambdaTools \
  --lambda-arn arn:aws:lambda:us-east-1:123456789012:function:my-func \
  --tool-schema-file tools.json \
  --gateway my-gateway

Auth Matrix

Target TypeOutbound Auth Options
mcp-serveroauth or none
api-gatewayapi-key or none
open-api-schemaoauth or api-key (required)
smithy-modelIAM role only (no flag needed)
lambda-function-arnIAM role only (no flag needed)

Inbound Auth

TypeDescriptionWhen to Use
NONENo auth (open)Dev/testing only
AWS_IAMSigV4 signed requestsAWS-native agents
CUSTOM_JWTOIDC/JWT validationExternal IdPs, M2M

Hands-On Labs

โ–ผ
cd ~/myagentcore
agentcore add gateway --name my-gateway
cat agentcore/project.json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('agentCoreGateways',[]), indent=2))"

Questions: What authorizer type is configured by default? What env var does the agent use to find this gateway's URL?

โ–ผ
agentcore add gateway-target --help

Observe: What are the five --type values? Which target types require --schema? Which support --outbound-auth oauth?

โ–ผ
Pre-requisite: Run agentcore deploy -y after adding the gateway in Lab 7.1.
cd ~/myagentcore
agentcore fetch access --name my-gateway --type gateway --json

What URL does the gateway expose? What auth method is in use?

โ–ผ
Pre-requisite: Gateway deployed from Lab 7.3.
cd ~/myagentcore
agentcore status --type gateway
agentcore invoke "What tools do you have available?" --stream

Knowledge Check

Q1: An open-api-schema gateway target requires what for outbound authentication?
a) No auth โ€” it uses the public API
b) IAM role only
c) Either oauth or api-key โ€” outbound auth is required
d) Only oauth is supported for OpenAPI targets
Answer: C โ€” open-api-schema targets require outbound auth (oauth or api-key). Unlike mcp-server which can use none, OpenAPI schema targets must have outbound auth configured.
Q2: You want to connect your gateway to an existing Lambda function. Which target type do you use?
a) mcp-server
b) api-gateway
c) smithy-model
d) lambda-function-arn
Answer: D โ€” lambda-function-arn is the target type for connecting to an existing Lambda function by its ARN. You also need --tool-schema-file.
Q3: For a lambda-function-arn target, how does the gateway authenticate with the Lambda?
a) API key passed in a header
b) OAuth client credentials flow
c) IAM role (automatic, no configuration needed)
d) Bearer token from CUSTOM_JWT
Answer: C โ€” Lambda function ARN targets use IAM role authentication exclusively. The gateway's execution role gets lambda:InvokeFunction permission. No outbound auth flags needed.
Q4: You set up a gateway with --authorizer-type CUSTOM_JWT and provide --client-id and --client-secret. What does the CLI create automatically?
a) A Cognito User Pool
b) A managed OAuth credential that the agent uses to get Bearer tokens at runtime
c) An API Gateway authorizer
d) An IAM role for the gateway
Answer: B โ€” When you provide --client-id and --client-secret, the CLI creates a managed OAuth credential in AgentCore Identity (Secrets Manager). The agent's generated code uses this to obtain Bearer tokens automatically.
Q5: What environment variable does the agent use to find the gateway URL at runtime?
a) GATEWAY_URL
b) AGENTCORE_GATEWAY_URL
c) AGENTCORE_GATEWAY_<NAME>_URL (where NAME is uppercased)
d) MCP_SERVER_URL
Answer: C โ€” The pattern is AGENTCORE_GATEWAY_<UPPERCASENAME>_URL. So a gateway named my-gateway โ†’ AGENTCORE_GATEWAY_MY_GATEWAY_URL.

Key Takeaways

  • Gateway = MCP-compatible proxy between agent and tools
  • Create gateway BEFORE creating agents โ€” new agents auto-wire gateway client code
  • Five target types: mcp-server, api-gateway, open-api-schema, smithy-model, lambda-function-arn
  • Lambda and Smithy targets use IAM role auth exclusively (no flags needed)
  • open-api-schema requires outbound auth; mcp-server and api-gateway support none
  • Inbound auth: NONE (dev), AWS_IAM (native), CUSTOM_JWT (external IdPs)
  • Gateway URL injected as AGENTCORE_GATEWAY_<NAME>_URL env var at runtime
  • --exception-level valid values: NONE or ALL (not DEBUG)

Module 08 โ€” Credentials & Identity

  • Understand AgentCore's identity model and how credentials flow
  • Add API key and OAuth credential providers
  • Understand inbound vs outbound credentials
  • Know where secrets are stored locally vs in AWS

The Identity Problem AgentCore Solves

AgentCore Identity uses AWS Secrets Manager under the hood to store credentials securely. Your agent code never sees the raw secret โ€” it's injected at runtime through the AgentCore Identity service.

Two Types of Credentials

1. API Key Credentials

agentcore add credential \
  --name OpenAI \
  --api-key sk-...

# Or just name it โ€” CLI will prompt for the key
agentcore add credential --name MyTool

Stored in: local dev โ€” .env.local as AGENTCORE_CREDENTIAL_<PROJECT><NAME>=<value> | deployed โ€” AgentCore Identity (Secrets Manager)

2. OAuth Credentials

agentcore add credential \
  --name MyOAuthProvider \
  --type oauth \
  --discovery-url https://idp.example.com/.well-known/openid-configuration \
  --client-id my-client-id \
  --client-secret my-client-secret \
  --scopes read,write

Credential Configuration in project.json

{
  "credentials": [
    { "authorizerType": "ApiKeyCredentialProvider", "name": "OpenAI" },
    {
      "authorizerType": "OAuthCredentialProvider",
      "name": "MyOAuthProvider",
      "discoveryUrl": "https://idp.example.com/.well-known/openid-configuration",
      "scopes": ["read", "write"]
    }
  ]
}
Key rule: The actual secrets are NOT stored in project.json โ€” only the configuration. Secrets live in .env.local (local) and Secrets Manager (deployed).

The .env.local File

# API key credential named "OpenAI" in project "MyProject"
AGENTCORE_CREDENTIAL_MYPROJECTOPENAI=sk-...

# OAuth credential named "MyOAuth" in project "MyProject"
AGENTCORE_CREDENTIAL_MYPROJECTMYOAUTH_CLIENT_ID=my-client-id
AGENTCORE_CREDENTIAL_MYPROJECTMYOAUTH_CLIENT_SECRET=my-secret

Pattern: AGENTCORE_CREDENTIAL_<PROJECTNAME><CREDNAME> (all uppercase, no separators).

Credentials for Gateway Outbound Auth

# Named credential (reusable across multiple targets)
agentcore add credential \
  --name MyOAuthProvider \
  --type oauth \
  --discovery-url https://auth.example.com/.well-known/openid-configuration \
  --client-id my-client \
  --client-secret my-secret

agentcore add gateway-target \
  --type mcp-server \
  --name secure-tools \
  --endpoint https://api.example.com/mcp \
  --gateway my-gateway \
  --outbound-auth oauth \
  --credential-name MyOAuthProvider

# Inline (single-target, not reusable)
agentcore add gateway-target \
  --type mcp-server \
  --name secure-tools \
  --endpoint https://api.example.com/mcp \
  --gateway my-gateway \
  --outbound-auth oauth \
  --oauth-client-id my-client \
  --oauth-client-secret my-secret \
  --oauth-discovery-url https://auth.example.com/.well-known/openid-configuration

Inbound vs Outbound Authentication

DirectionWhat It IsConfig Location
InboundHow callers authenticate TO your agent or gatewayauthorizerType on agent/gateway
OutboundHow your agent/gateway authenticates TO upstream servicesoutboundAuth on gateway targets

Inbound options: AWS_IAM (default for agents), CUSTOM_JWT, NONE (gateways only, dev)

Outbound options: none, api-key, oauth, IAM role (implicit for Lambda/Smithy)

CUSTOM_JWT Deep Dive

agentcore add agent \
  --name MyAgent \
  --framework Strands \
  --authorizer-type CUSTOM_JWT \
  --discovery-url https://idp.example.com/.well-known/openid-configuration \
  --allowed-audience my-api \
  --allowed-clients my-client-id \
  --allowed-scopes read write \
  --client-id agent-bearer-client \
  --client-secret agent-bearer-secret \
  --custom-claims '[{"claim": "tenant_id", "value": "acme-corp"}]'
Credential Rotation Pattern: (1) agentcore add credential --name MyAPI --api-key <new-key> updates .env.local. (2) agentcore deploy pushes the new key to Secrets Manager. (3) The next agent invocation picks up the new secret automatically. Zero-downtime rotation.

Hands-On Labs

โ–ผ
cd ~/myagentcore
cat agentcore/project.json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('credentials',[]), indent=2))"

Questions: What credentials are defined? Are they API key or OAuth type? Where is a non-Bedrock model provider's credential stored?

โ–ผ
cd ~/myagentcore
ls -la agentcore/.env.local 2>/dev/null && \
  grep -o 'AGENTCORE_[A-Z_]*' agentcore/.env.local 2>/dev/null || \
  echo "No .env.local yet"

What env var names follow the AGENTCORE_CREDENTIAL_<PROJECTNAME><CREDNAME> pattern?

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore
agentcore status --type credential --json

Knowledge Check

Q1: Your project is named MyProject and you have a credential named WeatherAPI. What is the key name in .env.local?
a) WEATHER_API_KEY
b) AGENTCORE_CREDENTIAL_MYPROJECTWEATHERAPI
c) AGENTCORE_MYPROJECT_WEATHERAPI
d) CREDENTIAL_WEATHERAPI
Answer: B โ€” Pattern: AGENTCORE_CREDENTIAL_<PROJECTNAME><CREDNAME> all uppercase, no separators.
Q2: What is the difference between "inbound auth" and "outbound auth" in the gateway context?
a) Inbound = how agents call each other; outbound = how agents call AWS services
b) Inbound = how callers authenticate to the gateway; outbound = how the gateway authenticates to targets
c) They always use different auth methods (inbound = JWT, outbound = API key)
d) They are the same thing, just different names
Answer: B โ€” Inbound controls who can call the gateway. Outbound controls how the gateway identifies itself to upstream backend services. These are independent configurations.
Q3: A lambda-function-arn gateway target uses what outbound authentication?
a) API key passed in the x-api-key header
b) OAuth client credentials
c) IAM role (automatic, no configuration)
d) No authentication โ€” Lambda functions are always public
Answer: C โ€” Lambda function ARN targets use IAM role authentication automatically. The gateway's execution role gets lambda:InvokeFunction permission.
Q4: What is an advantage of creating a separate named credential with agentcore add credential instead of inline?
a) Inline credentials are less secure
b) Named credentials can be reused across multiple gateway targets
c) Separate credentials support more auth types
d) There is no advantage
Answer: B โ€” Named credentials can be referenced by name across multiple gateway targets with --credential-name. Inline credentials create a one-off credential tied to that specific target.
Q5: Actual secret values (API keys, client secrets) are stored in project.json. True or false?
a) True โ€” all config is in project.json
b) False โ€” project.json stores config only; secrets are in .env.local (local) and Secrets Manager (deployed)
Answer: B โ€” False. project.json contains ONLY configuration (names, URLs, types). Actual secrets live in .env.local (local dev) and AgentCore Identity (Secrets Manager) for deployed environments. You can safely commit project.json.

Key Takeaways

  • Two credential types: ApiKeyCredentialProvider (string secret) and OAuthCredentialProvider (client credentials)
  • Secrets are NEVER in project.json โ€” they're in .env.local (local) and Secrets Manager (deployed)
  • Local env var pattern: AGENTCORE_CREDENTIAL_<PROJECTNAME><CREDNAME>
  • Inbound auth = who can call your resource; outbound auth = how your resource calls upstream
  • Named credentials are reusable; inline credentials are single-target
  • Lambda and Smithy targets use IAM role auth exclusively
  • CUSTOM_JWT enables external IdPs, M2M flows, non-AWS callers

Module 9 โ€” Observability: Logs & Traces

  • Stream and search agent runtime logs using agentcore logs
  • List and download traces using agentcore traces
  • Understand the structure of a trace and what it contains
  • Debug common agent issues using logs and traces
  • Use JSON output to build observability workflows
SRE Context: Agents are non-deterministic โ€” the same input can produce different reasoning paths. Traditional unit testing doesn't tell you why the agent chose tool A over tool B. Logs tell you what happened; traces tell you why. You need both.

The agentcore logs Command

Stream or search agent runtime logs from CloudWatch.

# Stream logs in real-time (follow mode โ€” Ctrl+C to stop)
agentcore logs

# Target a specific runtime
agentcore logs --runtime MyAgent

# Search historical logs (last 1 hour for errors)
agentcore logs --since 1h --level error

# Search a time range
agentcore logs --since 2d --until 1d --query "timeout"

# JSON Lines output (one JSON object per line)
agentcore logs --json

# Limit number of lines
agentcore logs --since 1h -n 100

Time Format Options

Both --since and --until accept relative (30m, 1h, 2d) or ISO 8601 (2026-05-13T10:00:00Z) timestamps. With no flags, the command streams in real-time.

Log Levels

LevelUseFlag
debugVerbose internal detail--level debug
infoNormal operations--level info
warnWarnings--level warn
errorErrors only--level error

All logs Flags

FlagDescription
--runtime <name>Target specific runtime
--since <time>Start time (defaults to 1h ago in search mode)
--until <time>End time (defaults to now)
--level <level>Filter: error, warn, info, debug
-n, --limit <n>Max lines to return
--query <text>Server-side text filter
--jsonJSON Lines output

Traces: agentcore traces list / get

Traces capture the full reasoning chain for one agent invocation. They take 5โ€“10 minutes to appear after an invocation โ€” processed asynchronously.

# List recent traces
agentcore traces list
agentcore traces list --runtime MyAgent --limit 50
agentcore traces list --since 1h

# Download a full trace by ID
agentcore traces get <traceId>
agentcore traces get abc123 --output ./debug-trace.json
agentcore traces get abc123 --runtime MyAgent

What's In a Trace?

FieldDescription
InputThe user's prompt
ThinkingThe LLM's reasoning steps
Tool callsWhich tools were invoked, with input arguments
Tool resultsWhat each tool returned
OutputThe final agent response
TimingLatency at each step
Session/user IDsFor multi-turn context correlation
Debugging tip: "Why did the agent call the wrong tool?" โ€” the trace shows you exactly what context it had when it made that decision. Look at the Thinking and Tool calls fields.

Observability Architecture

Agent Runtime myagentcore CloudWatch Logs agentcore logs X-Ray Traces agentcore traces AgentCore CLI agentcore logs agentcore traces list agentcore traces get --json | jq ... Eval Logs (agentcore logs evals)

Debugging Patterns

# Pattern 1: Find recent errors
agentcore logs --since 1h --level error

# Pattern 2: Debug a specific invocation
agentcore invoke "Hello" --json > response.json
agentcore traces list --runtime MyAgent --limit 5
agentcore traces get <traceId> --output ./debug.json

# Pattern 3: Real-time monitoring while testing
# Terminal 1: agentcore logs --runtime MyAgent
# Terminal 2: agentcore invoke "Test message"

# Pattern 4: Search for a specific error
agentcore logs --since 24h --level error --query "timeout"

# Pattern 5: JSON pipeline for custom analysis
agentcore logs --since 1h --level error --json | \
  jq -r '[.timestamp, .message] | @tsv'

Quick Troubleshooting Reference

SymptomFirst CommandWhat to Look For
Agent returns wrong answeragentcore traces get <id>Tool call inputs โ€” was context correct?
Agent ignores a toolagentcore traces listAvailable tools list in trace; gateway reachable?
Invocation timeoutagentcore logs --level error --since 1h"timeout" or "deadline exceeded" messages
No traces appearingagentcore status --runtime MyAgentIs state "deployed"? Wait 5โ€“10 min after invoke
Gateway auth failureagentcore logs --since 1h --query "401"401/403 responses from gateway targets
Memory not persistingagentcore logs --since 1h --query "memory"Memory errors; check MEMORY_ID env var

Hands-On Labs

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore

# Stream logs in real-time (Ctrl+C to stop)
agentcore logs --runtime myagentcore

# Or search recent logs
agentcore logs --runtime myagentcore --since 30m

What do you observe? Are there any errors? What log level are most messages?

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore

# Step 1: Invoke the agent
agentcore invoke "What tools do you have available?" --json

# Step 2: Wait 5-10 minutes for traces to propagate
# Then list traces
agentcore traces list --runtime myagentcore --limit 5

# Step 3: If a trace ID shows up, download it
# agentcore traces get <traceId> --output ./my-trace.json

How many steps appear in the trace? Can you see the tool selection reasoning?

โ–ผ
cd ~/myagentcore

# Search for any errors in the last 24 hours
agentcore logs --runtime myagentcore --since 24h --level error

# If no errors, search for info messages
agentcore logs --runtime myagentcore --since 1h --level info -n 20

# JSON pipeline: count log levels
agentcore logs --since 1h --json 2>/dev/null | jq '.level' | sort | uniq -c
โ–ผ
cd ~/myagentcore

# What's the current deployment state of all resources?
agentcore status --json | python3 -c "
import sys, json
data = json.load(sys.stdin)
for r in data.get('resources', []):
    print(f\"{r['resourceType']:20} {r['name']:30} {r['state']}\")
"

Are all resources in deployed state? Any in error or updating?

Knowledge Check

Q1: You invoke an agent and want to see the trace. How long should you wait before listing traces?
a) Immediately โ€” traces are real-time
b) About 5โ€“10 minutes โ€” traces are processed asynchronously
c) Up to 1 hour
d) Until the next day โ€” traces are batched daily
Answer: b โ€” Traces take 5โ€“10 minutes to appear after invocation. They're processed asynchronously by the trace pipeline. If you list traces immediately and see nothing, wait and try again.
Q2: You want to see all error logs from the last 2 hours. Which command is correct?
a) agentcore logs --time 2h --filter error
b) agentcore logs --since 2h --level error
c) agentcore logs --last 2h --severity error
d) agentcore logs --hours 2 --level error
Answer: b โ€” --since 2h and --level error is the correct syntax. The --since flag accepts relative times like 30m, 1h, 2d.
Q3: Which command saves the full trace to a file so you can share it?
a) agentcore traces save <traceId> trace.json
b) agentcore traces get <traceId> --output trace.json
c) agentcore traces export <traceId> --file trace.json
d) agentcore logs --trace <traceId> > trace.json
Answer: b โ€” agentcore traces get <traceId> --output <path> downloads and saves the full trace. The --output flag writes to a file rather than printing to stdout.
Q4: What does agentcore logs --json produce?
a) A single JSON array with all log entries
b) JSON Lines (one JSON object per line)
c) Pretty-printed JSON to stdout
d) A JSON file written to the current directory
Answer: b โ€” --json outputs JSON Lines format โ€” one valid JSON object per line. This is designed for piping through tools like jq and log processors that handle streaming line-by-line.
Q5: You want to monitor logs for agent DataProcessor in real-time. Which command?
a) agentcore logs --runtime DataProcessor --follow
b) agentcore logs --runtime DataProcessor (streaming is the default with no time flags)
c) agentcore logs --runtime DataProcessor --stream
d) agentcore logs --runtime DataProcessor --tail
Answer: b โ€” agentcore logs with no time flags defaults to follow/streaming mode. Adding --runtime scopes it to a specific agent. Ctrl+C to stop.

Key Takeaways

  • agentcore logs โ€” streaming or historical search; --level error for filtering; --since 1h for time range
  • agentcore traces list โ€” see recent invocation traces (allow 5โ€“10 min after invoke)
  • agentcore traces get <id> --output file.json โ€” full trace for detailed debugging or sharing
  • --json outputs JSON Lines โ€” one object per line, perfect for jq pipelines
  • agentcore logs evals โ€” separate command for evaluation/monitoring logs
  • Debugging workflow: invoke โ†’ wait 5โ€“10 min โ†’ list traces โ†’ get trace โ†’ examine tool calls
  • agentcore status --json โ€” check deployment state of all resources programmatically

Module 10 โ€” Evaluations

  • Create custom LLM-as-a-Judge evaluators with rating scales and placeholders
  • Run on-demand evaluations against historical agent traces
  • Set up continuous online evaluations for live traffic sampling
  • Use builtin evaluators like Builtin.Faithfulness
  • Interpret evaluation scores and build CI/CD quality gates
Why Evaluate Agents? Agent quality is subjective and hard to measure with traditional tests. Did the agent actually fulfill the user's request? Select the right tool? Give a faithful answer? AgentCore Evaluations use LLM-as-a-Judge โ€” a separate LLM grades the agent's responses against your rubric.

Four Evaluation Concepts

ConceptDescription
EvaluatorA custom LLM judge: model + instructions + rating scale
On-demand evalOne-off run against historical traces
Online evalContinuous sampling and scoring of live traffic
Builtin evaluatorPre-built evaluators (e.g. Builtin.Faithfulness)

Three Evaluation Levels

LevelWhat It Evaluates
SESSIONOverall quality across an entire conversation
TRACEPer-turn accuracy of individual agent responses
TOOL_CALLCorrectness of individual tool selections

Creating Evaluators

# Interactive wizard
agentcore add evaluator

# Non-interactive
agentcore add evaluator \
  --name ResponseQuality \
  --level SESSION \
  --model us.anthropic.claude-sonnet-4-5-20250514-v1:0 \
  --instructions "Evaluate the agent response quality. Context: {context}" \
  --rating-scale 1-5-quality

Instruction Placeholders

Your --instructions must include placeholders appropriate for the level:

PlaceholderAvailable AtWhat It Contains
{context}SESSION, TRACE, TOOL_CALLFull conversation history
{assistant_turn}TRACE onlyThe specific assistant response being judged
{available_tools}SESSION, TOOL_CALLList of available tools
{tool_turn}TOOL_CALL onlyThe specific tool call + result
# SESSION โ€” did the agent complete the task?
"Evaluate whether the agent fulfilled the user's request. Context: {context}"

# TRACE โ€” per-turn accuracy
"Rate the accuracy of this response. Context: {context}. Response: {assistant_turn}"

# TOOL_CALL โ€” did it pick the right tool?
"Evaluate tool selection. Context: {context}. Tool call: {tool_turn}"

Rating Scale Presets

PresetTypeValues
1-5-qualityNumericalPoor(1), Fair(2), Good(3), Very Good(4), Excellent(5)
1-3-simpleNumericalLow(1), Medium(2), High(3)
pass-failCategoricalPass, Fail
good-neutral-badCategoricalGood, Neutral, Bad

Score Normalization

Scores normalize to 0.0โ€“1.0 regardless of scale. AgentCore uses value/max:

  • 1-5 scale: score 4 โ†’ 4/5 = 0.8
  • pass-fail: Pass โ†’ 1.0, Fail โ†’ 0.0
  • 1-3 scale: score 2 โ†’ 2/3 โ‰ˆ 0.67

Running Evaluations

On-Demand Evaluations

# Evaluate a specific agent against recent traces
agentcore run eval \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --days 7

# Multiple evaluators
agentcore run eval \
  --runtime MyAgent \
  --evaluator ResponseQuality Builtin.Faithfulness \
  --days 14

# Target a specific session
agentcore run eval \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --session-id abc123 \
  --days 7

# Save results to file
agentcore run eval --runtime MyAgent --evaluator ResponseQuality --days 7 --output ./eval-result.json

# View eval history
agentcore evals history
agentcore evals history --runtime MyAgent --limit 5
agentcore evals history --json
Note: Traces must exist first. Traces take 5โ€“10 minutes to propagate after invocation. Results are stored locally in agentcore/.cli/eval-runs/.

Online Evaluations (Continuous Monitoring)

# Set up continuous evaluation (samples X% of live requests)
agentcore add online-eval \
  --name QualityMonitor \
  --runtime MyAgent \
  --evaluator ResponseQuality Builtin.Faithfulness \
  --sampling-rate 10   # evaluate 10% of requests

# Enable immediately on deploy
agentcore add online-eval \
  --name QualityMonitor \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --sampling-rate 5 \
  --enable-on-create

# Pause and resume
agentcore pause online-eval QualityMonitor
agentcore resume online-eval QualityMonitor
Sampling RateUse Case
1โ€“5%Production monitoring (cost-sensitive)
10โ€“25%Development and staging
100%Full coverage during testing

Builtin Evaluators

# Use a builtin โ€” no custom definition needed
agentcore run eval --runtime MyAgent --evaluator Builtin.Faithfulness

# Mix builtins with custom evaluators
agentcore run eval --runtime MyAgent --evaluator ResponseQuality Builtin.Faithfulness

Removal Constraint

# Wrong order โ€” will fail if referenced by an online eval config
agentcore remove evaluator --name ResponseQuality

# Right order: remove online eval config first
agentcore remove online-eval --name QualityMonitor
agentcore remove evaluator --name ResponseQuality

CI/CD Quality Gate Pattern

# Run eval and fail pipeline if score is below threshold
result=$(agentcore run eval --runtime MyAgent --evaluator ResponseQuality --days 1 --json)
score=$(echo "$result" | jq '.run.results[0].aggregateScore')

if (( $(echo "$score < 0.7" | bc -l) )); then
  echo "Quality gate FAILED: score $score < 0.7"
  exit 1
fi

echo "Quality gate PASSED: score $score"

Full Eval Setup Workflow

# 1. Add a custom evaluator
agentcore add evaluator \
  --name ResponseQuality \
  --level SESSION \
  --model us.anthropic.claude-sonnet-4-5-20250514-v1:0 \
  --instructions "Evaluate whether the agent fulfilled the user's request. Context: {context}"

# 2. Deploy (creates the evaluator in AWS)
agentcore deploy -y

# 3. Generate traces
agentcore invoke "Hello, what can you do?"
agentcore invoke "Search AWS docs for S3 pricing"

# 4. Wait ~10 min, then run on-demand eval
agentcore run eval --runtime MyAgent --evaluator ResponseQuality --days 1

# 5. Review results
agentcore evals history --runtime MyAgent

# 6. Set up continuous monitoring
agentcore add online-eval \
  --name QualityMonitor \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --sampling-rate 10
agentcore deploy -y

Hands-On Labs

โ–ผ
cd ~/myagentcore

cat agentcore/project.json | \
  python3 -c "
import sys, json
d = json.load(sys.stdin)
evals = d.get('evaluators', [])
online = d.get('onlineEvalConfigs', [])
print('Evaluators:', json.dumps(evals, indent=2))
print('Online eval configs:', json.dumps(online, indent=2))
"

Are any evaluators configured? Are there online eval configs?

โ–ผ
cd ~/myagentcore
agentcore evals history --json 2>/dev/null || echo "No eval history yet"
โ–ผ

Without running any commands, design an evaluator for the myagentcore agent:

  • Name: DocSearchQuality
  • Level: SESSION
  • What instructions would you write? What placeholder(s) are needed?
  • What rating scale makes sense?

Write out the agentcore add evaluator command you would use, then compare to:

agentcore add evaluator \
  --name DocSearchQuality \
  --level SESSION \
  --model us.anthropic.claude-sonnet-4-5-20250514-v1:0 \
  --instructions "Evaluate whether the agent answered the user's question accurately and completely using the available documentation tools. Context: {context}" \
  --rating-scale 1-5-quality
โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore

# Generate traces to evaluate against later
agentcore invoke "What is Amazon Bedrock AgentCore?" --json
agentcore invoke "What are the differences between CodeZip and Container build types?" --json
agentcore invoke "How does the flat resource model work in AgentCore?" --json

These invocations generate traces. After deploying an evaluator, you can run agentcore run eval against them.

Knowledge Check

Q1: You add a TRACE-level evaluator. Which placeholder is available that is NOT available at SESSION level?
a) {context}
b) {available_tools}
c) {assistant_turn}
d) {tool_turn}
Answer: c โ€” {assistant_turn} is only available at TRACE level. It contains the specific assistant response being evaluated. At SESSION level you only have {context} and {available_tools}.
Q2: An agent gets a score of 4 on a 1-5 numerical scale. What is the normalized score?
a) 0.4
b) 0.8
c) 4.0
d) 80
Answer: b โ€” AgentCore uses value/max normalization: 4/5 = 0.8. This simple formula maps the score proportionally to the 0.0โ€“1.0 range.
Q3: You want to evaluate 5% of live traffic continuously. Which command sets this up?
a) agentcore run eval --runtime MyAgent --sampling 5
b) agentcore add online-eval --runtime MyAgent --evaluator MyEval --sampling-rate 5
c) agentcore add evaluator --continuous --rate 5
d) agentcore add online-eval --runtime MyAgent --evaluator MyEval --sampling-rate 5
Answer: d โ€” agentcore add online-eval creates the config with --sampling-rate 5 for 5% sampling. After adding, run agentcore deploy to activate it. (b and d are identical here โ€” the correct flag is --sampling-rate on add online-eval.)
Q4: You try to remove an evaluator and get an error. What is the most likely cause?
a) The evaluator is currently running an evaluation
b) The evaluator is referenced by an active online eval config
c) Evaluators cannot be removed once deployed
d) The evaluator has history that must be archived first
Answer: b โ€” AgentCore enforces referential integrity. You must remove the onlineEvalConfig that references the evaluator before you can remove the evaluator itself. This prevents broken references in deployed configurations.
Q5: How would you use Builtin.Faithfulness in an on-demand eval? (No custom definition needed.)
a) agentcore run eval --runtime MyAgent --builtin Faithfulness
b) agentcore run eval --runtime MyAgent --evaluator Builtin.Faithfulness
c) agentcore run eval --runtime MyAgent --evaluator-type builtin --name Faithfulness
d) You must first create a builtin evaluator with agentcore add evaluator --type builtin
Answer: b โ€” Reference builtin evaluators with the Builtin.<Name> prefix in the --evaluator flag. No setup required โ€” builtins are pre-deployed by AgentCore. You can mix builtins with custom evaluators.

Key Takeaways

  • LLM-as-a-Judge: a separate LLM grades your agent's responses against your rubric
  • Three evaluation levels: SESSION (whole conversation), TRACE (per turn), TOOL_CALL (per tool use)
  • Placeholders inject real data: {context}, {assistant_turn}, {tool_turn}, {available_tools}
  • Scores normalize to 0.0โ€“1.0: AgentCore uses value/max (e.g. 4 on 1-5 scale = 0.8)
  • agentcore run eval = on-demand; agentcore add online-eval = continuous sampling
  • Builtin.Faithfulness and other builtins work without custom definitions
  • Remove online eval configs before removing evaluators (referential integrity)
  • CI/CD gate: run eval โ†’ check JSON score โ†’ fail pipeline if below threshold

Module 11 โ€” Advanced Topics

  • Understand and use Config Bundles for versioned runtime configuration
  • Run batch evaluations across all agent sessions at scale
  • Use the run recommendation command to optimize agent prompts and tools
  • Configure Cedar policy engines for fine-grained tool authorization
  • Know the import command and multi-agent patterns (A2A/MCP protocols)

Config Bundles [preview]

Config bundles let you version, branch, and A/B test your agent's runtime configuration (prompts, model settings, tool descriptions) without redeploying code.

Why it matters: Change a system prompt, model temperature, or tool description โ†’ deploy a new bundle version โ†’ test it โ†’ promote or roll back. No code change, no CDK synthesis + CloudFormation redeploy cycle.
# Add a config bundle to your project
agentcore add config-bundle --name MyBundle

# List versions of a bundle
agentcore config-bundle versions MyBundle
# or: agentcore cb versions MyBundle

# Diff two versions
agentcore cb diff MyBundle --v1 1 --v2 2

# Create a new branch (for A/B testing)
agentcore cb create-branch MyBundle --branch experiment-a

# Promote a version (make it the primary)
agentcore promote config-bundle MyBundle --version 3

A/B Testing with Config Bundles

# View A/B test details and results
agentcore ab-test <testName>

# List A/B tests (use status, not list)
agentcore status --type ab-test

A/B tests route traffic between two bundle versions (or branches) to compare quality scores.

Creating an Agent with Config Bundle Support

agentcore add agent \
  --name MyAgent \
  --framework Strands \
  --model-provider Bedrock \
  --with-config-bundle

The --with-config-bundle flag auto-wires config bundle support. A configBundleName field is added to the runtime spec in project.json:

{
  "runtimes": [
    {
      "name": "MyAgent",
      "configBundleName": "MyBundle"
    }
  ]
}

Batch Evaluations [preview]

While on-demand evals run against a time window of traces, batch evaluations run across all sessions โ€” useful for comprehensive quality reporting and periodic audits.

# Run batch evaluation
agentcore run batch-evaluation \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --days 30

# Stop a running batch evaluation
agentcore stop batch-evaluation <jobId>

# View batch eval history
agentcore evals history --runtime MyAgent
Eval TypeUse CaseCommand
On-demandDebug a time window of tracesagentcore run eval
OnlineContinuous live traffic samplingagentcore add online-eval
BatchPeriodic audits across all sessionsagentcore run batch-evaluation

Recommendations [preview]

The run recommendation command uses AI to suggest improvements to your agent's prompts and tool descriptions based on evaluation results.

# Run recommendation analysis
agentcore run recommendation \
  --runtime MyAgent \
  --evaluator ResponseQuality \
  --days 7

# View recommendation history
agentcore recommendations
agentcore recommendations --runtime MyAgent

The output suggests specific changes: "Rewrite your system prompt to include X" or "The tool description for Y should be clearer about Z." This is the AI-powered optimization loop โ€” eval reveals weak spots, recommendations fix them.

Cedar Policy Engines

AgentCore integrates with Cedar for fine-grained authorization on gateway tool calls. Cedar is AWS's open-source authorization language used in IAM and Verified Permissions.

# Add a policy engine (attached to a gateway)
agentcore add policy-engine \
  --name MyPolicyEngine \
  --gateway my-gateway \
  --mode ENFORCE   # or LOG_ONLY

# Add a Cedar policy to the engine
agentcore add policy \
  --name AllowReadonly \
  --engine MyPolicyEngine \
  --policy-file ./policies/readonly.cedar

# Create gateway with policy engine
agentcore add gateway \
  --name my-gateway \
  --policy-engine MyPolicyEngine \
  --policy-engine-mode ENFORCE
ModeBehaviorWhen to Use
LOG_ONLYLogs policy decisions but does NOT block unauthorized callsInitial setup โ€” observe what would be blocked
ENFORCEActively denies unauthorized tool callsProduction โ€” after tuning policies in LOG_ONLY
Best practice: Always deploy in LOG_ONLY first. Observe what Cedar would have blocked. Tune policies. Then switch to ENFORCE. Avoids production outages from over-blocking.

The import Command

Import resources from an existing Bedrock AgentCore Starter Toolkit project, or import a deployed runtime/memory/gateway into the current CLI project model.

# Import from starter toolkit project
agentcore import --source ./old-toolkit-project

# Import a specific runtime by ARN
agentcore import --runtime-arn arn:aws:bedrock-agentcore:...

# Import a memory by ARN
agentcore import --memory-arn arn:aws:bedrock-agentcore:...

# Import a gateway
agentcore import --gateway-arn arn:aws:bedrock-agentcore:...

import updates project.json and deployed-state.json to reference the existing AWS resource โ€” letting you adopt the CLI project model without destroying and recreating existing deployments.

Multi-Agent Patterns

Orchestrator Agent calls others as tools Worker Agent --protocol A2A Specialist Agent --protocol MCP A2A protocol MCP protocol Any MCP Client Claude, other agents

A2A Protocol (Agent-to-Agent)

# Create an agent that exposes the A2A protocol
agentcore add agent \
  --name WorkerAgent \
  --framework Strands \
  --protocol A2A

An agent with --protocol A2A exposes itself as an A2A-compatible endpoint. Other agents discover and invoke it as a tool. It's the "tool server" side of A2A.

MCP Protocol (Agent as Tool Server)

agentcore add agent \
  --name SpecialistAgent \
  --framework Strands \
  --protocol MCP

This agent appears as a tool in any MCP client that connects to its endpoint โ€” including Claude, other AgentCore agents, or any MCP-compatible client.

Container Builds & VPC Networking

Container Builds

# Create with container build
agentcore add agent \
  --name MyAgent \
  --build Container \
  --framework Strands

# Customize the Dockerfile
cat app/MyAgent/Dockerfile

# Dev with container
agentcore dev            # builds and runs Docker locally
agentcore dev --exec "pip list"  # exec into local container

Container build flow: agentcore deploy โ†’ CodeBuild โ†’ Docker image (ARM64) โ†’ ECR โ†’ AgentCore runtime pulls from ECR.

VPC Networking

agentcore add agent \
  --name PrivateAgent \
  --framework Strands \
  --network-mode VPC \
  --subnets subnet-abc123,subnet-def456 \
  --security-groups sg-abc123

For agents that need to access private resources (RDS, private APIs). The runtime runs inside your VPC and accesses private resources through the VPC's routing.

CI/CD Pipeline Pattern (Full)

#!/bin/bash
# 1. Validate config
agentcore validate || exit 1

# 2. Preview changes
agentcore deploy --diff

# 3. Deploy
agentcore deploy -y --json

# 4. Verify deployment
agentcore status --json | jq '.resources[] | select(.state != "deployed")' | \
  grep -q '.' && { echo "Some resources not deployed!"; exit 1; }

# 5. Run smoke test
agentcore invoke "Health check" --json | jq -e '.response' || exit 1

# 6. Wait for traces
sleep 300  # 5 min

# 7. Quality gate
score=$(agentcore run eval --runtime MyAgent --evaluator QualityCheck --days 1 --json | \
  jq '.run.results[0].aggregateScore')
if (( $(echo "$score < 0.7" | bc -l) )); then
  echo "Quality gate failed: $score < 0.7"
  exit 1
fi
echo "Pipeline passed! Score: $score"

Other Advanced Features

Telemetry

agentcore telemetry --status    # Check current setting
agentcore telemetry --enable    # Opt in to anonymous analytics
agentcore telemetry --disable   # Opt out

Resource Tags for Cost Allocation

{
  "name": "MyProject",
  "tags": {
    "Environment": "production",
    "Team": "platform",
    "CostCenter": "engineering"
  },
  "runtimes": [
    {
      "name": "MyAgent",
      "tags": {
        "Environment": "staging"
      }
    }
  ]
}

Tags flow through to CloudFormation resources and appear in Cost Explorer. Runtime-level tags override project-level tags for the same key.

Hands-On Labs

โ–ผ
# Check what config-bundle commands are available
agentcore config-bundle --help
agentcore cb --help

# Check ab-test commands
agentcore ab-test --help

What operations are available on config bundles? Can you list bundles, diff versions, create branches?

โ–ผ
agentcore run batch-evaluation --help

# And the recommendation command
agentcore run recommendation --help

What flags are required for batch evaluation? What does --days control?

โ–ผ
agentcore add policy-engine --help
agentcore add policy --help

What modes are available? What policy format does it accept?

โ–ผ
agentcore import --help

What can you import? What types of ARNs does it accept?

โ–ผ
Pre-requisite: Run agentcore deploy -y before this lab.
cd ~/myagentcore

# Full config
cat agentcore/project.json | python3 -m json.tool

# What resources are deployed?
agentcore status

# Invoke the agent
agentcore invoke "Give me a summary of what Amazon Bedrock AgentCore is and what you can help me with" --stream

SME Challenge โ€” without referring to the docs, explain:

  1. How does the agent discover the gateway URL at runtime?
  2. How does the flat resource model enable sharing memory across multiple agents?
  3. What would happen if you renamed the agent in project.json and redeployed?
  4. What is the difference between a harness project and an agent project?
  5. Why is cdk/ at the project root rather than inside agentcore/?

Knowledge Check

Q1: What is the primary benefit of using Config Bundles instead of hardcoding prompts in agent code?
a) Config bundles are faster at inference time
b) You can version, branch, and A/B test prompts without redeploying agent code
c) Config bundles are required for Container build agents
d) Config bundles enable VPC networking
Answer: b โ€” Config bundles decouple runtime configuration (prompts, tool descriptions, model settings) from code. You can ship a new bundle version with a prompt change in seconds, without the CDK synthesis + CloudFormation deploy cycle. This also enables A/B testing by routing traffic to different bundle versions.
Q2: Cedar policy engine LOG_ONLY mode does what?
a) Only logs authorized tool calls, skips unauthorized ones silently
b) Logs policy evaluation results but does not block unauthorized tool calls
c) Logs tool calls to S3 for audit purposes
d) Enforces policies and logs all decisions
Answer: b โ€” LOG_ONLY evaluates Cedar policies and logs the result (allowed/denied) but does NOT block the request. Deploy in LOG_ONLY first, observe what would have been blocked, tune the policies, then switch to ENFORCE mode.
Q3: An agent with --protocol A2A exposes what capability?
a) It can call other agents using the A2A protocol
b) It exposes itself as an A2A endpoint that other agents can call
c) It enables asynchronous invocation
d) It connects to agent registries automatically
Answer: b โ€” An agent with --protocol A2A exposes itself as an A2A-compatible endpoint. Other agents discover and invoke it. It's the "tool server" side of A2A. The orchestrator that calls it uses standard tool-calling.
Q4: What does agentcore run recommendation produce?
a) A recommended deployment target for your agent
b) AI-suggested improvements to your agent's prompts and tool descriptions based on eval results
c) A recommendation on which model provider to use
d) A list of recommended gateway targets to add
Answer: b โ€” run recommendation analyzes evaluation results (low scores, failure patterns) and suggests specific changes to system prompts, tool descriptions, or model parameters. It's an AI-powered optimization loop.
Q5: You want to migrate an existing deployed AgentCore runtime (from the old starter toolkit) into your new CLI project. Which command?
a) agentcore create --type import
b) agentcore import --runtime-arn <arn>
c) agentcore add agent --type import --source arn:...
d) Manually edit project.json with the ARN
Answer: b โ€” agentcore import --runtime-arn <arn> imports an existing deployed runtime into the current project, updating project.json and deployed-state.json to reference the existing AWS resource without destroying it.

Key Takeaways

  • Config bundles = versioned runtime config; enables A/B testing without code redeploys
  • Batch evaluation = run evaluators across all sessions at scale (for periodic audits)
  • run recommendation = AI suggestions to improve prompts/tools based on eval results
  • Cedar policy engines = fine-grained tool authorization (LOG_ONLY first, then ENFORCE)
  • import = adopt existing deployed resources into a CLI project without data loss
  • A2A and MCP protocols = agents can be tools for other agents (multi-agent orchestration)
  • Container builds = full control over runtime, ARM64, ECR-hosted
  • VPC networking = private resource access within your network
  • Tags = cost allocation and resource organization across CloudFormation stacks
Congratulations โ€” You've Completed the Curriculum! You now have comprehensive knowledge of AgentCore architecture, CLI modes, project lifecycle, all agent types and frameworks, local development, memory strategies, gateway and target types, credential management, observability, evaluations, and advanced features.