前回、Amazon Bedrock MantleでGPT-5.6 Lunaを呼び出し、Models APIには表示されるのに推論時は 401 access_denied になる現象を検証しました。
ただし、GPT-5.6が使えないからといって、古い gpt-oss へ戻る必要があるとは限りません。
Mantleのモデルカタログを公開日とAPI互換性で見直したところ、このAWSアカウントでは 2026年6月公開の xai.grok-4.3 を実行できました。さらに、LiteLLMをOpenAI互換プロキシとしてDocker Composeへ組み込み、Docker内のCodex CLIからも応答を得られました。
この記事では、単なる疎通確認ではなく、実運用で問題になりやすい次の点まで扱います。
- Models APIへの掲載とアカウント利用資格は別
- Mantleには
/v1/responsesと/openai/v1/responsesがある - LiteLLMでBedrock MantleのSigV4認証を扱う
-
aws loginのキャッシュをコンテナから安全に利用する - Codex CLIが送るResponses APIツールとMantleの互換性
- shell tool、サブエージェント、
/goalの実動作 -
store=falseと推論トークン上限
この記事は2026年7月24日時点のAWSドキュメント、LiteLLM v1.93.0、Codex CLI 0.145.0、および実機検証に基づきます。
結論
結果を先に示します。
| モデル | 公開日 | このアカウントでの実測 | API |
|---|---|---|---|
| GPT-5.6 Sol/Terra/Luna | 2026-07-13 | 401 利用不可 | Responses |
| Claude Sonnet 5 | 2026-06-30 | 403 利用不可 | Messages |
| Grok 4.3 | 2026-06-15 | 200 成功 | Responses/Chat Completions |
| Claude Fable 5 | 2026-06-09 | 403 利用不可 | Messages |
| Claude Opus 4.8 | 2026-05-28 | 未検証 | Messages |
| MiniMax M2.5 | 2026-02-12 | 未検証 | Chat Completions |
| GLM-5 | 2026-02-11 | 未検証 | Chat Completions |
| Qwen3 Coder Next | 2026-02-04 | 未検証 | Chat Completions |
| Kimi K2.5 | 2026-01-27 | 未検証 | Chat Completions |
Grok 4.3では、次の経路とCodex機能を確認できました。
AWS Bedrock Mantleへ直接 -> HTTP 200
LiteLLMの /v1/responses -> completed
Docker内Codex CLI -> LiteLLM -> GROK_CODEX_OK
Codex shell tool -> ファイル読取・結果返却に成功
Codex spawn_agent -> /root/subagent_default を生成
Codex /goal -> 作成・表示・pause・clearに成功
今回の構成では、既存の gpt-oss-20b を消さず、Grok 4.3を追加モデルとして登録しています。Codexのデフォルトモデルも変更せず、--model で明示的に切り替えました。
なぜGrok 4.3なのか
AWSのモデルカードによると、Grok 4.3は2026年6月15日公開のreasoning-firstモデルです。
- モデルID:
xai.grok-4.3 - コンテキストウィンドウ: 1Mトークン
- 入力: テキスト、画像
- API: Responses、Chat Completions
- 推論強度:
none、low、medium、high - ツール呼び出し、構造化出力、ストリーミングをサポート
- エンドポイント:
bedrock-mantle
特に重要なのは、Responses APIを直接利用できる点です。Codex CLIはOpenAI Responses APIを利用できるため、Chat Completionsしか持たないモデルを変換して使うより、変換層を減らせます。
Grok 4.3は次のパスを使用します。
https://bedrock-mantle.us-east-1.api.aws/openai/v1/responses
通常のgpt-ossが使うパスとは異なります。
https://bedrock-mantle.us-east-1.api.aws/v1/responses
モデルIDだけを差し替えてパスを変えないと、権限エラーではなくAPI非互換の400になる可能性があります。
全体構成
LiteLLMが担う役割は次のとおりです。
- Codex CLIにOpenAI互換の
/v1/responsesを公開する - 外部向けモデル名を内部のMantleモデルIDへ変換する
- AWS認証情報からSigV4署名を作成する
- モデルごとのエンドポイント差を吸収する
- 未対応パラメーターやツール定義を必要に応じて除外する
検証環境
OS Windows
AWS Region us-east-1
AWS認証 aws login
LiteLLM v1.93.0
Codex CLI 0.145.0
Node.js 22
Docker Compose LiteLLM / Open WebUI / Codex
Responses store false
長期Access KeyやSecret Access Keyは新規発行していません。ホスト側で aws login を実行し、その短期認証キャッシュをLiteLLMコンテナへマウントしています。
最初にAWS認証を確認します。
aws sts get-caller-identity
記事やログへAWSアカウントID、Access Key、Secret Access Key、セッショントークンを掲載しないでください。
LiteLLMへGrok 4.3を登録する
litellm-config.yaml にGrok 4.3を追加します。
model_list:
- model_name: bedrock-mantle-grok-4.3
litellm_params:
model: bedrock_mantle/xai.grok-4.3
aws_region_name: us-east-1
- model_name: bedrock-mantle-gpt-oss-20b
litellm_params:
model: bedrock_mantle/openai.gpt-oss-20b
aws_region_name: us-east-1
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
disable_spend_logs: true
litellm_settings:
drop_params: true
request_timeout: 300
telemetry: false
外部からは bedrock-mantle-grok-4.3 を指定し、LiteLLM内部で bedrock_mantle/xai.grok-4.3 へルーティングします。
LiteLLMでは、Bedrock MantleのGrok 4.3をResponses APIへルーティングする修正がすでにマージされています。
aws login をコンテナから利用する
今回のLiteLLMイメージでは、BotocoreのLogin Credential Providerを動かすためにCRT依存関係を追加しました。
ARG LITELLM_TAG=v1.93.0
FROM ghcr.io/berriai/litellm:${LITELLM_TAG}
RUN python -m ensurepip \
&& python -m pip install --no-cache-dir "botocore[crt]"
Docker ComposeではAWS設定ファイルを読み取り専用、ログインキャッシュを読み書き可能でマウントします。
services:
litellm:
build:
context: .
dockerfile: Dockerfile.litellm
args:
LITELLM_TAG: v1.93.0
command: ["--config", "/app/config.yaml", "--port", "4000"]
ports:
- "127.0.0.1:4000:4000"
environment:
LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}
AWS_PROFILE: default
AWS_REGION: us-east-1
BEDROCK_MANTLE_REGION: us-east-1
volumes:
- ./litellm-config.yaml:/app/config.yaml:ro
- type: bind
source: ${USERPROFILE}/.aws/config
target: /root/.aws/config
read_only: true
- type: bind
source: ${USERPROFILE}/.aws/login
target: /root/.aws/login
~/.aws/login を読み取り専用にすると、Botocoreが期限更新したキャッシュを書き戻せず、次のエラーになる場合があります。
[Errno 30] Read-only file system
設定ファイル全体を無制限に書き込み可能にする必要はありません。config は読み取り専用、更新対象の login ディレクトリだけ読み書き可能に分離できます。
LiteLLMを起動する
docker compose up -d --build litellm
docker compose ps
確認結果:
open-webui-litellm open-webui-litellm-mantle:v1.93.0
Up (healthy) 127.0.0.1:4000->4000/tcp
まずLiteLLMへ普通にリクエストする
Codexを接続する前に、LiteLLM単体でResponses APIを確認します。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["LITELLM_MASTER_KEY"],
base_url="http://127.0.0.1:4000/v1",
)
response = client.responses.create(
model="bedrock-mantle-grok-4.3",
input="Reply exactly: GROK_LITELLM_OK",
reasoning={"effort": "none"},
max_output_tokens=512,
store=False,
)
print(response.status)
print(response.output_text)
print(response.usage.total_tokens)
実測結果:
completed
GROK_LITELLM_OK
34
ここで一度、reasoning={"effort": "low"} と max_output_tokens=128 を組み合わせたところ、HTTP通信は成功したものの status=incomplete、output_text は空になりました。
Grok 4.3は短い回答でも推論トークンを先に消費することがあります。疎通確認では reasoning=none を使うか、十分な max_output_tokens を確保した方が原因を切り分けやすくなります。
Docker内へCodex CLIを用意する
Codex CLI用のイメージです。
FROM node:22-bookworm-slim
ARG CODEX_VERSION=0.145.0
RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
bubblewrap \
ca-certificates \
git \
ripgrep \
&& rm -rf /var/lib/apt/lists/* \
&& npm install --global "@openai/codex@${CODEX_VERSION}" \
&& codex --version
WORKDIR /workspace
ENTRYPOINT ["codex"]
Composeにはプロファイル付きで追加します。
services:
codex:
profiles: ["codex"]
build:
context: .
dockerfile: Dockerfile.codex
args:
CODEX_VERSION: 0.145.0
depends_on:
litellm:
condition: service_healthy
environment:
LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}
volumes:
- ./codex-config.toml:/root/.codex/config.toml:ro
- ./codex-workspace:/workspace
working_dir: /workspace
Codex CLIをLiteLLMへ向ける
codex-config.toml でカスタムモデルプロバイダーを定義します。
model = "bedrock-mantle-gpt-oss-20b"
model_provider = "litellm"
model_reasoning_effort = "low"
model_verbosity = "low"
web_search = "disabled"
[model_providers.litellm]
name = "Local LiteLLM"
base_url = "http://litellm:4000/v1"
env_key = "LITELLM_MASTER_KEY"
wire_api = "responses"
request_max_retries = 2
stream_max_retries = 2
stream_idle_timeout_ms = 300000
[features]
unified_exec = false
shell_tool = false
ここでは既存環境への影響を避けるため、デフォルトモデルを変更していません。Grok 4.3は実行時に指定します。
docker compose --profile codex run --rm -T codex exec `
--model bedrock-mantle-grok-4.3 `
--config 'model_reasoning_effort="none"' `
--skip-git-repo-check `
--sandbox read-only `
"Reply exactly: GROK_CODEX_OK"
実測結果:
OpenAI Codex v0.145.0
model: bedrock-mantle-grok-4.3
provider: litellm
sandbox: read-only
reasoning effort: none
GROK_CODEX_OK
通信経路は次のようになります。
Codex CLI
-> http://litellm:4000/v1/responses
-> LiteLLM model alias
-> https://bedrock-mantle.us-east-1.api.aws/openai/v1/responses
-> xai.grok-4.3
shell toolを実行する
Codexの推論経路だけでなく、モデルが実際にツールを選択し、ツール結果を使って回答できるかを確認しました。
ワークスペースへ次の内容を持つ tool-probe.txt を置きます。
GROK_TOOL_PROBE_20260724
shell_tool を有効にし、ファイルを必ずツールで読むよう指示します。
docker compose --profile codex run --rm -T codex exec `
--json `
--model bedrock-mantle-grok-4.3 `
--config 'model_reasoning_effort="none"' `
--enable shell_tool `
--skip-git-repo-check `
--sandbox danger-full-access `
"You must use the shell tool to read /workspace/tool-probe.txt. Return only its exact contents."
CodexのJSONイベントでは、Grok 4.3がコマンド実行を要求し、結果を回答へ戻すところまで確認できました。
command: /bin/bash -lc 'cat /workspace/tool-probe.txt'
exit_code: 0
output: GROK_TOOL_PROBE_20260724
final: GROK_TOOL_PROBE_20260724
ここでの danger-full-access はホストOS全体ではなく、隔離したCodexコンテナ内に対する指定です。--sandbox read-only も試しましたが、このDocker環境ではBubblewrapがunprivileged user namespaceを作成できず失敗しました。
bwrap: setting up uid map: Permission denied
これはGrokやMantleのツール互換性ではなく、Dockerホスト側のuser namespace/seccomp条件です。本番では、コンテナ境界とマウント範囲を最小化したうえで使うか、Bubblewrapを利用できるDocker設定へ変更してください。
Codexの namespace 問題
今回の構成で最も注意が必要だったのは、モデル本体ではなくツール定義です。
Codex CLI 0.145.0はResponses APIリクエストに namespace 型のツールを含めることがあります。一方、Mantle上のモデルやAPI経路によって、受理されるツール種別が異なります。
LiteLLMにも、Codexなどのクライアントが送る未対応ツールを下流へ転送し、プロバイダー側で拒否される同系統のIssueがあります。
当初はMantleへ転送するツールを function と mcp に制限し、namespace を落とす互換パッチを適用しました。
old = 'frozenset({"function", "mcp", "custom", "namespace", "tool_search"})'
new = 'frozenset({"function", "mcp"})'
Codex実行時のLiteLLMログでは、次の処理を確認できました。
Bedrock Mantle Responses API:
dropping unsupported tool type(s) ['namespace']
POST /v1/responses HTTP/1.1" 200 OK
ただし、この方法ではCodexのサブエージェント機能に必要な namespace も消えます。追加検証では、Grok 4.3とgpt-ossでCapabilityを分けました。
DEFAULT_TOOLS = frozenset(
{"function", "mcp", "custom", "namespace", "tool_search"}
)
GPT_OSS_TOOLS = frozenset({"function", "mcp"})
さらに、Grok 4.3は namespace ツール自体を受理するものの、Mantleから返る function_call では次の namespace フィールドが欠落しました。
{
"type": "function_call",
"name": "spawn_agent",
"arguments": "{\"task_name\":\"subagent_default\",...}"
}
Codex CLIが期待する形式は次です。
{
"type": "function_call",
"namespace": "collaboration",
"name": "spawn_agent",
"arguments": "{\"task_name\":\"subagent_default\",...}"
}
そこで、LiteLLMのMantleアダプターで、Codex collaboration関数に限ってレスポンスの namespace を復元しました。ストリーミングでは response.output_item.added、response.output_item.done、response.completed.response.output のすべてを補正する必要があります。
COLLABORATION_FUNCTIONS = {
"spawn_agent",
"send_message",
"followup_task",
"wait_agent",
"interrupt_agent",
"list_agents",
}
def restore_collaboration_namespace(item: dict) -> dict:
if (
item.get("type") == "function_call"
and item.get("name") in COLLABORATION_FUNCTIONS
and not item.get("namespace")
):
item["namespace"] = "collaboration"
return item
この補正はCodex固有の互換レイヤーです。任意の関数へ機械的に namespace を付けるのではなく、対象関数とモデルを限定してください。
サブエージェントをspawnする
Codex CLI 0.145.0では multi_agent はstableで有効、multi_agent_v2 はstableですがデフォルト無効でした。Grok 4.3でnamespaced collaboration toolsを使うため、両方を明示的に有効化しました。
docker compose --profile codex run --rm -T `
-e RUST_LOG=codex_core::tools=trace,codex_core::agent=trace `
codex exec `
--model bedrock-mantle-grok-4.3 `
--config 'model_reasoning_effort="none"' `
--enable multi_agent `
--enable multi_agent_v2 `
--skip-git-repo-check `
--sandbox danger-full-access `
"Spawn one default subagent named subagent_default with fork_turns none."
トレースでは、Grok 4.3が collaboration.spawn_agent を選択し、Codex側のハンドラーが正常終了しました。
tool_name=collaborationspawn_agent
execution_started=true
handler_duration_ms=788
Spawn result: {"task_name":"/root/subagent_default"}
別の実行では list_agents に /root/child_task が running として現れるところまで確認しました。つまり「spawn要求を文章で返した」だけではなく、Codex内部で実際に子エージェントが生成されています。
ただし、親子を同時にGrok 4.3へ接続した長時間waitでは、AWS側の一時的なhigh demandエラーも発生しました。spawn機能は動作しますが、並列数、再試行、タイムアウト、利用枠は実運用に合わせて調整が必要です。
/goal コマンドを使う
/goal は codex exec へ渡すプロンプトではなく、対話TUIのローカルスラッシュコマンドです。ComposeでTUIを起動します。
docker compose --profile codex run --rm codex `
--model bedrock-mantle-grok-4.3 `
--config 'model_reasoning_effort="none"' `
--enable goals `
--no-alt-screen
目標を設定します。
/goal Grok 4.3 goal command verification
実測では次の表示になり、設定直後からGrok 4.3による目標追跡が開始されました。
Goal active
Objective: Grok 4.3 goal command verification
Pursuing goal
中断すると目標はpauseされ、引数なしの /goal で状態を確認できました。
Goal
Status: paused
Objective: Grok 4.3 goal command verification
Time used: 10s
Tokens used: 31.1K
Commands: /goal edit, /goal resume, /goal clear
最後に /goal clear を実行し、Goal cleared も確認しました。/goal の状態管理自体はCodex CLI側の機能ですが、目標を追跡する各ターンは選択中のGrok 4.3をLiteLLM経由で呼び出します。
推奨する実行フラグ
今回の構成で検証した機能を有効化する最小セットは次です。
--enable shell_tool
--enable multi_agent
--enable multi_agent_v2
--enable goals
ただし、設定ファイルでは安全側に shell_tool=false を残し、必要な実行だけCLIフラグで有効化する運用も可能です。danger-full-access はコンテナのマウント範囲を確認したうえで指定してください。
store=false にする理由
MantleのResponses APIでは、store=true がデフォルトです。AWSの説明では、保存された入力と出力はリクエスト元リージョンに30日間保持され、previous_response_id による会話継続に利用できます。
今回の検証では、すべて store=false を指定しました。
response = client.responses.create(
model="bedrock-mantle-grok-4.3",
input="Hello",
store=False,
)
store=false では、Bedrockはそのリクエストとレスポンスを保存しません。その代わり、サーバー側に保存されたレスポンスIDを使う会話継続はできず、クライアント側が必要な履歴を再送する必要があります。
Codex CLIの今回のカスタムプロバイダー経路では store=false で送信されることも、LiteLLMへの通常リクエストで明示的に確認しました。
失敗から得た切り分けポイント
Models APIに表示されても実行できるとは限らない
GPT-5.6、Claude Sonnet 5、Claude Fable 5はModels APIに表示されましたが、実際の推論はアカウント単位の拒否になりました。
MODEL_ID is not available for this account
モデル探索と推論資格は別々に確認する必要があります。
同じResponses APIでもパスが異なる
/v1/responses
/openai/v1/responses
モデルカードに書かれたパスを使わないと、資格の有無を調べる前にAPI互換性エラーになります。
incomplete は必ずしも通信失敗ではない
reasoningトークンが出力上限を使い切ると、HTTP 200でもテキストが空になる場合があります。
確認項目:
response.statusresponse.incomplete_detailsresponse.usage.output_tokens_details.reasoning_tokensmax_output_tokensreasoning.effort
まずプロキシ単体、次にCodexを試す
最初からCodex経由で検証すると、AWS認証、LiteLLMルーティング、Responses変換、Codexツール定義を同時に調べることになります。
次の順番が効率的です。
- AWSへモデルを直接呼び出す
- LiteLLMへツールなしの最小リクエストを送る
- LiteLLMへ
store=false、reasoning設定付きで送る - Codex CLIから短い固定応答を要求する
- 最後にツール利用を段階的に有効化する
実運用へ進める前の課題
今回、単純応答に加えてshell tool、サブエージェントspawn、/goal まで動作を確認しました。ただし、すべてのCodex機能を保証するものではありません。
追加で必要な検証は次のとおりです。
- 複数ターンでのツール結果の再投入
- ストリーミング中のtool call index
- 複数サブエージェントの完走と長時間wait
- AWS high demand時のバックオフ
- プロンプトキャッシュ
- 画像入力
- 大きなリポジトリでのコンテキスト消費
- LiteLLMのコスト計測
- モデル別ツールCapabilityの分離
特に、Codex CLI側は未知のモデル名に対してフォールバックメタデータを使用します。
Model metadata for `bedrock-mantle-grok-4.3` not found.
Defaulting to fallback metadata.
簡単な推論は成功しましたが、コンテキスト上限や最適化されたトークン管理が正しく反映されない可能性があります。
まとめ
GPT-5.6を利用できないAWSアカウントでも、Bedrock Mantle上の新しいモデルを諦める必要はありません。
今回の実測では、2026年6月公開の xai.grok-4.3 が利用でき、次の経路を通せました。
Docker版Codex CLI
-> LiteLLM v1.93.0
-> AWS SigV4
-> Bedrock Mantle
-> xai.grok-4.3
重要なポイントは次のとおりです。
- モデルの新しさとアカウント利用資格を分けて確認する
- モデルごとのMantle APIパスを確認する
- Codex接続前にLiteLLM単体でResponses APIを検証する
- reasoningモデルでは極端に小さな出力上限を避ける
-
store=falseのデータ保持上の利点と会話継続上の制約を理解する - Codexのツール定義とMantle側Capabilityをモデル単位で調整する
-
namespaceを落とさず、Codexが期待するレスポンスへ補正する - Docker内サンドボックスとホスト側の隔離境界を分けて考える
現時点では、Grok 4.3は「GPT-5.6が使えない場合の古い代替」ではなく、Responses API、1Mコンテキスト、ツール利用を備えた新世代の有力候補です。
LiteLLM側にはモデル別ツールCapabilityとCodex namespace互換の補正が必要でしたが、それを加えることで、Docker版Codex CLIのshell tool、サブエージェントspawn、/goal をGrok 4.3で実行できました。次の段階は、複数エージェントが長時間タスクを最後まで完走する条件と、AWS側の混雑時制御を詰めることです。