mcpField
A
autoresearch

autoresearch

github.com/moedesuxエージェントワークフロー19765 回インストール31 週間前に更新
リポジトリ

autoresearch について

autoresearchは、指定コマンドと指標に沿ってコードや設定を自律的に試すスキルです。Git、JSONLの状態記録、作業ログ、ダッシュボードで実験結果を管理します。

主な機能

  1. 01目標と指標に沿った実験ループ
  2. 02改善を保持し他の変更を戻す処理
  3. 03JSONLによる実験状態の記録
  4. 04作業ログでの進捗追跡
  5. 05実験ダッシュボードの生成
  6. 06実験状態のバックアップと復元

活用シーン

  1. 01ベンチマーク指標の反復最適化
  2. 02セッションをまたいだ実験の再開
  3. 03実験の変更と結果の確認

インストール

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

$npx skills add https://github.com/moedesux/autoresearch-opencode --skill autoresearch

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

詳細

Autoresearch

自律的な実験ループ:アイデアを試し、うまくいくものを残し、うまくいかないものを破棄し、決して止まりません。

セットアップ

  1. 目標、コマンド、指標(方向性も含む)、対象ファイル、制約を質問する(または推測する)。
  2. git checkout -b autoresearch/<goal>-<date>
  3. ソースファイルを読みます。何かを書く前に、対象のワークロードを深く理解します。
  4. mkdir -p experiments を実行し、autoresearch.md、autoresearch.sh、experiments/worklog.md を作成します(以下を参照)。3つすべてをコミットします。
  5. 実験を初期化し(設定ヘッダーを autoresearch.jsonl に書き込む)、ベースラインを実行して結果を記録したら、すぐにループを開始します。
autoresearch.md

これはセッションの中核です。コンテキストを持たない新しいエージェントがこのファイルを読んで、ループを効果的に実行できるようにします。優れたファイルにするため、時間をかけてください。

# Autoresearch: <goal>

## Objective
<Specific description of what we're optimizing and the workload.>

## Metrics
- **Primary**: <name> (<unit>, lower/higher is better)
- **Secondary**: <name>, <name>, ...

## How to Run
`./autoresearch.sh` — outputs `METRIC name=number` lines.

## Files in Scope
<Every file the agent may modify, with a brief note on what it does.>

## Off Limits
<What must NOT be touched.>

## Constraints
<Hard rules: tests must pass, no new deps, etc.>

## What's Been Tried
<Update this section as experiments accumulate. Note key wins, dead ends,
and architectural insights so the agent doesn't repeat failed approaches.>

autoresearch.md は定期的に更新してください。特に「試したこと」セクションを更新し、再開するエージェントが完全なコンテキストを把握できるようにします。

autoresearch.sh

Bash スクリプト(set -euo pipefail)で、次の処理を行います。高速な事前チェック(構文エラーの検出を1秒未満で行う)、ベンチマークの実行、METRIC name=number 形式の行の出力です。高速に保ってください。実行時間が1秒増えるごとに、数百回分の実行時間が増加します。必要に応じてループ中に更新してください。


JSONL 状態プロトコル

すべての実験状態は autoresearch.jsonl に保存されます。これはセッションをまたいで再開する際の信頼できる唯一の情報源です。

設定ヘッダー

最初の行と、再初期化時の行は設定ヘッダーです。

{"type":"config","name":"<session name>","metricName":"<primary metric name>","metricUnit":"<unit>","bestDirection":"lower|higher"}

ルール:

  • ファイルの最初の行は必ず設定ヘッダーにします。
  • 後続の設定ヘッダー(再初期化)があるたびに、新しいセグメントが始まります。セグメントのインデックスは、設定ヘッダーごとに増加します。
  • セグメントのベースラインは、設定ヘッダーの後に続く最初の結果行です。
結果行

各実験の結果は、JSON 行として追記されます。

{"run":1,"commit":"abc1234","metric":42.3,"metrics":{"secondary_metric":123},"status":"keep","description":"baseline","timestamp":1234567890,"segment":0}

