aws

Amazon Bedrock Agentsのカスタムオーケストレーション|Lambda実装とAgents Classicの現状

Amazon Bedrock Agentsのカスタムオーケストレーション|Lambda実装とAgents Classicの現状

Amazon Bedrock Agentsのカスタムオーケストレーションは、エージェントが「いつモデルを呼び、いつツールを実行し、いつ回答を確定するか」の判断そのものを、自前のAWS Lambda関数に置き換える機能です。標準のオーケストレーションループがブラックボックスで困る場面、たとえば検証ステップを必ず挟みたい、ツール呼び出しの回数を制御したい、といった要件に対応します。ただし2026年7月30日以降、Bedrock AgentsはAmazon Bedrock Agents Classicへ改称され新規顧客に開放されなくなったため、この機能を今から使えるかどうかはAWSアカウントの利用実績次第です。前提条件と実装の契約を、AWS公式ドキュメントの記述に沿って整理します。

まとめ

カスタムオーケストレーションは、エージェントのループ制御をLambda関数へ委譲する仕組みです。エージェントはSTARTから始まる状態をLambdaへ送り、LambdaはINVOKE_MODELINVOKE_TOOLAPPLY_GUARDRAILFINISH(またはユーザー定義の値)のいずれかを返して次の動作を指示します。設定はAPIのorchestrationTypeCUSTOM_ORCHESTRATIONにし、customOrchestration.executor.lambdaにLambdaのARNを渡します(必須フィールドの同時送信とPrepareAgentが必要です)。Amazon Bedrock Agentsが提供されている全AWSリージョンで利用できます。

一方で前提が2026年に変わりました。Bedrock Agents Classicは2026年7月30日からメンテナンスモードに入り、過去12か月に利用実績のないアカウントはCreateAgentを呼べません。既存ワークロードは継続稼働しますが新機能の追加予定はなく、AWSはAgentCoreへの移行を推奨しています。本文では状態遷移の実際、Lambdaの入出力契約、DynamoDBを外部ストアとして置くべきかの判断基準、AgentCore移行後の扱いまでを順に説明します。

カスタムオーケストレーションの動作モデル

STARTから始まる状態遷移とイベント応答

カスタムオーケストレーションでは、エージェントとLambda関数が状態とイベントを交換しながらループを回します。エージェントがLambdaへ送るstateは、STARTMODEL_INVOKEDTOOL_INVOKEDAPPLY_GUARDRAIL_INVOKED、およびユーザー定義の値です。AWS公式ドキュメントは「会話の最初の状態は常にSTART」と明記しています。

Lambdaはこれを受けてactionEventを返し、次にエージェントが何をするかを決めます。返せる値はINVOKE_MODELINVOKE_TOOLAPPLY_GUARDRAILFINISH、およびユーザー定義の値です。公式サンプルのchain of thought実装では、STARTINVOKE_MODELを返し、MODEL_INVOKEDのときはモデルの停止理由を見てtool_useならINVOKE_TOOLend_turnならFINISHを返し、TOOL_INVOKEDでは再びINVOKE_MODELへ戻す、という分岐になっています。想定外の状態はエラーとして投げる構成です。

重要なのは、この分岐がLambdaのコードとして手元にある点です。標準オーケストレーションではモデルが次の行動を決めますが、カスタムオーケストレーションでは「モデルがツール呼び出しを提案しても、条件を満たさなければ実行しない」といった制御をコードで書き切れます。

標準オーケストレーション(DEFAULT)との使い分け基準

orchestrationTypeは既定でDEFAULTで、このときの戦略はReAct(Reason and Action)です。基盤モデルのツール利用パターンに沿って、推論と行動を繰り返しながらモデルが次の一手を選ぶ方式です。カスタムへ切り替えると、ループ制御の責任はAWSから開発者側へ完全に移ります。移した分だけ、モデルの停止理由の解釈、無限ループの防止、エラー時のフォールバックまで自前で実装が必要になります。

切り替える価値があるのは、標準ループでは表現できない制約が要件に含まれる場合に限られます。具体的には、最終回答の前に必ず外部システムで検証を通す、複数のアクションを決められた順序で実行してから回答する、モデルの提案を業務ルールで却下する、といったケースです。逆に「エージェントが期待どおり動かない」程度の理由でカスタムへ倒すのは筋が悪く、まずは指示文とアクショングループのスキーマを見直すほうが早い。ループ制御を持つということは、AWS側の改善を受け取れなくなるということでもあります。なおAWSは、カスタム側で実装できる戦略の例としてPlan and Solve、Tree of Thought、SOP(標準作業手順)を挙げています。

