/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

WebのAIしか使えない環境で、リポジトリ全体に質問する(code2promptでコードをテキスト化)

会社で使えるAIツールが、Webインターフェースのものに限られている人は多いと思います。私の場合はM365 Copilotで、ブラウザのチャットからしか触れません。

普段プライベートではClaude CodeやCursorのような「コードエージェント」を使っていると、これがけっこうもどかしい。コードエージェントはリポジトリの中を勝手に読んで、ファイルをまたいだ質問に答えてくれます。でもWebのAIチャットは、基本ファイルを1個ずつ貼るくらいしかできない。「このリポジトリ全体を見て、この処理がどこで呼ばれてるか教えて」みたいな聞き方ができないわけです。

この差をどう埋めるか。結論から言うと、リポジトリ全体を1つのテキストファイルにまとめて添付する、という力技で大体解決しました。そのときに使ったツール(code2prompt)と、選んだ理由・インストール手順をまとめておきます。

なぜWebのAIだと難しいのか

コードエージェントが強いのは、ローカルのファイルシステムを直接読めるからです。質問に応じて必要なファイルを開き、grepし、ディレクトリ構造を把握する。この「文脈を自分で集める」動きがWebのAIチャットには無い。

WebのAIチャットでできるのは、

  • プロンプトに直接コードを貼る
  • ファイルを添付する

の2つくらい。1ファイルずつ貼っていたら全体像は渡せないし、ファイル間の関係も伝わりません。

ならば、最初からリポジトリ全部を1つのテキストに固めて渡してしまえばいい。ディレクトリツリーと全ファイルの中身が1枚のテキストに入っていれば、AIはそれを「文脈」として読めます。コードエージェントが内部でやっている「文脈集め」を、人間が手動で1回やってあげるイメージです。

リポジトリをテキスト化するツールの候補

調べてみると、この「リポジトリ → LLM用テキスト」の変換ツールはすでにいくつもありました。代表的なものを並べます。

ツール 言語 / 入手 特徴
repomix Node(npx) デファクト。多機能でMCPサーバにもなる
gitingest Web / Python 公開GitHubならURL変えるだけ。インストール不要
code2prompt Rust 単一バイナリ repomix同等の機能を単一バイナリで
files-to-prompt Python 最小・Unixパイプ前提(simonw作)
yek Rust 単一バイナリ 軽量・高速。機能は絞り気味

どれも基本は同じで、ディレクトリツリー+全ファイル内容を1ファイルに連結し、.gitignore を尊重してノイズ(node_modules など)を除外してくれます。トークン数を出してくれるものも多い。

あえて選ばなかったもの:Graph/MCP系

調べる過程で、コードを「知識グラフ」化する重量級のツール(tree-sitterで関数の呼び出し関係をグラフにしてMCP経由でAIに探索させる、みたいなもの)も見つけました。確かに巨大なリポジトリで影響範囲を正確に追いたいなら強力です。

でも今回やりたいのは「Webのチャットに添付して質疑応答する」だけ。グラフDBやMCPサーバを立てるのは明らかに過剰です。用途に対して構成が重すぎるものは選ばない、という判断で、シンプルなテキストダンプ系に絞りました。

なぜcode2promptにしたか

候補の中からcode2promptを選んだ理由は2つです。

1つめは機能。repomixと同等で、ディレクトリツリー+ファイル内容の出力、トークン数表示、.gitignore尊重、globでの絞り込みがそろっています。やりたいことには十分。

2つめが選定の決め手で、Rust製の単一バイナリだという点。repomixはnpxで動かすのが手軽なんですが、その裏でnpmの依存パッケージを取りに行きます。最近npm界隈はサプライチェーン的に不安なニュースが続いているので、実行時に外部の依存ツリーをネット越しに引いてくる形より、手元で完結する単一バイナリのほうが安心できる、という判断です。

ここは一点だけ正確に書いておくと、後述のインストール手段で安心度が変わります。cargo installやmiseのcargo:はcrates.ioのソースを手元でビルドする形。一方GitHub Releasesの配布バイナリなら、ダウンロードしてチェックサムを確認すれば、それ以上の余計なものが動かない状態にできます。依存を最小に絞りたいならReleasesバイナリが一番堅い、ということです。

インストール

Rust製の単一バイナリなので、入れ方はいくつかあります。今回の「npmの依存を避けたい」という動機からすると、依存が一番少ない順に並べるとこうなります。

① GitHub Releasesのバイナリを置くだけ(依存最小・おすすめ)

