AIが生成したコードの品質を定量的に測定・比較してみた

AIが生成したコードの品質を定量的に測定・比較してみた

ソフトウェアアーキテクチャ手法の利用有無で、 AIが生成したコード品質のうち可読性と保守性に違いがどれくらい発生するのかTODOアプリ用のAPIを作成し比較してみました。
2026.01.15

リテールアプリ共創部マッハチームの五反田です。

マッハチームでは小売業界のお客様に向け、新規アプリ開発の立ち上げを専門に行っています。
新規開発の立ち上げでは、短期間で高品質なアプリケーションを開発することが求められます。

マッハチームのメンバーで「品質」をテーマに知見を共有するブログの連載を始めました。
今回は私から、第4弾としてAIが生成したコードの品質を定量的に測定・比較してみた内容をご紹介します。

メンバーによる過去の投稿もぜひ読んでみてください!

https://dev.classmethod.jp/articles/quality-from-project-start/
https://dev.classmethod.jp/articles/cursor-slash-commands-auto-generate-issue-pr/
https://dev.classmethod.jp/articles/ai-generated-test-code-review-tips/

はじめに

現在生産性をあげるため、CursorやClaude Codeなどを利用して開発を進めています。
ソフトウェアアーキテクチャ手法(以下、アーキテクチャと記載)の有無が品質に影響するのかを実際にTODOアプリのAPIを作成し、定量的に比較してみます。

結論

TODOアプリのAPIという小さなアプリケーションであり、あくまで数値上の話とはなりますが、
今回の検証では、TODOアプリのAPIという小規模なアプリケーションにおいて、
アーキテクチャをコンテキストに含めた方が可読性・保守性ともに高い傾向が見られました。

メトリクス アーキテクチャあり アーキテクチャなし
コード行数(平均) 29.46 39.50
サイクロマチック複雑度(平均) 2.39 4.73
サイクロマチック複雑度(最大) 9 22
保守容易性インデックス(平均) 133.49 125.45

検証条件

比較のため以下の内容で実施し、プロンプト以外の条件を統制することで、定量的な比較を行うように検証しました。

  • CLAUDE.mdファイルを共通化
  • アーキテクチャに関する情報を含めないようにCLAUDE.mdファイルを作成
  • 初期のプロンプトの基本部分を同じとする
  • TODOアプリとして動作しない場合は、動作するまで修正を実行
  • 比較は定量的に実施するため、ツールを使用し比較を実施

使用したCLAUDE.md


# アプリのバックエンド プロジェクト概要

## 技術スタック

- Runtime: Node.js + TypeScript
- Framework: Hono
- Validation: Zod
- Database: SQLite
- ORM: Prisma(マイグレーション) + Kysely(クエリビルダー)
- Monorepo: pnpm workspaces

## コーディング規約

### 命名規則

- ファイル名: kebab-case
- 型/インターフェース: PascalCase
- 関数/変数: camelCase
- 定数: UPPER_SNAKE_CASE

### TypeScript

- `any`禁止、`unknown`を使用
- 明示的な戻り値の型定義を推奨
- Branded Types で型安全性を確保
- `as`によるキャストは値オブジェクトのファクトリ関数内のみ許可

### テスト

- ユニットテスト: Vitest
- テストファイル: `*.test.ts`
- モック: `vi.mock()`を使用

## 開発コマンド

```bash
pnpm install          # 依存関係インストール
pnpm dev              # 開発サーバー起動
pnpm build            # ビルド
pnpm test             # テスト実行
pnpm lint             # リント
pnpm db:migrate       # DBマイグレーション
pnpm db:generate      # Prismaクライアント生成
```

プロンプトの差分

今回は1文だけ足して、アーキテクチャの内容をコンテキストに含めて、アーキテクチャありとなしを実装するようにします。

下記に仕様書を記載します。
全てのAPIを作成してください。
+ドメイン駆動設計でかつDIPを用いたレイヤードアーキテクチャを基本のアーキテクチャとして作成をしてください。

# TODOアプリ バックエンドAPI仕様書

## 概要

マルチユーザー対応のTODOアプリケーションのバックエンドAPI

---

## データモデル

### User

| フィールド | 型 | 必須 | 説明 |
|-----------|------|:----:|------|
| id | string (UUID) | ✓ | 一意識別子 |
| email | string | ✓ | メールアドレス(ログインID) |
| password | string | ✓ | ハッシュ化パスワード |
| name | string | ✓ | 表示名 |
| createdAt | datetime | ✓ | 作成日時 |
| updatedAt | datetime | ✓ | 更新日時 |

### Todo