オーケストレーションLambdaの入出力契約

エージェントからLambdaへ渡るリクエストペイロード

エージェントがLambdaへ送るペイロードはversion1.0で、stateinputcontextの3要素で構成されます。contextにはリクエストIDとセッションID、エージェント設定(指示文、既定モデルID、ツール定義、ガードレール設定)、それまでのセッション履歴の3点。会話の最初に届くSTART状態は、公式のペイロード構造をあてはめると次の形になります。

{
  "version": "1.0",
  "state": "START",
  "input": {
    "text": "{\"text\":\"ユーザーの入力テキスト\"}"
  },
  "context": {
    "requestId": "InvokeAgentのリクエストID",
    "sessionId": "InvokeAgentのセッションID",
    "agentConfiguration": {
      "instruction": "エージェントの指示文",
      "defaultModelId": "エージェントの既定モデルID",
      "tools": [ { "toolSpec": {} } ],
      "guardrails": {
        "version": "ガードレールのバージョン",
        "identifier": "ガードレールの識別子"
      }
    },
    "session": [],
    "sessionAttributes": {},
    "promptSessionAttributes": {}
  }
}

context.session配下のintermediaryStepsには、これまでのorchestrationInputorchestrationOutputの組が積まれます。つまりループの経過はエージェント側からLambdaへ毎回渡されるため、Lambda自身が前回までの流れを外部に保存しておく必要はありません。この点は後述する状態管理の設計判断に直結します。

Lambdaが返すactionEventと出力ペイロード

Lambdaの戻り値もversion1.0で、actionEventoutput、必要に応じてcontextを返します。output.textに入れる内容はイベントによって変わり、INVOKE_MODELINVOKE_TOOLAPPLY_GUARDRAILではConverse APIのリクエスト形式、FINISHでは最終回答のテキストです。モデル呼び出しの指示はAmazon Bedrock Converse APIの使い方(messages・stopReasonのリクエスト構造)をそのまま組み立てる形になります。次の例ではtracecontextも添えていますが、いずれも任意項目です。

{
  "version": "1.0",
  "actionEvent": "INVOKE_TOOL",
  "output": {
    "text": "{\"toolUse\":{\"toolUseId\":\"一意のID\",\"name\":\"ツール名\",\"input\":{}}}",
    "trace": {
      "event": {
        "text": "InvokeAgentのレスポンスへ出すトレース文字列"
      }
    }
  },
  "context": {
    "sessionAttributes": {},
    "promptSessionAttributes": {}
  }
}

output.trace.event.textに入れた文字列はInvokeAgentのレスポンスにイベントとして流れます。公式が定義しているのはこのtraceだけで、標準オーケストレーション時と同じ粒度のトレースが自動で出るとは保証されていません。どの状態でどのイベントを返したかを自分で書き出しておかないと、本番での切り分けがCloudWatch Logsだけに頼ることになります。実装時に最初に用意すべきはこのトレース出力です。

状態遷移を処理する最小ハンドラ(Python)

ここまでの契約をそのままコードにすると、分岐は次の形に収まります。公式サンプルはJavaScriptですが、構造は言語を問いません。

import json

def lambda_handler(event, context):
    state = event["state"]

    if state == "START":
        action, text = "INVOKE_MODEL", converse_request(event)
    elif state == "MODEL_INVOKED":
        stop_reason = model_stop_reason(event)
        if stop_reason == "tool_use":
            action, text = "INVOKE_TOOL", tool_use_payload(event)
        elif stop_reason == "end_turn":
            action, text = "FINISH", final_answer(event)
        else:
            raise ValueError("unhandled stopReason: " + str(stop_reason))
    elif state == "TOOL_INVOKED":
        action, text = "INVOKE_MODEL", converse_request(event)
    else:
        raise ValueError("unhandled state: " + state)

    return {
        "version": "1.0",
        "actionEvent": action,
        "output": {
            "text": text,
            "trace": {"event": {"text": "state=" + state + " event=" + action}},
        },
    }

converse_requestmodel_stop_reasontool_use_payloadfinal_answerはユースケース固有の組み立て処理で、公式サンプルでも同じ位置にヘルパー関数が置かれています。骨格として押さえるのは、versionactionEventtraceを必ず埋めること、そして未知の状態を握りつぶさずに例外へ落とすことの2点です。ガードレールを併用する構成ではAPPLY_GUARDRAIL_INVOKEDの分岐を追加し、対応するAPPLY_GUARDRAILを返します。上のコードのままだとガードレール状態は例外になります。

コンソールとAPIでの有効化手順

