はじめに
AWS re:Invent 2025で開催されたLevel 500セッション「Virtualization Architecture Behind AgentCore's Runtime Security Model」に参加してきました。スピーカーはMarc Brookerさんで、AWSで17年間、EC2、EBS、Lambda、Aurora Serverless、Aurora DSQL、そして最近ではAgentCoreの開発に携わってこられた方です。
Level 500のセッションは今年から始まった新しい形式で、今年初めのre:Inforceで試験的に実施され好評だったそうです。特定のトピックについて技術的に深く掘り下げることを目的としており、スライドは別の担当者の方がタイトルスライドを作成されたとのことでそれを常時表示しつつ、あとはホワイトボードのみ(と最初は言われましたが実際は口頭説明のみ)で進行するというスタイルでした。
セッションを文字起こしした内容を中心に記載しております。
ある程度裏どりはしていますが、誤った文字起こしを元に記載している可能性がある点ご注意ください。
読み返してみて、伝聞と私の主張が混ざっているのですが、本筋間違ってないなと思いそのままにしています。
ごちゃついている点についてはご容赦くださいませ...
AgentCore
AgentCoreとは
Amazon Bedrock AgentCore は、高機能エージェントを安全かつ大規模に構築、デプロイ、運用できるエージェントプラットフォームです。
AgentCore を使用すると、エージェントをより迅速に構築できるほか、エージェントはツールやデータを横断してアクションを実行できるようになります。
また、低レイテンシーで長時間エージェントを安全に実行し、本番環境でエージェントをモニタリングできます。
これらすべてをインフラストラクチャの管理なしで実行できます。
AgentCore は、開発者が実際のデプロイに不可欠な規模、信頼性、セキュリティを備えたエージェントを本番環境へと加速できます。
そのサービスとツールは構成可能で、あらゆるオープンソースのフレームワークやモデルで動作するため、オープンソースの柔軟性とエンタープライズグレードのセキュリティと信頼性のどちらかを選択する必要はありません。
いつもお世話になっております、みのるんさんの以下の資料がイメージアップに良いと思います。
AgentCoreランタイムとは(セッションで行われた解説より)
AgentCoreランタイムは、AgentCoreの一機能として提供されている、AIエージェントを実行するためのコンピューティング環境です。Python、TypeScript、Rustなどで書かれたエージェントコードを、ライブラリや環境と共に実行する汎用的なコンピューティング環境として機能します。
セッション内容
分離の重要性
AgentCoreランタイムの最も重要な要件は「分離(isolation)」です。AIエージェントを安全なボックスの中に入れることで、そのエージェントができることを厳密に制御できます。
具体的には以下のような制御が可能になります。
- AgentCore Gatewayを通じてのみ外部世界にアクセス可能
- 推論のためにBedrockを呼び出すなど、指定したエンドポイントのAIモデルのみ呼び出し可能
- Bedrockガードレールを適用したレイヤーを通じてのみ顧客とやり取り
この仕組みにより、エージェントが持つ権限について明確に推論できます。エージェントの安全性を考える上で重要なのは、「エージェントが何をできるか(ツールとのやり取り)」と「エージェントが何を言えるか(人間への発言)」の2点です。
また、Matt Garmanさん(AWS CEO)が紹介された新機能のAgentCore Policyによって、エージェントが何をできるかを明確に制御できるようになっています。
セッションレベルの分離
さらに重要なのが、セッションレベルでの細かい分離です。セッションとは、人間とエージェントの会話にマッピングされる概念で、複数のターンを含み、数秒から数時間(現在は最大8時間)続く可能性があります。
AgentCoreランタイムでは、各セッションに専用のマイクロVMが割り当てられます。これにより以下のような特性があります。
- セッション内ではディスクやメモリへの書き込みが自由にできる
- セッション終了時にすべての内容が消える
- プロンプトインジェクションやリモートコード実行の脆弱性を突かれても、攻撃者は自分の権限でしか動作できないため実害は少ない
これは非常に優れたセキュリティ特性であり、AI安全性の観点からも理想的なアーキテクチャです。
コスト効率の実現
エージェントはほとんどの時間を待機に費やします。推論を待つ、人間を待つ、ツールを待つ、という具合です。開発エージェントでRustコンパイラを実行するような例外ケースを除けば、ローカルコンピューティングが重いわけではありません。
そこでAgentCoreランタイムは、アクティビティベースの課金モデルを採用しています。
- ビジー状態の時間:CPUとメモリの両方について、実際の消費量のみ課金
- アイドル状態の時間:メモリのみ課金(CPUは課金なし)
このモデルを実現するために、以下の要件を満たすシステムを構築する必要がありました。
- 強力に分離されている
- セッションごとにVMを提供する
- 数百ミリ秒という短いセッションにも対応できる
- メモリコストが使用量に比例して線形にスケールする
- CPU実行中のみCPUコストが発生する
- 分離、セキュリティ、パフォーマンス要件を損なわない
この講演の中で、これをどのように達成するかについて非常に素朴なアーキテクチャから始め、その後、段階的な最適化について話します。
技術的な実装
素朴な実装の課題
最初に考えられる素朴な実装は以下のようなものです。
- 新しいセッションリクエストが到着
- ルーティングレイヤーが容量のあるホストを検索
- ホスト上のコントロールプレーンコンポーネントに指示
- FirecrackerマイクロVMを起動
- Linuxカーネルのブート、Linuxユーザーランドの起動、エージェントコードの起動
- セッション開始
この方法では起動に約2秒かかります。カーネルを小さくしたり、コンテナのダウンロードとブートを並列化すれば改善できますが、それでも十分ではありません。また、課金モデルにあったコスト要件も満たしていません。
では、これをどのように行うのでしょうか?ホストを拡大してみます。ここでは、単一のFirecrackerホストマシンに拡大しています。これらは文字通り、EC2から取得できるのとまったく同じ種類のEC2メタルインスタンスです。AgentCoreランタイムではM7gで実行しています。
Firecrackerとは、AWSが開発したオープンソースの軽量仮想化技術(VMM: Virtual Machine Monitor)です。2018年にオープンソース化され、AWS LambdaやAWS Fargateの基盤技術として使用されています。125ミリ秒以下でマイクロVMを起動でき、各マイクロVMのメモリオーバーヘッドは約5MBと非常に軽量です。
Amazon Elastic Compute Cloud (EC2) M7gインスタンスは、最新世代のAWS Graviton3プロセッサを搭載し、汎用ワークロード向けに設計されています。M7gインスタンスは、高速かつ低レイテンシーのストレージを必要とするアプリケーション向けに、ローカルNVMeベースのSSDブロックレベルストレージオプション(M7gd)で利用できます。
このホスト上にはホストカーネルがあります。これは通常のAmazon Linuxボックスです。そして、ゲストがあります。このゲストの内部には次のものがあります。
- ゲストカーネル
- ゲストユーザースペース
- 顧客のエージェントコード
そして、VMの外側かつホストの内側にはFirecrackerプロセスがあります。これは、以下2つのことを行うLinuxプロセスです。
- 起動
- ホストカーネルの機能であるKVMを設定し、CPUの仮想化サポートを設定して、このVMを作成します。これは実際には非常に高速です。このステップは1桁のミリ秒、一般的には1桁の低いミリ秒がかかります。慎重に最適化すれば、1ミリ秒未満にすることができます。
- I/Oエミュレーション
- このVMの起動で遅い部分は、ゲストカーネルのブートとゲストユーザースペースの起動です。そして、Firecrackerの動作方法は、ストレージ、ネットワークなどのI/Oデバイスを、ホスト上のユーザースペースのFirecrackerプロセスでエミュレートすることです。
この時、ゲストVMをブートする時に何が起こるでしょうか。そうです、ストレージからカーネルイメージを読みとる必要があります。その読み取りの流れは以下です。
- ゲストVMが仮想ディスクから読み取り
- KVMがホストにトラップ
- Firecrackerが処理
- FirecrackerがI/O要求があったことを判断
- ホストカーネルからファイル読み取り
- そのデータがFirecrackerに戻る
- Firecrackerがデータをパッケージ化
- VMに送信
このループは、ブートプロセス全体でシステムが行うすべてのI/Oに対して発生します。この実装により、ブートはかなり遅くなります。
また、別の問題もあります。それはホストが多くの作業を行っていることにより、Firecrackerを通過するすべてのトラフィックのせいで、ゲストVMのブート中に、ホストのCPU使用率がたとえば50%になってしまう可能性があることです。
AWSはゲストVMで発生しているサイクルに対してのみ顧客に課金をしており、ホストで発生しているCPU稼働は課金をしていません。そのため、この「ホストがしている多くの作業」は、AWSにとって「顧客に課金できない赤字の作業」といえます。
最適化1:スナップショットと復元
この問題を解決するのがスナップショット機能です。
【準備編】
- 特定のエージェントの参照VMを起動
- カーネル、ユーザースペース、ライブラリ、顧客コードをロード
- 実行中のVMのスナップショットを取得(メモリ、ディスク、CPU状態を保存)
【起動編】
- 新しいセッション要求時が来ると、ブートプロセスを経ることなく、Firecrackerがスナップショットから復元
この時、メモリ、ディスク、CPU状態をロードする
これにより、ブートプロセスをスキップして数十ミリ秒で起動できます。
userfaultfdによるメモリ最適化
素朴にはスナップショット復元時に2GB全体をコピーすることになりますが、これでは遅すぎます。そこでLinuxのuserfaultfd機能を活用します。
- Firecrackerに「このVMは2GBのメモリを持つ」と伝える
- 実際には最初にメモリを割り当てない
- VM実行開始
- VMが特定のページにアクセスしようとする
- カーネルがFirecrackerに問い合わせ
- Firecrackerがスナップショットから該当ページを読み取り
- カーネルがVMのメモリに配置
- VM実行継続
つまり、実際にアクセスされるページのみをロードするため、起動が大幅に高速化されます。具体的には数秒ではなく、数十ミリ秒でVM起動ができます。
メモリの重複排除
同じエージェントコードを実行する複数のVMは、多くの同一ページを持ちます(カーネルページ、ライブラリページ、コード部分など)。これらは読み取り専用なので、物理メモリページを複数のVMで共有できます。
これらのページは読み取り専用であるため、複数のVMが互いに干渉することなく同じ物理メモリページを共有しても安全です。
100個のセッションを実行していても、カーネル、Pythonランタイム、エージェントコードのコピーは1つだけメモリに保持すれば済むわけです。
VMが共有ページに書き込もうとした場合は、OSの標準的な技術であるコピーオンライト技術を使用して対応します。
VMが共有ページに書き込もうとすると、
- カーネルが書き込みをインターセプト
- そのVM専用のページコピーを作成
- VM専用コピーへの書き込みを許可
VMはそのページの独自のプライベートコピーを持ち、他のVMはまだ共有コピーを持っています。そして、これはすべてVMに対して透過的のため、このような最適化が起こっていることを知りません。
最適化2:CPUスケジューリング
エージェントがアイドル状態のときはCPU課金を避けたいという要件があります。これを実現するのが一時停止・再開の仕組みです。
これを行う素朴な方法は、「OK、エージェントがアイドル状態のときは、vCPUのスケジューリングを停止して」と言うことです。しかし、これはあまりうまく機能しません。
なぜなら、
- エージェントが実際にアイドル状態なのか、単に短時間待機しているだけなのかを知るのは難しい
- vCPUの停止と起動にはオーバーヘッドがある
- ホスト上でFirecrackerプロセスがまだCPUを消費している
そのため考えられたのが、「VMの一時停止と再開」と呼ばれる技術です。
VMの一時停止
推論APIへの呼び出しを行い応答を待っているときなど、VMがアイドル状態と判断されると
- ゲストvCPUの実行を停止
- Firecrackerプロセスをスリープ
- Firecrackerがファイルディスクリプタでブロック
ファイルディスクリプタ(File Descriptor)は、Linuxなどのオペレーティングシステムで、ファイルやソケット、パイプなどのI/Oリソースを識別するための番号です。プロセスがこれらのリソースとやり取りする際の「ハンドル」のようなものです。
プロセスが「ブロックする」とは、何かのイベント(データの到着、シグナルの受信など)が発生するまで、そのプロセスの実行が一時停止される状態を指します。
この状態では、ゲストVMもFirecrackerも実行されず、ホストのCPUを消費しません。
つまり、CPUについて顧客に課金しなくて良いことを指します。
VMの再開
推論APIから応答が返ると
- Firecrackerプロセスを起動
- FirecrackerがゲストvCPUを再開
- ゲストVMが中断した地点から正確に実行を継続
そして、CPUの課金を再開します。
アイドル状態の検出
アイドル状態の検出には、以下の技術を使用しています。
- 明示的な呼び出し
- エージェントコードは、特別なAPI呼び出しを行うことで「今からアイドル状態になります」と伝えることができます。
- ブロッキングI/O
- ゲストがI/O(ネットワーク応答の待機など)でブロックすると、それを検出してVMを一時停止できます。
- ヒューリスティック
- VMがあまりCPU作業を行っていない場合、おそらくアイドル状態であると推測できます。
そして、レイテンシを導入することなくアイドル状態をより適切に検出するために、これらのヒューリスティックを常に調整しています。
最適化3:メモリ管理
続いてメモリ最適化です。VMが一時停止されているときも、メモリに対して課金が発生しています。しかし、VMが実際にメモリを使用している時のみ課金したいと考えています。
Linuxはメモリを積極的に使用する傾向があり、ファイルのページキャッシュ、I/Oのバッファキャッシュ、各種カーネルデータ構造に2GBすべてを使い切ろうとします。これは通常は効率的ですが、メモリ使用量で課金している環境では問題です。
5分間ルール
この問題の解決には、約20〜30年前にJim Grayさんたちによる「5分間ルール」という考え方を適用しています。
採用されている考え方は、
「メモリ内に最も人気のないページを保持するコストが、ディスクから再ロードするコストと等しくなる点が最適点である」
というものです。
この原則に基づき、
- 保持コスト > 再ロードコストとなったページは削除
- より頻繁に再ロード発生 = より多くのメモリが必要
実装としては、以下のプロセスを実行します。
- メモリページに対してルールをチェック
- 再ロードの方が安いページを特定
- ゲストVMからページを回収
- Firecracker経由でシステムに返却
- 他のVMに割り当て可能に
これにより、
- お金を節約できる(必要のないメモリに対して課金されません)
- AWSもお金を節約できる(各ホストにより多くのVMを詰め込むことができます)
- 全員のためにシステムの全体的なコストを最適化
これはAurora Serverlessでも採用した最適化の一つで、昨年のVLDBで論文を発表しているとのことでした。
この論文は "Resource Management in Aurora Serverless" というタイトルで、VLDB 2023(Proceedings of the VLDB Endowment, Vol. 17, No. 12)に掲載されています。Marc Brookerさんを含む15名の著者による共著で、Aurora Serverless v1からv2への進化と、そこで採用されたリソース管理戦略について詳細に解説されています。
https://vldb.org/pvldb/vol17/p4038-urgaonkar.pdf
この論文について、日本語で解説した資料もありました。
コールドスタートへの対応
各セッションが専用VMを持つということは、コールドスタートの問題が気になります。この対策として、キャッシングで最適化を図っています。
スナップショットキャッシング
特定のエージェントのスナップショットを保持しておき、新しいセッションが入ってくると
- チェックします:このエージェントのスナップショットをすでに持っていますか?
- はいの場合、そのスナップショットから復元します(高速 - 数十ミリ秒)
- いいえの場合、ゼロからブートする必要があります(遅い - 約2秒)が、次回のためにスナップショットを作成します
これにより、新しいエージェントの最初のセッションは遅いですが、その後のセッションは高速です。
ウォームプール
人気のあるエージェントについては、常に一定数のVMをウォーム状態で維持しています。
例えば、
- 多くのトラフィックを受けるこのエージェントについて、常に5つのVMをウォームで準備しておく
- セッションリクエストが入ってきたら、ウォームプールから1つを取得する
- プールを補充するために、バックグラウンドで新しいVMを起動する
これにより、最初のリクエストも高速にすることを意味しています。
今後の課題
現状、これらのエージェントはLLM推論が全体パフォーマンスの大部分を占めています。しかし、student-teacherモデルなどの技術が進化し、推論レイテンシとコストが下がっていくと、コールドスタートの重要性が相対的に高まっていくと考えられます。
student-teacherモデルというのは、AWS界隈でいうところのモデルの蒸留のことを指すようです。
機能で言うと「Amazon Bedrock Model Distillation」に相当しそうですね。
https://dev.classmethod.jp/articles/bedrock-model-distillation-basic/
質疑応答セッション
セッションの後半では、参加者からの質問に答える時間が設けられました。
質疑応答セッションは、できる限り発言をそのまま記載しています。
Q1: Lambdaとの関係について
質問者: これは一般的な意味でのLambdaの進化と考えてよいですか?
Marc Brookerさん: Yes。ただし、それ以上のことはお答えできません。
Q2: アーキテクチャの選択について
質問者: なぜクラスター型のアプローチ(複数のエージェントを同じホストで実行するようなFargate的なアプローチ)ではなく、ワーカーとマイクロVMとエージェントセッションを分離するパターンを採用したのですか?
Marc Brookerさん:
まず、どこかから始める必要があり、これが最もシンプルな出発点だと考えました。エージェントを構築する際には考えるべきことが非常に多いため、最もシンプルなインフラから始めることは重要です。
また、ローカリティ最適化(同じボックス上での通信)について補足すると、慎重に実装しないと実際にはあまり効果がありません。AZ内のネットワーク呼び出しのレイテンシを分析すると、約90%はシリアライズとデシリアライズで、ネットワーク時間は約10%に過ぎません。
したがって、同じボックス上でローカルTCPソケット経由で通信しても、多くのアプリケーションでは実際には速くなりません。メモリ共有などの最適化を行えば別ですが、素朴なローカリティだけでは大きなメリットはないのです。
シリアライズ(Serialization)とはプログラム内のデータ構造やオブジェクトを、ネットワーク経由で送信できる形式(バイト列)に変換する処理です。
デシリアライズ(Deserialization)とは受信したバイト列を、プログラムが扱えるデータ構造やオブジェクトに復元する処理です。
Q3: セキュリティモデルの設計思想
質問者: 核となるアイデアは、すべてのセッションが独自のVMを取得できるように、たくさんの小さなインスタンスを提供したいということですか?
Marc Brookerさん:
その通りです。核となるアイデアは、すべてのセッションが独自のVMを取得できるように、たくさんの小さなインスタンスを提供することです。これにより、エージェントのセキュリティについて考える脅威モデルが非常にクリーンでシンプルになります。
これらのセッションは単一の認証済みユーザーのみに属しているため、プロンプトインジェクションで他のユーザーの認証情報を取得させることはできません。それらの情報へのアクセス権はなく、単にそのメモリ空間に存在しません。
これは本当に優れた脅威モデルの単純化です。エージェントの世界では、まず正確な脅威モデルに到達することが最優先事項です。
時間の経過とともに、「その脅威モデルはオーバーヘッドに値しない」と考える人も出てくると思います。そのときはより密度の高いアプローチも検討しますが、現時点ではこのモデルが最適です。
Q4: コールドスタートとキャッシング
質問者: SnapStartが有効になっているLambdaと同様に、キャッシュを共有できるのでしょうか?
Marc Brookerさん:
はい、定期的にコールドスタートが発生するはずです。なぜなら、同じハードウェアに到着する可能性が高いからです。そして、この最適化を行うことができます。しかし、コールドスタートがより多く発生することになります。
これはLambdaで見られる動作と非常に似ています。トラフィックが多いほど、コールドスタートの割合は低くなります。SnapStartが有効になっているLambdaのように、ユーザー間でキャッシュを共有することになりますし、それは確かに役立ちます。
ちなみに、この分野でまだそれを行っていない理由の一つは、これらのエージェントが再びLLM推論を行う傾向があり、それが基本的に他のどの要因よりもエージェントパフォーマンスへの大きな貢献要因となっているからです。
今後、時間の経過とともに、人々がエージェント構築とエージェント最適化により優れるようになり、今朝Swamiが話していたようなstudent-teacherスモールモデルのようなことを始めるにつれて、推論レイテンシを下げようとするでしょう。そしてそれに成功するでしょう。推論レイテンシを下げることは、推論コストも下げることになります。そのため、コールドスタートのような要素が今後ますます重要になっていきます。
ですので、私たちは、人々が気にするようになると思われるパフォーマンスレベルのトレンドに先んじて、それを最適化するために取り組んでいます。
おわりに
500レベルのセッションは初めての体験でしたが、改めて読んでみると(聞いてみると...と言いたかったですが)実装の詳細まで踏み込んだ内容は非常に...非常に興味深い内容でした。
サーバレスとか、マネージメントだからインフラ面は意識しなくて良い!と言うのは幾度となく聞いてきましたが、当然ながらそこにはインフラがあります。サーバーがあります。そのサーバーを効率的に運用するための考え方を知ることができました。
また、AIが騒がれてからまだそれほど日が経っていないにもかかわらず、ここまで考え尽くされたサービスが提供されていることにただただ脱帽です。自身の業務、興味関心のあるサービスでなければLevel 500セッションはついていけないと思いつつ、インフラレイヤであればまた機会があれば参加してみたいと思います。