この記事のゴール
AIコーディング支援を使っていて、こんな経験はないでしょうか。
「このバグ直して」ってリポジトリごと渡したのに、全然関係ないファイルをいじってくる。
「この機能どこで実装されてる?」って聞いたら、それっぽいけど微妙にズレた答えが返ってくる。
小さなToyプロジェクトだと天才なのに、仕事の本物のコードベースになった途端に急に頼りなくなる。
あの感じ…ありますよね。
正直に言いましょう。あれ、AIが賢くないからじゃないんです。
こっちが地図を渡してないから、なんですよね。
この記事では、「コードベースをAIに丸ごと渡す」のをやめて、コードベースを“地図”に変換してから任せるという発想と、その具体的な手順を書きます。明日、自分のリポジトリでそのまま試せるコードとプロンプトを厚めに入れました。AI開発にまだ慣れていない方でも読み進められるように、専門用語は出すたびに噛み砕きます。
ゴールはひとつ。「巨大なコードがこわくなくなる」。それだけです。
1. 「コードを丸ごと渡したのに、見当外れ」——あの感覚の正体
まず、よくある失敗の場面を思い出してみましょう。
あなたは、初めて触る5,000ファイルくらいの中規模リポジトリに配属されました。「決済まわりのバグを直したい」。とりあえずこうします。
grep -rn "checkout" .
# → 217件ヒット。controller, service, util, test, 設定ファイル…どれが本筋か分からない
200件以上のヒット。どれが本丸で、どれがただの命名のかぶりなのか、ぱっと見では分かりません。これ、人間でも迷子になる「grep地獄」ですよね。
で、思うわけです。「AIに全部読ませたら一発じゃない?」と。
でも、5,000ファイル全部をチャットに貼ることはできません。仮に貼れたとしても、AIはどこが重要で、どこが脇道かを教えてもらっていないので、結局あなたと同じように迷子になります。
ここで大事な気づきがひとつあります。
情報を見つけることと、理解することは、全然違う。
grepは「情報を見つける」のは得意です。でも「このコードベースがどう成り立っているか」を理解するのは、また別の話なんですよね。そして今のAIに足りていないのは、たいてい後者のほうです。
2. なぜ巨大・レガシーなコードでAIは急に下手になるのか(3つの壁)
AIが大きなコードで弱る理由は、わりとシンプルです。3つの壁にまとめられます。
① 窓の壁(コンテキスト長は有限)
AIが一度に読める文章の量(これを「コンテキストウィンドウ=AIの作業机の広さ」と思ってください)には上限があります。机がどれだけ広くなっても、数千ファイルのコードを丸ごと広げることはできません。
② 構造の壁(依存関係は行間に書いてない)
仮に全部読めたとしても、ファイルAの関数がファイルBを呼び、その設定はファイルCにある…みたいな「つながり」は、1ファイルを眺めただけでは見えません。アーキテクチャ(全体の構造)は、コードの“行間”に隠れているんです。
③ 暗黙知の壁(コードに書いてない事情)
「この処理がここに置いてあるのは、3年前の障害対応の名残」みたいな、コードのどこにも書いていない知識。チームの頭の中にだけある“暗黙知(tribal knowledge)”ですね。AIはここに一番アクセスしづらい。
比喩で言うと、こういうことかなと。
初めての街に来た観光客に、分厚い電話帳を渡しても目的地には着けない。
必要なのは、路線図と「観光案内所はここ」という1枚の地図。
AIに「電話帳(=全コード)」を渡しても迷うのは、当たり前なんですよね。渡すべきは地図のほうです。
3. 発想を変える:「全部渡す」から「地図を渡す」へ
ここ数年、AIまわりは「コンテキストウィンドウを大きくする競争」で盛り上がってきました。机をどんどん広くする方向ですね。でも、現場の手触りとしては、そこじゃない気がしてて。
実際、2026年のAIコーディングの流れは、はっきり変わってきています。「より大きい窓に丸投げ」から、「永続的で構造化された“コードベースの地図(repo map)”をAIに参照させる」 方向へ。いくつか実在のツールを挙げておきます(どれも考え方の参考になります)。
- Aider(オープンソースのCLIエージェント)の repo map:Tree-sitter(=コードを文法的に解析して、関数やクラスといった“部品”を取り出す道具)でリポジトリ全体からシンボル(クラス名・関数名・呼び出しの形)を抜き出し、今のタスクに関係しそうな順に並べて、コンパクトにAIへ渡します。全ファイルを読み込まずに、多ファイル編集に強い。
- Repomix:リポジトリ全体を、AIが読みやすい構造化テキスト(1枚にまとめたパック)に変換するツール。
- ctags / Tree-sitter:「どこに何が定義されているか」のシンボル索引を作る、昔からある定番。
共通しているのは、「コードをそのまま渡す」のではなく、「コードから“索引と地図”を作って渡す」 という発想です。大手の開発組織でも、巨大なパイプラインの暗黙知を、AIにナビゲーション用のガイドとして書き起こさせる、といった取り組みが出てきています。
僕はこれを、ひとことで「整地(せいち)」と呼んでいます。
更地のジャングルにAIを放り込むんじゃなくて、先に道を通してから歩かせる。地ならしをするのは、ちょっと地味な作業です。でも、ここをやるかやらないかで、AIの働きは別物になる気がします。
4. コードベースの地図は「3層」でできている
では、地図ってどう作るのか。難しそうに聞こえますが、ざっくり3層に分けると、一気に作りやすくなります。
- 俯瞰マップ:上空から見た全体図(ディレクトリ構成・規模・入口)
- ルータ表:「○○したいなら、ここを見ろ」という道案内表
- フロー追跡:ある1機能を、入口から出口まで一本でたどった図
順番に、コードとプロンプトで作っていきましょう。
4-1. 俯瞰マップ —— まず「上空写真」を1枚作る
いきなりコードを読ませる前に、機械的に集められる事実を1枚にまとめます。ここはAIじゃなくて、ふつうのコマンドの仕事です。
#!/usr/bin/env bash
# repo-overview.sh — コードベースの「上空写真」を1枚に出力する
set -euo pipefail
OUT="repo-overview.txt"
{
echo "# Directory tree (depth 2, ディレクトリのみ)"
# gitが追跡しているパスから、上位2階層のディレクトリだけ抽出
git ls-files | awk -F/ '{print $1"/"$2}' | sort -u | head -80
echo
echo "# 言語別の規模(行数)"
# clocが無ければ: git ls-files | xargs wc -l などでも代用可
cloc --quiet . 2>/dev/null || echo "(cloc未インストール: スキップ)"
echo
echo "# エントリポイント候補(main / index / app / server 等)"
git ls-files | grep -Ei '(^|/)(main|index|app|server|cli)\.[a-z]+$' | head -40
echo
echo "# 主要シンボル索引(ctags: 関数・クラスの定義位置)"
# -R 再帰, --languages で対象言語を絞ると軽い
ctags -R --fields=+n -f - . 2>/dev/null | awk '{print $1"\t"$2}' | head -120
} > "$OUT"
echo "wrote $OUT"
これで「ディレクトリ構成・言語別の規模・入口らしきファイル・主要な関数の定義位置」が1枚のテキストになります。全コードじゃなくて、この“目次”だけをAIに渡すのがポイントです。
そのうえで、最初の要約をお願いします。
▼ プロンプト例①:俯瞰要約をつくる
あなたは、このコードベースに今日初めて参加したシニアエンジニアです。
添付の repo-overview.txt(ディレクトリ構成・規模・エントリポイント・シンボル索引)だけを根拠に、
初見の開発者向けに以下を日本語でまとめてください。推測した箇所は「推測」と明記すること。
1. このプロジェクトは何をするものか(1〜2行の仮説)
2. アーキテクチャの俯瞰(層・主要モジュール・想定される責務)
3. 処理の入口(エントリポイント)はどれか、根拠とともに
4. 「最初に読むべきファイル」トップ5と、その理由
5. この情報だけでは分からない点(追加で見たいファイル名)
ポイントは最後の「分からない点を聞く」ところ。AIに「知らないことを知らないと言わせる」ことで、次に何を渡せばいいかが見えてきます。
4-2. ルータ表 —— 「○○したいなら、ここ」を作る
俯瞰の次は、道案内表です。英語圏では "where to look for X"(Xを探すならどこ)と呼ばれたりします。これが地図のいちばん実用的な部分かなと。
▼ プロンプト例②:ルータ表をMarkdownで作らせる
先ほどの俯瞰と、私が追加で貼るファイル(ルーティング定義・ディレクトリ一覧)を根拠に、
「やりたいこと → 最初に見るべき場所」の対応表を、Markdownの表で作ってください。
- 列は: やりたいこと / 関連ディレクトリ・ファイル / 入口の関数やルート / 補足
- 行は、実務でよくある作業を最低10個(例: 認証を直す, APIを1本追加する,
決済フローを追う, DBスキーマを変える, ログを足す, テストを追加する 等)
- 各行に、根拠が無い場合は「未確認」と書くこと。事実と推測を混ぜないこと。
出てきた表は、その場限りにせずファイルに保存して資産化します。たとえば docs/atlas/repo-map.md のような場所に置いて、Gitにコミットしておく。こうすると、次に来た人も、次に動くAIも、同じ地図を再利用できます。AIが毎回ゼロから探索しなくて済むので、地味にトークンも時間も節約できるんですよね。
4-3. フロー追跡 —— 1本の機能を、入口から出口まで
最後は、ある1機能を、入口から出口まで一本でたどる地図です。バグ修正や機能追加の前に、これが一番効きます。
ただ、ここでAIに「決済フロー全部読んで」と丸投げすると、また迷子になります。なので、たどる材料を機械的に集めてから渡します。
#!/usr/bin/env bash
# trace-symbol.sh — ある関数の「呼び出し元・呼び出し先」候補を集める
# 使い方: ./trace-symbol.sh createCheckout
set -euo pipefail
SYM="${1:?関数名やシンボル名を引数で渡してください}"
echo "## 定義箇所(definition 候補)"
git grep -nE "(function|def|fn|const|class)\s+${SYM}\b" || true
echo
echo "## 使用箇所(呼び出し元の候補)"
git grep -nE "\b${SYM}\s*\(" || true
echo
echo "## 近接する重要キーワード(同じファイル内のimport/route定義)"
git grep -lE "\b${SYM}\b" | while read -r f; do
echo "### $f"
grep -nE "^(import|from|require|route|app\.(get|post|put|delete))" "$f" | head -10 || true
done
この出力(=「この関数はどこで定義され、どこから呼ばれ、どんなimportと一緒にいるか」)をAIに渡して、こうお願いします。
▼ プロンプト例③:機能フローを一本でたどらせる
添付は、関数 createCheckout に関する grep 結果(定義・呼び出し元・近接import)です。
この材料だけを根拠に、「ユーザーが決済ボタンを押してから、決済が確定するまで」の
処理フローを、呼び出し順に並べてください。
- 各ステップに「ファイル:行 / 関数名 / 役割(1行)」を付ける
- 材料に存在しないステップは創作しないこと。欠けている箇所は「ここは材料に無いので要確認」と書く
- 最後に、このバグ(決済が二重に走る)を調べるなら最初に疑うべき箇所トップ3を挙げる
ここまで来ると、AIは「全体のどこを、どの順でいじればいいか」を、根拠つきで答えられるようになります。最初の grep 地獄とは、もう別世界ですよね。
5. ただし——AIが描いた地図を、そのまま信じてはいけない
ここ、いちばん大事なところです。声を大にして言いたい。
AIが作った地図を、検収せずに信じない。
理由は3つあります。
- ハルシネーション(もっともらしい嘘):AIは、存在しない依存関係や、それっぽいけど実在しない関数を、平気で“それらしく”書くことがあります。地図が間違っていると、その上の作業が全部ズレます。
- 地図の陳腐化:一度作った地図は、コードが変われば古くなります。半年前の路線図で歩いたら、廃線になった駅に着く、みたいなことが起きる。
- 機密の流出:社内コードを安易に外部サービスへ貼るのは、規約・セキュリティの観点でアウトな場合があります。何を外に出していいかは、人間が必ず線を引く。
地図を検収するための、もう1本プロンプトを足しておくと安全です。
▼ プロンプト例④(検収用):根拠を全部出させる
あなたが作成したルータ表・フロー図について、各行・各ステップに
「根拠となるファイル:行」を付け直してください。
- 実際の grep 結果や貼られたコードに根拠がある項目だけ「確認済」とする
- 根拠が無い、または推測で書いた項目は、すべて「未確認」と明記する
- 「未確認」の項目について、確認するために私が次に調べるべきコマンド(grep等)を提案する
そして人間がやることは、シンプルです。ルータ表の上位5項目だけ、実物のコードと突き合わせる。 全部を検証する必要はありません。よく使う入口だけ正しければ、地図は十分に「使える」ものになります。
6. 人間がやること、AIに任せること
ここで、役割をはっきり線引きしておきましょう。AI時代のエンジニアは「実装する人」から「コードベースの地図を設計し、その正しさを保証する人」へ、少しずつ重心が移っている気がします。
| フェーズ | 人間が握る(設計・判断) | AIに任せる(生成・抽出) |
|---|---|---|
| 何を地図化するか | 対象範囲・優先順位を決める | 候補の洗い出しを手伝う |
| 俯瞰マップ | 機械抽出のコマンド設計/結果の取捨選択 | 索引からの要約・初見向け説明 |
| ルータ表 | 「実務でよくある作業」リストの妥当性判断 | 表のドラフト作成 |
| フロー追跡 | どの機能を追うか決める/材料の準備 | 呼び出し順の組み立て |
| 検収 | 上位項目を実物と突き合わせる | 根拠(ファイル:行)の提示 |
| 暗黙知 | 「なぜこうなっているか」を言語化する | 言語化を質問で引き出す |
| 機密境界 | 何を外に出すか決める | (触らせない) |
そして、いちばん効くのは、作った地図を“その場限り”にしないことです。docs/atlas/repo-map.md や CONTRIBUTING.md にコミットして、チームの資産にする。次に入る新人も、次に動くAIエージェントも、同じ地図の上を歩けます。暗黙知が、少しずつ「書かれた知識」に変わっていく。これって、けっこう尊い変化だと思うんですよね。
7. まとめ:最初の一歩は、たった5分でいい
長く書いてきましたが、明日いちばん最初にやることは、これだけでいいと思います。
READMEとディレクトリ一覧だけをAIに渡して、「やりたいこと → どこを見ればいいか」の表を作らせる。
たったこれだけ。git ls-files | head -100 の結果と README を貼って、プロンプト例②を投げるだけです。5分で、あなたのコードベースに小さな地図が1枚できます。
そこから、規模に応じて俯瞰マップ・フロー追跡・検収を足していけばいい。最初から完璧な地図はいりません。1枚の道案内表から始めればいいんです。
最後に、もう一度だけ。
AIが大きなコードで見当外れになるのは、AIのせいじゃない。地図を渡してないだけ。
そして、その地図を設計して、正しさを保証するのは——まだしばらく、僕たち人間の仕事なんですよね。
今日も、いい整地を。