コンソールでは、エージェント作成後の編集時に設定します。Amazon Bedrockコンソールの左ナビゲーションで「Agents」を開き、対象エージェントの詳細ページで「Working draft」を選択します。「Orchestration strategy」セクションの「Edit」から「Custom orchestration」を選び、Lambda関数と関数バージョンをドロップダウンで指定してください。テンプレートを使わせる場合は「Activate template」をオン。オフのままだとエージェントはテンプレートを使いません。保存後、テストウィンドウの「Prepare」で反映を確認します。

APIから設定する場合は、ビルド時エンドポイントに対してUpdateAgentを送ります。orchestrationTypeの有効値はDEFAULTCUSTOM_ORCHESTRATIONの2つです。customOrchestration.executorはUNION型で、指定できるメンバーはlambdaのみ、値はLambda関数のARN(最大2,048文字)です。

import boto3

client = boto3.client("bedrock-agent", region_name="ap-northeast-1")

client.update_agent(
    agentId="ABCDEFGHIJ",
    agentName="my-agent",
    agentResourceRoleArn="arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForAgents_user",
    foundationModel="anthropic.claude-haiku-4-5-20251001-v1:0",
    orchestrationType="CUSTOM_ORCHESTRATION",
    customOrchestration={
        "executor": {
            "lambda": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-orchestrator"
        }
    },
)

UpdateAgentはパスのagentIdに加え、ボディでagentNameagentResourceRoleArnfoundationModelが必須のため、既存値をそのまま渡さないと設定が消えます。既存設定をGetAgentで取得してから差分を当てる運用が安全です。成功時のHTTPステータスは202で、反映にはその後のPrepareAgentが必要です。なおAgents Classicのモデルカタログは2026年7月30日で凍結されているため、foundationModelに指定できるのは同日時点で提供されていたモデルに限られます。

2026年7月30日以降の前提|Bedrock Agents Classicのメンテナンスモード

2023年11月に提供が始まったAmazon Bedrock Agentsは、Amazon Bedrock Agents Classicへ名称が変わり、2026年7月30日から新規顧客に開放されなくなりました。AWSはこれをメンテナンスモードと呼んでいます。影響範囲は限定的で、Amazon Bedrock本体、モデル推論、ナレッジベース、ガードレールは対象外です。

項目 2026年7月30日以降の扱い
既存エージェントの稼働 影響なし・継続
CreateAgent / InvokeInlineAgent 実績のないアカウントは不可
その他のAPI UpdateAgent / GetAgent / ListAgents / DeleteAgent / PrepareAgent / InvokeAgent ほか利用可
モデルカタログ 7月30日時点で凍結
新機能の追加 予定なし
サービス終了日 未定(移行期限なし)
Agents Classic自体の料金 課金なし

使えるかどうかを分けるのは、AWSアカウントに過去12か月のBedrock Agents利用実績があるかどうかです。実績のあるアカウントは自動的に許可リストへ入り、影響を受けません。実績のないアカウントがCreateAgentまたはInvokeInlineAgentを呼ぶと、HTTP 403のAccessDeniedExceptionが返り、メッセージは「Bedrock Agents is in Maintenance Mode. New agent creation is not available for accounts without prior service usage.(以下、ドキュメントへの案内が続きます)」です。判定はアカウント単位のため、複数アカウントを持つ組織では、実績のあるアカウントだけが許可リストに入ります。実績のないアカウントは同じ組織内でもCreateAgentを呼べません。例外申請の窓口はありません。

カスタムオーケストレーションを新規に検証したい場合、この制約が最初の関門になります。エージェント自体を作れないアカウントでは機能を試せないため、既存の検証用アカウントを使うか、後述のAgentCore側で設計するかの二択です。なお名称変更はラベルだけの話で、APIネームスペースのbedrock-agent、SDKクライアント、CloudFormationのリソースタイプ、IAMアクションのプレフィックスはいずれも変わりません。既存のIaCテンプレートは許可リスト内のアカウントであればそのまま動きます。モデルカタログが凍結された点は見落としやすく、2026年7月30日より後に出たモデルはAgents Classicのオーケストレーション層では選べません。

DynamoDB前提設計の見直し|状態管理を外部ストアに置く判断基準

カスタムオーケストレーションの構成図では、LambdaとDynamoDBがセットで描かれることがあります。しかしAWS公式のカスタムオーケストレーション仕様に、DynamoDBは一度も登場しません。オーケストレーションLambdaが必要とする文脈は、前述のとおりcontext.sessionintermediaryStepsとしてエージェント側から毎回渡されるためです。ターンをまたぐ小さな値もsessionAttributespromptSessionAttributesのキーバリューで運べます。ループを回すだけなら外部ストアは要りません。

