Serverless Strands Agent

January 2, 2026 Β· View on GitHub

A serverless AI agent built with Amazon Bedrock AgentCore + Strands Agents + Yahoo DSP Agent SDK.
Deploys to AWS as a fully managed runtime with persistent conversation memory.

πŸš€ Quick Start

# Setup
make setup

# Run locally with memory
make local MEMORY_ID=your-memory-id

# Or without memory (in-memory only)
make local

# Or with Docker
make start

# Once you are ready, deploy to AWS
make deploy

πŸ“‹ Prerequisites

  • Python 3.13+
  • uv - Fast Python package manager
  • Docker/Rancher (for containerized development and CDK deployment)
  • AWS CLI + credentials

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    AWS Bedrock AgentCore                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                 β”‚
β”‚  β”‚  Agent Runtime  │───▢│  Bedrock LLM    β”‚                 β”‚
β”‚  β”‚  (Strands)      β”‚    β”‚  (Claude)       β”‚                 β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β”‚
β”‚           β”‚                                                 β”‚
β”‚           β–Ό                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                        β”‚
β”‚  β”‚  AgentCore      β”‚  (Persistent conversation memory)      β”‚
β”‚  β”‚  Memory         β”‚                                        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Stack:

πŸ“ Project Structure

.
β”œβ”€β”€ agent/
β”‚   β”œβ”€β”€ main.py                 # Agent entrypoint (BedrockAgentCoreApp)
β”‚   β”œβ”€β”€ agent.py                # Agent configuration with tools
β”‚   └── settings.py             # Configuration (Pydantic)
β”œβ”€β”€ iac/
β”‚   β”œβ”€β”€ app.py                  # CDK app entry point
β”‚   └── stack.py                # CDK stack (Runtime + Memory + Cross-account role)
β”œβ”€β”€ scripts/
β”‚   └── invoke.py               # CLI to invoke deployed agent (supports streaming)
β”œβ”€β”€ .vscode/
β”‚   β”œβ”€β”€ launch.json             # Debug configuration
β”‚   └── settings.json           # Ruff formatter settings
β”œβ”€β”€ Dockerfile                  # Container definition
β”œβ”€β”€ docker-compose.yml          # Local Docker development
β”œβ”€β”€ cdk.json                    # CDK configuration
β”œβ”€β”€ Makefile                    # Task automation
└── pyproject.toml              # Python dependencies

πŸ› οΈ Available Commands

Run make help to see all commands:

Setup & Dependencies
  make setup       Install uv and sync dependencies
  make sync        Sync dependencies with uv
  make aws-auth    Setup AWS authentication (federate)

Code Quality
  make lint        Check code with ruff
  make format      Format code with ruff
  make fix         Format and fix linting issues

Docker Development
  make build       Build Docker image
  make start       Start container (detached)
  make restart     Rebuild and restart container
  make down        Stop and remove container
  make logs        Follow container logs
  make dev         Start with hot reload (watch mode)

Local Development
  make local       Run agent locally without Docker

Deployment
  make deploy         Deploy to AWS with CDK
  make invoke         Invoke deployed agent (non-streaming)
  make invoke-stream  Invoke with plain text streaming
  make invoke-agui    Invoke with AG-UI protocol streaming

Utilities
  make clean       Clean cache files

πŸ’» Development Modes

1. Local with Memory

Uses AgentCore Memory for persistent conversations across requests.

make local MEMORY_ID=memory-YkJACvBGME
# Agent runs at http://localhost:8080

2. Local without Memory

Uses in-memory storage (conversations reset on restart).

make local

3. Test the Agent

# First message
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello! My name is Iker", "user_id": "iker", "session_id": "test-session"}'

# Memory test - should remember the name
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"input": "What is my name?", "user_id": "iker", "session_id": "test-session"}'

4. Docker

Closer to production environment.

make start       # Start container
make logs        # View logs
make dev         # Hot reload mode

5. VS Code Debugging

Press F5 to start debugging with breakpoints.

☁️ AWS Deployment

Deploy

make aws-auth    # Authenticate
make deploy      # Deploy via CDK

Outputs:

  • RuntimeName: Agent runtime ID (e.g., dsp_agent-grrXst44Ca)
  • MemoryId: Memory store ID (e.g., memory-YkJACvBGME)

Invoke Deployed Agent

make invoke INPUT="Hello, what can you do?"

With persistent memory:

make invoke \
  INPUT="Hello, what can you do?" \
  SESSION_ID="my-session-123456789012345678" \
  USER_ID="user-123"

Note: Session ID must be at least 33 characters for memory persistence.

Streaming Responses

The agent supports three invocation modes:

CommandDescriptionUse Case
make invokeNon-streaming JSONSimple integrations
make invoke-streamPlain text streamingReal-time text output
make invoke-aguiAG-UI protocol streamingRich UI with tool visibility

Plain Text Streaming

make invoke-stream INPUT="What is 25 * 4?"

Output:

[Session: default-session-abc123...]
I'll help you calculate that using the calculator tool.
The result of 25 * 4 is 100.
[Done]

AG-UI Protocol Streaming

Full event stream with tool call visibility - ideal for building rich UIs.

make invoke-agui INPUT="What is 100 / 4?"

Output:

[Run: default-session-abc123_default-user]
I'll help you calculate that using the calculator tool.
[Tool: calculator] -> Tool executed successfully...
The result of 100 divided by 4 is 25.
[Run finished]

AG-UI events include:

  • RUN_STARTED / RUN_FINISHED - Run lifecycle
  • TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_END - Text streaming
  • TOOL_CALL_START / TOOL_CALL_ARGS / TOOL_CALL_RESULT / TOOL_CALL_END - Tool execution

Streaming via curl

# Plain streaming
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"input": "What is 10 + 5?", "stream": true}'

# AG-UI streaming
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"input": "What is 10 + 5?", "stream_agui": true}'

AWS Console Sandbox

Test your deployed agent directly from the AWS Console:

  1. Go to Bedrock AgentCore
  2. Go to Test/Agent Sandbox in the left sidebar
  3. Select your agent from the dropdown (dsp_agent)
  4. Choose Endpoint: DEFAULT
  5. Paste this JSON payload in the Input field:
{
  "input": "Hello!",
  "user_id": "console-user",
  "session_id": "console-session-123456789012345678"
}
  1. Click β–Ά Run
  2. View response in the Output section

βš™οΈ Configuration

Environment Variables

VariableDescriptionDefault
MODELBedrock model IDRequired
AWS_REGIONAWS regionus-east-1
MEMORY_IDAgentCore Memory IDOptional (uses in-memory if not set)

CDK Configuration

Edit cdk.json to change bootstrap qualifier:

{
  "app": "uv run python -m iac.app",
  "context": {
    "@aws-cdk/core:bootstrapQualifier": "your-qualifier"
  }
}

πŸ”§ Customization

Change the Model

Edit iac/stack.py:

environment_variables={
    "MODEL": "bedrock:global.anthropic.claude-sonnet-4-5-20250929-v1:0",
}

Memory Strategies

AgentCore Memory supports advanced strategies:

  • Short-term memory (STM): Conversation persistence within sessions
  • Long-term memory (LTM): User preferences, facts, session summaries

See AgentCore Memory documentation.

πŸ“š Resources