はじめに

「ジェンスパーク(Genspark)が書いたコードだから、完璧なはず」

多くの人がそう考えがちですが、これは大きな誤解です。私もWebサイトの開発初期は、AIが生成したコードをそのまま信じてデプロイしていました。その結果は...バグだらけのアプリケーションでした。

ジェンスパークは確かに高速にコードを生成してくれます。しかし、人間と同じように、AIもバグを埋め込みます。 今回は、前回の記事に続き、実際に遭遇したAI由来のバグと、その対策方法をご紹介します。

AIコーディングの現実:バグ発生率は意外と高い

2025年の最新調査によると、AIが生成したコードの約15〜30%に何らかの問題が含まれると報告されています。特に以下のような問題が頻発します:

よくあるAI由来のバグ

1. ロジックエラー

  • 条件分岐の抜け漏れ
  • エッジケースへの対応不足
  • 非同期処理の競合

2. セキュリティ問題

  • 入力値の検証不足
  • SQLインジェクション脆弱性
  • 認証・認可の不備

3. パフォーマンス問題

  • 無駄なループ処理
  • データベースクエリの非効率
  • メモリリーク

AIツール開発企業Cursorは、2025年8月に「Bugbot」という専用のバグ検出ツールをリリースしました。これは、AIが書いたコードのバグをAIで検出するツールです。この事実自体が、AI生成コードに問題が多いことを物語っています。

実体験1: 無限ループを生成したAI

Webサイトで、ユーザーのWeb機能結果をキャッシュする機能を実装していた時のことです。

私の依頼:「キャッシュが存在する場合は再計算をスキップする関数を作成してください」

ジェンスパーク(Genspark)が生成したコード

async function getCachedResult(userId: string) {
  let result = await cache.get(userId);
  
  while (!result) {
    result = await calculateCompatibility(userId);
    await cache.set(userId, result);
  }
  
  return result;
}

一見問題ないように見えますが、実際に実行すると...

問題点

  • cache.get()が失敗した場合、whileループが永遠に続く
  • resultnullundefinedの場合、無限ループに陥る
  • キャッシュ保存に失敗しても、ループを抜けられない

正しい実装

async function getCachedResult(userId: string) {
  let result = await cache.get(userId);
  
  if (!result) {
    result = await calculateCompatibility(userId);
    await cache.set(userId, result);
  }
  
  return result;
}

ジェンスパークは「キャッシュがない場合に計算する」という意図を理解しましたが、while文とif文を混同してしまったのです。

実体験2: 非同期処理の競合問題

Twitter API連携では、さらに深刻なバグに遭遇しました。

ジェンスパーク(Genspark)が生成したコード

async function postToTwitter(tweets: Tweet[]) {
  for (const tweet of tweets) {
    await api.post(tweet);
    console.log('Posted:', tweet.id);
  }
}

問題点

  • ループ内でawaitを使っているため、1件ずつしか投稿できず非常に遅い
  • API制限に引っかかる可能性がある
  • エラー処理が一切ない

改善版

async function postToTwitter(tweets: Tweet[]) {
  const results = await Promise.allSettled(
    tweets.map(tweet => 
      api.post(tweet)
        .then(() => ({ success: true, id: tweet.id }))
        .catch(error => ({ success: false, id: tweet.id, error }))
    )
  );
  
  const succeeded = results.filter(r => r.status === 'fulfilled' && r.value.success);
  const failed = results.filter(r => r.status === 'rejected' || !r.value.success);
  
  console.log(`Posted: ${succeeded.length}, Failed: ${failed.length}`);
  return { succeeded, failed };
}

ジェンスパークは「順番に投稿する」というシンプルな実装を提案しましたが、並列処理やエラーハンドリングの重要性を考慮していませんでした。

実体験3: データベースクエリの非効率

記事一覧表示機能で、ジェンスパーク(Genspark)がこんなコードを生成しました:

問題のあるコード

async function getArticlesWithCategories() {
  const articles = await db.query('SELECT * FROM articles');
  
  for (const article of articles) {
    article.category = await db.query(
      'SELECT name FROM categories WHERE id = ?',
      [article.category_id]
    );
  }
  
  return articles;
}

何が問題か

  • N+1問題:記事が100件あれば、合計101回のクエリが実行される
  • データベースへの負荷が非常に高い
  • レスポンスが極端に遅くなる

正しい実装(JOIN使用)

