GPT-4.1 vs Claude 3.7 Sonnet vs Gemini 2.5 Pro on Roo Code

# 概要
GW中にOpenAI社・Anthoropic社・Google社の3社における最新モデル（当時）のコード生成性能比較を実施した結果を記録します。

- ソースコード一式：[GitHub リポジトリ](https://github.com/MokonaSato/compare-gen-ai-models)

# 検証方法
**Roo Code**を用いて、下記生成AI 3モデルに同一プロンプトを入力し、出力を比較しました。

今回のプロンプトでは具体的な指示は
- 作って欲しい画面
- 実装して欲しい機能
- 最低限の技術要素

のみにし、**ある程度曖昧な指示からどこまで高品質なアプリケーションを作成できるか**を検証しました。

## 使用したツール類
- エディタ：VSCode
- AIコーディングアシスタント：Roo Code
- 生成AIモデル：
    - gpt-4.1
    - claude-3-7-Sonnet-20250219
    - gemini-2.5-pro-exp-03-25

## プロンプト
```markdown
## アプリケーション概要
「単語帳管理アプリ」を作成してください。
ユーザーは、様々な科目ごとの単語帳を作成し、その中に単語カードを登録・管理できるアプリです。
ディレクトリを作成し、その中に必要なファイルを全て作成してください。

## 使用技術・前提
- フロントエンド：React + TypeScript + Vite を使用すること（必須）
- バックエンド：Python を使用すること（必須）
- データベース：MySQL を使用すること（必須）
- コンテナ：Docker を使用し、全体をDocker Composeで起動できるようにすること（必須）
- 上記以外のフレームワーク、ライブラリ、ORM、状態管理ライブラリ、CSSフレームワークなどは、適切なものを自由に選択して使用してもよい。

## 画面要件
### 単語帳一覧画面（ホーム画面）
- 各単語帳について「編集」「削除」が可能

### 単語帳詳細・編集画面
- 単語帳内の単語カード一覧を表示
- 各単語カードについて「編集」「削除」が可能

## 機能要件
- 単語カードには「お気に入り登録」機能を設けること
- フィルタリング機能：お気に入り登録された単語カードのみ、またはされていない単語カードのみを表示できる
- 単語カードには「ソート機能」を設けること
- ソート基準は自由に設計してよい
- 単語カードの内容はMarkdown形式で保存・表示できるようにすること
- 単語カードには複数の「タグ」を付与できること
- タグはユーザーが自由に作成できること

## その他
- 全体をDocker Composeで起動できるよう、適切なDockerfileおよびdocker-compose.ymlを作成すること
- コードは正確性・保守性・可読性を意識して記述すること
- 画面デザインは、モダンでユーザビリティを意識したものにすること
- アプリケーション起動時に、データベースにはテストデータが入っている状態にすること
```

## モデルの基本情報
| モデル名 | 開発会社 | SWE-Bench Verifiedスコア | リリース日 | API利用料(per 1M token) |
|:-:|:-:|:-:|:-:|:-:|
| GPT-4.1 | OpenAI社 | 55% | 2025年4月14日 | Input `$2` / Output `$8` |
| Claude 3.7 Sonnet | Anthoropic社 | 62.3% | 2025年2月24日 | Input `$3` / Output `$15` |
| Gemini 2.5 Pro | Google社 | 63.8% | 2025年3月25日 | 無料枠を利用 |


# 結果
## サマリー
### 優勝はClaude 3.7 Sonnet🏆
- 指定した**すべての機能を一度で実装しきり**、イメージ通りのアプリケーションが立ち上がるまでの修正箇所は一番少なかった
- ソースコードも役割ごとにファイル分割されていて読みやすかった
- 画面デザインは最も見やすく、直感的に使いやすいUIになっていた

### 2位はGPT-4.1🥈
- すべての機能を一発で実装してはくれなかったが、**要件を満たしているかどうかを判断させると1回で修正しきった**
- backendはmain.pyにモデル定義とエンドポイント定義を一緒くたに記述しており、可読性が低い
- 画面デザインは見やすく、直感的に使いやすいUIではあるが、やや殺風景

### 3位はGemini 2.5 Pro🥉
- すべての機能を一発で実装してはくれなかった
- 要件を満たしているかどうかを判断させても1回では修正しきらなかった（例えばボタンにonClick属性がないため、アクションが実行されない等の欠陥が残った）
- frontendの画面はすべてApp.tsxに実装され、可読性が低い
- 画面は見づらく、直感的に使いやすいUIとは言えない（Material UI等の画面資材系ライブラリを使用していないことも一因か）

## GPT-4.1
### 使用フレームワーク・ライブラリ等
- frontend
    - React
    - TypeScript
    - Vite
    - Material UI
    - React Router Dom
- backend
    - FastAPI
    - Uvicorn
    - SQLAlchemy
- db
    - MySQL

### プロジェクト構成
```markdown
wordbook-app/
├── docker-compose.yml      # Docker Compose設定ファイル
├── README.md               # プロジェクト説明書
├── backend/                # バックエンドアプリケーション
│   ├── Dockerfile          # Pythonアプリケーションのコンテナ設定
│   ├── main.py             # FastAPIアプリケーションのメインファイル
│   └── requirements.txt    # Python依存パッケージリスト
├── db/                     # データベース関連ファイル
│   ├── init.sql            # 初期データ投入用SQLファイル
│   └── my.cnf              # MySQLの設定ファイル
└── frontend/               # フロントエンドアプリケーション
    ├── Dockerfile          # Reactアプリケーションのコンテナ設定
    ├── index.html          # HTMLエントリーポイント
    ├── package.json        # npm設定とパッケージ管理
    ├── tsconfig.json       # TypeScript設定
    ├── tsconfig.node.json  # Node用TypeScript設定
    ├── vite.config.ts      # Vite設定ファイル
    └── src/                # ソースコード
        ├── App.tsx         # メインアプリケーションコンポーネント
        ├── main.tsx        # Reactエントリーポイント
        └── pages/          # ページコンポーネント
            ├── Home.tsx            # ホーム画面
            └── NotebookDetail.tsx  # 単語帳詳細画面
```
### ソースコードの正確性
最初に出力してきたソースコード一式では正常に動作しなかったが、下記を修正することで正常に動作するようになった。
- 画面・機能要件（お気に入り、タグ、Markdown対応、ソート・フィルタ、編集・削除UIなど）の実装
- テストデーをDB初期化時に投入
-　DBとbackendの疎通（`vite.config.ts`でカスタムプロキシ設定）
-　DBの文字コード設定
- FastAPIのレスポンスバリデーション修正

### UIデザイン
#### ホーム画面
![GPT-4.1_Home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/de6f971d-6933-46ee-af1d-86506bfc335e.png)

#### 単語帳詳細画面
![GPT-4.1_words.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/d97d0968-6270-42b9-a1d3-c97b29761f9a.png)


## Claude 3.7 Sonnet
### 使用フレームワーク・ライブラリ等
- frontend
    - React
    - TypeScript
    - Vite
    - Material UI
    - React Router Dom
- backend
    - FastAPI
    - Uvicorn
    - SQLAlchemy
- db
    - MySQL
- ミドルウェア
    - Nginx   

### プロジェクト構成
```
flashcard-app/
├── frontend/             # フロントエンドアプリケーション
│   ├── src/              # ソースコード
│   │   ├── components/   # コンポーネント
│   │   ├── pages/        # ページコンポーネント
│   │   ├── hooks/        # カスタムフック
│   │   ├── services/     # APIサービス
│   │   ├── types/        # 型定義
│   │   └── utils/        # ユーティリティ関数
│   └── public/           # 静的ファイル
├── backend/              # バックエンドアプリケーション
│   ├── app/              # アプリケーションコード
│   │   ├── models.py     # データモデル
│   │   ├── schemas.py    # Pydanticスキーマ
│   │   ├── crud.py       # CRUDオペレーション
│   │   └── main.py       # メインアプリケーション
│   ├── tests/            # テスト
│   └── migrations/       # データベースマイグレーション
├── mysql/                # MySQLデータ
│   ├── data/             # データファイル
│   └── init/             # 初期化スクリプト
├── nginx/                # Nginxの設定
└── docker-compose.yml    # Docker Compose設定
```

### ソースコードの正確性
最初に出力してきたソースコード一式では正常に動作しなかったが、下記を修正することで正常に動作するようになった。
- 不足していたライブラリの追加（backendのDockerfile）
-　DBとbackendの疎通（`vite.config.ts`でカスタムプロキシ設定）
-　DBの文字コード設定
-　backendの不要なコード削除（markdownをHTML形式に変換する記述があった）

### UIデザイン
#### ホーム画面
![Claude-3.7-Sonnet_Home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/fe10c3a2-1e7c-4f18-82f4-291deef84448.png)

#### 単語帳詳細画面
![Claude-3.7-Sonnet_words.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/df83d33f-6982-435d-a950-bd0657f91033.png)

## Gemini 2.5 Pro
### 使用フレームワーク・ライブラリ等
- frontend
    - React
    - TypeScript
    - Vite
    - React Router Dom
- backend
    - FastAPI
    - Uvicorn
    - SQLAlchemy
- db
    - MySQL
- ミドルウェア
    - Nginx   
 
### プロジェクト構成
```markdown
wordbook-app/                      # 単語帳アプリケーションのルートディレクトリ
├── docker-compose.yml             # 全サービス（フロントエンド、バックエンド、DB）の構成ファイル
├── backend/                       # バックエンドサービスのディレクトリ
│   ├── Dockerfile                 # バックエンドのコンテナ構成ファイル
│   ├── requirements.txt           # Pythonの依存パッケージリスト
│   └── app/                       # FastAPIアプリケーションのソースコード
│       ├── config.py              # アプリケーション設定ファイル
│       ├── crud.py                # DBへのCRUD操作関数
│       ├── database.py            # DB接続設定
│       ├── dependencies.py        # 依存性注入の定義
│       ├── main.py                # アプリケーションのエントリーポイント
│       ├── models.py              # SQLAlchemyのDBモデル定義
│       ├── schemas.py             # Pydanticスキーマ（リクエスト/レスポンス定義）
│       └── routers/               # APIエンドポイントのルーター
│           ├── auth.py            # 認証関連のエンドポイント
│           ├── tags.py            # タグ管理のエンドポイント
│           ├── word_cards.py      # 単語カード管理のエンドポイント
│           └── wordbooks.py       # 単語帳管理のエンドポイント
├── db/                            # データベース関連ファイル
└── frontend/                      # フロントエンドサービスのディレクトリ
    ├── Dockerfile                 # フロントエンドのコンテナ構成ファイル
    ├── index.html                 # メインHTMLファイル
    ├── nginx.conf                 # Nginxの設定ファイル（APIリクエストのプロキシ設定含む）
    ├── tsconfig.json              # TypeScriptの基本設定
    ├── tsconfig.node.json         # Node.js用TypeScript設定
    ├── vite.config.ts             # Viteビルドツールの設定
    ├── public/                    # 静的ファイル格納ディレクトリ
    └── src/                       # ソースコードディレクトリ
        ├── App.css                # アプリケーションのメインCSS
        ├── App.tsx                # アプリケーションのルートコンポーネント
        ├── index.css              # グローバルCSS設定
        ├── main.tsx               # アプリケーションのエントリーポイント
        ├── vite-env.d.ts          # Vite環境変数の型定義
        ├── services/              # APIサービス関連モジュール
        └── types/                 # TypeScript型定義
```
### ソースコードの正確性
最初に出力してきたソースコード一式では正常に動作しなかったが、下記を修正することで正常に動作するようになった。
- frontendのDockerfileおよびnginx.confの追加（Gemini 2.5 Proに書かせた）
- バックエンドのDockerfileのCMD命令を修正
- 画面・機能要件（単語カード一覧を表示、お気に入り、タグ、Markdown対応、フィルタ、編集・削除UIなど）の実装
-　DBとbackendの疎通（`vite.config.ts`でカスタムプロキシ設定）
-　DBの文字コード設定

### UIデザイン
#### ホーム画面
![Gemini-2.5-Pro_Home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/449f540d-3c64-413e-9447-f6450ea3b2a2.png)

#### 単語帳詳細画面
![Gemini-2.5-Pro_words.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/d2b5f189-93f9-443c-9901-d5602a79d575.png)


# おまけ（GitHub Copilot）
当初GitHub Copilotを用いて検証を開始しましたが、いずれのモデルも同様の誤り・同様の画面デザインを出力してきたため、Roo Codeでの検証に切り替えました。
GitHub Copilot側で入力しているコードサンプルに由来するのかな...？


<details open><summary>複数のモデルで共通していた特徴</summary>

- frontendのDockerfileの生成を忘れる
- Dockerイメージが古い（mysql: 5.7, python:3.9-slim, node:16）
- React Router Domがv5以前の記述方法をとる（`Switch`を利用）

</details>


#### 画面イメージ
![GitHub_Copilot_UI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/874b3a2b-9604-474b-a263-1022884c5342.png)