If you're staring at a Bedrock Agents Classic agent wondering how to move it, here is the honest headline: there is no converter, and the migration is a rewrite of the part AWS used to run for you. Classic hosted a managed orchestration loop over your action groups, Knowledge Base, and Guardrail. AgentCore hosts your agent code instead and hands you the operational layer — Runtime, Gateway, Memory, Identity, Observability — as separate pieces. The good news: the expensive assets (your Lambdas, your Knowledge Base, your Guardrail) all survive and get reused. This walkthrough is the concrete port map plus the CLI and SDK calls that replace each Classic construct.
If you haven't decided whether to migrate at all — coast on frozen Classic, move to AgentCore, or abstract behind a portable framework — that's a separate call, and we broke it down in the Classic freeze decision piece. This piece assumes you've chosen AgentCore.
The mental model: config becomes code#
Classic was declarative. You gave it instructions and action groups; Bedrock decided when to call what. AgentCore is the opposite: you write the agent loop — in Strands, LangGraph, CrewAI, or plain Python — and AgentCore only runs and instruments it. So the migration has exactly two halves:
- Rewrite the orchestration, the instructions-to-system-prompt copy, and the session/memory handling.
- Reuse the Lambda functions (now Gateway tools), the Knowledge Base (called directly), and the Guardrail (re-applied in code).
The compare table above is the whole map. Everything below is how to execute each row.
Step 1 — Inventory the Classic agent#
Before you touch AgentCore, export from the Classic agent: the system instructions, every action-group Lambda (ARN + its OpenAPI/function schema), the attached Knowledge Base IDs, the Guardrail ID, and any assumptions about session memory. This list is your migration checklist — each item maps to a row below.
Step 2 — Wrap your agent for Runtime#
Install the SDK and starter toolkit, then wrap your agent. This is the verified minimal shape from AWS's own quickstart:
pip install bedrock-agentcore strands-agents bedrock-agentcore-starter-toolkit
from bedrock_agentcore import BedrockAgentCoreApp
from strands import Agent
app = BedrockAgentCoreApp()
agent = Agent()
@app.entrypoint
def invoke(payload):
"""Your AI agent function"""
user_message = payload.get("prompt", "Hello! How can I help you today?")
result = agent(user_message)
return {"result": result.message}
if __name__ == "__main__":
app.run()
Paste your Classic instructions into the agent's system prompt here. app.run() serves POST /invocations and GET /ping on port 8080, so you can test the whole loop before it ever hits AWS:
python my_agent.py
curl -X POST http://localhost:8080/invocations \
-H "Content-Type: application/json" \
-d '{"prompt": "Hello!"}'
Step 3 — Re-expose your action-group Lambdas through Gateway#
Classic's action-group binding is gone, but the Lambda behind it isn't. Gateway turns a Lambda (or an OpenAPI spec, or a Smithy model) into an MCP tool behind a managed endpoint. Register each existing function as a target:
from bedrock_agentcore_starter_toolkit.operations.gateway.client import GatewayClient
client = GatewayClient(region_name=region)
cognito_response = client.create_oauth_authorizer_with_cognito("TestGateway")
gateway = client.create_mcp_gateway(
name=None,
role_arn=None, # trust policy must trust bedrock-agentcore.amazonaws.com
authorizer_config=cognito_response["authorizer_config"],
enable_semantic_search=True,
)
lambda_target = client.create_mcp_gateway_target(
gateway=gateway,
name=None,
target_type="lambda", # also: "openApiSchema", "smithyModel"
target_payload=None, # point this at YOUR Lambda ARN + tool schema
credentials=None,
)
Set target_payload to your existing function's ARN and tool schema (leaving it None auto-generates a demo Lambda, which is only useful for a smoke test). Your framework agent then connects to the gateway URL as an MCP client. One gotcha the AWS doc bakes in: after fixing IAM permissions, wait ~30 seconds for propagation before the gateway answers.
Step 4 — Re-wire the Knowledge Base and Guardrail#
Neither of these is deprecated, and neither needs rebuilding. Your Knowledge Base is a standalone Bedrock resource; from AgentCore-hosted code you call it directly — Retrieve for raw chunks, RetrieveAndGenerate for a RAG answer (standard bedrock-agent-runtime APIs; confirm the exact boto3 signature against the current reference before you ship). Your Guardrail is likewise still there — re-apply it with ApplyGuardrail in your code, or at the model call. The rule of thumb: resources persist, bindings don't.
Step 5 — Provision Memory explicitly#
Classic hid session memory. In AgentCore you create a memory store and a strategy (the thing that promotes raw events into extracted long-term records), then read short-term and long-term separately:
from bedrock_agentcore_starter_toolkit.operations.memory.manager import MemoryManager
from bedrock_agentcore.memory.session import MemorySessionManager
from bedrock_agentcore.memory.constants import ConversationalMessage, MessageRole
from bedrock_agentcore_starter_toolkit.operations.memory.models.strategies import SemanticStrategy
memory_manager = MemoryManager(region_name="us-west-2")
memory = memory_manager.get_or_create_memory(
name="CustomerSupportSemantic",
description="Customer support memory store",
strategies=[SemanticStrategy(
name="semanticLongTermMemory",
namespaces=['/strategies/{memoryStrategyId}/actors/{actorId}/'],
)],
)
session_manager = MemorySessionManager(memory_id=memory.get("id"), region_name="us-west-2")
session = session_manager.create_memory_session(actor_id="User1", session_id="OrderSupportSession1")
session.add_turns(messages=[ConversationalMessage("...", MessageRole.USER)])
# short-term: the last k conversational turns
turns = session.get_last_k_turns(k=5)
# long-term: semantic recall over extracted records
records = session.search_long_term_memories(
query="summarize the support issue", namespace_prefix="/", top_k=3)
One behavioral difference to design around: long-term extraction is asynchronous — expect a couple of minutes before written events surface as searchable long-term records. Don't write a turn and immediately read it back long-term.
Step 6 — Configure, deploy, invoke#
With the agent tested locally, hand it to the toolkit:
agentcore configure -e my_agent.py # writes .bedrock_agentcore.yaml
agentcore deploy # build + deploy (ARM64 handled for you)
agentcore status
agentcore invoke '{"prompt": "tell me a joke"}'
The single most common "worked locally, failed deployed" cause: AgentCore Runtime requires ARM64 (Graviton) containers. The managed build produces ARM64 in the cloud; only a local x86 Docker build hits this wall. If you must build locally, build on ARM64.
A version note worth internalizing: the current starter-toolkit docs use agentcore deploy, but many blog posts still show agentcore launch. Same step, renamed verb — don't mix guides without noticing which era they're from. AWS is also steering new projects toward a separate agentcore-cli, so check which tool a tutorial assumes.
From application code, invocation is explicit about the session:
import boto3, json, uuid
client = boto3.client('bedrock-agentcore')
payload = json.dumps({"prompt": "Tell me a joke"}).encode()
response = client.invoke_agent_runtime(
agentRuntimeArn=agent_arn,
runtimeSessionId=str(uuid.uuid4()),
payload=payload,
qualifier="DEFAULT",
)
That runtimeSessionId is the seam Classic used to hide. Reuse the same ID across turns to keep a conversation — and its memory — continuous.
The cost shift to expect#
Classic billed you opaquely per invocation. AgentCore meters components: Runtime at $0.0895 per vCPU-hour and $0.00945 per GB-hour — billed only for active compute, so time spent waiting on a model or a tool call isn't charged — plus separate lines for Memory, Gateway, Identity, and the rest. The headline is that infra is usage-priced and cheap; the reality is that your Bedrock model tokens still dominate the bill. Migrate for the newer models and the real operational platform, not to shave the infra line — that line was never where the money was. Verify the current Memory and Gateway per-unit decimals on the official AgentCore pricing page before you build a cost model on them.
For the wider picture of what AgentCore's seven services do and why the framework-neutrality is the strategy, see AWS Bedrock AgentCore, Explained.



