---
title: "Bedrock Agentsのカスタムオーケストレーション｜Lambda実装・権限設定とAgentCore移行"
url: "https://www.issoh.co.jp/tech/details/4482/"
published: 2024-12-12
updated: 2026-11-03
categories: ["AWS"]
publisher: "株式会社一創"
---

# Bedrock Agentsのカスタムオーケストレーション｜Lambda実装・権限設定とAgentCore移行

Amazon Bedrock Agentsのカスタムオーケストレーションは、エージェントが「いつモデルを呼び、いつツールを実行し、いつ回答を確定するか」という判断を、自前のAWS Lambda関数に任せる機能です。2024年11月27日に提供が始まりました。2026年7月30日にBedrock AgentsはAmazon Bedrock Agents Classicへ改称されてメンテナンスモードに入ったため、今から使えるかどうかはAWSアカウントの利用実績で決まります。この記事では、Lambdaが受け取るイベントの中身と返すべき値、権限設定、そしてAgentCoreへ移すときにどこまで書き直しが要るかを、AWS公式ドキュメントと公式サンプルに沿って説明します。

## まとめ

カスタムオーケストレーションでは、エージェントが`START`・`MODEL_INVOKED`・`TOOL_INVOKED`・`APPLY_GUARDRAIL_INVOKED`のいずれかの`state`をLambdaへ送り、Lambdaは`INVOKE_MODEL`・`INVOKE_TOOL`・`APPLY_GUARDRAIL`・`FINISH`のいずれかを`actionEvent`として返します。`INVOKE_MODEL`で返すのはConverse APIのリクエストそのものです。有効化は`UpdateAgent`で`orchestrationType`を`CUSTOM_ORCHESTRATION`にし、`customOrchestration.executor.lambda`にLambdaのARNを渡したうえで`PrepareAgent`を実行します。Lambda側には`bedrock.amazonaws.com`からの呼び出しを許可するリソースベースポリシーが要ります。

過去12か月にBedrock Agentsを使っていないアカウントは、`CreateAgent`がHTTP 403になり、例外申請もできません。AgentCoreへの移行では、ツール呼び出しの却下や呼び出しの停止だけが目的なら、ハーネスのライフサイクルフック（2026年9月追加）で代わりが利きます（挙動は同じではありません）。ReWOOのようにループの形そのものを変えている構成は、AgentCore Runtimeにコードとして移すしかありません。

## カスタムオーケストレーションで制御できる範囲と状態遷移

### STARTからFINISHまでのstateとactionEvent

[AWSのユーザーガイド](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-custom-orchestration.html)は、会話の最初の状態は常に`START`だと明記しています。以降は、Lambdaが返した`actionEvent`をエージェントが実行し、その結果を次の`state`としてLambdaへ戻す、という往復が`FINISH`まで続きます。ユーザー定義の値を`state`と`actionEvent`の両方に使えるため、独自の段階を挟むこともできます。

| Lambdaが受け取るstate          | 直前にエージェントがしたこと  | 公式サンプルが返すactionEvent                      |
| ------------------------- | --------------- | ----------------------------------------- |
| START                     | InvokeAgentを受けた | INVOKE\_MODEL                             |
| MODEL\_INVOKED            | モデルを呼んだ         | tool\_useならINVOKE\_TOOL／end\_turnならFINISH |
| TOOL\_INVOKED             | ツールを実行した        | INVOKE\_MODEL                             |
| APPLY\_GUARDRAIL\_INVOKED | ガードレールを適用した     | （サンプルに分岐なし）                               |

