はじめに:AIエージェント開発の真のボトルネックは「推論」ではなく「統合」にある
AIエージェントの導入事例を読むと、モデルの推論精度やプロンプト設計に焦点が当たる傾向がある。しかし、実際にAWS上で生産環境を構築すると、モデルの選択よりもインフラ統合のコストの方が開発期間を支配するケースが多い。推論エンジンの性能はモデルベンダーが改善していくが、統合レイヤーの設計は自チームの責任であり、モデルのバージョンアップだけで解決するものではない。Lambdaの無状態性、API Gatewayの認証設計、Knowledge Baseのインデックス管理、Memoryの永続化——これらの統合タスクがプロジェクトのクリティカルパスを形成し、モデル選定で数日で終わる判断が、統合設計では数週間を要することがある。
この記述は、Amazon Bedrock AgentCoreとStrands SDKを用いてカスタマーサポートAIエージェントを構築した経験に基づくものである(実際の構築体験の記録)。プロジェクトの難所は、モデルに正しい応答をさせることではなく、エージェントが実際のシステム操作をトリガーし、その結果に基づいて応答を返すための統合レイヤーの設計にある場合が多い。特に返金処理では、エージェントが単にテキストを生成するだけでなく、バックエンドの決済システムに対してアクションを実行し、その戻り値を解釈してユーザーに報告する必要がある。この「情報生成」と「システム操作」の境界をどう設計するかで、実装コストは大きく変わる可能性がある。
具体的には、注文追跡の機能を例にとれば、ユーザーの質問から注文IDを抽出し、バックエンドの注文管理APIを呼び出し、返されたステータスを自然言語で説明するという一連の流れを、Lambda関数とAPI Gateway、AgentCore Gatewayの3層にまたがって実装する必要がある。各層の責任範囲、エラー時の挙動、認証情報の受け渡し——これらの設計が曖昧なまま実装を始めると、統合テスト段階で障害が発生するリスクがある。モデルの推論は正しくても、統合レイヤーの設計ミスによりユーザーに誤った情報を届けたり、応答がタイムアウトしたりするケースが実際に報告されている。
既存の技術記事はプロンプト制御やセキュリティ対策に偏りがちだが、本記事は「State管理」「ツール連携」「RAG実装」という実装基盤の難しさに焦点を当てる。読者はAWS上でAIエージェントの生産環境を構築・運用するシニアエンジニアおよび技術責任者であり、設計判断のトレードオフを理解することを目的とする。モデル選定の比較表ではなく、統合レイヤーの設計判断がなぜ必要なのか、失敗すると何が起こるのかを、実装の文脈で扱う。
アーキテクチャの前提:AgentCore RuntimeとStrands SDKの役割分担
Amazon Bedrock AgentCoreは、エージェントの実行環境を支えるコンポーネント群から構成される。Lambda、API Gateway、Knowledge Base、Memory、Code Interpreter、IAM、CloudWatchといったAWSリソースを統合する基盤として機能する。一方、Strands SDKはエージェントのフレームワークとして、モデルの振る舞い制御とツール接続の抽象化を提供する。この2者は「どこで動くか」と「どう振る舞うか」という異なるレイヤーの責任を担っており、混同すると設計判断が歪む可能性がある。
推論エンジンとしてはAmazon Nova 2 LiteをAmazon Bedrock経由で利用する場合を考える。Nova 2 Liteはモデルという計算資源であり、エージェントの振る舞いを決めるのはStrands SDKの制御ロジックである。Strands SDKは、モデルにどのツールをいつ呼び出すかを指示する制御フロー、ツールの入出力スキーマの定義、エラー時のリトライ戦略などをコードレベルで記述するフレームワークである。この分離により、モデルをNova 2 Liteから別のモデルに差し替える場合、変更の影響範囲がStrands SDKのモデル参照箇所と推論品質の確認に限定されることが期待できる。ツール定義や統合レイヤーのコードはそのまま使える可能性がある。
AgentCore Gatewayの役割は、外部システムとエージェント間の通信プロトコルを標準化することである。注文追跡の機能では、API Gatewayを通じてLambda関数を公開し、AgentCore Gatewayを介してエージェントとバックエンド操作を接続する。Gateway層が中間に存在することで、Lambda側のAPI仕様が変わってもエージェント側への影響をGatewayの変換ロジックで吸収できる可能性がある。ただし、この分離にはトレードオフがある。Gateway層でのデータ変換が1回追加されるため、レイテンシがわずかに増加し、変換ロジックのバグが新たな障害要因になるリスクがある。モデル変更時の影響範囲を最小限にする利得と、Gateway層のデータ変換コストの増加——このトレードオフを認識した上で、どのツールにGatewayを介すかを設計判断する必要がある。
flowchart LR
A["ユーザーリクエスト"] --> B["Strands SDK"]
B --> C["AgentCore Gateway"]
C --> D["Lambda関数"]
C --> E["外部API"]
D --> F["バックエンドDB"]
State管理の落とし穴:セッション状態の永続化と一貫性の設計
エージェントが複数ターンにわたって会話を維持するためには、セッション状態の永続化が不可欠である。AgentCoreのMemory機能はセッション内の短期記憶を提供するが、注文追跡のようなステートフルな処理では、Memoryだけでは不十分なケースが多い。ユーザーが3回目に「さっきの注文の配送状況は?」と質問した場合、エージェントは2回目のターンで取得した注文IDを参照する必要がある。この参照先がMemoryに収まればよいが、セッションが途切れた後の再開や、バックエンドDBとの整合性を保つ必要がある場合は、外部DBやS3との連携が設計上必要になる。
ここで直面するのが、Lambdaの無状態性とエージェントのステートフルな要求のギャップである。Lambdaは各インボケーションが独立したコンテキストで実行されるが、エージェントはセッション全体の文脈を保持して振る舞う必要がある。API Gateway経由でLambdaを公開する際、認証情報やコンテキスト情報をどのように安全に渡すかは設計判断の分岐点になる。API GatewayのJWT認証でユーザーIDを取得し、Lambdaの環境変数ではなくリクエストペイロードにセッションキーを含めてMemoryにアクセスする、というパターンが一般的だが、この場合ペイロード改ざんのリスクをどう防ぐかが課題になる。
State管理の失敗は、表面的には「AIが前回の会話を覚えていない」という症状として現れるが、根本原因は多くの場合、Memoryと外部DBの同期処理の競合や、Lambdaのタイムアウトによる書き込み中断にある。リカバリ戦略として、CloudWatch Logsを活用したデバッグが有効である。各ステート遷移の前後でログを出力し、どの処理で状態が不整合になったかを特定する。さらに、状態の巻き戻し処理——すなわち、不整合を検出した際に直前の既知の安全な状態にロールバックするロジック——をLambda関数内に実装しておくことで、ユーザーに不整合な情報を提示するリスクを低減できる可能性がある。この巻き戻し処理の設計を後回しにすると、本番で不整合を検知しても復旧手段がなく、手動でのデータ修正が必要になるケースがある。
sequenceDiagram
participant A as API Gateway
participant B as Lambda
participant C as AgentCore Memory
participant D as 外部DB
A->>B: リクエスト(認証情報付き)
B->>C: セッション状態の読み込み
C-->>B: 状態データ
B->>D: 業務データ参照
D-->>B: 参照結果
B->>C: 状態の更新
B-->>A: 応答
ツール連携の設計:アクションと情報の境界線(RAG vs Code Interpreter)
エージェントが外部リソースとやり取りする際、最も重要な設計判断は「この要求は情報取得なのか、それともシステム操作(アクション)なのか」という境界線の引き方である。この境界を誤ると、本来確実な計算結果が必要な場面でモデルの推論に依存してしまい、あるいは読み取り専用の情報源に対して書き込み操作を試みてエラーを発生させることになる。
情報参照:Knowledge Baseの位置づけ
商品情報や返金ポリシーの質問には、Amazon Bedrock Knowledge Baseを用いるのが適切である(AgentCore実装事例)。Knowledge BaseはRAG(Retrieval-Augmented Generation)の仕組みとして、アプリケーション固有のドキュメントから関連情報を検索し、モデルにコンテキストとして提供する。ここで重要なのは、この処理が本質的に「読み取り専用」であるという点だ。Knowledge Baseはソースデータの更新をトリガーする機能を持たず、エージェントがユーザーに「返金ポリシーはこうです」と応答できるだけで、ポリシー自体を変更したり、新しいドキュメントを登録したりすることはできない。
アクションと精密計算:Code Interpreterとカスタムツール
一方、ロイヤルティ割引の計算のように、モデルの推論精度に依存せず確実な数値結果が必要な場面では、Code Interpreterが有効である。Code Interpreterはモデルがコードを生成し、それを安全なサンドボックス環境で実行することで、四則演算や条件分岐を含む計算を正確に行う(AgentCore実装事例)。モデルが「10%割引後の金額を計算して」という指示を正しくコードに変換できる限り、計算ミスは発生しない可能性がある。
さらに、返金処理のように実際のシステム操作をトリガーする必要がある場合、Knowledge BaseやCode Interpreterでは不十分である。エージェントは単に情報を生成するだけでなく、バックエンドの注文管理システムに対して返金リクエストを送信し、その結果に基づいてユーザーに応答する必要がある(AgentCore実装事例)。このようなアクション系ツールは、Lambda関数として実装し、AgentCore Gatewayを介してエージェントに公開するのが一般的である。
| ツール種別 | 代表例 | 向いている場面 | 注意点 |
|---|---|---|---|
| Knowledge Base(RAG) | Bedrock Knowledge Base | ポリシー・商品情報の参照 | 読み取り専用。データ更新は別途必要 |
| Code Interpreter | AgentCore Code Interpreter | 割引計算・数値演算 | コード生成の品質に依存。サンドボックス制約あり |
| カスタムツール(アクション) | Lambda via AgentCore Gateway | 返金処理・注文ステータス変更 | 冪等性の保証・権限管理が必須 |
ツール選択を誤った場合のコストは、単一のエラーではなくエラーハンドリングの複雑さの増大として表れる。例えば、Knowledge Baseに存在しない情報に対してCode Interpreterを呼び出しても、コードは実行されるが意味のある結果を返さない可能性がある。逆に、アクション系ツールをKnowledge Baseとして登録すると、モデルが書き込み操作を「参照」として扱おうとし、意図しない副作用が発生する可能性がある。
インフラ統合コスト:IAM権限とネットワーク設定の複雑さ
AWS AgentCoreベースのエージェントは、AgentCore Runtime、Lambda、API Gateway、Knowledge Base、Memory、Code Interpreter、Browser Tool、IAM、CloudWatchなど多様なAWSリソースを統合して動作する。この多様性がもたらす課題の一つに、IAMポリシーの設計がある。最小権限原則を適用しようとすると、各リソースに対するアクション単位で許可を定義する必要があり、ツール数が増えるほどポリシーの管理コストが増大する傾向にある。
IAMポリシーの設計判断
実務では、エージェントのLambda関数がKnowledge Baseの検索、Memoryの読み書き、Code Interpreterの呼び出し、外部APIへのアクセスなどを担うため、単一のLambda関数に複数のサービス権限が付与されることが多い。ここで「エージェント全体に権限を付与する」のか「ツールごとにLambdaを分離して権限を細分化する」のかという設計判断が求められる。前者は運用が簡単だが、一つのLambdaの権限が漏洩した際の影響範囲が広がる可能性がある。後者はセキュリティ上望ましいが、Lambda関数の数が増え、デプロイパイプラインの複雑さとコストが上がる傾向がある。Strands SDKがエージェントのフレームワークとしてツール接続を抽象化しているため、コードレベルではツールを分離しやすいが、インフラレベルでの分離は別途設計する必要がある。
ネットワーク分離と接続性
セキュリティ要件が厳しい環境では、LambdaをVPC内に配置し、VPCエンドポイント経由で他のAWSサービスにアクセスさせる必要がある。この場合、AgentCore GatewayがLambdaと通信するためのネットワーク経路も確保しなければならず、セキュリティグループやNACL(Network ACL)のルール設計が複雑になる。特に、AgentCore Gatewayがパブリックエンドポイントで提供される場合と、VPC内で動作する場合では、Lambda側の設定が異なる点に注意が必要だ。この差異を事前に把握しておかないと、デプロイ後に「接続タイムアウト」が発生し、原因の特定に時間を要する可能性がある。
もう一つの課題は、インフラチームとAI開発チーム間の責任境界の曖昧さである。IAMポリシーはインフラチームが管理するが、どの権限が必要かはAI開発チームが把握していることが多い。この情報の非対称を解消しないままデプロイすると、権限不足によるエラーが本番で初めて発見されるパターンが起こり得る。対応策として、ツール登録時に必要なIAMアクションをドキュメント化し、インフラチームへの引き継ぎ手順を定石化しておくことが有効である。
エラーハンドリングとフォールバック:推論暴走を防ぐインフラ層の対策
エージェントが本番環境で動作し始めると、モデルが予期せぬツール呼び出しを繰り返す、あるいは同じエラーをリトライし続けるなどの「推論暴走」が発生する可能性がある。CloudWatchによるモニタリングは事後的に問題を特定する手段としては有効だが、ユーザーが既にエラー応答を受けてからでは手遅れである場合もある。インフラ層での能動的な保護機構が不可欠である。
タイムアウトとCircuit Breaker
まず基本となるのは、各ツール呼び出しへのタイムアウト設定である。Code Interpreterの実行が長時間ブロックされる場合や、外部APIが応答しない場合に、エージェント全体がハングアップすることを防ぐためだ。タイムアウトの閾値はツールごとに異なり、Knowledge Baseの検索は数秒で完了するべきだが、外部システムの操作を伴うアクション系ツールでは数十秒を許容する必要がある。
さらに、一定回数エラーが連続した際にツールへの呼び出しを一時的に停止するCircuit Breakerパターンを適用することも検討できる。例えば、外部注文管理APIが5連続で5xxエラーを返した場合、次の一定期間はそのAPIへのリクエストをスキップし、代わりにフォールバック応答を返す。これにより、ダウンした外部システムへのリトライストリームがLambdaのコンカレンシーを消費し続けることを防げる。
フォールバックの設計とユーザーへの透明性
Code Interpreterの実行失敗時やKnowledge Baseの検索結果が空の場合のデフォルト動作(フォールバック)は、設計段階で明示的に定義しておく必要がある。検索結果が空の場合に「情報が見つかりませんでした」と返すのか、それとも人間のオペレーターにエスカレーションするのかは、ビジネス要件に依存する。重要なのは、エラー発生時にユーザーに対して「AIが間違えた」と伝えるのではなく、「この処理は現在利用できません。オペレーターに接続します」といった形で、システム側の制限としてコミュニケーションすることである。これにより、ユーザーのAIへの信頼を不当に損なわず、サポート負荷の急増も抑えられる可能性がある。
flowchart TD
A["ツール呼び出し"] --> B{"タイムアウト?"}
B -->|"Yes"| C["Circuit Breaker判定"]
B -->|"No"| D{"実行結果?"}
D -->|"成功"| E["結果をエージェントに返却"]
D -->|"失敗"| F{"連続エラー回数 >= 閾値?"}
F -->|"Yes"| G["Circuit Breaker ON"]
F -->|"No"| H["リトライ(指数バックオフ)"]
H --> A
G --> I["フォールバック応答を返す"]
C -->|"BreakerがON"| I
C -->|"BreakerがOFF"| H
I --> J["CloudWatchにアラート記録"]
このフローをLambda関数内に実装する際、Circuit Breakerの状態(開/閉/半開)をどこに保存するかが設計上の分岐点になる。Lambdaは無状態であるため、状態はDynamoDBやElastiCacheに外部化する必要がある。状態管理のオーバーヘッドを考えると、ツール数が少ない段階ではLambda環境変数+CloudWatchメトリクスの組み合わせで簡易的に実装し、ツール数が増えた際に外部ストレージへ移行する段階的なアプローチが現実的である。
実装手順:Strands SDKを用いたカスタムツールの登録とテスト
Lambda関数をエージェントツールとして登録する
Strands SDKはエージェントのフレームワークとして振る舞いとツール接続を提供する。注文追跡のようなバックエンド操作をエージェントから呼び出す際、API Gatewayを通じてLambda関数を公開し、AgentCore Gatewayを介してエージェントとバックエンドを接続する構成になる。この接続をStrands SDK側から定義する際、ツールには「この関数が何をするか」「引数と戻り値の型」をモデルが理解できる形で記述する必要がある。
ツール定義の最小構成として、以下のようなパターンになる。モデルがツールを正しく選択し、正しい引数で呼び出すためには、このメタ情報が唯一の判断材料となる。
# 概念例:Strands SDKでのツール登録パターン
# 実際のSDK APIは公式ドキュメントを参照
# ここでは設計上の構造を示す
tool_name: "track_order"
description: "注文IDを受け取り、配送ステータスを返す"
parameters:
order_id:
type: "string"
description: "16桁の注文識別子"
pattern: "^[A-Z0-9]{16}$"
returns:
status: "string"
estimated_delivery: "string"
tracking_url: "string"
この例で重要なのはpatternフィールドである。モデルが生成する引数が不正な形式だった場合、Lambda関数側で400エラーを返すだけでなく、ツール定義の段階でモデルに「正しい形式」を学習させる効果がある。パターン制約を緩くすると、モデルが推測した値で呼び出しを行い、バックエンドで例外が発生する確率が上がる可能性がある。
ローカルモックとStage環境テストの分岐
ツール単体の動作確認はローカルで可能だが、AgentCore Gateway経由でのエンドツーエンドの振る舞いはStage環境でしか検証できない。特に注意すべきは、API Gatewayの認証設定(IAM SigV4 or API Key)がローカルでは再現しにくい点だ。Stage環境では、AgentCore GatewayがLambdaにリクエストを転送する際のヘッダ変換やタイムアウト値が本番と異なる可能性があるため、Stageでのテスト結果を本番にそのまま適用しないことが原則である。
Infrastructure as Codeでのリソース管理
AgentCore Runtime、Gateway、Lambda、API Gateway、Knowledge Base、Memory、CloudWatchといった複数のリソースをCDKやTerraformで管理する場合、リソース間の依存関係の定義が複雑になる。特にAgentCore GatewayがLambdaを参照する際のARNは、Lambdaのデプロイ後に確定する値であり、CDKではFn::GetAttやTerraformではdepends_onで依存を明示する必要がある。この依存関係を誤ると、デプロイ時にリソースが存在しない状態でGatewayがLambdaを呼び出そうとして失敗する可能性がある。デプロイ順序を制御するだけでなく、デプロイ直後にGatewayからLambdaへの接続性を確認するヘルスチェックをパイプラインに組み込むことを推奨する。
運用と監視:コスト最適化とパフォーマンスチューニング
AgentCoreの呼び出しはToken数に応じた課金モデルとなるため、エージェントの設計判断が直接コストに反映される。特にKnowledge Baseのインデックス更新頻度は、データ新鮮性とコストのトレードオフを伴う。ポリシー文書が日次で更新される場合、毎時更新は過剰であり、日次更新で十分である場合が多い。一方、在庫ステータスのように実時間性が求められるデータは、Knowledge BaseではなくLambda経由のリアルタイムAPI呼び出しに切り替える設計判断が必要になる。
Lambda関数のプロビジョニングコンカレンシ設定は、レスポンス時間とコストのバランスを決定する。カスタマーサポートのようなユーザーが待機する場面では、冷启动による数百ミリ秒の遅延が体験を損なう可能性がある。プロビジョニングコンカレンシを常時確保すれば冷启动を回避できるが、オフピーク時のコストが上昇する。ツール呼び出しのピーク時間(例:営業時間中)にだけプロビジョニングを確保し、それ以外はオンデマンドに切り替えるスケジュール運用が現実的である。
長期記憶のスケーラビリティについては、会話履歴の蓄積に伴い検索性能が劣化することが懸念される。AgentCoreのMemory機能はセッション単位の管理を前提としており、顧客単位の長期記憶を跨ぐ場合は、外部DBへのエクスポートと要約処理の定期実行を別途設計する必要がある。データ量が増大するにつれ、全量検索からベクトル検索+メタデータフィルタリングへの移行が性能維持の鍵になる。
| パラメータ | 上げる場合の効果 | コスト・リスク |
|---|---|---|
| Knowledge Base更新頻度 | データ新鮮性向上 | インデックス構築コスト増 |
| Lambdaプロビジョニング | 冷启动回避、応答高速化 | オフピーク時の常時コスト |
| Token上限(max_tokens) | 複雑な推論の対応力向上 | 1リクエストあたりの課金増 |
| Memory保持期間 | 会話文脈の維持 | ストレージ・検索負荷増 |
まとめ:AIエージェント開発における「インフラ設計力」の重要性
本記事で扱ったState管理、ツール連携の境界線引き、IAM権限設計、エラーハンドリングの各論は、いずれもモデルの推論品質とは独立した課題である。Amazon Bedrock AgentCoreとStrands SDKを用いて注文追跡や返金処理など6つの機能を持つカスタマーサポートAIエージェントを構築した実例(構築事例)でも、最も困難だったのはAIそのものではなく、これらのインフラ統合であった。
返金処理の事例が示す通り、エージェントが「情報を生成する」だけでなく「実際のシステム操作をトリガーし、その結果に基づいて応答する」(同上)場合、設計の責任はプロンプトエンジニアリングの領域を超え、インフラエンジニアの領域に及ぶ。Lambdaの権限設定、API Gatewayのレートリミット、Circuit Breakerの状態管理——これらはAIの知識では解決できない、インフラ設計の判断である。
したがって、AIエージェントのプロジェクトにインフラエンジニアを参画させるタイミングは、モデル選定やプロンプト設計と並行して、あるいはそれ以前であるべきだ。Stateの永続化方針やツール間の権限境界が後から決まると、アーキテクチャの再設計を伴う変更が発生し、開発期間が延伸する可能性がある。設計フェーズで「どのデータがどこに格納され、誰がアクセス権を持つのか」をインフラ側と合意形成しておくことが、プロジェクトの品質と納期に影響を与える重要な要素となる。
今後の展望として、マルチエージェント構成や自律型学習の導入が進むにつれ、エージェント同士の通信経路や共有Stateの整合性管理が新たな複雑さとして追加される。そのとき、単一エージェントの段階でインフラ基盤の堅牢性を確保しておくことが、拡張性の観点で有利に働く可能性がある。AIの能力は年々向上するが、それを支える基盤の設計判断は、依然として人間の責任の範囲にある。
関連記事
- AIエージェントの暴走を防ぐ:while(true)ループの限界とEventStoreによる状態管理の実践
- AIエージェント開発の「脱フレームワーク化」:LangChain依存からの脱却と実装の本質
- AI生成コードの信頼性:C4モデルからDSTまで、実装検証のためのリライアビリティスタック構築指南
参考
本記事は海外の技術トレンド「I Built My First AI Agent With AWS AgentCore, and the Hardest Part Wasn't the AI」(DEV)で話題のテーマをもとに、両儀システムソリューションズが独自に解説したものです。