Bedrock GPT-5.5 の高 effort 指定時に発生した重複・JSON 破損の回避を試みてみた
はじめに
GPT-5.5 が Amazon Bedrock で利用可能になり、Lambda 上でも動作することを確認できました。
今回は GPT-5.5 をブログ記事のレビュー役として使い、セカンドオピニオンを得られるか試しました。AWS公式ブログのサンプルコードに従い reasoning={"effort": "medium"} で呼び出したところ、出力の重複や JSON 破損に遭遇しました。
OpenAI Community でも GPT-5.x 系で類似の重複出力が複数報告されています。
- GPT-5.4 での重複報告(2026年3月〜、記事執筆時点で未解決)
- GPT-5.2 でも同様の報告
- Responses API で複数の類似メッセージ
- Codex CLI: Duplicate outputs (Issue #2913)
Bedrock 経由に限った現象ではなさそうですが、回避策の情報が少ないため自分で検証しました。
検証環境・条件
| 項目 | 内容 |
|---|---|
| 実行環境 | AWS Lambda (Python 3.14, arm64, 256MB) |
| SDK | openai >= 2.40.0 + aws-bedrock-token-generator (Lambda Layer) |
| リージョン | us-east-2 |
| モデル ID | openai.gpt-5.5 |
| API | /openai/v1/responses (Responses API) |
max_output_tokens |
4096 (plain) / 2048 (structured) |
入力記事は以下の 2 本を使用しました。
- A1: Bedrock で OpenAI GPT-5.5 / GPT-5.4 が GA になったので Responses API で試してみた(約 7,300 文字)
- A2: Bedrock GPT-5.5 を OpenAI SDK の Lambda レイヤーで動かしてみた(約 15,800 文字)
以下は表の読み方に関する補足です。
- structured は JSON スキーマで出力件数・項目を絞っているため
max_output_tokensを 2048 としています。plain と structured の token 数は単純比較ではなく、各モード内での傾向を見る目的です noneはreasoningパラメータを指定しない条件として扱っていますOut tokensは API usage のoutput_tokens、Reasoningはその内訳のreasoning_tokensです- 表1・表2 は Lambda 実行時の代表例であり、厳密なベンチマークではありません。遭遇した現象と傾向を示す目的です
呼び出しコード
本検証では、Bedrock の OpenAI 互換エンドポイントで Responses API(/openai/v1/responses)を使用しています。従来の Chat Completions API とはパラメータ名(input, text 等)が異なります。
plain + 非ストリーム
params = {
"model": "openai.gpt-5.5",
"input": [
{"role": "developer", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"以下の記事ドラフトをレビューしてください:\n\n{draft}"},
],
"max_output_tokens": 4096,
}
if effort != "none":
params["reasoning"] = {"effort": effort}
response = client.responses.create(**params)
output_text = response.output_text
structured + 非ストリーム
params = {
"model": "openai.gpt-5.5",
"input": [...],
"text": {"format": {
"type": "json_schema",
"name": "review_result",
"strict": True,
"schema": {
"type": "object",
"properties": {
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"location": {"type": "string"},
"reason": {"type": "string"},
},
"required": ["location", "reason"],
"additionalProperties": False,
},
}
},
"required": ["issues"],
"additionalProperties": False,
},
}},
"max_output_tokens": 2048,
}
if effort != "none":
params["reasoning"] = {"effort": effort}
response = client.responses.create(**params)
output_text = response.output_text
ストリーミング時は stream=True を追加し、response.output_text.delta イベントを連結して output_text 相当を取得しました。ストリーミングでも非ストリームと同様の重複・破損傾向を確認しています。
plain モードで effort を比較
| Effort | Time | Out tokens | Reasoning | 重複 |
|---|---|---|---|---|
| none | 6.6s | 564 | 0 | なし |
| low | 8.2s | 597 | 387 | あり |
| medium | 10.2s | 700 | 516 | あり |
| high | 26.9s | 2274 | 2070 | あり |
※ いずれも status=completed。
今回の plain 出力では、low 以上で重複が見られました。
重複出力の実例(effort=low, plain)
1. 該当箇所
`# Amazon Bedrock で OpenAI GPT-5.5 / GPT-5.4 が GA になったので Responses API で試してみた`
理由
記事タイトルは CMS のメタ1. 該当箇所
`# Amazon Bedrock で OpenAI GPT-5.5 / GPT-5.4 が GA になったので Responses API で試してみた`
理由
記事タイトルは CMS のメタ欄で管理する想定のため、本文内に H1 として含めないほうがよいです。
2.1. 該当箇所
`# Amazon Bedrock で OpenAI GPT-5.5 / GPT-5.4 が GA になったので...`
理由
記事タイトルは CMS のメタ欄で管理する想定のため、...
2. 該当1. 該当箇所
`# Amazon Bedrock で OpenAI GPT-5.5 / GPT-5.4 が GA になったので...`
理由
記事タイトルは CMS のメタ欄で管理する想定のため、...
2. 該当箇所
タイトル直下のリード文
「1. 該当箇所」が途中で再挿入され、番号がリセットされています。「2.1. 該当」のような番号崩れも発生しました。high では 27 秒かけて重複が多く含まれる出力になりました。
Structured Outputs で effort を比較
strict:true を有効にした Structured Outputs での結果です。
| Effort | Time | Out tokens | Reasoning | Status | JSON |
|---|---|---|---|---|---|
| none | 5.5s | 460 | 0 | completed | ✅ valid |
| low | 3.8s | 250 | 0 | completed | ✅ valid |
| medium | 13.6s | 1089 | 912 | completed | ❌ 破損 |
| high | 24.2s | 2048 | 2048 | incomplete | ❌ 未完了 |
none と low は valid JSON を返しました。一方、medium と high では問題が発生しました。
medium の問題: status=completed かつ incomplete_details=None にもかかわらず、json.loads() に失敗しました。strict:true を指定していてもアプリケーション側での parse / validation は省略できません。
high の問題: max_output_tokens=2048 を使い切り status=incomplete になりました。output_tokens=2048、reasoning_tokens=2048 という結果から、max_output_tokens の予算を reasoning(思考)側だけで使い切り、JSON 出力に割り当てられるトークンが残らなかった可能性があります。利用可能な valid JSON は得られませんでした。
壊れ方の違いをまとめます。
- medium: JSON の途中で
{"issues":[が再挿入され、valid JSON として parse できない - high: token budget を使い切って出力が途中で打ち切られる
破損した JSON の実例(effort=medium, status=completed)
{
"issues": [
{
"location": "タイトル直下のリード文「Amazon Bedrock で...",
"reason": "リード文は1段落ありますが、...定量的結果が含まれていません。"
},
{
"location": "# Amazon Bedrock で OpenAI GPT-5.5 /...",
"reason": "記事タイトルはCMSメタ{
"issues": [
{
"location": "タイトル直下のリード文「Amazon Bedrock で...",
"reason": "リード文は1段落ありますが、...定量的結果が含まれていません。"
},
{
"location": "# Amazon Bedrock で OpenAI GPT-5.5 /...",
"reason": "記事タイトルはCMSメタ欄用のため、本文内にH1として含めない想定です。"
}
]
}
再現性の確認
plain モード全測定の中央値(n=3)
実行環境を変えても同じ傾向が見られるかを確認しました。ローカル SDK 直接呼び出し 2 回 + Lambda 経由 1 回の計 3 回です。
| Effort | Time 中央値 | Out tokens 中央値 | Reasoning 中央値 |
|---|---|---|---|
| none | 6.6s | 564 | 0 |
| low | 5.6s | 467 | 293 |
| medium | 7.8s | 693 | 516 |
| high | 17.8s | 1589 | 1384 |
環境が異なっても同傾向でした。
low + structured 安定性テスト(n=7)
採用候補構成の安定性を確認しました。
| # | 記事 | Time | Out tokens | Reasoning | JSON |
|---|---|---|---|---|---|
| 1 | A1 約7,300文字 | 3.8s | 250 | 0 | ✅ |
| 2 | A1 約7,300文字 | 17.1s | 769 | 0 | ✅ |
| 3 | A1 約7,300文字 | 7.4s | 554 | 0 | ✅ |
| 4 | A1 約7,300文字 | 4.4s | 318 | 0 | ✅ |
| 5 | A2 約15,800文字 | 3.8s | 163 | 0 | ✅ |
| 6 | A2 約15,800文字 | 11.1s | 684 | 516 | ✅ |
| 7 | A2 約15,800文字 | 4.4s | 280 | 0 | ✅ |
7 回中 7 回 valid JSON でした。reasoning_tokens は effort=low でも常に 0 になるわけではなく、今回の測定では 0〜516 のばらつきがありました。特に #6 は effort=low でも reasoning_tokens=516 が出ていますが、JSON は valid でした。
観測結果から見えた傾向
- JSON の途中で
{"issues":[が再挿入される現象は、生成が途中で巻き戻ったように見える出力でした。ただし内部実装は公開情報だけでは断定できません - 今回の条件では、重複・破損は reasoning 指定時にのみ観測されました
- OpenAI Community / Codex CLI Issue でも同様の報告があり、Bedrock 固有とは考えにくそうです
- ストリーミングでも同様に発生し、回避策にはなりませんでした
- 表1・表2 は各条件の代表例であり、サンプル数は限定的です
まとめ
今回のブログ記事レビュー用途では、reasoning 未指定または effort=low が扱いやすく、low + Structured Outputs では検証中に JSON 破損は発生しませんでした。
medium / high では重複出力や JSON 破損が発生したため、少なくとも今回の用途では low を基本にし、parse / validation とフォールバックを前提に使う予定です。