| フィールド | 型 | 必須 | 説明 |
|-----------|------|:----:|------|
| id | string (UUID) | ✓ | 一意識別子 |
| userId | string (UUID) | ✓ | 所有ユーザーID |
| title | string | ✓ | タイトル(最大100文字) |
| description | string | | 説明(最大1000文字) |
| dueDate | datetime | | 期限 |
| priority | enum | ✓ | 優先度: `low` / `medium` / `high` |
| category | string | | カテゴリ(最大50文字) |
| completed | boolean | ✓ | 完了状態(デフォルト: false) |
| createdAt | datetime | ✓ | 作成日時 |
| updatedAt | datetime | ✓ | 更新日時 |

---

## 認証

Basic認証を使用。`Authorization: Basic <Base64(email:password)>` ヘッダーで送信する。

---

## APIエンドポイント

### ユーザーAPI

| メソッド | パス | 説明 |
|---------|------|------|
| POST | /api/users | ユーザー登録 |

### TODO API(要認証)

| メソッド | パス | 説明 |
|---------|------|------|
| GET | /api/todos | TODO一覧取得 |
| GET | /api/todos/:id | TODO詳細取得 |
| POST | /api/todos | TODO作成 |
| PUT | /api/todos/:id | TODO更新 |
| DELETE | /api/todos/:id | TODO削除 |

---

## エラーレスポンス

| ステータスコード | 説明 |
|-----------------|------|
| 400 | バリデーションエラー |
| 401 | 認証エラー |
| 403 | 権限エラー |
| 404 | リソースが存在しない |
| 409 | 競合(メールアドレス重複など) |
| 500 | サーバーエラー |

評価指標と測定ツール

1ファイルあたりのコード行数

1ファイルあたりのコード行数が高いと可読性が悪くなる傾向にあるため、比較を実施します。
使用ツール: cloc

サイクロマチック複雑度(Cyclomatic Complexity)

コードの複雑性(コード分岐の多さ)を比較し、それぞれのコードの保守性を比較します。
使用ツール: typhonjs-escomplex

保守容易性インデックス(Maintainability Index)

保守容易性インデックスの値を比較し、保守性の高さを比較します。
計算式:

Maintainability Index = MAX(0,(171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code))*100 / 171)
インデックス値 意味
0-9 🔴 赤 コードの保守性が低い
10-19 🟡 黄色 コードの中程度の保守容易性
20-100 🟢 緑 コードの保守性が良好

引用: Microsoft - コード メトリックス

測定結果

メトリクス アーキテクチャあり アーキテクチャなし
コード行数(平均) 29.46 39.50
サイクロマチック複雑度(平均) 2.39 4.73
サイクロマチック複雑度(最大) 9 22
保守容易性インデックス(平均) 133.49 125.45
  • コード行数
    アーキテクチャありの方が1ファイルあたりのコード行数が少なく、やや優位
  • 循環的複雑度(平均)
    アーキテクチャありの方がサイクロマチック複雑度が低くやや優位
  • 循環的複雑度(最大)
    アーキテクチャなしの方が保守性に欠けているため、アーキテクチャありの方が優位
  • 保守容易性インデックス
    両方とも高い保守容易性インデックスだが、アーキテクチャありがやや優位

また、今回の検証では、生成AIがファイルを作成する際に以下の傾向が見られました。
アーキテクチャがコンテキストに記載されている場合、
複数ファイルに分けて記載しようとする。
アーキテクチャがコンテキストに記載されていない場合、
1ファイルにまとめて記載しようとする。

まとめ

今回の検証結果から、少なくともアーキテクチャ設計に関する知識を持つことで、AIとのやりとりがより効果的になることが期待できそうです。

もちろん、AIとやりとりをする上で、アーキテクチャの内容を聞かれる可能性はありますが、
アーキテクチャという認識がない状態で、AIとのやりとりで情報が出てこなかった場合、
今回の結果のようなコーディングをしてしまう可能性があるため、人間側で認識しておく必要がありそうです。

エンジニア募集のお知らせ

リテールアプリ共創部マッハチームではエンジニアを大募集しています!

マッハチームでは 0→1 の新規案件の立ち上げを専門に、AI駆動で高速にプロダクトを開発しています。
AI駆動開発がしたい方、モダン技術を用いてフロントエンドもサーバーサイドもインフラもTypeScriptでフルスタックに開発したい方、プリセール・顧客折衝も要件定義も開発も全部やりたい方は、是非以下のブログも読んでみてください。
お気軽にカジュアル面談もお待ちしています!

https://dev.classmethod.jp/articles/retaila-app-mach-serverside-engineer/
https://careers.classmethod.jp/requirements/mach-serverside-enginner/

この記事をシェアする

FacebookHatena blogX

関連記事