
aws-benchのCloudFormation復旧タスクで実行できる手順を答えたKiro CLIが不合格になった理由を確認してみた
はじめに
AWS が公開した AI エージェント向けベンチマーク aws-bench について、これまで4本の記事を書きました。1本目はベンチマークの仕組み、2本目は単一アカウントで動かすミニテスト環境の構築です。3本目と4本目では、そのミニ環境で測った Step Functions と VPC Flow Logs の診断タスクの結果を扱いました。
今回も同じミニテスト環境で測った結果です。取り上げるのは fix-cloudformation-update-failed-stack の1タスク。UPDATE_FAILED で止まったスタックの原因と復旧手順を答えさせる内容です。
先行2タスクの正答は、Step Functions が51件中51件、VPC Flow Logs が51件中22件でした。今回は12件です。この差が生まれた理由は、タスクの難しさではなく、判定に使える材料の少なさにあります。
以降、1セルはモデル1つの1周を指し、分母の51は17モデル × 3周を表します。
| 項目 | 内容 |
|---|---|
| 対象モデル | 17。測定時に kiro-cli から選べたモデルのうち auto と qwen3-coder-next を除くすべて |
| 実行回数 | 同一条件で3周。1タスクあたり51セル |
| エージェント | kiro-cli 2.15.1 をヘッドレス実行。Docker コンテナに隔離し、ホスト側のベンチマーク資材はマウントしない |
| AWS 権限 | read-only ロールのみ。復旧操作は実行させず、手順の回答だけを求める |
| 1セルの上限 | エージェント300秒。公式の600秒から短縮したが、51セルすべてが上限内で完了 |
| 判定モデル | ホスト側で claude-sonnet-5 に固定 |
| クレジット | ヘッドレス実行の Credits にモデル倍率を掛けた比較用の値。金額には換算しない |
| 測定期間 | 2026-07-29 14:16〜2026-07-30 03:34 |
タスク定義はデータセットのコミット 2daf77d2d41c21bae00bf8227fc463be51f721d0 を参照しています。ベンチマーク本体は edfab47710a505b7e73de66584a84f8b9bb6e26c です。なお、判定に使った claude-sonnet-5 は評価対象の17モデルにも含まれます。この重なりが判定に与える影響は、本記事では検証していません。
記事中の識別子は伏せています。スタック名、アカウントID、論理IDはダミーに置き換えました。
比較はこのタスクの中だけで行い、他のタスクの結果との合計やモデルの総合順位は出しません。
タスクの内容
タスク定義は公開データセットにあります。以下は要点で、指示文や参照回答の原文はリンク先で確認できます。
| 項目 | 内容 |
|---|---|
| 種別 | introspection(読み取り・診断のみ)。名前に fix が付くが、復旧操作は実行させない |
| 対象サービス | CloudFormation、Lambda |
| リージョン | us-east-1 |
| 公式のタイムアウト | エージェント600秒 / 判定240秒 |
事前にデプロイするリソース
診断対象のリソースは、シナリオ付属の CDK スタック1本で作られます。
| リソース | 役割 |
|---|---|
| Lambda 関数 2つ | 更新対象 |
| Lambda エイリアス 2つ | 現在のバージョンを指す。setup スクリプトがこの参照先を壊す |
| CloudWatch Logs ロググループ 2つ | 上記 Lambda のログ出力先 |
| IAM ロール 3つ | CloudFormation 実行と Lambda 実行 |
| S3 バケット | デプロイ資材置き場 |
setup スクリプトが作る異常
デプロイ後に setup スクリプトが動き、スタックを UPDATE_FAILED にします。
- 元のテンプレートを取得する
AWS::Lambda::AliasのFunctionVersionを、存在しないバージョン番号に差し替えるDisableRollback=Trueを指定して更新する- スタックが
UPDATE_FAILEDになったことを確認する
異常の作り方は2本目の記事にコード付きで載せています。結果を読むうえで鍵になるのは3の DisableRollback=True です。ロールバックされないため、スタックは UPDATE_ROLLBACK_FAILED ではなく UPDATE_FAILED で止まります。
エージェントへの依頼
指示文の要旨は「指定したスタックが UPDATE_FAILED になっている。どう直してデプロイを続ければよいか」です。状態はここで明示されています。プレースホルダを実際のスタック名に置き換えたうえで、隔離コンテナ内のエージェントに渡します。エージェントは read-only の一時認証情報で AWS を調べ、最終回答を /logs/agent/agent-output.txt に書きます。参照回答やルーブリックはコンテナに渡していません。
回答の判定方法
判定は、回答と参照回答が同等かどうかの二値です。部分点はありません。
| 項目 | 内容 |
|---|---|
| 判定基準 | answers_equivalent。回答に従った実務者が、参照回答に従った場合と同じ結論・同じ行動に至るか |
| ルーブリック | judge_prompt.md。troubleshooting-multiservice の21タスク共通のファイルで、タスク固有の記述はない |
| 判定モデルに渡すもの | エージェントの回答と参照回答だけ。AWS の実状態は渡さない |
参照回答が挙げているのは、原因2点と復旧手順1点です。原因は、2つの Lambda エイリアスに存在しない関数バージョンが直書きされていること、そして直書きの代わりに !GetAtt Function.Version を使うべきことです。復旧手順は、continue-update-rollback に2つのエイリアスの論理IDを --resources-to-skip で渡して実行することです。
ルーブリックが挙げる不合格条件のうち、このタスクで効くのは次の2つです。
- インフラの実状態やリソース構成について参照回答と矛盾している
- 提案した修正が実際には動かない(パラメータ不足、対象違い)
残りは4つあります。判断の正誤が逆、原因が違う、主要な原因の欠落、そして誤った断定で実務者を誤らせることです。
このタスクは修正の提示を求めているため、2つ目の「実際には動かない」が該当します。この条件と参照回答の復旧手順の関係が、結果を決めています。
公式判定の結果
正答は12/51でした。タイムアウトは0件です。
| モデル | 倍率 | 1周目 | 2周目 | 3周目 | 正答 |
|---|---|---|---|---|---|
claude-opus-4.5 |
2.2 | pass | pass | pass | 3/3 |
claude-opus-4.6 |
2.2 | pass | fail | pass | 2/3 |
claude-sonnet-4 |
1.3 | pass | pass | fail | 2/3 |
claude-sonnet-5 |
1.3 | pass | fail | pass | 2/3 |
claude-opus-5 |
2.2 | pass | fail | fail | 1/3 |
claude-opus-4.7 |
2.2 | fail | fail | pass | 1/3 |
claude-sonnet-4.6 |
1.3 | pass | fail | fail | 1/3 |
claude-opus-4.8 |
2.2 | fail | fail | fail | 0/3 |
claude-haiku-4.5 |
0.4 | fail | fail | fail | 0/3 |
claude-sonnet-4.5 |
1.3 | fail | fail | fail | 0/3 |
deepseek-3.2 |
0.25 | fail | fail | fail | 0/3 |
glm-5 |
0.5 | fail | fail | fail | 0/3 |
gpt-5.6-luna |
0.6 | fail | fail | fail | 0/3 |
gpt-5.6-sol |
2.4 | fail | fail | fail | 0/3 |
gpt-5.6-terra |
1.2 | fail | fail | fail | 0/3 |
minimax-m2.1 |
0.15 | fail | fail | fail | 0/3 |
minimax-m2.5 |
0.25 | fail | fail | fail | 0/3 |
合否の分かれ目は --resources-to-skip の明示でした。正答12件はすべて continue-update-rollback を挙げており、そのうち11件は --resources-to-skip まで書いています。不合格の39件には、--resources-to-skip を書いた回答が1件もありません。一方で continue-update-rollback 自体は、不合格39件のうち26件が挙げています。オプションの有無だけで51セル中50セルの合否が説明できます。
回答の中身を読む
対象スタックの実状態は UPDATE_FAILED で、DisableRollback は true です。参照回答が求める continue-update-rollback は UPDATE_ROLLBACK_FAILED 用の API で、この状態のスタックには使えません。
UPDATE_FAILED で取れる選択肢は、更新のリトライ、--disable-rollback を付けた update-stack、rollback-stack です。
不合格39件の判定理由は、多くが同じ形をしています。原因の診断は参照回答と一致しているが、復旧手順が continue-update-rollback --resources-to-skip に至っていない、というものです。この API が使えないと明示した回答も、同じく不合格になりました。claude-opus-5 の2周目は、使えない理由まで添えています。
Step 2 - Resume the deployment. The stack is in UPDATE_FAILED with DisableRollback=true,
which means it is directly updatable; you do NOT need continue-update-rollback (that API
only applies to UPDATE_ROLLBACK_FAILED, which is not the case here).
この回答は代わりに、修正済みテンプレートによる直接更新(Option A)と rollback-stack(Option B)を挙げています。どちらもドキュメントに照らせば、UPDATE_FAILED のスタックに対して実行できる操作です。
Option B - return to the last known good state first, then deploy the fix:
aws cloudformation rollback-stack \
--stack-name troubleshooting-multiservice-cloudformation-example-us-east-1 \
--role-arn arn:aws:iam::111122223333:role/cdk-hnb659fds-cfn-exec-role-...
判定はこれを「参照回答が求める操作と違う」として不合格にしました。
正答側の例を挙げます。claude-opus-4.5 の1周目は、参照回答と同じコマンドをそのまま提示しています。
2. **Continue the stack update** with the corrected template:
aws cloudformation continue-update-rollback \
--stack-name troubleshooting-multiservice-cloudformation-example-us-east-1 \
--resources-to-skip <2つのエイリアスの論理ID> \
--region us-east-1
判定に使えるのは回答と参照回答の2つだけで、スタックの実状態はそこに含まれません。そのため、参照回答どおりに continue-update-rollback を書いた回答は、API が受け付けない手順であっても pass します。前述の「提案した修正が実際には動かない」という条件も、動くかどうかを確かめる材料がないまま適用されます。
データセットの中にも記述の食い違いがあります。CDK スタックのコメントには、setup スクリプトがスタックを UPDATE_ROLLBACK_FAILED にすると書かれています。しかし、setup スクリプトが実際に作り、自身で確認しているのは UPDATE_FAILED です。参照回答は UPDATE_ROLLBACK_FAILED を前提に書かれたと考えると筋は通りますが、これは推測です。
ミニ環境固有の事情は、このタスクの結果に影響していません。51件の回答のうち、対象スタック以外のリソースに触れたのは claude-opus-5 の2周目と3周目だけです。どちらも同じシナリオに含まれる別スタックへの言及で、このスタックは公式手順でも同じアカウントに置かれます。この2件の判定理由も continue-update-rollback だけを根拠にしており、別スタックへの言及は不合格の理由になっていません。
別基準で数え直した結果
このタスクでは、不合格側の取りこぼしを足すだけの補正では済みません。参照回答どおりに書いた側にも、実行できない手順という同じ問題があるためです。そこで、公式判定の pass と fail の区別を外して、51セルすべてに同じ基準を当て直しました。
基準は「UPDATE_FAILED かつ DisableRollback が true のスタックに対して実行できる復旧操作を回答に含むか」です。具体的には、rollback-stack の提示、または --disable-rollback を付けた update-stack の提示を数えます。continue-update-rollback は --resources-to-skip 付きでも該当としません。判定は回答テキストの文字列一致で行っており、実際に API を実行して確認したわけではありません。
該当は10/51でした。10件すべてが rollback-stack を含んでおり、update-stack 側だけで該当したものはありません。公式判定の12件と重なるのは2件だけです。
| モデル | 公式判定 | 別基準の該当 |
|---|---|---|
claude-opus-5 |
1/3 | 3/3 |
claude-opus-4.7 |
1/3 | 3/3 |
claude-opus-4.6 |
2/3 | 1/3 |
claude-opus-4.8 |
0/3 | 1/3 |
claude-sonnet-5 |
2/3 | 1/3 |
deepseek-3.2 |
0/3 | 1/3 |
claude-opus-4.5 |
3/3 | 0/3 |
claude-sonnet-4 |
2/3 | 0/3 |
claude-sonnet-4.6 |
1/3 | 0/3 |
表に出ていない8モデルは、公式判定と別基準のどちらも0/3です。
公式判定で正答となった12件のうち10件は、実状態で実行できる操作をまったく含まず、continue-update-rollback だけを復旧手順にしています。逆に、claude-opus-5 と claude-opus-4.7 は3周とも実行できる手順を出していますが、公式判定はそれぞれ1/3です。
1回答あたりのクレジットと所要時間
別基準に該当した10件だけを対象に、1件あたりのクレジットと所要時間を出しました。該当しなかった回答のぶんは除いてあります。表の件数は公式判定の正答数と別で、実行できる手順を含んでいた回数を表します。
| モデル | 倍率 | 実行できる手順を含む回数 | 1件あたりクレジット | 1件あたり所要時間 |
|---|---|---|---|---|
claude-opus-5 |
2.2 | 3/3 | 10.52 | 116秒 |
claude-opus-4.8 |
2.2 | 1/3 | 9.24 | 119秒 |
claude-opus-4.7 |
2.2 | 3/3 | 9.09 | 95秒 |
claude-opus-4.6 |
2.2 | 1/3 | 4.05 | 49秒 |
claude-sonnet-5 |
1.3 | 1/3 | 1.86 | 78秒 |
deepseek-3.2 |
0.25 | 1/3 | 0.65 | 180秒 |
公式判定で3/3だった claude-opus-4.5 は、この表には出てきません。3周とも実行できる操作を含まず、continue-update-rollback だけを挙げていたためです。代わりに、公式判定が0/3だった claude-opus-4.8 と deepseek-3.2 が入ります。同じ回答群でも、基準を変えると表に載るモデルが入れ替わります。
まとめ
このタスクの結果は、モデルの能力よりも判定のしくみを映していました。判定材料が回答と参照回答だけだと、実行できない手順が正答になり、実状態を踏まえた回答が落ちます。
今回取り上げたのは aws-bench の134タスクのうちの1本で、ここでの結果をそのまま全体には広げられません。また aws-bench はリサーチプレビューであり、公式手順ではシナリオごとにクリーンなテストアカウントを用意します。それでも、参照回答が特定のコマンドを前提にしている限り、判定はその文字列の一致に寄ります。自分の環境でベンチマークを使うなら、正答と判定された回答の中身も読む工程を挟むほうが安全です。









