mcpField
R
research-codebase

research-codebase

github.com/jurgendn開発1166 回インストール6 週間前に更新
リポジトリ

research-codebase について

research-codebaseは、再現可能な実験環境を必要とする研究者、特にプログラミングに不慣れな人向けのスキルです。固定パイプラインと設定ベースの実行・集計で、実験結果を論文の表にまとめます。

主な機能

  1. 014段階の固定パイプライン契約
  2. 02設定とシードに基づく実験実行
  3. 03実行情報と指標の自動記録
  4. 04CSVとLaTeXへの集計
  5. 05試験実行と妥当性チェック

活用シーン

  1. 01再現可能な研究実験の構築
  2. 02パラメーターとシードの一括実行
  3. 03結果から論文用の表を生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jurgendn/agent-skills --skill research-codebase

インストール後、Claude Code で/research-codebaseを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/project-template/
.gitignore
aggregate.py
configs.py
data.py
metrics.py
README.md
requirements.txt
run.py
sanity_check.py
assets/project-template/algorithms/
__init__.py
mean_baseline.py
ridge.py
assets/project-template/results/
README.md
references/
codebase-cleanup-guide.md
evidence-base.md

詳細

研究用コードベース

科学を支えるハーネスを構築します。固定されたパイプライン契約、多数の設定を実行するランナー、完了した実行結果を論文の表にまとめるアグリゲーターを用意します。数式はユーザーが用意し、このスキルは数式を何度も実行し、正しく報告できるようにします。

重要なルールは次の 2 つです。

  • 最初に契約を固定し、その後は共有コードを編集しません。 実験の追加は、リストに 1 行追加するか、辞書に 1 つ項目を加えるだけで済む必要があります。エントリーポイントの編集が必要なら、契約が間違っています。
  • 来歴は意識の問題ではなく、仕組みで担保します。 実行ごとに、その実行を生み出したものをすべて記録します。ユーザーが何かを忘れずに記録することには依存しません。

2 つ目のルールがあるため、「痛みを感じてから構造を加える」という考え方は、ここでは 採用しません。構造を後回しにするのは、問題に気づき、リファクタリングを実行できる人がいることを前提としています。ユーザーがコーディングできなければ、リファクタリングは行われず、プロジェクトには train_v2_final_REAL.py が増えていくだけです。小さく固定された骨組みを最初に正しく用意し、それ以上大きくしないようにします。

公開されたエビデンスがどこまでを裏付けているかについては、references/evidence-base.md を参照してください。既存のコードの乱雑な状態を整理する場合は、references/codebase-cleanup-guide.md を参照してください。

ステップ 0 — ヒアリング(ファイルを作成する前に、まとめて一度だけ)

以下の質問を一度にまとめて行います。ソフトウェアの用語ではなく、論文で使う用語で尋ねてください。

  1. 主な表または図は何ですか? 行、列、セルに入る内容を確認します。これをもとにアグリゲーターを逆算して設計します。成果物となるものです。
  2. 1 回の実行では何をしますか? 何を計算し、どの数値を返すのかを確認します。主要な指標だけでなく、診断情報も含めます(収束までの反復回数、実行時間、ランク、スパース性、最終ギャップ、収束したかどうかなど)。この回答が結果 dict の必須キーになります。
  3. 実行ごとに何が変わりますか? 手法、データセット、1 つか 2 つのパラメーター、シードなどです。これが params リストになり、実行回数によって、完了済みの実行をスキップする機能や並列処理を用意する価値があるかが決まります。
  4. 1 回の実行にどのくらいかかり、どこで実行しますか? ノート PC で数秒、1 台の GPU で数分、スケジューラーを使うクラスターで数時間などです。生成されるコードの構成を最も大きく左右します。
  5. 新規プロジェクトですか、それとも再整理する既存コードがありますか? まず ls で確認し、本当に判断がつかない場合に限って尋ねます。

以下については尋ねないでください。指標の保存先、出力ディレクトリの構成、シードの数、LaTeX を出力するかどうか、設定システムを構築するかどうかです。どれにも適切な答えがあります。デフォルトを使い、その内容を 1 行で伝えてください。

質問は 1 回だけです。 確認のためのやり取りを重ねるたびに、コーディングできない人に、判断材料のない選択をさせることになります。回答が曖昧なら、デフォルトを使うと明示して、そのまま進めてください。決して作業を止めないでください。Q1 に回答がなければ、実行ごとに 1 行となる縦長の CSV に集約し、表の形式がまだ必要であることを伝えます。Q4 に回答がなければ、遅くても常に正しく動作する直列ループを使います。

