mcpField
A
autoresearch

autoresearch

github.com/moedesuxAgent 工作流19765 次安装31 周前更新
代码仓库

关于 autoresearch

autoresearch 是用于代码或配置优化的自主实验循环技能,面向希望按指定命令和指标持续试验的 Agent。它通过 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(见下文)。提交这三个文件。
  5. 初始化实验(将配置标头写入 autoresearch.jsonl)→ 运行基线 → 记录结果 → 立即开始循环。
autoresearch.md

这是本次会话的核心。一个没有上下文的新 Agent 应该能够阅读此文件并有效运行循环。投入时间把它打磨好。

# 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——尤其是“已尝试的内容”部分——以便恢复工作的 Agent 能掌握完整上下文。

autoresearch.sh

Bash 脚本(set -euo pipefail),用于:快速预检查(语法错误检查在 <1s 内完成)、运行基准测试、输出 METRIC name=number 行。保持脚本快速——每秒都会在数百次运行中累积。根据需要在循环期间更新脚本。


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. 如果没有备份:根据工作日志中的记录手动重新创建缺失的运行
  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:命令失败(退出代码非零)

次要指标仅用于监控,几乎不会影响保留或丢弃的决定。只有当次要指标严重恶化时,才丢弃主要指标有所改善的结果,并在描述中说明原因。

2. Git 操作

如果保留:

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

如果丢弃或崩溃:

git checkout -- .
git clean -fd

将当前 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 追加一条简短记录。该文件可在上下文压缩和崩溃后保留,为任何恢复工作的 Agent(或用户)完整记录会话过程。格式:

### 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>

学到新内容时,也要更新工作日志底部的“关键见解”和“后续想法”部分。

设置时,创建 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,尤其是“已尝试事项”部分,确保接手循环的新 Agent 能充分了解哪些方法有效、哪些无效,以及获得了哪些架构方面的见解。每进行 5–10 次实验后,或取得重大突破后,更新一次。

评论

支持 Markdown