この表の右列は、AWSが公開している[aws-samplesのReAct実装（lambda\_react.py）](https://github.com/aws-samples/amazon-bedrock-samples/tree/main/agents-and-function-calling/bedrock-agents/features-examples/14-create-agent-with-custom-orchestration)の分岐です。標準のReActと同じ動きをLambdaで再現したもので、ここに「このツールは呼ばせない」「3回呼んだら打ち切る」といった条件を足していくのがカスタムオーケストレーションの使い方になります。

### 標準オーケストレーション（DEFAULT）から切り替える条件

`orchestrationType`を省略すると`DEFAULT`になり、モデルが推論と行動を繰り返しながら次の一手を選びます。カスタムに切り替えると、停止理由の解釈、無限ループの防止、失敗時の返答まで全部Lambda側の責任です。切り替えてよいのは、次のように標準のループでは書けない制約が要件にある場合だけです。

- 最終回答の前に、外部システムでの検証を必ず通す
- モデルが提案したツール呼び出しを、業務ルールで却下する
- 計画を最初に1回だけ立て、途中でモデルに再評価させずに実行する（ReWOO）

3つ目について、[AWSのブログ](https://aws.amazon.com/blogs/machine-learning/getting-started-with-amazon-bedrock-agents-custom-orchestrator/)はレストラン予約の例で、複雑な問い合わせのレイテンシがReActより50〜70%下がったと報告しています。ただしこれは1つの事例の数字で、ReWOOは途中経過を検証せずに計画を実行するため、前の手順の結果で次の手順を変える必要がある業務には向きません。「エージェントが思いどおりに動かない」程度の理由なら、カスタムへ切り替える前に指示文とアクショングループのスキーマを見直すほうが早く片付きます。

## オーケストレーションLambdaの入出力仕様と実装

### 受け取るイベントとinput.textの中身

Lambdaが受け取るイベントは、`version`（`"1.0"`）、`state`、`input`、`context`で構成されます。`context.agentConfiguration`には指示文・既定モデルID・ツール定義・ガードレール設定が、`context.session`にはそれまでの`intermediarySteps`（各ステップの`orchestrationInput`と`orchestrationOutput`の組）が入ります。

実装で迷うのは`input.text`です。ユーザーガイドは「ユーザーの入力、またはConverse形式のツール結果」としか書いていません。公式サンプルは`input.text`を毎回JSONとして読み、状態ごとに次のように扱っています。

```
// START：ユーザーの発話
{"text": "明日19時に2名で予約したい"}

// MODEL_INVOKED：モデルの応答（outputはそのままmessagesへ積める形）
{"output": {"role": "assistant",
            "content": [{"toolUse": {"toolUseId": "t1", "name": "create_booking", "input": {"people": 2}}}]},
 "stopReason": "tool_use"}

// TOOL_INVOKED：ツールの実行結果
{"toolResult": {"toolUseId": "t1", "content": [{"text": "予約番号 123"}]}}
```

値は説明用に置き換えています。ユーザーガイドが示すのは構造例までで、全フィールドの必須・任意を定めたスキーマは公開されていません。公式サンプルと同じく、届いたイベントを最初に`print(json.dumps(event))`でCloudWatch Logsへ出し、実物で確かめてから分岐を固めてください。イベントには会話の全文やツール結果、セッション属性が入るので、全文を出すのは機密を含まない検証データのときだけにし、本番では記録する項目を絞ってマスキングします。

### INVOKE\_MODELで返すConverseリクエスト

`INVOKE_MODEL`を返すとき、`output.text`にはConverse APIのリクエストをJSON文字列で入れます。公式サンプルは`modelId`・指示文・ツール定義を`agentConfiguration`から取り、`messages`を`intermediarySteps`から組み立てています。書式は通常のConverse APIと同じなので、[Amazon Bedrock Converse APIの使い方｜boto3実装・ConverseStream・Tool Use・IAM権限](/tech/details/2391/)のTool Useの章がそのまま参考になります。`FINISH`のときだけは、`output.text`にユーザーへ返す回答の文字列を入れます。

`output.trace.event.text`に入れた文字列は、`enableTrace`を有効にして`InvokeAgent`を呼んだとき、レスポンスにトレースとして流れます（トレースは既定で無効です）。どの`state`で何を返したかをここに書いておくと、本番の調査をCloudWatch Logsだけに頼らずに済みます。

### ツールの許可リストと回数上限を入れたハンドラ（Python）

公式サンプルの入出力の扱い方に沿って、許可していないツールの呼び出しを打ち切る処理と、1ターン内のツール呼び出しを5回までに抑える処理を足したハンドラです。`converse_request`と`build_messages`も含めた全体像で、使うときは`ALLOWED_TOOLS`を自分のアクショングループの関数名に合わせ、検証用アカウントで実際のイベントに当てて確かめてください。モデルが1回の応答で複数のツールを同時に要求した場合は、対応を簡単にするため終了させています。

```
import json

MAX_TOOL_CALLS = 5
ALLOWED_TOOLS = {"get_booking", "create_booking"}


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

    if state in ("START", "TOOL_INVOKED"):
        action, text = "INVOKE_MODEL", json.dumps(converse_request(event))
    elif state == "MODEL_INVOKED":
        result = json.loads(event["input"]["text"])
        stop_reason = result.get("stopReason")
        content = result.get("output", {}).get("content", [])
        tool_uses = [c for c in content if "toolUse" in c]
        if stop_reason == "tool_use" and tool_uses:
            name = tool_uses[0]["toolUse"]["name"]
            if len(tool_uses) > 1:
                action, text = "FINISH", "複数ツールの同時呼び出しには対応していません。"
            elif name not in ALLOWED_TOOLS:
                action, text = "FINISH", "この操作は受け付けられません。"
            elif count_tool_calls(ctx) >= MAX_TOOL_CALLS:
                action, text = "FINISH", "処理が規定回数を超えたため中断しました。"
            else:
                action, text = "INVOKE_TOOL", json.dumps(tool_uses[0])
        elif stop_reason == "end_turn":
            texts = [c["text"] for c in content if "text" in c]
            action, text = "FINISH", "".join(texts) or "回答を生成できませんでした。"
        else:
            raise ValueError("unhandled stopReason: " + str(stop_reason))
    else:
        raise ValueError("unhandled state: " + state)

    return {
        "version": "1.0",
        "actionEvent": action,
        "output": {
            "text": text,
            "trace": {"event": {"text": "state=" + state + " event=" + action}},
        },
        "context": {
            "sessionAttributes": ctx.get("sessionAttributes", {}),
            "promptSessionAttributes": ctx.get("promptSessionAttributes", {}),
        },
    }


def count_tool_calls(ctx):
    turn = (ctx.get("session") or [{}])[-1]
    return sum(
        1 for step in turn.get("intermediarySteps", [])
        if step.get("orchestrationOutput", {}).get("event") == "INVOKE_TOOL"
    )


def converse_request(event):
    ctx = event["context"]
    conf = ctx["agentConfiguration"]
    request = {
        "modelId": conf["defaultModelId"],
        "system": [{"text": conf["instruction"]}],
        "messages": build_messages(ctx, event["input"]),
        "inferenceConfig": {"maxTokens": 1024},
    }
    if conf.get("tools"):
        request["toolConfig"] = {"tools": conf["tools"]}
    return request


def build_messages(ctx, current_input):
    messages = []
    for turn in ctx.get("session", []):
        for step in turn.get("intermediarySteps", []):
            src = step.get("orchestrationInput", {})
            if src.get("state") == "START":
                messages.append({"role": "user", "content": [{"text": src["text"]}]})
            elif src.get("state") == "MODEL_INVOKED":
                messages.append(json.loads(src["text"])["output"])
            elif src.get("state") == "TOOL_INVOKED":
                messages.append({"role": "user", "content": [json.loads(src["text"])]})
    messages.append({"role": "user", "content": [json.loads(current_input["text"])]})
    return messages
```

返り値の`context`で`sessionAttributes`を返し直しているのは、公式サンプルと同じく、ターンをまたいで値を持ち越すためです。ガードレールを使うときは、Lambdaが`APPLY_GUARDRAIL`を返し、その結果が`APPLY_GUARDRAIL_INVOKED`として戻ってくる流れになります。このコードには分岐が無く例外になるので、拒否されたときの終了処理も含めて足してください。ガードレール側の設定は[Amazon Bedrock Guardrails（AWSのガードレール）とは｜日本語で効かせる設定・料金・実装](/tech/details/4265/)で扱っています。

## エージェントへの設定とLambdaの呼び出し権限

### bedrock.amazonaws.comによるLambda呼び出しの許可設定

オーケストレーションLambdaはエージェント（Bedrockのサービス）から呼ばれるため、Lambdaのリソースベースポリシーで`bedrock.amazonaws.com`に`lambda:InvokeFunction`を許可します。公式サンプルは呼び出し元をエージェントのARNに絞っています。

```
import boto3

region, account_id, agent_id = "ap-northeast-1", "123456789012", "ABCDEFGHIJ"

boto3.client("lambda", region_name=region).add_permission(
    FunctionName="my-orchestrator",
    StatementId="allow-bedrock-agent",
    Action="lambda:InvokeFunction",
    Principal="bedrock.amazonaws.com",
    SourceArn=f"arn:aws:bedrock:{region}:{account_id}:agent/{agent_id}",
)
```

アクショングループのLambda向けに[AWSが掲載しているポリシー例](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-permissions.html)は、`AWS:SourceArn`に加えて`AWS:SourceAccount`でも呼び出し元を絞っています。上のコードもエージェントARNを固定しているので呼び出し元は特定のエージェントに絞れていますが、オーケストレーションLambda専用のポリシー要件は公式に明記されていないため、アクショングループと同じく`SourceAccount`も併せて指定しておくと条件の書き方を揃えられます。

### UpdateAgentによるCUSTOM\_ORCHESTRATIONの有効化

APIでは、ビルド時エンドポイント（`bedrock-agent`）へ`UpdateAgent`を送ります。`orchestrationType`に指定できるのは`DEFAULT`と`CUSTOM_ORCHESTRATION`の2つで、`customOrchestration.executor`に指定できるのは`lambda`（関数ARN）だけです。`CreateAgent`でも同じ2項目を渡せます。

```
import boto3

import time

client = boto3.client("bedrock-agent", region_name="ap-northeast-1")
agent = client.get_agent(agentId="ABCDEFGHIJ")["agent"]
optional = {"instruction": agent["instruction"]} if agent.get("instruction") else {}

client.update_agent(
    agentId=agent["agentId"],
    agentName=agent["agentName"],
    agentResourceRoleArn=agent["agentResourceRoleArn"],
    foundationModel=agent["foundationModel"],
    orchestrationType="CUSTOM_ORCHESTRATION",
    customOrchestration={
        "executor": {
            "lambda": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-orchestrator"
        }
    },
    **optional,
)


def wait_status(agent_id, done, timeout=300):
    for _ in range(0, timeout, 5):
        status = client.get_agent(agentId=agent_id)["agent"]["agentStatus"]
        if status in done:
            return status
        if status == "FAILED":
            raise RuntimeError("agent status FAILED")
        time.sleep(5)
    raise TimeoutError(agent_id)


wait_status(agent["agentId"], {"NOT_PREPARED", "PREPARED"})
client.prepare_agent(agentId=agent["agentId"])
wait_status(agent["agentId"], {"PREPARED"})
```

`UpdateAgent`は`agentName`・`agentResourceRoleArn`・`foundationModel`が必須で、差分だけを送る作りではありません。上の例のように`GetAgent`で読んだ現在の値を渡し直し、指示文などの任意項目も含めて設定を落とさないようにします。指示文は指定するなら40〜4,000文字で空文字は送れないため、既存値があるときだけ渡しています。`UpdateAgent`と`PrepareAgent`はどちらも非同期（HTTP 202）なので、`agentStatus`が`PREPARED`になるのを待ってから、DRAFTを指すテスト用エイリアス`TSTALIASID`に`InvokeAgent`を送って確認します（[AWSのテスト手順](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-test.html)）。

コンソールでは、Amazon Bedrockの「Agents」から対象エージェントを開き、「Working draft」の「Orchestration strategy」で「Edit」を押し、「Custom orchestration」を選んでLambda関数とバージョンを指定します。保存後、テストウィンドウの「Prepare」で反映されます。

## Agents Classicのメンテナンスモードで変わった前提

[AWSの案内](https://docs.aws.amazon.com/bedrock/latest/userguide/agents-classic-maintenance-mode.html)によると、2023年11月に始まったAmazon Bedrock Agentsは2026年7月30日からAgents Classicとしてメンテナンスモードに入りました（告知はユーザーガイドの変更履歴で2026年6月30日）。Amazon Bedrock本体、モデル推論、ナレッジベース、ガードレールは対象外です。

| 項目                                     | 2026年7月30日以降         |
| -------------------------------------- | -------------------- |
| 既存エージェントの稼働                            | 継続                   |
| CreateAgent・InvokeInlineAgent          | 利用実績のないアカウントは403     |
| UpdateAgent・PrepareAgent・InvokeAgentほか | 全アカウントで利用可           |
| モデルカタログ                                | 7月30日時点で凍結           |
| 新機能・移行期限・終了日                           | いずれも予定なし             |
| Agents Classic自体の料金                    | 無料（モデル推論・Lambda等は課金） |

使えるかどうかはアカウント単位で、過去12か月にBedrock Agentsの利用があれば自動で許可リストに入ります。利用のないアカウントが`CreateAgent`を呼ぶと`AccessDeniedException`（HTTP 403）で「Bedrock Agents is in Maintenance Mode. New agent creation is not available for accounts without prior service usage.」と返り、例外申請の窓口はありません。カスタムオーケストレーションを新しく試すには、利用実績のある検証用アカウントを使うしかないということです。

モデルカタログの凍結により、7月30日より後に出たモデルはAgents Classicのオーケストレーション層では選べません。新しいモデルへ上げ続けたいなら、それ自体がAgentCoreへ移す理由になります。名称変更はラベルだけで、`bedrock-agent`のAPIネームスペース、SDK、CloudFormationのリソースタイプ、IAMアクションのプレフィックスは変わっていません。

## 状態をDynamoDBに置くかの判断基準

ループを回すだけなら外部ストアは要りません。経過は`intermediarySteps`として毎回渡され、ターンをまたぐ小さな値は`sessionAttributes`で運べます。公式サンプルでもDynamoDBを使うのは予約データを保存するアクショングループ側で、オーケストレーションLambdaは何も保存していません。

外部ストアが要るかどうかは、セッションより長く残したいデータがあるかで決まります。`idleSessionTTLInSeconds`に指定できるのは60〜5,400秒（90分）で、会話が途切れてこの時間が過ぎるとセッションの情報は消えます。申込の途中状態や監査ログはアクショングループのLambdaからDynamoDBなどへ書き出し、オーケストレーションLambdaは状態を持たない作りにしておくと、後で戦略を差し替えても業務データを巻き込みません。

## AgentCoreへ移すときの判断：ハーネスのフックか、Runtimeでの書き直しか

AWSの推奨移行先はAmazon Bedrock AgentCoreで、モデル・ツール・指示を宣言するだけの「ハーネス」と、任意のフレームワークで書いたコードを載せる「コード定義エージェント（AgentCore Runtime）」の2つの道があります。AWSの機能対応表は、カスタムオーケストレーターを「AgentCore Runtimeで独自コードをデプロイすればサポート、ハーネスでは利用不可」としています。ただ、カスタムにしていた理由によってはハーネスで足ります。

### ツール却下と呼び出し停止に使うハーネスのライフサイクルフック

2026年9月、ハーネスに`before_invocation`・`before_tool_call`・`after_tool_call`・`after_invocation`の4つのライフサイクルフックが加わりました（[AgentCoreのフックの解説](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/harness-lifecycle-hooks.html)）。Lambdaを宛先にすると同期で呼ばれ、`{"decision": "deny"}`を返せば次のように動きます。

- `before_tool_call`：そのツール呼び出しだけを飛ばし、ループは続く。Lambdaには`toolName`・`toolType`・`toolInput`・`toolUseId`が渡る
- `after_tool_call`：ツールの結果は残したまま、呼び出し全体を止める（`stopReason`は`hook_stopped`）
- `before_invocation`：エージェントが動き出す前に止める

上のハンドラの「許可していないツールは実行させない」部分は、`before_tool_call`で`toolName`を見て`deny`を返せば移せます。ただし、上のハンドラは未許可ツールが出た時点で会話を終えますが、`before_tool_call`の`deny`はそのツールを飛ばしてループを続けます。打ち切りたいなら`after_tool_call`の`deny`で止める形になり、その場合は直前のツールが実行された後に止まります。フックの`context`には呼び出し回数が入らないため、回数上限もLambda側で数える必要があります。`sessionId`は複数ターンで共有されるので、それだけをキーにするとセッション全体の上限になります。1ターン単位にするには、`before_invocation`でカウンタを初期化するなど、ターンの区切りを自分で持たなければなりません。Lambdaの`timeoutSeconds`は既定60秒（1〜900秒）で、タイムアウトや不正な応答のときは`failureMode`の既定どおり`deny`扱いになります。フックを設定できるのは`CreateHarness`と`UpdateHarness`だけで、`UpdateHarness`に`hooks`を渡すと既存のフック設定は丸ごと置き換わります。ハーネスそのものの仕組みと料金は[Bedrock AgentCoreハーネスGAとは？仕組み・料金・導入判断を解説](/tech/details/12934/)にまとめています。

### 独自ループを持つ構成のAgentCore Runtimeへのコード移行

入力やツール呼び出し・ツール結果の検証は、AWSもフックの用途に挙げています。一方、ReWOOのように計画を先に立てて一括実行する、検証に失敗したらモデルに再生成させる、独自の`state`で段階を増やす、といった「次に何をするかを自分で選ぶ」構成はフックでは表現できません。フックが返せるのは特定の時点での許可・拒否だけで、次にモデルを呼ぶかツールを呼ぶかという分岐そのものは変えられないからです。この場合はStrands AgentsやLangGraphなどでループを書き、AgentCore Runtimeにデプロイします。

移行ツールはこの区別に合わせて振る舞いが分かれます。AWSの[agent toolkit for AWS](https://github.com/aws/agent-toolkit-for-aws)の`amazon-bedrock`スキルはハーネスへの移行を案内しますが、マルチエージェント連携・マルチモーダル入力・カスタムオーケストレーションを使うエージェントは適格性判定で止まります。一方、2026年10月28日に一般提供となったAgentCore CLI 1.0（npmの`@aws/agentcore`、11月3日時点の最新は1.0.1）では、`agentcore add runtime`に`--agent-id`・`--agent-alias-id`・`--framework strands|langgraph`のオプションがあり、既存のBedrock AgentをRuntime用のコードへ変換できます。エイリアスはDRAFTではなく準備済みのバージョンを指している必要があります。

ただし、このインポートでオーケストレーションLambdaまで変換されるとは考えないでください。1.0.1の配布コードを読むと、変換時の注記はアクショングループのスタブや`AMAZON.UserInput`などが対象で、`orchestrationType`を読む処理は見当たりません。Lambdaに書いていた状態分岐は、生成されたコードのループへ手で移すことになります。CLIの導入とデプロイの手順は[AgentCore APIの使い方：SDK・CLI 1.0・InvokeAgentRuntimeでエージェントを本番に載せる手順](/tech/details/8230/)を参照してください。ループを自前で書くときの代表的な型は[マルチエージェントオーケストレーションとは？LLMエージェントを束ねる5パターンと実装コード](/tech/details/13600/)で比べています。業務システムとの接続や権限設計まで含めて移行を進める場合は、[AIエージェント開発](/service/ai/agent/)の支援も相談先になります。

処理の順番を完全に固定したいだけで、モデルに次の一手を選ばせる必要がないなら、エージェントではなく[Amazon Bedrock Flowsとは｜ノード14種・料金・上限とboto3実装](/tech/details/3376/)のようなワークフローで組むほうが素直です。ただしFlowsのエージェントノードが呼ぶのはAgents Classicのエージェントなので、利用実績のないアカウントではノードに指定するエージェント自体を新しく作れません。

## よくある質問

### Bedrock Agentsのカスタムオーケストレーションとは何ですか？

エージェントがいつモデルを呼び、いつツールを実行し、いつ回答を確定するかを、AWS Lambda関数のコードで決める方式です。`orchestrationType`を既定の`DEFAULT`から`CUSTOM_ORCHESTRATION`に切り替えると有効になります。

### 新しいAWSアカウントでカスタムオーケストレーションを試せますか？

過去12か月にBedrock Agentsの利用がないアカウントでは試せません。`CreateAgent`がHTTP 403になり、例外申請の仕組みもないため、新規に作るならAgentCoreを使います。

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

Agents Classic自体は無料で、支払うのはモデル推論と関連リソースの利用料です。カスタムオーケストレーションでは、1回の`InvokeAgent`の中でもオーケストレーションLambdaが状態の数だけ呼ばれます。公式サンプルの流れでツールを2回使う会話なら、`START`で1回、モデル呼び出し後に3回、ツール実行後に2回の計6回です。ループの回数はそのままLambdaの課金に響きます。

### AgentCoreのハーネスにカスタムオーケストレーションを移せますか？

そのままでは移せません。AWSの対応表はハーネスでは利用不可としています。ツールの却下や呼び出しの停止が目的ならライフサイクルフックで代わりが利き、ループの形を変えている構成はAgentCore Runtimeにコードとして移します。

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

Amazon Bedrock Agentsが提供されている全リージョンで使えます（[2024年11月27日の発表](https://aws.amazon.com/about-aws/whats-new/2024/11/amazon-bedrock-agents-custom-orchestration/)）。カスタムオーケストレーション単独のリージョン制限はありません。

## 関連記事

- [AgentCore APIの使い方：SDK・CLI 1.0・InvokeAgentRuntimeでエージェントを本番に載せる手順【2026年10月】](/tech/details/8230/)
- [Bedrock AgentCoreハーネスGAとは？仕組み・料金・導入判断を解説](/tech/details/12934/)
- [Amazon Bedrock Converse APIの使い方｜boto3実装・ConverseStream・Tool Use・IAM権限【2026年10月】](/tech/details/2391/)
- [Amazon Bedrock Flowsとは｜ノード14種・料金・上限とboto3実装【2026年11月】](/tech/details/3376/)
- [マルチエージェントオーケストレーションとは？LLMエージェントを束ねる5パターンと実装コード【2026年10月】](/tech/details/13600/)

---

出典: [Bedrock Agentsのカスタムオーケストレーション｜Lambda実装・権限設定とAgentCore移行](<https://www.issoh.co.jp/tech/details/4482/>)（株式会社一創）