実はこれが一番きれいです。ビルドもパッケージマネージャも介さず、配布済みの実行ファイルを1個落として置くだけ。cargoもnodeも要りません。

# 実際のURL・ファイル名はReleasesページで確認してください
curl -LO https://github.com/mufeedvh/code2prompt/releases/download/<tag>/code2prompt-<os>-<arch>
# Releasesにsha256があれば照合(落としたバイナリ以外の余計なものは動かない、を担保できる)
sha256sum code2prompt-<os>-<arch>
chmod +x code2prompt-<os>-<arch>
mv code2prompt-<os>-<arch> ~/.local/bin/code2prompt   # PATHの通った場所へ
code2prompt --help

これなら依存ツリーがゼロで、チェックサム確認も素直に効きます。サプライチェーンを気にするならこれが本命。

(注:Rustバイナリは通常システムのlibcに動的リンクされるので、極端に古い環境だと稀に動かないことがあります。その場合は musl の static ビルドが提供されていないか確認してください。普通の環境ならまず問題ないです)

② miseで管理する

私はツール管理にmiseを使っているので、設定ごとリポジトリで管理したいときはこちら。cargo backend経由で入ります。

mise use -g cargo:code2prompt

このコマンド1発でconfig.tomlへの追記とビルド・インストールまで完了します(別途mise installは不要)。ただしcargo:はcrates.ioのソースを手元でビルドする形なので、①のチェックサム確認のような担保とは別物だという点だけ意識しておくといいです。

③ Homebrew / cargo

手元にあるなら手軽な方で。

brew install code2prompt
# または
cargo install code2prompt

使ってみる

基本はカレントディレクトリ配下を1ファイルに吐くだけ。

code2prompt . --output-file dump.md

これでdump.mdにディレクトリツリーと全ファイルの中身が入ります。あとはこれをM365 Copilotのチャットにドラッグ&ドロップで添付するだけ。

特定のディレクトリだけ渡したいときはglobで絞れます。パターンはクオートで囲むのがお作法です(シェルに展開されるのを防ぐため)。

code2prompt . --include="src/**" --output-file dump.md

除外したいものは--excludeで指定します。

code2prompt . --include="src/**" --exclude="tests/*" --output-file dump.md

トークン数も確認できるので、添付前に「これ大きすぎないか」を見ておくといいです。

code2prompt . --tokens

注意:code2promptはバージョンによってフラグ名が変わることがあります。動かないときはcode2prompt --helpで手元のバージョンのオプションを確認してください。

M365 Copilotに添付するときの注意

ここが実際に使って分かった現実的なところです。

私が使っているのは会社の有償ライセンス版のM365 Copilotで、この場合の添付サイズ上限は512MBとされています(ライセンス種別やテナント設定で変わるので、あくまで有償版での話です。ちなみに無償のCopilot Chatだと1MBまでというケースもあります)。いずれにせよサイズはまず問題になりません。リポジトリのテキストダンプ程度なら余裕です。

ただ、サイズに余裕があっても1回の質問でファイル全体を均等に読んでくれるとは限らない。これは自分が使った範囲での体感ですが、大きいファイルを添付すると回答が先頭寄りの内容に偏って、後半のファイルが薄くなる感触がありました。少なくとも私の使い方では、サイズの上限よりも「1プロンプトでどこまで深く読むか」のほうが実質的な制約になっています。

なので運用としては、

  • 全体像を聞きたいとき:リポジトリ全部をダンプしたdump.mdを添付
  • 特定の処理を深く聞きたいとき:--includeでそのモジュールだけに絞った版を添付

と使い分けると、回答の鋭さが変わります。全部入れれば賢くなるわけではなく、的を絞ったほうが良い答えが返ってくることが多い。

あと当然ですが、業務リポジトリのソースをCopilotに上げてよいかは社内のポリシーを確認してください。テナント内で処理され学習には使われないのが基本ですが、コードの持ち込み可否は組織の判断です。ここはツールの話とは別問題として押さえておくべきところ。

結果:WebのAIでもコードエージェントっぽく聞ける

これで、WebのAIチャットしか使えない環境でも、「このリポジトリのこの処理はどこで呼ばれてる?」「全体構成をざっくり説明して」みたいな、コードエージェント的な質問ができるようになりました。

コードエージェントが内部で自動でやっている「文脈集め」を、code2promptで1回手動でやってAIに渡す。やってみると単純な発想ですが、Webインターフェースの制約をかなり埋めてくれます。同じように「会社ではWebのAIしか使えない」という人は、一度試してみる価値があると思います。