async function getArticlesWithCategories() {
  const articles = await db.query(`
    SELECT 
      articles.*, 
      categories.name as category_name
    FROM articles
    LEFT JOIN categories ON articles.category_id = categories.id
  `);
  
  return articles;
}

ジェンスパークは基本的なSQLは生成できますが、パフォーマンスを考慮した最適化は苦手な傾向があります。

なぜジェンスパーク(Genspark)はバグを埋め込むのか

AIがバグを生成する主な理由:

1. トレーニングデータの質

  • 学習データに含まれるコードの約20%自体がバグを含んでいる
  • StackOverflowなどの「間違った解答」も学習してしまう

2. 文脈理解の限界

  • プロジェクト全体の構造を理解できない
  • 既存コードとの整合性を考慮できない
  • エッジケースを想定できない

3. 最適化の欠如

  • 「動くコード」は生成できても「良いコード」は生成できない
  • パフォーマンスやセキュリティは後回し

人間のコーディング知識が重要な理由

では、コーディング初心者はAI開発を諦めるべきでしょうか?答えはNoです。

ただし、最低限のコーディング知識は必要です:

必要なスキルレベル

1. 基本構文の理解

  • 変数、関数、条件分岐、ループ
  • データ型と型エラーの読み方

2. デバッグ基礎

  • エラーメッセージの読み方
  • console.logでの動作確認
  • ブレークポイントの使い方

3. 基本的なアルゴリズム

  • 配列操作
  • 非同期処理の基本
  • データベース操作の基礎

これらの知識があれば、ジェンスパーク(Genspark)が生成したコードの問題点に気づき、修正を指示できます。

実践的なデバッグ手法

1. AIコードレビューの習慣化

ジェンスパーク(Genspark)が生成したコードは、必ず以下をチェック:

  • ✓ エラーハンドリングはあるか?
  • ✓ エッジケース(null、空配列など)に対応しているか?
  • ✓ ループの終了条件は正しいか?
  • ✓ 非同期処理の競合はないか?
  • ✓ データベースクエリは効率的か?
  • ✓ セキュリティ上の問題はないか?

2. 段階的なテスト実行

いきなり全機能を実装せず、小さく試す:

// ステップ1: 基本機能のテスト
console.log('Test 1: Basic function');
const result1 = await basicFunction();
console.log('Result:', result1);

// ステップ2: エッジケースのテスト
console.log('Test 2: Empty input');
const result2 = await basicFunction([]);
console.log('Result:', result2);

// ステップ3: エラーケースのテスト
console.log('Test 3: Invalid input');
try {
  const result3 = await basicFunction(null);
} catch (error) {
  console.log('Error caught:', error);
}

3. AIに「修正理由を説明させる」

バグ修正を依頼する際:

❌ 悪い例:「このコードを修正してください」

✅ 良い例:「このコードで無限ループが発生しています。原因を特定し、修正案と修正理由を説明してください」

理由を説明させることで、AIの理解度を確認でき、新たなバグの埋め込みを防げます。

Cursor BugbotとAIデバッグツール

2025年8月にCursorがリリースした「Bugbot」は、AI生成コードのバグを自動検出するツールです。

Bugbotの特徴

  • 論理エラーの検出
  • セキュリティ脆弱性のスキャン
  • エッジケースの洗い出し

ただし、Bugbot自体もAIであるため、100%の精度は保証されません。最終的な判断は人間が行う必要があります。

まとめ:AIと人間の協働が理想

覚えておくべきポイント:
  1. ジェンスパーク(Genspark)は高速にコードを生成するが、完璧ではない - バグ混入率15〜30%は想定内
  2. 人間の最低限のコーディング知識が必須 - 基本構文、デバッグ、アルゴリズムの理解
  3. コードレビューとテストを怠らない - AI生成コードこそ慎重にチェック
  4. 段階的な実装と検証 - 小さく作って、小さくテスト
  5. AIデバッグツールも活用する - ただし過信はしない

ジェンスパークは開発速度を10倍にしてくれますが、バグチェックを省略すると、後で10倍の時間がかかることになります。

AIを信頼しつつ、人間がしっかり監督する—これが2025年のAI開発のベストプラクティスです。

次回は「ジェンスパークは固まる・ループする」というテーマで、AIチャットのフリーズ問題と、データ消失を防ぐバックアップ戦略をご紹介します。