CDKタスクは本当にKiro CLIが有効?Copilot CLIとベンチマーク比較してみた
こんにちは!現在APでインターンをしている学部3年の鈴木鴻太です!
最近、Amazon Q Developerと Kiro CLI が統合されました。そこで今回、性能を測るためにKiro CLI と GitHub Copilot CLI を同じ条件下でベンチマーク比較してみました。
本記事では、5つの段階的難易度のCDKタスクを両CLIに解かせ、LLM-as-a-Judge(LLMによる自動評価)を用いて定量的・定性的に比較した結果をまとめます。
背景:なぜ比較しようと思ったか
AWS開発では、Q devやKiroが有名ですが、逆に以下の疑問が生まれました。
- その他のAI CLIツールで同じLLM(Claude Sonnet 4.5など)を使った場合、推論層(RAG・システムプロンプト等) の違いだけでどれだけ性能が変わるのか?
- AWS CDK という「抽象化された IaC」において、どちらのツールが「CDK らしい書き方」を生成するのか?
Kiro CLI は .kiro/steering/ ディレクトリでプロジェクト固有の規約を注入でき、GitHub Copilot CLI は「カスタムインストラクション」や GitHub Spaces を通じたナレッジ管理が可能です。つまり、モデル性能ではなく、ツール設計の差 を純粋に見たかったのが背景です。
検証手法
1. 前提条件:同一モデルの使用
公平性を担保するため、両CLIとも Claude Sonnet 4.5 を統一して使用しました。これにより、「学習段階などのモデルの違い」ではなく「推論層の違い」だけを抽出できます。
2. 評価方法:LLM-as-a-Judge
生成されたコードの品質を人間が一つずつレビューするのは時間がかかるため、LLM-as-a-Judge(LLMによる自動評価)を採用しました。
Judge構成
- プライマリJudge: Gemini 3.0
- セカンダリJudge: GPT-5.1
単一のJudgeだと評価観点にバイアスが出るため、2つの異なるモデルで評価し、結果の一貫性を確認しました。
評価フレームワーク(4軸)
各コードを以下の4軸で採点しました。
総合スコア計算式:
Total = (機能的正確性 × 0.35) + (AWSベストプラクティス × 0.25)
+ (コード品質 × 0.20) + (完全性 × 0.20)
Chain-of-Thought(CoT)による説明可能性
CoTと呼ばれるLLMに思考過程を明示させる推論手法があるのですが、今回それも用いました。
各Judgeには、スコアだけでなく 「なぜその点数なのか」という理由 も出力させます。これにより、単なる数値比較ではなく、「どこが強くてどこが弱いか」という定性的な傾向も把握できます。
3. 解かせたタスク(5段階の難易度設定)
AWS CDK(TypeScript)で、以下の5つのタスクを設計しました。
各タスクには明確な「要件」「成功基準」「セキュリティ要件」を定義し、両CLIに同じプロンプトを投入しました。
検証結果
総合スコア比較
両Judge(Gemini 3.0 / GPT-5.1)による評価結果の平均は以下の通りです。
Gemini 3.0 による評価
GPT-5.1 による評価
結果の解釈
- 両Judgeともに Copilot がやや優位(Gemini: +0.27点、GPT-5.1: +1.78点)
- Gemini 3.0 は「ほぼ互角」と評価し、GPT-5.1 は「Copilot が明確に上」と評価
- Judge間の評価傾向の違いは、後述の「気づき・学び」で詳しく考察します
タスクごとの特徴と傾向
タスク1:API Gateway + Lambda(簡単)
要件: GET /hello で {"message": "Hello from CDK"} を返すAPI
評価傾向:
- Kiro: シンプルで動作確実だが、API URL の出力やレスポンスヘッダー設定が省略
- Copilot: CfnOutput でAPI URLを出力し、レスポンスヘッダー(Content-Type)も明示。開発者体験(DX)が高い
コメント: 基本タスクでは両者ともほぼ満点だが、Copilot は「使いやすさ」まで配慮している印象。
タスク2:To-Doアプリバックエンド(中級)
要件: POST /todos でアイテム作成、GET /todos/{id} で取得
評価傾向:
- Kiro: AWS SDK(v2)の低レベルAPIを使用。エラーハンドリングは最小限
- Copilot: AWS SDK v3(@aws-sdk/lib-dynamodb)を使用し、DocumentClient でモダンな実装。エラーログ・ID自動生成も実装
コメント: Copilot は「実務で使える」レベルまで仕上げる傾向。Kiro はシンプルだが、エラーケースの考慮がやや薄い。
タスク3:セキュアなDB接続(中上級)最も差が出たタスク
要件: VPC + Aurora Serverless v2 + Lambda、Secrets Manager でDB認証情報管理
評価傾向:
- Kiro: CDKネイティブな書き方(抽象化)
- .connections.allowFrom() で1行でSG設定完了
- Credentials.fromGeneratedSecret() でSecretsを自動生成&紐付け
- コード行数: 約40行
- Copilot: Terraform的な書き方(明示的)
- SecurityGroup を個別に定義し、addIngressRule() で手動設定
- Secrets Manager を先に作成し、RDSに渡す
- コード行数: 約90行
具体例(コード比較):
Kiro のコード(抜粋)
typescript
// Lambda から RDS への接続許可(1行で完結)
dbCluster.connections.allowFrom(lambdaFn, ec2.Port.tcp(5432));
// シークレット自動生成&紐付け
credentials: rds.Credentials.fromGeneratedSecret('dbadmin'),
Copilot のコード(抜粋)
typescript
// SecurityGroup を個別に作成
const lambdaSg = new ec2.SecurityGroup(this, 'LambdaSecurityGroup', { vpc, ... });
const dbSg = new ec2.SecurityGroup(this, 'DatabaseSecurityGroup', { vpc, ... });
// Ingress Rule を手動で追加
dbSg.addIngressRule(lambdaSg, ec2.Port.tcp(5432), 'Allow Lambda access');
// Secrets Manager を先に定義
const dbCredentials = new secretsmanager.Secret(this, 'DatabaseCredentials', { ... });
credentials: rds.Credentials.fromSecret(dbCredentials),
コメント:
Kiro は 「CDKを使うメリット(抽象化による記述量削減)」 をフル活用。Copilot は 「丁寧で明示的だが、Terraform的」 な実装。どちらも動作するが、CDKの思想に沿っているのは Kiro。
タスク4:イベント駆動型注文処理(上級)
要件: EventBridge → Lambda A → DynamoDB → Stream → Lambda B → DLQ(SQS)
評価傾向:
- Kiro: インフラ構成は正確だが、Lambda A が DynamoDB に書き込むロジックが未実装(要件未達)
- Copilot: イベント受信→DB書き込み→Stream処理まで、アプリケーションロジックも実装
コメント: Copilot は「指示以上のこと」をしてくれる一方、Kiro はインフラ構成に特化。実務では「どこまで書くか」の判断が分かれる。
タスク5:本番CI/CD + 監視(エキスパート)
要件: CDK Pipeline + GitHub連携 + CloudWatch Dashboard + Alarm
評価傾向:
- Kiro: 要件は満たすが、アラーム設定(EvaluationPeriods: 1)が誤検知を起こしやすい設定
- Copilot: treatMissingData や詳細メトリクス有効化など、運用視点の設定が充実。Dashboard URLも出力
コメント: 本番運用を見据えた設定の丁寧さでは Copilot が優位。
全体的な傾向まとめ
Copilot の特徴:なんでも・張り切り屋
- エラーハンドリング、ログ出力、ID自動生成など、「実際に動かす」ために必要な周辺実装まで含める
- CfnOutput でエンドポイントURLやARNを出力し、運用者の利便性を考慮
- 指示以上のことをしてくれるが、コード行数が増える傾向
Kiro の特徴:簡潔・AWSネイティブ・インフラ設計者向け
- CDKの抽象化機能(.connections, fromGeneratedSecret)を最大限活用
- 記述量が少なく、「意図」だけを書くコードスタイル
- インフラ構成に特化し、アプリロジックは最小限
気づき・学び
1. LLM-as-a-Judge の難しさ
今回、評価自動化のためにLLM-as-a-Judgeを採用しましたが、以下の課題に直面しました。
データセット設計の難しさ
- 「何が正解か」を定義するのが難しい(特にコード品質や完全性)
- タスクが適切に性能を測れる設計になっているか、事前検証が必要
- 今回は簡単に5タスクだけだったが、より大規模なベンチマークには数十〜数百のタスクが必要
LLMのバイアス
- 位置バイアス: 「最初に出てきたコードを優遇する」傾向がある
- 長さバイアス: コード行数が多い方を「丁寧」と評価しがち
今回は、2つの異なるJudge(Gemini / GPT-5.1) を置くことで、単一Judgeの評価観点バイアスを軽減しました。
2. 評価観点の違い:Gemini vs GPT-5.1
同じコードに対して、2つのJudgeは異なる観点で評価していました。
- Gemini 3.0: 「CDKの抽象化をどれだけ使っているか」を重視
→ タスク3で Kiro を高く評価 - GPT-5.1: 「実運用で使えるか(エラーハンドリング、出力情報、監視)」を重視
→ 全タスクで Copilot を高く評価
この違いは、「何をもって良いコードとするか」という価値観の違い を反映しています。
3. スコアリング実装の失敗と学び
実は当初、Judgeに「総合スコアも計算して出力してほしい」と指示していましたが、
- Gemini 3.0 は重み付けを無視して「素点の合計」を出力
- GPT-5.1 は計算式と理由テキストが矛盾
という事態が発生しました。
対策: Judgeには 軸スコアだけ を出力させ、総合スコア計算は自前のスクリプトで実行する方針に切り替えました。
これは 「LLMに任せすぎると、検証できない数値が混入する」 という重要な教訓です。
4. Kiro vs Copilot の使い分け
今回の検証から、以下の使い分けが見えました。
個人的には、より実務レベルの複雑なタスクになると、「指示以上のことを勝手にしてしまう」Copilot よりも、「意図だけを簡潔に表現する」Kiro の方が扱いやすい と感じました。
注意事項
本検証結果は、以下の条件下での結果であり、今後変わる可能性があります。
- 使用モデル: Claude Sonnet 4.5
- タスク: 比較的シンプルなCDKタスク5問
- 評価方法: LLM-as-a-Judge(Gemini 3.0 / GPT-5.1)
より大規模で実務的なタスク、あるいは異なるモデル・バージョンでは結果が変わる可能性があります。
まとめ
Kiro CLI と Copilot CLI を、同一モデル(Claude Sonnet 4.5)・同一タスクで比較した結果、
- 総合スコアだけでは Copilot がやや優位(特に実務的な完成度で評価)
- Kiro は CDK抽象を活用した簡潔なコードで優位
- 用途によって使い分けが重要
という結論に至りました。
また、LLM-as-a-Judge を用いた自動評価には多くの課題(データセット設計、バイアス、スコア計算の信頼性)があり、複数Judge + 軸スコア分離 + 自前集計 という設計が重要であることも学びました。
今後も、AI開発ツールの進化に合わせて、継続的にベンチマークを更新していきたいと思います。