9月4日、AWSが「Migrate agentic workloads to Amazon Bedrock AgentCore」と題した記事を公開した。LangGraphで構築した既存のエージェントをAmazon Bedrock AgentCoreへ段階的に本番移行する具体的な手順を、コード変更45行・新規追加22行という実測値とともに解説している。
「ノートブックで動く」から「本番で動く」への壁
LangGraphでエージェントを作り、ローカルで動作確認できた——そこからが本番運用の本題だ。セッション分離、OSパッチ適用、ツールの認証管理、プロセス跨ぎの状態保持。こうした推論ロジックとは無関係な運用負担が積み上がる。AWSの本記事はその負担を10項目に整理し、Amazon Bedrock AgentCoreの各機能がどれを引き受けるかを段階的に示している。
移行対象は「カスタマーサポートエージェント」だ。メッセージを分類し、怒った顧客はエスカレーション、それ以外は3つのツール(注文照会・返品処理・FAQ検索)で回答する。モデル呼び出しはすでにAmazon Bedrockへ向いているが、コンテナ・Webサーバー・会話状態の管理はすべて自前という構成を出発点とする。
移行は2ステージ構成
| LangGraph構成要素 | AgentCore対応機能 |
|---|---|
build_graph(...) + コンテナ・Webサーバー |
Runtime: セッション毎にマイクロVM |
@tool 関数 + ToolNode |
Gateway: LambdaをMCPツールとして公開 |
MemorySaver() + thread_id |
Memory: actor_idとセッションで状態管理 |
add_conditional_edgesによる分岐 |
Runtime上でそのまま動作(変更不要) |
重要な点として、AgentCoreはエージェントの意思決定ロジックを奪わない。Runtimeはエージェントが動く場所であり、次のステップを決める主体ではない。条件分岐をモデル駆動に置き換えるかどうかはステージ2以降の選択肢であり、ステージ1では手書きのルーターをそのまま維持できる。
ステージ1の核心:変更45行+追加22行で5つの負担を手放す
記事ではコードの変更量を実際のファイルから計測している。ステージ0のコードは2つのimportで丸ごと再利用し、変更は45行、新規追加は22行、合計67行の差分だ。
from examples.stage0_langgraph.agent import build_graph
from examples.stage0_langgraph.tools import SUPPORT_TOOLS
グラフトポロジー・ルーター・状態スキーマ・プロンプト・ツール本体はすべてimport元から引き継がれるため、移行時のドリフト(実装のズレ)が起きない。
Runtime:ループをBedrockAgentCoreAppにラップする
from bedrock_agentcore import BedrockAgentCoreApp
app = BedrockAgentCoreApp()
@app.entrypoint
def agent_invocation(payload, context):
state = support_graph().invoke(
{"messages": [HumanMessage(payload.get("prompt", ""))]},
config={"configurable": {"thread_id": context.session_id or "local-session"}},
)
return {"result": state["messages"][-1].text}
変更点はthread_idの出所だけだ。ステージ0では自前で決めていたが、ここではRuntimeが渡すcontext.session_idを使う。OSパッチ適用とセッション分離(セッション毎のマイクロVM)がこれで手放せる。CrewAIやLlamaIndexのループも同じラッパーで動く。
Gateway:ツール認証をコードの外に出す
lookup_orderとprocess_returnの2つをAgentCore Gateway経由のMCP(Model Context Protocol)ツールとして公開する。MCPはツール定義・呼び出し・結果返却を標準化するオープンプロトコルであり、AgentCoreはこれをLambda関数と紐付けてIAM認証付きで公開する仕組みを持つ。
search_faqはローカルのPython関数のまま残す——他のエージェントから呼ばれることもなく、ポリシーで制御する必要もないためだ。これが「妥協」ではなく記事が示す「通常ケース」である点は押さえておきたい。
Gateway登録はSDKの2コールで完結する。
gateway = client.create_gateway(
name="MigratedAgentGateway",
roleArn=role_arn,
protocolType="MCP",
authorizerType="AWS_IAM", # または CUSTOM_JWT
)
ターゲット登録でLambda関数とツールのJSONスキーマを紐付ける。GATEWAY_IAM_ROLEを指定すると、GatewayはツールをLambdaとして自身のIAMロールで呼び出す。エージェント側からはSigV4署名付きのMCPクライアントで接続し、発見されたツール名はsupportTools___lookup_orderのようにターゲット名のプレフィックスが付く。
Gatewayが引き受けるのは認証・認可・ツール発見の仕組みだけであり、ツール本体のビジネスロジックには一切触れない。Lambdaに書いた処理をそのまま流用できる点は、移行コストを下げる上で実質的な意味を持つ。
ステージ2以降とセキュリティの扱い
ステージ2ではグラフループをStrands Agentsによるモデル駆動プランニングに置き換える選択肢が示されている。ただしステージ1で止めても完結したホスト型エージェントとして機能する。ステージ3はドキュメント参照の形で示されるにとどまる。
セキュリティ面では、IAMポリシー・VPC設定・WAFルール・シークレットローテーションはどのステージでも引き続き自前の責務だ。AgentCoreが引き受けない領域を明示している点は実装判断に直接効いてくる。加えて、本番移行後はAmazon Bedrock Guardrailsを追加してハームフィルタリング・グラウンディング検証・プロンプトインジェクション対策を適用することが推奨されている。Guardrailsはエージェントのグラフトポロジーを変更せずにランタイムレイヤーで適用できる。
試す前に確認すること
- Python 3.12、AWS CLI、Amazon Bedrockのモデルアクセス有効化が前提
- CloudWatch Transaction Searchをアカウントで一度有効化しないとトレースが参照できない
- サンプルリポジトリ: aws-samples/sample-migrate-agents-to-amazon-bedrock-agentcore
git clone https://github.com/aws-samples/sample-migrate-agents-to-amazon-bedrock-agentcore.git
cd sample-migrate-agents-to-amazon-bedrock-agentcore
./setup.sh
追加される主要パッケージはstrands-agents・bedrock-agentcore・mcp・langgraph-checkpoint-awsの4つ。最後のlanggraph-checkpoint-awsはLangGraphのチェックポインターインターフェースをAWS(DynamoDB等)バックエンドで実装したパッケージであり、MemorySaverをプロセス外の永続ストレージに切り替える役割を担う。
詳細はMigrate agentic workloads to Amazon Bedrock AgentCoreを参照していただきたい。