フィールド:

  • run:セグメント全体を通じた連続した実行番号(1から始まる)
  • commit:7文字の Git 短縮ハッシュ(採用時は自動コミット後のコミットハッシュ、破棄時またはクラッシュ時は現在の HEAD)
  • metric:主要指標の値(クラッシュ時は0)
  • metrics:副次指標の値を格納するオブジェクト。副次指標の追跡を開始したら、以降のすべての結果に含めてください。
  • status:keep | discard | crash
  • description:この実験で試したことの簡潔な説明
  • timestamp:Unix エポック秒
  • segment:現在のセグメントインデックス
初期化(init_experiment 相当)

初期化するには、設定ヘッダーを autoresearch.jsonl に書き込みます。

echo '{"type":"config","name":"<name>","metricName":"<metric>","metricUnit":"<unit>","bestDirection":"<lower|higher>"}' > autoresearch.jsonl

再初期化する場合(最適化対象を変更する場合)は、新しい設定ヘッダーを追記します。

echo '{"type":"config","name":"<name>","metricName":"<metric>","metricUnit":"<unit>","bestDirection":"<lower|higher>"}' >> autoresearch.jsonl

データ整合性プロトコル

重要:JSONL データを破損または消失させてはなりません。

書き込み前の検証(JSONL に追記する前)

新しい実験結果を書き込む前に、JSONL ファイルを検証します。

# Validate JSONL file before writing
validate_jsonl() {
    local jsonl_file="autoresearch.jsonl"
    
    if [[ -f "$jsonl_file" ]]; then
        # Count existing runs
        local run_count=$(grep -c '"run":' "$jsonl_file" 2>/dev/null || echo 0)
        echo "Current runs in JSONL: $run_count" >&2
        
        # Verify last 5 lines are valid JSON
        tail -n 5 "$jsonl_file" 2>/dev/null | while IFS= read -r line; do
            if ! echo "$line" | python3 -m json.tool >/dev/null 2>&1; then
                echo "WARNING: Invalid JSON found in state file" >&2
                return 1
            fi
        done
        
        echo "JSONL validation: OK" >&2
        return 0
    fi
    return 0  # File doesn't exist yet, that's OK
}

# Call validation before any write
validate_jsonl || {
    echo "  WARNING: JSONL validation failed. Proceeding with caution." >&2
}
アトミック書き込みパターン

JSONL に直接追記してはいけません。アトミック書き込みパターンを使用します。

write_jsonl_entry() {
    local entry="$1"
    local jsonl_file="autoresearch.jsonl"
    local temp_file="${jsonl_file}.tmp.$$"
    
    # Create temp file
    cat "$jsonl_file" > "$temp_file" 2>/dev/null || touch "$temp_file"
    
    # Append entry
    echo "$entry" >> "$temp_file"
    
    # Validate the new entry
    if ! echo "$entry" | python3 -m json.tool >/dev/null 2>&1; then
        rm -f "$temp_file"
        echo "  WARNING: Invalid JSON entry, not writing" >&2
        return 1
    fi
    
    # Atomic move (guaranteed all-or-nothing)
    mv "$temp_file" "$jsonl_file"
    
    # Verify write succeeded
    local new_count=$(grep -c '"run":' "$jsonl_file" 2>/dev/null || echo 0)
    echo "Write verification: $new_count runs in JSONL" >&2
    
    return 0
}
書き込み後の検証

書き込み操作のたびに、データが正しく書き込まれたことを検証します。

verify_write() {
    local expected_run=$1
    local jsonl_file="autoresearch.jsonl"
    
    if [[ -f "$jsonl_file" ]]; then
        local actual_count=$(grep -c '"run":' "$jsonl_file" 2>/dev/null || echo 0)
        
        if [[ "$actual_count" -lt "$expected_run" ]]; then
            echo "  WARNING: Run count mismatch! Expected $expected_run, got $actual_count" >&2
            echo "This may indicate data loss in previous writes." >&2
            return 1
        fi
        
        echo "Write verification: OK (run $expected_run present)" >&2
        return 0
    fi
    return 1
}