パイプラインの契約

固定シグネチャを持つ4つのステージです。これらを厳密に実装すれば、ハーネスは一度書くだけで済みます。

ステージ契約拡張方法
データload(name, seed) または generate(params, seed) → 問題インスタンス新しい関数
アルゴリズムALGORITHMS: dict[str, Callable]、統一された呼び出し形式dict に1行追加
メトリクスMETRICS: dict[str, Callable]、metric(result, data) -> floatdict に1行追加
保存outputs/<run_id>/{config.json, metrics.json} → aggregate.pyなし — 固定

ここでは通常の dict が適切なレジストリです。エントリーポイントの if 文の連鎖でも、デコレーターを使うプラグインシステムでもありません。 if 文の連鎖では、新しい手法を追加するたびに共有エントリーポイントを編集する必要があります。これは、コードを書けない人が行う編集の中で最もリスクが高く、失敗するとすべての実行が一度に壊れます。dict なら1行で済み、特別な仕組みもありません。

# algorithms/__init__.py — add a method by adding one line.
from algorithms.ridge import ridge
ALGORITHMS = {"ridge": ridge}

**メトリクスはモデルに依存しません。**各アルゴリズムは結果 dict を返し、メトリクスはそこから値を読み取るだけです。

{"preds": ..., "n_iters": 34, "rank": 7, "fit_seconds": 1.2}

「モデルが必要」なメトリクス(スパース性、ランク、反復回数、実行時間など)も、アルゴリズムが値を報告すれば対応できます。学習済みオブジェクトにメトリクスからアクセスさせてはいけません。ベースラインが sklearn の推定器で、手法が独自クラスになった途端、model.coef_ を読むメトリクスは、手法によってクラッシュしたりしなかったりします。これは、コードを書けない人にはデバッグできない失敗です。統一された結果 dict によって、設計上この問題が起きないようにできます。学習済みオブジェクトをどうしても再度調べる必要がある場合(3つ目の分割データで評価する、学習後にしきい値を調整するなど)は、任意の "model" キーを、ドキュメントに記載した例外的な手段として許可します。通常の経路にはしません。

だからこそ、Q2 ではすべての数値を最初に確認します。後から新しい診断項目を追加する場合、各アルゴリズムのファイルに1行ずつ追加すれば済むため、手間のかからないこの判断は前もって行ってください。

必須事項(それぞれに対応する仕組み)

  • すべての実行で、argv、解決済みパラメーター、seed、git rev-parse HEAD を含む config.json を書き込みます。手作業で管理する対応表は使いません。数百回の実行では、手作業による来歴管理は脆弱なのではなく、不可能です。
  • すべての実行で、Q2 のキーを含む metrics.json を書き込みます。キーが欠けている場合は、200回実行した後に表の欠落として現れるのではなく、実行時にエラーを明確に発生させます。
  • 使用するすべての RNG に対して、seed を設定して記録します。
  • data/raw/ は変更しません。
  • results/ はバージョン管理対象とし、outputs/ は git の追跡対象外にして再生成可能にします。
  • 最終的な数値はノートブックではなく、スクリプトから取得します。
  • 論文の表は手作業で転記せず、aggregate.py で生成します。

実行スクリプト

パラメーターのリストに対して1つのスクリプトを使います。実行ごとにシェルスクリプトを1つ作る方法は使いません。N 個の設定 × M 個の seed がある場合、その方法ではボトルネックになり、N×M 個のファイルを手作業で編集すると、コードを書けない人が気づかないエラーを持ち込むことになります。

# configs.py — the whole experiment plan lives here.
CONFIGS = [
    {"data": "synthetic", "algorithm": a, "n": n}
    for a in ("ridge", "lasso")
    for n in (100, 1000)
]
SEEDS = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

実行スクリプトは CONFIGS × SEEDS を反復処理し、設定から決定論的な run_id を導出し、metrics.json がすでに存在する実行はスキップして、outputs/<run_id>/ に書き込みます。スイープの途中でクラッシュしても、未完了の実行だけをやり直せば済みます。デフォルトでは逐次実行とし、実行時間が長いと Q4 で分かった場合に限り、並列ワーカーやスケジューラーの配列ジョブを使います。

およそ50回を超える実行がある場合、またはマシン間で設定を共有する必要がある場合にのみ、設定ファイル(YAML/TOML)に切り替えます。それ以下なら Python のリストのほうが仕組みが少なく、ユーザーにも読みやすくなります。

集計

