実際のシーン

昨日、CursorにNode.jsプロジェクトのリファクタリングを依頼した。すぐに美しいコードが返ってきた:ロジックの分離、パフォーマンスの最適化、型注釈の追加。

その後、私は2時間かけて:

  • 40以上のimportパスを手動調整
  • 単体テストを再実行(AIはJestかMochaか知らなかった)
  • 3つのバージョン競合を解決(AIは新しいAPIを使ったが、依存関係は古いバージョン)
  • READMEを書き直し(AI生成のドキュメントは使えない)

AIがコードを書くのに3分、私が後始末に2時間。

これは歴史の授業で聞いた話を思い出させた:19世紀初頭、イギリス人は蒸気機関車を作ったが、鉄道はまだ普及していない。どうする?蒸気機関を馬車に載せる。

結果は?馬車の車輪は蒸気機関の重さに耐えられず、路面は壊れ、旋回半径は馬より悪い。

これが今のAIコーディング:2025年のAIで、1995年の馬車を引いている。


私たちの「馬車」とは?

1. ファイルシステム:AIの悪夢

AIはコード生成が速いが、知らない:

  • プロジェクトはsrc/lib/か?
  • ユーティリティ関数はutils/helpers/か?
  • 設定ファイルはconfig.jssettings.jsonか?

AIがコードを生成するたびに:

  1. コードを正しいファイルにコピー
  2. importパスを調整
  3. 既存のコードと手動でマージ

これはAIの問題ではなく、ファイルシステムの問題。

ファイルシステムは1960年代に人間のために設計された:src/components/Button.tsxを見れば、脳は自動的にコンポーネントディレクトリ内のボタンだと理解する。

しかしAIが見るのは文字列だけ。Button.tsxbutton.tsxが同じファイルかどうかわからない(Linuxでは違う、Windowsでは同じ)。

2. 依存関係管理:バージョン地獄

AIがこのコードをくれる:

1
2
3
4
5
6
import { useQuery } from '@tanstack/react-query'

function UserList() {
const { data } = useQuery('users', fetchUsers)
// ...
}

問題なさそう。しかし:

  • プロジェクトはReact Query v3、これはv4の構文
  • swrもインストール済み、今プロジェクトに2つのデータ取得ライブラリ
  • AIはnpmかyarnかpnpmか知らない

必要なこと:

  1. package.jsonを確認
  2. 依存関係をアップグレード(またはAIのコードをダウングレード)
  3. 再インストール
  4. 破壊的変更がないことを祈る

依存関係管理は手動コーディング用に設計された、人間が慎重にchangelogを読み、依存関係を一つずつアップグレードすることを想定。AIはコード生成が人間の100倍速いが、依存関係管理は2010年に留まっている。

3. テスト:AIはあなたが何をテストしているか知らない

AIがコードを書き終えたら、「テストを書いて」と頼む。

生成される:

1
2
3
4
5
describe('Calculator', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3)
})
})

しかし:

  • VitestでJestじゃない(構文は似ているが、importが違う)
  • プロジェクトの慣例:テストファイルは__tests__/ディレクトリ、.test.jsサフィックスではない
  • CIは80%以上のカバレッジが必要、AIは最も簡単なケースしかテストしていない

テストシステムは「コード後にテストを補足」を想定、しかしAI Codingのリズムは「生成しながら同時にテスト」。必要なのはリアルタイム検証、事後の宿題ではない。


真のAI-Native開発とは?

1. ファイルシステムを捨て、知識グラフを採用

src/utils/formatDate.jsの代わりに:

1
2
3
4
5
知識グラフ:
- [Function: formatDate]
- タイプ:ユーティリティ関数
- 依存:[dayjs]
- 使用者:[UserProfile, OrderList]

AIはパスを覚える必要がなく、「formatDateはユーティリティ関数、dayjsに依存、UserProfileで使用」とだけ知ればいい。

ファイルシステムは知識グラフのシリアライズ形式(Gitが追跡できるように)にすぎず、開発者とAIの主要インターフェースであるべきではない。

2. 宣言的依存関係

package.jsonの代わりに:

1
2
3
4
5
6
7
8
必要なもの:
- データ取得:高速、キャッシュサポート、TypeScriptフレンドリー
- 状態管理:シンプル、最小限のボイラープレート

AI推奨:
- TanStack Query v5(ニーズに合致)
- バージョン互換性処理済み
- TypeScript設定済み

AIは意図に基づいて依存関係を選択、手動で検索、比較、インストール、設定する必要なし。

3. リアルタイム検証がユニットテストに取って代わる

add.test.jsを書く代わりに:

1
2
3
4
リアルタイム制約:
- add(1, 2) は3でなければならない
- add(負の数) は明確な動作が必要
- パフォーマンス:1000回呼び出し < 10ms

AIはコード生成中にリアルタイムでこれらの制約をチェック、コード生成 → テスト書く → テスト実行 → 失敗 → コード修正ではない。


AI-Nativeまであとどれくらい?

技術的に:3-5年。

すでに初期の試みがある:

  • ReplitのAgent:ファイルパスを管理不要、Agentが見つける
  • val.town:コードはクラウド上、依存関係は自動処理
  • CursorのComposer:複数ファイルを同時編集可能

しかしこれらは「より良い馬車」、列車ではない。

本当の列車に必要なもの:

  1. 新しいプロジェクト組織方法(ファイルシステムではない)
  2. 新しい依存関係管理(package.jsonではない)
  3. 新しい検証メカニズム(ユニットテストではない)
  4. 新しいコラボレーション方法(Git + PRではない)

これにはエコシステム全体の再構築が必要、単一のAIエディタでは解決できない。


今できること

新しいエコシステムが成熟するまで、できること:

1. AI-Friendlyなプロジェクト規約を確立

悪い例:

1
2
3
4
project/
src/
components/
utils/

良い例:

1
2
3
4
project/
README.AI.md # AIにプロジェクト構造、慣例、注意事項を伝える
src/
各ディレクトリにREADME.mdで目的を説明

2. 暗黙の慣例を減らす

悪い例:
「チームの慣例:utilsは純粋関数のみ」(AIは知らない)

良い例:
ESLintルールで強制:utils/ディレクトリは副作用禁止

3. ツールで規約を強制

  • commit message → commitlint
  • コードフォーマット → prettier
  • import順序 → eslint-plugin-import

AIは暗黙のルールを覚えるのが苦手、しかしツールで強制できる。


結語

蒸気機関が馬車を引く時代は長く続かなかった。すぐに人類は気づいた:蒸気機関の力を発揮するには、鉄道、駅、信号システム—全く新しいインフラが必要だと。

AI Codingも同じ。

今はAIでコードを生成し、その後手動でパスを調整、依存関係を修正、テストを書き、commitを分割。これは非効率だが、移行期の必然。

真の変革は、より良いAIモデルではなく、AI用に設計された全く新しい開発インフラ。

その時、開発者の仕事は「コードを書く」ことではなく、「意図を定義し、結果を検証し、アーキテクチャの決定をする」ことになる。

コード生成、テスト、デプロイ—これらはすべてAIの仕事。

私たちは今この転換点に立っている。

蒸気機関がすでに馬車に載っている。鉄道はまだ遠いだろうか?