はじめに
「150件のテストを作成してください」
この依頼に対して、Codex(OpenAIのコード生成AI)は738件のテストを納品した。目標の492%。実行時間は目標30分に対して11.52秒。成功率100%。
これは偶然ではない。Phase 5.6、5.7、6と3つのフェーズを通じて、Codexは連続して最高評価(⭐⭐⭐⭐⭐ 5/5)を獲得した。
この記事では、なぜCodexに「直接依頼」する判断をしたのか、そしてどうやって目標の5倍という成果が生まれたのかを振り返る。
なお、このプロジェクトで開発しているポートフォリオサイトは miyakawa.codes で実際に運用中だ。
この記事に至った裏話は 3つのAIで作ったポートフォリオサイト - Kiro・Claude Code・Codexの使い分け として Miyakawa Codes Blog で公開中です。
普段の開発体制 - トライアングル実装
僕のポートフォリオ開発では、3つのAIエージェントを使い分けている。
| エージェント | 役割 | 得意なこと |
|---|---|---|
| Kiro | 仕様管理・レビュー | 要件定義、設計書、品質チェック |
| Claude Code | メイン実装 | 新機能の高速実装、リファクタリング |
| Codex | テスト・検証 | テスト作成、セキュリティ、慎重な実装 |
普段は「Claude Codeで実装 → Kiroでレビュー → 修正」というサイクル。スピード重視の開発にはClaude Codeが圧倒的に強い。
でも、Phase 5.6で転機が訪れた。
Phase 5.6: 発見 - Codexの実力が判明
Claude Codeの課題
Phase 5.6はパフォーマンス最適化のフェーズ。N+1問題の解消、キャッシュ導入などをClaude Codeに依頼した。
実装は完璧だった。データベースクエリは81件から5件に削減(94%減)。しかし、問題があった。
テストを作らなかった。
Claude Codeは「まず動くものを作る」タイプ。テストの重要性を認識していなかったのだ。
Codexの登場
そこでCodexにテスト作成と検証を依頼した。結果は驚きだった。
42件のテストを作成(すべて成功)
しかも、それだけではなかった。
「フラグメントキャッシュが実装されていません」
Codexはテストを書く過程で、Claude Codeが見落としていた実装の欠落を発見し、自らキャッシュ実装を追加した。
役割を超えた主体的な貢献。これがCodexの実力だった。
Kiroの評価
Phase 5.6でCodexが発見した問題と主体的な実装追加は、このプロジェクトの品質向上に大きく貢献しました。
評価: ⭐⭐⭐⭐⭐ 5/5
Phase 5.7: 信頼 - 直接依頼の判断
なぜCodexに直接依頼したか
Phase 5.7はテストカバレッジ向上がテーマ。150件のテスト作成が目標だった。
Phase 5.6での実績を踏まえ、僕は判断した。
「テスト作成はCodexの専門領域。Claude Codeを介さず、直接依頼しよう」
KiroがCodexへの依頼書を作成した。4つのパートに分かれた詳細な仕様書だ。
依頼書の構造
Kiroが作成した依頼書(CODEX-START-HERE.md)の冒頭には、こう書かれていた。
👋 Codex へ
Phase 5.6 での素晴らしい成果をありがとうございました。
42件のテスト作成、フラグメントキャッシュの実装追加、すべてのテストが成功という完璧な結果でした。今回は Phase 5.7 のテスト作成を直接あなたに依頼します。
依頼書は4つのパートで構成されていた。
Part 1: 概要(codex-phase5.7-part1-overview.md)
├── なぜCodexに直接依頼するのか(Phase 5.6での実績評価)
├── 150件のテスト内訳
│ ├── ユニットテスト: 75件(AI機能60件 + AI基盤15件)
│ ├── 統合テスト: 60件(記事CRUD20件 + 認証15件 + API25件)
│ └── E2Eテスト: 15件(記事作成10件 + メディア5件)
└── 目標: カバレッジ85%以上、実行時間30分以内
Part 2: 詳細タスク(codex-phase5.7-part2-tasks.md)
├── AI機能テスト60件の実装例(コード付き)
├── モック戦略(BedrockClientの外部API依存排除)
└── Setup手順(Capybara, SimpleCov, WebMock)
Part 3: 統合・E2Eテスト(codex-phase5.7-part3-integration-e2e.md)
├── 記事CRUD、認証、APIのテストコード例
└── Capybara + Seleniumの設定
Part 4: 成果物(codex-phase5.7-part4-deliverables.md)
├── SimpleCov設定
├── CI/CD統合(GitHub Actions)
└── レポート作成方法
依頼書に含めたコード例
Part 2には、AI機能テストの具体的な実装例を含めた。
📄 実際のファイル: spec/services/ai/title_suggester_spec.rb
# spec/services/ai/title_suggester_spec.rb
RSpec.describe Ai::TitleSuggester do
let(:article) { create(:article, content: "Sample content") }
let(:bedrock_client) { instance_double(Ai::BedrockClient) }
let(:suggester) { described_class.new(article) }
before do
allow(Ai::BedrockClient).to receive(:new).and_return(bedrock_client)
end
describe '#suggest' do
context '正常系' do
it 'タイトル提案が成功する' do
response = { titles: ["Title 1", "Title 2", "Title 3"] }
allow(bedrock_client).to receive(:generate).and_return(response)
result = suggester.suggest
expect(result).to be_success
expect(result.titles).to eq(["Title 1", "Title 2", "Title 3"])
end
end
context '異常系' do
it 'APIエラー時にエラーを返す' do
allow(bedrock_client).to receive(:generate)
.and_raise(Ai::BedrockClient::ApiError, "API Error")
result = suggester.suggest
expect(result).to be_failure
expect(result.error).to include("API Error")
end
end
end
end
このように、モック戦略(BedrockClientをモック化して外部API依存を排除)を明示し、テストの書き方を示した。
納品結果
| 項目 | 目標 | 実績 | 達成率 |
|---|---|---|---|
| テスト数 | 150件 | 738件 | 492% |
| カバレッジ | 85% | 89.01% | 105% |
| 実行時間 | 30分 | 11.52秒 | 0.04% |
| 成功率 | 95% | 100% | 105% |
目標の5倍近いテストを作成し、すべて成功。実行時間は目標30分→11.52秒(150分の1以下)を達成。
Codexのレポートから
Codexが提出したレポート(codex-phase5.7-report.md)には、作成したテストファイルの一覧が記載されていた。
ユニットテスト(AI/サービス/モデル/ヘルパー/ジョブ/メール)
spec/services/ai/title_suggester_spec.rbspec/services/ai/summary_generator_spec.rbspec/services/ai/tag_suggester_spec.rbspec/services/ai/slug_generator_spec.rbspec/services/ai/seo_meta_generator_spec.rbspec/services/ai/structure_suggester_spec.rbspec/services/ai/bedrock_client_spec.rbspec/services/ai/usage_tracker_spec.rb- ...(他40ファイル以上)
統合テスト(管理画面/公開API/公開ページ)
spec/requests/admin/articles_crud_spec.rbspec/requests/admin/authentication_spec.rbspec/requests/api/v1/articles_spec.rb- ...(他15ファイル以上)
E2Eテスト
追加で実装されたもの - 二人三脚のプロセス
ここで重要なのは、738件という数字が「Codexに丸投げした結果」ではないこと。
実際のプロセスはこうだった。
Codex: 「Article関連サービスのテストも必要では?」
↓
私: 「確かに。追加でお願いします」
↓
Codex: テスト作成
↓
私: レビュー・承認
この繰り返しで、以下のテストが追加された。
- Article関連サービスの完全テスト(5ファイル)
- Media関連サービスのテスト(2ファイル)
- Site設定関連サービスのテスト(3ファイル)
- MyStory関連サービスの完全テスト(6ファイル)
- モデルConcernsのテスト(3ファイル)
- ヘルパー全体のテスト(6ファイル)
- ジョブ・メーラーのテスト(4ファイル)
- CI/CD統合(GitHub Actions設定)
Codexが提案し、私が判断し、二人三脚でテストを作る。
この経験から、Codexとの関わり方の基本形が確立された。
Kiroの評価
Kiroの最終レビュー(kiro-phase5.7-final-review.md)より:
目標の150件に対して738件を作成(492%)。カバレッジ89.01%。実行時間11.52秒。
Codexは指示された150件のテストに加えて、以下を自主的に実装しました:
- Article関連サービスの完全テスト
- モデルConcernsのテスト
- ヘルパー全体のテスト
- ジョブ・メーラーのテスト
評価: 主体的な問題解決、プロジェクト全体への貢献
Phase 5.6に続き、Phase 5.7でも完璧な成果を達成しました。
評価: ⭐⭐⭐⭐⭐ 5/5
Phase 6: 定着 - 高難度も任せられる
セキュリティ強化という難題
Phase 6はセキュリティ強化。これは難易度が高い。
- Content Security Policy(CSP)の設定
- セキュリティヘッダーの最適化
- Rack::Attackのレート制限チューニング
- セキュリティログ機能の実装
- 91件のセキュリティテスト作成
セキュリティは「抜け漏れ」が致命的になる領域。慎重さと網羅性が求められる。
Phase 5.7での実績を踏まえ、Codexに依頼した。
依頼書のテストコード例
Phase 6の依頼書(codex-phase6-part3-testing.md)には、セキュリティテストの具体例が含まれていた。
📄 実際のファイル: spec/security/headers_spec.rb
# spec/security/headers_spec.rb
RSpec.describe 'Security Headers', type: :request do
describe 'Content Security Policy' do
it 'sets CSP header' do
get root_path
expect(response.headers['Content-Security-Policy']).to be_present
end
it 'sets object-src to none' do
get root_path
csp = response.headers['Content-Security-Policy']
expect(csp).to include('object-src \'none\'')
end
end
describe 'X-Frame-Options' do
it 'prevents clickjacking' do
get admin_root_path
expect(response.headers['X-Frame-Options']).to eq('SAMEORIGIN')
end
end
# プロパティベーステスト
describe 'Property: All responses include security headers' do
let(:paths) { [root_path, blog_path, portfolio_path] }
it 'includes required headers on all pages' do
paths.each do |path|
get path
expect(response.headers['X-Frame-Options']).to be_present
expect(response.headers['X-Content-Type-Options']).to be_present
expect(response.headers['Content-Security-Policy']).to be_present
end
end
end
end
プロパティベーステスト(複数のパスで同じ条件をテスト)を含めることで、網羅性を高めた。
納品結果
| 項目 | 目標 | 実績 |
|---|---|---|
| セキュリティテスト | 100件 | 91件 |
| 全体テスト | - | 837件 |
| カバレッジ | 90% | 89.28% |
| 実行時間 | - | 13.14秒 |
仕様を超えた追加実装
Codexは仕様にない改善も提案・実装した。
- Redis接続失敗時のフォールバック機構
- インラインスクリプトの削除(CSP整合性改善)
- 環境変数での柔軟な制御(
ENABLE_HSTS,ADMIN_WHITELIST_IPS) - 構造化ログ(JSON形式)
本番障害の発見と修正
さらに、Codexは本番環境の障害を発見した。
Codexのインシデントレポート(codex-production-incident-cache-sweeper.md)より:
概要
本番環境で保存系の操作(記事の作成/更新、カテゴリ更新)がすべて500になる障害が発生しました。
原因
CacheSweeper#clear_cache_matchedがSolidCache::Storeのdelete_matchedによりNotImplementedErrorを投げることでした。証跡(本番ログ)
NotImplementedError (SolidCache::Store does not support delete_matched) app/models/concerns/cache_sweeper.rb:43 app/models/article.rb:158 Admin::ArticlesController#update対応内容
CacheSweeper#clear_cache_matchedにNotImplementedErrorのrescueを追加し、例外を握りつぶして警告ログを出すようにしました。検証結果
本番で記事保存/カテゴリ更新が正常に完了することを確認
テストを書く過程で、本番環境のバグを発見し、修正までしてくれた。
Kiroの評価
セキュリティという高難度領域でも、期待通りの成果を達成しました。
評価: ⭐⭐⭐⭐⭐ 5/5
3連続5つ星の内訳
| Phase | テスト数 | 特記事項 | 評価 |
|---|---|---|---|
| 5.6 | 42件 | キャッシュ実装の自発追加 | ⭐⭐⭐⭐⭐ |
| 5.7 | 738件 | 目標の492%達成 | ⭐⭐⭐⭐⭐ |
| 6 | +91件 | 本番障害の発見・修正 | ⭐⭐⭐⭐⭐ |
合計: 871件のテスト、3つの主体的な追加実装、1件の本番障害修正
なぜこの成果が生まれたか
1. 適切な担当者選定
テスト作成は「慎重に、網羅的に、抜け漏れなく」が求められる。これはCodexの得意領域だった。
Claude Codeは「まず動かす」タイプ。スピード重視の実装には向いているが、テストの重要性を認識していなかった。
適材適所の判断が成果を生んだ。
2. 詳細な依頼書
Kiroが作成した依頼書は、以下を明確にしていた。
- なぜあなたに依頼するのか(Phase 5.6での実績を評価)
- 何を作るのか(150件の内訳、コード例)
- どこまでやれば完了か(カバレッジ85%、成功率95%)
- 参考にすべき資料(仕様書、既存コード)
依頼書の冒頭で「Phase 5.6での成功を期待している」と伝えたことで、Codexは期待に応えようとした。
3. 提案を受けて判断するプロセス
依頼書には「仕様を超えた貢献を期待している」と書いた。
Phase 5.6でのCodexの成果:
- ✅ 42件のテスト作成(すべて成功)
- ✅ フラグメントキャッシュの実装追加
- ✅ 問題発見と主体的な解決
Phase 5.7でも同様の成功を期待しています!
ただし、最終判断は人間がする。
Codexからの提案を受けて、私が「これは必要」「これは不要」を判断する。そして承認したものだけを実装してもらう。
この「提案 → 判断 → 実装」のサイクルが、738件という成果を生んだ。
Codexとの関わり方 - 確立された基本形
Phase 5.7を通じて、Codexとの関わり方の基本形が確立された。
1. Codexが提案する
Codex: 「このサービスにもテストが必要では?」
Codex: 「このエッジケースもカバーすべきでは?」
Codex: 「CI/CD統合も追加しましょうか?」
2. 人間が判断する
私: 「Article関連は必要。追加で」
私: 「このエッジケースは優先度低い。今回はスキップ」
私: 「CI/CDは必須。お願いします」
3. ユーザーテストを必ず実施
Codexのテストが通っても、最後に自分でユーザーテストをする。
このサイトはすでにAWS Lightsailにデプロイ済みで、機能を追加しながら運用している。そのため、テストは2段階で実施する。
開発環境でのテスト
- Docker環境で画面操作
- エッジケースの手動確認
- RSpecテストの実行
本番環境(miyakawa.codes)でのテスト
- デプロイ後の動作確認
- 実際のユーザー環境でのテスト
- パフォーマンス確認
開発環境で問題なければ本番にデプロイし、本番でも動作確認。両方で問題ないことを確認してから、Kiroに評価を依頼する。
4. Kiroに評価してもらう
開発環境・本番環境の両方でユーザーテストが完了したら、Kiroに最終レビューを依頼。
私: 「開発・本番ともにテスト完了。Kiroにレビューをお願い」
Kiro: 仕様との適合性を確認、受け入れ判断
完全に動作確認が済んでからの評価依頼なので、Kiroのレビューは「実装が仕様を満たしているか」に集中できる。
このサイクルが、品質を担保する仕組みになった。
使い分けの指針
この経験から見えてきた使い分け。
Claude Code 向き
- 新機能の高速プロトタイピング
- リファクタリング
- 「まず動くものを作る」フェーズ
- 技術的な判断が必要な実装
Codex 向き
- テスト作成(特にセキュリティ系)
- 慎重さが求められる実装
- 仕様に忠実な実装
- 網羅的なチェックが必要な作業
Kiro 向き
- 要件定義・設計
- レビュー・品質チェック
- ドキュメント作成
- 受け入れ判断
トライアングルで回すのが基本だが、フェーズによってはバッテリー(Kiro × Codex)で回す方が効率的なこともある。
まとめ
- 150件の依頼に738件で応えた。目標の492%。
- 3連続⭐⭐⭐⭐⭐。Phase 5.6、5.7、6すべてで最高評価。
- 仕様を超えた貢献。キャッシュ実装、追加テスト、本番障害修正。
ただし、これは「AIに丸投げ」の結果ではない。
Codexが提案し、人間が判断し、二人三脚でテストを作る。
最終的なユーザーテストは人間がやる。開発環境でも本番環境(miyakawa.codes)でも確認する。その後でKiroへの評価依頼をする。
AIの提案を活かしながら、最終判断は人間がする。このプロセスが、738件という成果と3連続5つ星を生んだ。
補足: Phase 5 の全体成果
| 項目 | 数値 |
|---|---|
| 完了Phase | 5つ(5.4〜5.8) |
| 実装日数 | 9日間 |
| テスト総数 | 820件以上 |
| カバレッジ | 89.01% |
| N+1問題 | 94%削減(81→5クエリ) |
| 本番環境 | AWS Lightsail(デプロイ済み・運用中) |
3つのAI(Kiro、Claude Code、Codex)の協働で、9日間でこれだけの成果を出せた。
使用ツール: Kiro, OpenAI Codex, Claude Code
開発対象: Rails ポートフォリオCMS
Phase: 5.6 → 5.7 → 6
リポジトリ: miyakawa2449/cms-ruby
運用サイト: miyakawa.codes