ユーザーの確認が必要な操作

ユーザーの確認が必要な操作(例:手動介入、大幅な変更、複数の実験の破棄)を行う前に、バックアップを作成します。

# Backup state before user-confirmable action
backup_before_confirm() {
    echo "  User confirmation required. Creating backup..." >&2
    
    # Use backup utility if available
    if [[ -f "./scripts/backup-state.sh" ]]; then
        ./scripts/backup-state.sh backup autoresearch.jsonl 2>/dev/null || true
    else
        # Fallback: simple backup
        cp autoresearch.jsonl "autoresearch.jsonl.backup.$(date +%s)" 2>/dev/null || true
    fi
    
    echo "Backup created. Awaiting user confirmation..." >&2
}

ユーザーの承認が必要な操作の前には、必ず backup_before_confirm を呼び出してください。


ダッシュボードのデータ整合性チェック

ダッシュボードを生成する際は、データの整合性を確認します。

データ整合性チェック

autoresearch.jsonl 内の実行数と experiments/worklog.md 内のエントリー数が一致しない場合:

  1. バックアップを確認する:scripts/backup-state.sh list autoresearch.jsonl
  2. バックアップがある場合:scripts/backup-state.sh restore-auto で復元する
  3. バックアップがない場合:worklog のメモをもとに、欠落している実行を手動で再作成する
  4. 不一致についてダッシュボードのヘッダーに記載する

不整合を検出した場合は、次の警告バナーをダッシュボードに追加します。

 **DATA INCONSISTENCY DETECTED**

- **Worklog documents**: <WORKLOG_RUN_COUNT> experiments
- **JSONL contains**: <JSONL_RUN_COUNT> runs
- **Missing**: <DIFF> runs **LOST!**

**Recovery steps:**
1. Check backups: `scripts/backup-state.sh list autoresearch.jsonl`
2. Restore if available: `scripts/backup-state.sh restore-auto`
3. Otherwise, manually recreate missing runs from worklog

実験の実行(run_experiment と同等)

ベンチマークコマンドを実行し、所要時間と出力を記録します。

START_TIME=$(date +%s%N)
bash -c "./autoresearch.sh" 2>&1 | tee /tmp/autoresearch-output.txt
EXIT_CODE=$?
END_TIME=$(date +%s%N)
DURATION=$(echo "scale=3; ($END_TIME - $START_TIME) / 1000000000" | bc)
echo "Duration: ${DURATION}s, Exit code: ${EXIT_CODE}"

実行後:

  • 出力から METRIC name=number の行を解析して、メトリクス値を抽出します
  • 終了コードが 0 以外の場合 → クラッシュです
  • 出力を読み、何が起きたかを把握します

結果の記録(log_experiment と同等)

実験を実行するたびに、次の手順を正確に実行します。

1. ステータスの判定
  • keep:主要メトリクスが改善した(bestDirection=lower の場合は値が小さく、bestDirection=higher の場合は値が大きい)
  • discard:主要メトリクスが、保持されている最良結果より悪いか、同等
  • crash:コマンドが失敗した(終了コードが 0 以外)

副次メトリクスは監視専用であり、keep/discard の判定に影響することはほとんどありません。副次メトリクスが壊滅的に悪化した場合に限り、主要メトリクスが改善していても discard とし、その理由を説明に記載します。

2. Git 操作

keep の場合:

git add -A
git diff --cached --quiet && echo "nothing to commit" || git commit -m "<description>