aggregate.py は outputs/*/metrics.json を glob で取得し、シードごとに設定単位でグループ化して、CSV と booktabs 対応の LaTeX 行を出力します。LaTeX は常に出力してください。ユーザーは LaTeX で執筆するため、行を生成すれば、転記ミスの原因をひとつ減らせます。

設定ごとに、n_seeds、平均、ブートストラップ信頼区間を報告してください。また、学習とテストの値は複合スコアにまとめず、別々の列(metric_train、metric_test、sigma_train、sigma_test)に分けてください。

スタイル上の問題ではない、次の 2 つのルールがあります。

  • 設定に一致するすべての実行を集計してください。 最大値を選んだり、シードの上位 N 件だけを選んだりしてはいけません。複数の試行から最良のものを選ぶことは、誤解を招く結果の既知の原因です。
  • 十分なシード数を固定値としてハードコードしないでください。 10 は妥当な初期値ですが、ハイパーパラメーターが同じでも、互いに独立した 5 シードのグループ 2 つから、統計的に異なる分布が得られることが示されています。信頼区間がベースラインと重なるほど広い場合、より大胆な主張をするのではなく、シードを増やしてください。「この差は本物か」という疑問は statistical-testing-guide に、アブレーションの構成は hypothesis-and-ablation-planner に振り分けてください。

過学習の診断と「この改善は本物に見えるか」という判断は experiment-design の担当です。このスキルは、その診断に必要な学習/テストの生の列を出力し、そこで処理を終えます。

プロトタイプのゲート

本格的なスイープを開始する前に、単純なデータ(小さな生成インスタンスや、データセットを縮小したもの)でパイプライン全体を一度実行してください。目的は数値を得ることではなく、ロギング、集計、LaTeX の出力までを一貫して実行し、実行時間を見積もって、本格的なスイープにかかるコストを支払う前に把握することです。この実行結果から所要時間を推定し、計画しているスイープを実施できるか判断してください。

sanity_check.py

テストスイートではなく、迅速な公開と撤回の間に立つ最小限のチェックです。以下の 4 つのチェックは、コードを書けなくても、ユーザーがそれぞれ数学的に適切なチェックだと確認できます。

  1. 決定性 — 同じシードを 2 回使うと、ビット単位で同一のメトリクスが得られます。シードが設定されていないランダム性を検出します。
  2. 必須キー — すべてのアルゴリズムが、すべての Q2 キーを返します。表の欠落を検出します。
  3. リーク — 学習用とテスト用のインデックス集合が互いに素です(学習を伴う設定のみ)。
  4. 学習/正しさ — この手法によって小さなバッチの損失がほぼ 0 になるか、閉形式解があるケースで既知の参照解と一致します(シミュレーションおよび数値計算の設定)。

省略するもの

具体的な理由が生じるまで、パッケージング(pyproject.toml、PyPI)、継続的インテグレーション、型チェック、ドキュメントサイトの生成、実験追跡サービス、抽象的な設定システム、クラス階層は省略してください。公開済みのガイダンスには、ML 研究全般において最初の 4 項目が重要だとするものもありますが、その主張の対象は リリース済みの成果物 であり、著者自身も「適切な場合に限る」としています。締め切りに追われるプログラマーではない人が、進行中の実験でこれらを導入するには実際のコストがかかる一方、メリットが得られるのは投稿後です。成果物のリリース時に改めて検討してください。その段階は artifact-release-packager が担当します。

同じガイダンスで省略できないものは、明示的に記録したシード、固定された依存関係、そして論文中のすべての実験を再実行するための単一のコマンドです。ランナーがそのコマンドです。

出力

アドバイスを行う際は、次のことを行います。

  • Step 0 の一括質問をしてから、記入済みの契約(4 つの段階、結果辞書のキー、パラメーターのリスト)を再掲します。
  • 質問せずに採用したデフォルト値を明示します。
  • ユーザーの数式を追加する前に、おもちゃのデータでエンドツーエンドに実行できる骨組みを生成します。TODO の穴があるテンプレートは、コーディングできない人には使えません。
  • コマンドからテーブルまでの経路を明示します:run.py → outputs/<run_id>/metrics.json → aggregate.py → results/
  • 既存のコードについては、references/codebase-cleanup-guide.md に従い、削除する前に何が基盤となっているかを明示します。

ユーザーが読めない生成コードであっても、正しくなければなりません。コードを目視で確認するのではなく、実行してハーネスを検証してください。一見もっともらしいコードが実行できても、結果が間違っていることが、ここで典型的に起こる失敗です。

コメント