それでもDynamoDBを置くべき場面は明確に存在します。判断基準はセッションの寿命です。idleSessionTTLInSecondsで指定できる値は最小60秒、最大5,400秒(90分)で、この時間内に会話がなければセッションは期限切れとなり、それまでに渡された情報はAmazon Bedrockから削除されます。つまりセッションを越えて保持したいデータ、たとえば申込内容の中間状態、監査ログ、ユーザーごとの累積履歴は、外部ストアに置かないと消えます。

逆に言えば、単一セッション内で完結する処理にDynamoDBテーブルを用意するのは、テーブル設計とIAMポリシーと課金を増やすだけで得るものがありません。オーケストレーションLambdaは冪等かつステートレスに保ち、業務データの永続化はアクショングループ側のLambdaに寄せる。この分離をしておくと、後からオーケストレーション部分を差し替えるときに業務ロジックを巻き込まずに済みます。

AgentCore移行|カスタムオーケストレーションはハーネスでは使えない

AWSが移行先として推奨するのはAmazon Bedrock AgentCoreです。移行パスは2つあり、モデル・ツール・指示文を宣言する設定ベースの「管理ハーネス」と、任意のフレームワークで書いたコードをデプロイする「コード定義エージェント」に分かれます。ハーネスはAgents Classicの管理された体験に最も近く、コンピュート、メモリ、アイデンティティ、可観測性をAgentCore側が受け持ちます。

ここで注意が要るのは、カスタムオーケストレーションの移行先がハーネスではないことです。AWSの機能対応表は、カスタムオーケストレーターについて「AgentCoreランタイム経由でサポート(カスタムオーケストレーションのコードを直接デプロイ)。ハーネスでは利用不可」と記載しています。Agents Classicでループ制御を自前で持っていた構成は、そのままハーネスへは移せず、コード定義エージェントとして書き直す前提。ステージ別のプロンプト上書きやルーティング型のマルチエージェントも、ハーネスでは同等の再現ができない項目として挙げられています。

移行に期限はなく、Agents Classicのサービス終了日も現時点で未定です。ただし新機能の追加予定がない以上、新規開発をAgents Classic上で始める理由はほぼありません。AgentCoreの導入手順はAmazon Bedrock AgentCore APIの使い方(SDK・CLI)で扱っています。移行の下調べには、AWSが公開しているagent-toolkit-for-awsamazon-bedrockスキルも用意されており、既存エージェントを調べて移行可否とAgentCore側の対応要素を提示したうえで、デプロイ前に承認を求める形で動きます。

よくある質問

カスタムオーケストレーションとは何ですか?

Amazon Bedrock Agentsが持つオーケストレーション戦略のひとつで、エージェントがマルチステップのタスクをどう処理し、いつモデルやツールを呼び、いつ最終回答を出すかをAWS Lambda関数で完全に制御する方式です。既定のDEFAULTに対して、orchestrationTypeCUSTOM_ORCHESTRATIONに切り替えることで有効になります。DEFAULTの戦略はReAct(推論と行動の繰り返し)で、次の一手を決めるのはモデル。カスタムでは、その決定をLambdaのコードが担います。

新規のAWSアカウントでカスタムオーケストレーションを試せますか?

試せません。2026年7月30日以降、過去12か月にBedrock Agentsの利用実績がないアカウントはCreateAgentでHTTP 403のAccessDeniedExceptionを受け取ります。エージェント自体を作成できないため、カスタムオーケストレーションの設定にも到達できません。例外申請の仕組みはなく、新規に必要な場合はAgentCoreを使います。

カスタムオーケストレーション自体に追加料金はかかりますか?

Bedrock Agents Classic自体には課金がありません。支払うのは従来どおり基盤モデルの推論と、関連リソースの利用分です。カスタムオーケストレーションの場合はオーケストレーションLambdaの実行回数と実行時間が加わるため、ループの回数がそのままコストに響きます。

オーケストレーションLambdaはどの状態まで処理する必要がありますか?

エージェントが送るstateSTARTMODEL_INVOKEDTOOL_INVOKEDAPPLY_GUARDRAIL_INVOKEDとユーザー定義値です。ガードレールを使わない構成でも、想定外の状態が届いたときに明示的にエラーを投げる分岐は入れておきます。公式サンプルも未知の状態を例外にしています。

カスタムオーケストレーションはどのリージョンで使えますか?

Amazon Bedrock Agentsが提供されている全AWSリージョンで利用できます。カスタムオーケストレーション単独でのリージョン制限はありません。

関連記事

資料請求

RELATED POSTS 関連記事