Result: {\"status\":\"keep\",\"<metricName>\":<value>,<secondary metrics>}"

続いて、新しいコミットハッシュを取得します。

git rev-parse --short=7 HEAD

discard または crash の場合:

git checkout -- .
git clean -fd

コミットフィールドには、revert 前の現在の HEAD ハッシュを使用します。

3. JSONL に結果を追加
echo '{"run":<N>,"commit":"<hash>","metric":<value>,"metrics":{<secondaries>},"status":"<status>","description":"<desc>","timestamp":'$(date +%s)',"segment":<seg>}' >> autoresearch.jsonl
4. ダッシュボードを更新

ログを記録するたびに、autoresearch-dashboard.md を再生成します(下記の「ダッシュボード」セクションを参照)。

5. ワークログに追記

実験を実行するたびに、experiments/worklog.md に簡潔な記録を追記します。このファイルはコンテキストの圧縮やクラッシュ後も保持されるため、再開するエージェント(またはユーザー)がセッションの全体像を把握できます。形式:

### Run N: <short description> — <primary_metric>=<value> (<STATUS>)
- Timestamp: YYYY-MM-DD HH:MM
- What changed: <1-2 sentences describing the code/config change>
- Result: <metric values>, <delta vs best>
- Insight: <what was learned, why it worked/failed>
- Next: <what to try next based on this result>

新たな知見が得られたら、ワークログ末尾の「Key Insights」と「Next Ideas」のセクションも更新します。

セットアップ時には、セッションヘッダー、データの概要、ベースラインの結果を含む experiments/worklog.md を作成します。再開時には、コンテキストを復元するために experiments/worklog.md を読みます。

6. 副次メトリクスの一貫性

副次メトリクスの追跡を開始したら、その後のすべての結果に必ず含めます。JSONL を解析して、追跡対象となっている副次メトリクスを確認し、すべてが含まれていることを確認してください。

セッションの途中で新しい副次メトリクスを追加しても構いません。ただし、追加後は常に含めてください。


ダッシュボード

実験のたびに、autoresearch-dashboard.md を再生成します。

# Autoresearch Dashboard: <name>

**Runs:** 12 | **Kept:** 8 | **Discarded:** 3 | **Crashed:** 1
**Baseline:** <metric_name>: <value><unit> (#1)
**Best:** <metric_name>: <value><unit> (#8, -26.2%)

| # | commit | <metric_name> | status | description |
|---|--------|---------------|--------|-------------|
| 1 | abc1234 | 42.3s | keep | baseline |
| 2 | def5678 | 40.1s (-5.2%) | keep | optimize hot loop |
| 3 | abc1234 | 43.0s (+1.7%) | discard | try vectorization |
...

各メトリクス値について、ベースラインに対する変化率を含めます。現在のセグメント内の実行をすべて表示します(直近の実行だけではありません)。


状態ファイルのバックアップ(強化版)

ユーザーが確認できる操作の前に、バックアップを作成します。

# Before any major operation requiring user confirmation
if [[ -f "./scripts/backup-state.sh" ]]; then
    ./scripts/backup-state.sh backup autoresearch.jsonl 2>/dev/null || true
else
    cp autoresearch.jsonl "autoresearch.jsonl.backup.$(date +%s)" 2>/dev/null || true
fi

ベストプラクティス:

  • 重大な変更やユーザーへの確認の前には、必ずバックアップします
  • 直近 5 件のバックアップを保持し、それより古いものは削除します
  • 実験がクラッシュした場合や状態が破損した場合は、バックアップから復元します

自動クリーンアップ:

# Keep only last 5 backups
ls -t autoresearch.jsonl.bak.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true

警告:JSONL のデータ損失が検出された場合は、処理を続ける前に直ちにバックアップを確認してください。


データ損失の検出と復旧

データ損失を検出した場合(例:ダッシュボードに不整合がある、JSONL の件数がワークログと一致しない):

  1. 直ちに行うこと:

    # Check for data loss
    JSONL_COUNT=$(grep -c '"run":' autoresearch.jsonl 2>/dev/null || echo 0)
    WORKLOG_COUNT=$(grep -c "^### Run" experiments/worklog.md 2>/dev/null || echo 0)
    
    if [[ "$JSONL_COUNT" -ne "$WORKLOG_COUNT" ]]; then
        echo "  DATA LOSS DETECTED: JSONL has $JSONL_COUNT runs, worklog has $WORKLOG_COUNT runs" >&2
    fi
    
  2. バックアップを確認:

    ./scripts/backup-state.sh list autoresearch.jsonl
    
  3. 復旧方法:

    • 最善:十分に新しいバックアップがあれば、そこから復元します
    • 代替策:ワークログのメモをもとに、不足している実行を手動で再作成します
    • 最終手段:新しい設定ヘッダーを使って、新しいセグメントを開始します
  4. 予防:ユーザーが確認できる操作の前には、必ずバックアップします(上記の「ユーザーが確認できる操作」を参照)

ループのルール

永遠にループしてください。「続けてもよいですか?」と尋ねてはいけません。ユーザーは自律的に作業を続けることを期待しています。

  • 最優先の指標が最重要です。 改善した場合は keep。悪化または同等の場合は discard。二次指標が影響することはほとんどありません。
  • シンプルなほうが優れています。 パフォーマンスが同等なら、コードを削除できる変更は採用します。わずかな改善のために複雑さが増す場合は、おそらく破棄します。
  • 同じことを繰り返さないでください。 同じアイデアを何度も元に戻すことになったら、構造的に異なる方法を試してください。
  • クラッシュした場合: 簡単に直せるなら修正し、そうでなければ記録して先に進みます。深入りしすぎないでください。
  • 行き詰まったら、じっくり考えてください。 ソースファイルを読み直し、プロファイリングデータを調べ、CPUが実際に何をしているのかを考察します。優れたアイデアは、ランダムな変更を試すのではなく、深い理解から生まれます。
  • 再開する場合: autoresearch.md が存在する場合は、まず autoresearch.jsonl が存在するか確認します。
    • 存在する場合:そのファイル、experiments/worklog.md、git log を読み、ループを続けます
    • 存在しない場合:以下の「状態ファイルが見つからない場合」セクションのフォールバック動作を確認します

絶対に停止しないでください。 ユーザーは何時間も席を外している場合があります。中断されるまで続けてください。

状態ファイルが見つからない場合

再開時に autoresearch.jsonl が見つからない場合:

  1. autoresearch.md のコンテキストを維持します - 目的、指標、対象ファイルを読みます
  2. ユーザーに確認を求めます - 「状態ファイルが見つかりません。次の選択肢があります。
    • A) 新しい状態を作成する(新規開始)
    • B) autoresearch.md のコンテキストのみで続行する
    • C) バックアップから復元する(利用可能な場合) 」
  3. 新規開始する場合:設定ヘッダーを含む新しい JSONL を初期化します
  4. コンテキストのみで続行する場合:autoresearch.md のデータを使って進めますが、制限があることを記録します

