こんにちは、Diverse developer blogです。
はじめに
プロダクトの仕様について、エンジニアなら誰しも一度は「これってどういう仕様でしたっけ?」と質問された経験があると思います。
プロダクトを運営していると、仕様の全てを把握するのは難しく、仕様確認の依頼はエンジニアのところに集まってきます。その都度コードを読みに行くことになり、こうしたコストは地味に積み重なっていきます。
今回はそのやり取りを、NotebookLMに肩代わりしてもらう仕組みを整えました。
これまでの仕様確認フロー
これまでYYCでは仕様調査の一部を Devin に任せてきました。コードベースを一定理解しているAIに質問ができる、というのは非常に便利です。
エンジニア以外のメンバーが自分で仕様を確認できる手段ができたことで、エンジニアへの問い合わせが減り、運用としても定着していました。
運用見直しのきっかけ
しかしDevinの料金体系が変更され、これまで無料で気軽に使えていた範囲が有料化されました。
そのまま課金して使い続ける選択肢もありましたが、仕様確認の用途であればコストを抑える方法があるはず。
そう考え、代わりになるツールを検討した結果、NotebookLMを採用することにしました。
なぜ NotebookLMを選んだのか
判断の軸になったのは、次の4つの観点です。
1. 料金
Devin で行っていた仕様調査と同じことが、NotebookLM なら追加コストなしでできる。
2. Google Workspace との統合
弊社ではGoogle Workspace を使っているため、社員のアカウントとアクセス管理がそのまま利用できる。
3. Devinの良いところを継承している
具体的には次の2点
引用付きの回答:答えの根拠(どのファイルのどの部分を参照したか)が明示されるので、AI の答えを鵜呑みにせず裏取りできる
参照範囲の限定:NotebookLMにアップロードしたソース以外は参照しないので、ハルシネーションが起こりにくい
4. Google エコシステムの将来的な恩恵
NotebookLM と Workspace は Google が継続的に改善している領域で、便利に改善してくれる流れにも乗れる。例えば、今手動で行なっているNotebookLMのソースの更新も、将来的に自動化できる可能性があり、新しいツールや契約を増やさずに、できることが広がっていくという期待ができる。
これらを踏まえ、引き続きコストがかからず・安全に・コードベースで仕様確認ができるという点が決定打でした。
NotebookLMにソースコードを渡したいが、膨大なコードは「そのまま」では渡せない
NotebookLMにはソース1ファイルあたり約 50 万語という上限があります。
一方、YYCは長年培ってきた大量のコードを抱えており、様々なコードが入り混じっています。とても1ファイルに収まる規模ではありません。
NotebookLMのソースとしてプロダクトのコードをアップロードするには、「単にコードを集めるツール」ではなく「何を含めて何を含めないかを決める、適切な単位に分けて渡せるツール」が必要でした。
Repomixを使ってNotebookLM向けにコードを分割する
この問題を解決するために、Repomix を使って NotebookLM 向けのコードパックを生成しつつ、その分割方法を設計しました。
Repomix とは、リポジトリのファイル群を1つのテキストファイルに集約してくれるCLI です。includeやignore のglob指定、出力フォーマット選択(plain / xml / markdown)、コメント圧縮といった「LLM向けにコンテキストを渡す」前提の機能が揃っています。
まずは「どのコードを含めて、どの単位でファイルに分けるか」を整理することから始めました。実際の思考フローは、次のような順で進みました。
容量制限
→ ソース1ファイルあたり約50万語という上限を超えないようにする
不要コードの除外
→ 仕様確認に使わないコード(テストコードなど)は含めない
残すコードの判断軸
→「仕様やSQLの質問に答えられる」を満たす範囲で取捨選択
サーバーとクライアント両方の参照
→ 画面の情報を参照しつつ、裏側のサーバーの仕様も答えられる構成にしたいが、両方を1ファイルにまとめると上限を超えてしまう
分割方針の決定
→ サーバーは論理レイヤーで複数ファイルに切り分け、クライアントは1ファイルに収める
この結果、サーバー側5ファイル + クライアント側1ファイルとして書き出し、それらをすべて同じノートブックにまとめてアップロードする構成に落ち着きました。
設計はこれで決まったので、あとは実行できる形にまとめるだけです。
弊社ではMakefile にターゲットを作成し、ファイルを書き出す運用にしました。
以下は実際に Makefile に追加した内容です(一部抜粋)。
REPOMIX_OPTS := --style plain --compress
REPOMIX := npm run --silent repomix --
REPOMIX_DATE := $(shell date +%Y%m%d)
repomix:
@echo "==> server/Data層 (+本番スキーマ)"
@$(REPOMIX) $(REPOMIX_OPTS) --output repomix-server-data-$(REPOMIX_DATE).txt \
--include "Data層ファイル, スキーマ" \
--ignore "***/**/*"
@echo "==> server/Model層"
@$(REPOMIX) $(REPOMIX_OPTS) --output repomix-server-model-$(REPOMIX_DATE).txt \
--include "Model層ファイル" \
--ignore "***/**/*"
@echo "==> server/Handler+Site層"
@$(REPOMIX) $(REPOMIX_OPTS) --output repomix-server-handler-$(REPOMIX_DATE).txt \
--include "Handler+Site層ファイル" \
--ignore "***/**/*"
# ... 管理画面系、その他、クライアントと続く
分割の単位は以下の6つ
| ファイル | 含まれるもの |
|---|---|
| repomix-server-data-{date}.txt | Data 層のソースコード + DB スキーマ |
| repomix-server-model-{date}.txt | Model 層のソースコード |
| repomix-server-handler-{date}.txt | Controller 層(リクエスト処理層) |
| repomix-backend-admin-{date}.txt | 管理画面系のコード(複数の管理プロダクトを一括) |
| repomix-backend-misc-{date}.txt | 上記以外のバックエンドコード(共通ユーティリティ等) |
| repomix-client-{date}.txt | クライアント |
--compress
コード圧縮を有効にします。本質的な構造要素を抽出・保持しながら、実装の詳細を除外することで、LLM処理のためのトークン数を削減することができます。
--style
出力形式を指定できます。今回はNotebookLMが読みやすいplainで出力するようにしました。
実際の使い方
あとは make repomix で生成された6ファイルを NotebookLM のノートブックにドラッグ&ドロップでアップロードするだけです。
「メッセージを1通送るのに、ポイントはいくつ必要?」「足あとがつくのはどのタイミング?」「特定のユーザーのプロフィールを取得するSQLを教えて!」などの質問にコードを根拠にした回答が返ってきます。
まとめ
今回の取り組みで、Devinに頼っていた『コードベースの仕様確認』を追加コストなしで継続できるようになりました。
ポイントは、NotebookLM のソース容量制限という壁を Repomix で突破できたことです。「何を含めて、どう分けるか」さえ一度設計してしまえば、あとは出力してアップロードという作業だけで、いつでも最新の状態に更新できます
また、Google Workspace 上で完結するため、アクセス管理も既存の仕組みをそのまま使えます。新しいツール契約や情シスとの調整なしに移行できたのも、大きなメリットでした。
NotebookLM 側ではソース自動同期に向けたアップデートも進められており、手動で行なっているソースファイルの生成も、いずれ不要になりそうな見込みです。
workspaceupdates.googleblog.com
こうしたエコシステム側の進化に合わせて、開発フローの中で自然に使い続けられる仕組みにしていきたいと思っています。