0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIに「コード丸ごと渡し」はもう卒業。巨大・レガシーなコードを“地図化”して調査も改修も任せる技術

0
Posted at

この記事のゴール

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. 俯瞰マップ:上空から見た全体図(ディレクトリ構成・規模・入口)
  2. ルータ表:「○○したいなら、ここを見ろ」という道案内表
  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.mdCONTRIBUTING.md にコミットして、チームの資産にする。次に入る新人も、次に動くAIエージェントも、同じ地図の上を歩けます。暗黙知が、少しずつ「書かれた知識」に変わっていく。これって、けっこう尊い変化だと思うんですよね。


7. まとめ:最初の一歩は、たった5分でいい

長く書いてきましたが、明日いちばん最初にやることは、これだけでいいと思います。

READMEとディレクトリ一覧だけをAIに渡して、「やりたいこと → どこを見ればいいか」の表を作らせる。

たったこれだけ。git ls-files | head -100 の結果と README を貼って、プロンプト例②を投げるだけです。5分で、あなたのコードベースに小さな地図が1枚できます。

そこから、規模に応じて俯瞰マップ・フロー追跡・検収を足していけばいい。最初から完璧な地図はいりません。1枚の道案内表から始めればいいんです。

最後に、もう一度だけ。

AIが大きなコードで見当外れになるのは、AIのせいじゃない。地図を渡してないだけ
そして、その地図を設計して、正しさを保証するのは——まだしばらく、僕たち人間の仕事なんですよね。

今日も、いい整地を。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?