アイデアのバックログ

複雑でも有望な最適化を見つけ、今すぐ取り組まないと判断した場合は、autoresearch.ideas.md に箇条書きで追記してください。有用なアイデアを失わないようにします。

ループが停止した場合(コンテキストの上限、クラッシュなど)、autoresearch.ideas.md が存在すれば、次の作業を行うよう求められます。

  1. アイデアファイルを読み、新しい実験の方針を考える参考にする
  2. 重複しているもの、すでに試したもの、明らかに不適切なものを削除する
  3. 残ったアイデアに基づいて実験を作成する
  4. 何も残らなければ、新しいアイデアを自分で考える
  5. すべての可能性を試し尽くした場合は、autoresearch.ideas.md を削除し、最終報告を作成する

ループ終了時に autoresearch.ideas.md が存在しない場合、リサーチは完了です。

ユーザーによる方針の指定

実験中に届いたユーザーメッセージは記録し、次の実験に反映してください。現在の実験を終えてから対応します。作業を中断したり、確認を求めたりしないでください。ユーザーのアイデアは次の実験に取り入れます。

autoresearch.md の更新

autoresearch.md は定期的に更新してください。特に「試したこと」セクションは、新たに作業を再開するエージェントが、何がうまくいき、何がうまくいかなかったのか、またどのようなアーキテクチャ上の知見が得られたのかを把握できるようにします。5~10 回の実験ごと、または大きな進展があった後に更新してください。

コメント