実験レポートが増えすぎたので、検索用catalogを作った
Splendor の機械学習プロジェクトでは、モデル構造や入力特徴量、探索手法、自己対局レシピなどをかなりの高頻度で試している。実験の実行自体は自動化によって数をこなせるようになったものの、思わぬところで開発のボトルネックが発生し始めた。
過去の実験レポートが蓄積しすぎた結果、「この仮説は過去に検証済みか」「以前に似たような失敗はなかったか」「現在のコードベースでも有効な知見はどれか」を探し出す作業に膨大な時間を奪われるようになったのだ。
そこで、実験レポート群を素早く横断検索できる軽量なカタログツールを導入した。いわゆる本格的で重厚な実験管理システム(experiment tracking system)ではなく、Markdownで書かれたレポートのフロントマターを読み取り、検証した問い・実験結果・結論・現在の有効性・スコープのみを一覧表示するシンプルな仕組みである。これが想像以上に開発効率の向上に貢献してくれた。
レポートが増えると「過去の検索」が研究の主要コストになる
実験数が10本程度であれば、ファイル名を眺めて順次開いていけば事足りる。
しかし実験が何十本にも達すると、ファイル名の一覧だけでは太刀打ちできなくなる。新しい仮説を思い立った際に確認したいのは、次のような情報だからだ。
- 似た問いを過去にすでに検証していないか
- そのときの実験結果と結論は何だったか
- 当時の実験結果は、最新のモデルでも依然として有効(active)なのか
- 前提条件が異なるだけで、現在も示唆として役立つ知見なのか
- その後の実験で上書き(superseded)され、もはや参照不要なのか
ファイル名だけではこうした文脈は判断できない。
全文検索(grep)をかける手もあるが、当時の正確な言い回しを知らないとヒットせず、検索結果から何本ものMarkdownファイルを直接開いて確認する手間が生じる。また、すべてのレポートをLLMに丸ごと読み込ませて要約させるアプローチも、レポート数が増えるにつれてコンテキスト長を浪費し、コスト的にも現実的ではなくなっていく。
実験の蓄積に伴い、「過去のエビデンスを探し出す時間」が新たなボトルネックと化していた。
必要だったのは「問いと結論」を鳥瞰できる目次
この状況で真に求められていたのは、Weights & Biases や MLflow のような実行ごとのメトリクスを可視化するダッシュボードではなかった。ランや成果物の管理そのものよりも、各実験が扱った「研究上の問い」と「得られた結論」を素早く横断検索できる仕組みだった。
たとえば、次のようなシンプルな表を一望できれば、詳細を読むべきレポートを数本に絞り込むには十分だった。
| report | question | outcome | conclusion | relevance |
|---|---|---|---|---|
| … | … | … | … | … |
そこで各レポートのMarkdownフロントマターに、検索・分類用のメタデータを直接持たせる設計を採用した。
具体的には kind、status、question、hypothesis、outcome、conclusion、relevance、scope、tags といったフィールドを定義している。これらは単に本文を機械的に要約するためではなく、研究の知識ベースを効率よくナビゲートするためのインデックスとして機能する。
軽量なカタログCLIツールの実装
カタログツールは、リポジトリ内の全レポートのフロントマターをパースし、その場でインデックスを動的に生成する。普段の開発時はMarkdown形式のテーブルとしてターミナル上に出力して確認できる。
CIやスクリプトなどの自動処理で扱いたい場合にはJSON形式での出力もサポートしており、基本的には単一のコマンドを叩くだけで動作する。
このツールのおかげで、たとえば「局面評価(value learning)に関する過去の実験をまとめて振り返りたい」といった場合に、個別ファイルを開く前に問いと結論を横並びで俯瞰できるようになった。その中から本当に読むべきレポートだけをピックアップして本文を読めば済む。
これはコーディングエージェントに調査を依頼する場合も同様である。エージェントにまずカタログの要約を渡して調査対象を絞り込ませ、その後に必要なレポートのみを読ませることで、コンテキストウィンドウの無駄遣いを大幅に抑えることが可能になった。
INDEX.md による手動管理を避けた理由
カタログ化を考える際、最も手軽に思えるのはリポジトリ内の INDEX.md に全レポートの要約を手作業で追記していく運用である。しかしこの手法は意図して採用しなかった。
レポートを新設するたびに、
- レポート本文を書く
INDEX.mdに追記する
という2段階の同期作業が発生してしまうためだ。さらに後日、実験の解釈や有効性のステータスが更新された際、両方のファイルを漏れなく同期し続けるのは極めて難しい。
特にLLMを活用した自律開発においては、この手の二重管理は致命的な情報の不整合(drift)を招きやすい。片方の記述だけが古いままでも文章として自然に成立してしまうため、内容の齟齬に気づきにくくなるのだ。
そのため、各レポートのフロントマターのみを唯一の正(Single Source of Truth)とし、カタログ自体の静的ファイルはリポジトリに保存しない方針をとった。インデックスはファイルとしてコミットするのではなく、必要な都度生成する「動的なビュー」として扱う。この設計であれば、レポート本文側を修正するだけで、カタログの内容も自動的に整合性が保たれる。
relevance(現在性)と scope(適用範囲)の重要性
単に問いと結論を一覧化するだけでも利便性は高いが、実際の意思決定において特に決定打となったのが relevance(現在の研究方針に対する有効性)と scope(適用範囲)のフィールドだった。実験で得られた知見の価値は、その後の研究の進展によって絶えず変化するためである。
たとえば、検証当時は非常に重要だった結果であっても、モデルアーキテクチャが大きく刷新されれば直接の適用が難しくなる場合がある。逆に、古い実験であっても特定の条件下では依然として有効な知見を提供し続けてくれることもある。
そこでレポート本文は「当時の測定エビデンス」としてそのまま保存し、現在の研究方針における有効性の判断のみをフロントマターのメタデータ側で表現する設計とした。これにより、過去のレポート本文を現在の視点に合わせてわざわざ書き直す必要がなくなる。歴史的な記録としての正確性を保ちつつ、今読むべき重要な知見をカタログ上で瞬時に見分けることができる。
スキーマ定義の二重管理も防ぐ
フロントマターに構造化データを導入すると、次に問題となるのがスキーマ定義の管理である。許可されるフィールド名や列挙値をドキュメントに書き、同時にリントスクリプト側にも同じバリデーションルールを書けば、そこでもまた2つの情報源が存在することになってしまう。
そこで、ドキュメント用の仕様(contract)もツール側から自動生成する方式を採用した。パーサーおよびバリデータが持っている内部のフィールド定義から、人間やコーディングエージェントが参照するスキーマ仕様を直接生成できるようにしている。
新しいレポートを作成する際は、まずそのコマンドを実行して最新の仕様を確認する。開発者向けガイドライン側にはスキーマの具体内容をハードコードせず、「このコマンドを実行して仕様を確認すること」とだけ記載しておく。これにより、スキーマに変更が加わっても、ドキュメントとバリデータの間に乖離が生じることがなくなった。
変更されたレポートのみをリント対象にする
もう一つ配慮したのが、カタログのスキーマをアップデートした際に、過去のすべてのレポートに修正を強要しないことだった。過去のレポート群はあくまで当時の貴重な実験記録であり、リポジトリの最新フォーマットへ逐一マイグレーションし続けること自体が目的ではない。
そのため、コミット時のリント処理では、main ブランチとのマージベースから見て変更・新規追加されたアクティブなレポートのみを検証対象とした。直近で執筆・編集したレポートは最新のスキーマ規約を満たす必要があるが、過去の古いレポートはバリデーションエラーを起こさず、無関係な変更をブロックしない。
この仕組みにより、メタデータの品質を厳格に維持しながらも、形式統一のためだけの不毛なメンテナンス作業を排除することができた。
導入の成果
カタログツールの導入により、以前のようにファイルツリーをさまよったり grep を多用したりしながら手当たり次第にレポートを開く作業は完全に過去のものとなった。
現在はまずカタログを確認し、問い・結論・有効性・スコープから対象を的確に絞り込んでから読み進めることができる。新しい仮説を立てる際も、過去の実験履歴を浅くスキャンして重複がないか確認した上で、スムーズに実験計画へと移行できるようになった。
LLMエージェントにとっても、全ファイルを無差別に読むより、最初に構造化メタデータでルーティングを行うアプローチの方が圧倒的に扱いやすい。
加えた変更は、Markdownのフロントマターへの属性追加と、数百行程度の軽量なCLIスクリプトの実装にとどまる。それでも、
- 過去のエビデンスを素早く探し出す
- 重複した実験の実施を防ぐ
- 古い実験結果の有効性を正しく見極める
- LLMに必要なレポートのみを効率的に読み込ませる
- インデックスやスキーマの二重管理を未然に防ぐ
といった日々の運用課題を包括的に解決することができた。機械学習の研究開発では派手な実験そのものに目を奪われがちだが、実験数が増加したフェーズにおいては、「過去の知識へいかにストレスなくアクセスできるか」という仕組み化もまた、開発スループットを大きく左右する重要な要素である。
この記事は、実装・実験記録をもとに、本文の大部分をLLMが執筆し、筆者が内容を確認・編集しています。