先週、Cursorが美しく、よく構成されたExpressミドルウェアを生成するのを見ました。型はクリーンで、適切なエラーハンドリング、JSDocコメント — すべて揃っていました。
問題はただ1つだけでした: それはnpmに存在しないパッケージをインポートしていました。
import { validateSchema } from 'express-json-validator'; // ❌ このパッケージは存在しません
No red squiggly. No ESLint warning. No TypeScript error (it was in a .js file). It passed code review because the name sounded right. It would have crashed in production the moment someone ran npm install.
これは私が呼ぶところの AIの幻覚 — そしてこれは、私が1万件を超えるAI生成のプルリクエストを横断して追跡してきた5つの失敗モードのうちの1つです。
ESLintが決して捕捉できない5つの失敗モード
1. 🔮 幻覚インポート
AIモデルは訓練データからインポート文を生成します。そのパッケージのいくつかはかつて存在したもの、いくつかは元々存在しなかったもの、そしていくつかはタイポスクワットの罠です。
import { createClient } from 'redis-async'; // 存在しません — 'redis' のはず
import { parseJSON } from 'json-parse-safe'; // 存在しません
import { sanitize } from 'express-sanitizer-plus'; // タイポスクワット候補
リンターがそれを見逃す理由: ESLintは構文を検証するだけで、レジストリの存在を検証しません。TypeScriptは、@typesをインストールしている場合に限り型を検査します(存在しないパッケージにはインストールできません)。
2. 📅 古いAPI
AIモデルは2021年〜2023年のコードを基に訓練されています。廃止または削除されたAPIを自信満々に使用します。
// Copilot は2026年にもまだこのコードを生成します:
const parsed = url.parse(req.url); // Node 11 以降は非推奨
const buf = new Buffer(data); // Node 20 で削除
app.del('/resource', handler); // Express 5 で削除
リンターがそれを見逃す理由: ESLint は一部の Node.js の非推奨を警告できますが、ライブラリごとの破壊的な変更をすべてバージョン間で追跡することはできません。
3. 🧩 文脈窓のアーティファクト
AIが複数のファイルにわたってコードを生成すると、論理的な矛盾が生じることがあります。ファイルAは、ファイルBが提供しない関数署名を前提としている場合があります。
// user-service.ts(AI生成)
export function getUser(id: string): Promise<User> { ... }
// auth-middleware.ts(別々にAI生成)
const user = await getUser(id, { includeRoles: true }); // ❌ シグネチャが間違っています
リンターがそれを見逃す理由: TypeScriptは両方のファイルが同じコンパイルに含まれていればこれを検出します。しかし、巨大なモノレポジトリで部分的なビルドを行う場合、これがすり抜けることがあります。
4. 🏗️ 過剰設計パターン
AIは抽象化を好みます。ファクトリーファクトリーパターン、不要なジェネリクス、意味のないコードパスを生成して、価値を増やさずに複雑さを追加します。
// AI生成: バリデータを作成するファクトリを作るファクトリ
const createValidatorFactory = <T extends BaseValidator>(config: ValidatorConfig<T>) => (schema: Schema) => (data: unknown): ValidationResult<T> => {
// メールアドレスを検証する47行のコード
};
リンターがそれを見逃す理由: ESLintの複雑度ルール(max-depth、complexity)は粗すぎて、「必然的に複雑」か「AIが見せつけているだけ」かを区別できません。
5. 🔓 セキュリティのアンチパターン
AIは訓練例からのハードコードされた秘密、TLS検証の無効化、eval()の呼び出しなどを含むコードを生成します。
const API_KEY = 'sk-proj-abc123def456'; // 訓練データからハードコード
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // TLS無効化
const result = eval(userInput); // コードインジェクション
リンターがそれを見逃す理由: ESLint の no-eval は明らかなケースを検出しますが、AIは新しいバリアント(new Function()、vm.runInNewContext())を生成してすり抜けます。
私が作ったもの: Open Code Review
私はこれらのAI生成の失敗モード専用のCI/CD品質ゲートを6か月かけて構築しました。
Open Code Review は以下のとおりです:
- 🆓 永久無料 — オープンソース、MITライセンス
- 🏠 自己ホスト可能 — 100% ローカルで実行、データは機械を離れません
- ⚡ 高速 — L1スキャンは10秒以下
- 🔌 CIネイティブ — GitHub Actions、GitLab CI、または任意のCI
仕組み
L1: パターン検出(高速、ローカル、無料)
├── 幻覚インポート検出(npm/PyPIレジストリの検査)
├── 廃止API検出(ASTベース)
├── セキュリティアンチパターン検出
├── 過剰設計ヒューリスティクス
├── コードの重複分析
└── スコア: 0-100、アルファベット評価
L2: AIディープ分析(埋め込み + LLM)
├── 埋め込みリコール → リスクスコアリング → 上位N件の疑わしいブロック
├── LLM解析(Ollamaローカル or OpenAI/Anthropicクラウド)
├── ファイル間の文脈整合性
├── セマンティック重複検出
└── AI信頼度によるスコアの強化
30秒設定
# インストール
npm install -g @opencodereview/cli
# プロジェクトをスキャン
ocr scan src/ --sla L1
# GitHub Actionsに追加
# .github/workflows/code-review.yml
- uses: raye-deng/open-code-review@v1
with:
sla: L1
threshold: 60
scan-mode: diff
github-token: ${{ secrets.GITHUB_TOKEN }}
実際の結果
OCR自体をスキャンします。以下が見つかった内容です:
╔══════════════════════════════════════════════════════════════╗
║ Open Code Review V4 — 品質レポート ║
╚══════════════════════════════════════════════════════════════╝
📊 110ファイル中112の問題を検出
総合スコア: 67/100 🟠 D
AIの忠実度 ████████████████████ 35/35 (100%)
コードの新鮮さ ████████████░░░░░░░░ 15/25 (60%)
文脈の整合性 █████████████████░░░ 17/20 (85%)
比較対象との比較
| Open Code Review | CodeRabbit | GitHub Copilot | |
|---|---|---|---|
| 価格 | 無料 | $24/mo/seat | $10-39/mo |
| オープンソース | ✅ | ❌ | ❌ |
| AI幻覚検出 | ✅ | ❌ | ❌ |
| セルフホスト型 | ✅ | エンタープライズ | ❌ |
| データプライバシー | 100% ローカル | クラウド | クラウド |
試してみる
npm install -g @opencodereview/cli
ocr scan src/ --sla L1
⭐ GitHubでスターをつける — これにより、より多くの開発者がこのツールを知ることができます。
これまでに遭遇したAIコードの失敗モードは何ですか?コメントを残してください — コミュニティの報告に基づいて新しい検出器を作っています。
