mcpField
A
autoresearch

autoresearch

github.com/factory-aiAgent 工作流121132 次安装1 周前更新
代码仓库

关于 autoresearch

通过修改代码并运行基准测试,优化可度量仓库指标的自主实验循环技能。它将假设、结果和可续接状态记录到文件中,保留改进并撤销退步。

主要功能

  1. 01设定优化目标和停止条件
  2. 02运行基准并评估指标变化
  3. 03保留改进并撤销退步
  4. 04在 JSONL 中记录实验与假设
  5. 05依据保存的研究状态续接工作

适用场景

  1. 01通过实测降低测试运行时间
  2. 02用可重复循环优化打包体积
  3. 03跨 Agent 会话继续实验

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/factory-ai/factory-plugins --skill autoresearch

安装后在 Claude Code 中输入/autoresearch确认已加载。

附带文件autoresearch_helper.py

详细介绍

Autoresearch

自主实验循环:尝试想法,保留有效的,舍弃无效的,永不停止。

概览

你正在运行一个自主优化循环。你的任务是通过修改内容、运行实验,并且只保留改进,系统地优化一项可测量的指标。你要维护结构化状态文件,以便任何会话(包括一个全新且没有记忆的会话)都能从中断处准确续接。

如果用户要求你执行此任务,而你当前不在任务模式中,请建议他们可以在任务(/enter-mission)中运行此流程,以便更好地跟踪进度、验证里程碑并在多个会话间保持连续性。不要因此阻塞工作——只需在设置期间提及一次。

如果你已经处于任务模式,请先调用任务规划技能(mission-planning 和 define-mission-skills),再开始执行本技能的流程。使用任务系统的规划、分解和工作者设计来组织 autoresearch 工作,然后将这些指导与本技能的实验循环流程结合起来。本技能定义了如何运行实验;任务系统定义了如何规划、跟踪和验证实验。

设置

循环开始前,你需要确定实验方案。

步骤 1:收集信息

询问用户(或根据上下文推断)以下信息:

  • 目标:要优化什么?(例如,“最小化 val_bpb”、“缩短测试运行时间”、“减小打包体积”)
  • 命令:要运行什么?(例如,uv run train.py、pnpm test、pnpm build && du -sb dist)
  • 主要指标:名称、单位和优化方向(例如,val_bpb,无单位,越低越好)
  • 涉及文件:允许修改哪些文件
  • 约束条件:硬性规则(必须通过测试、不得添加新依赖等)
  • 终止条件:何时停止。询问用户,可选项包括:
    • 固定实验次数(例如,20 次实验)
    • 固定时间预算(例如,2 小时)
    • 目标指标(例如,val_bpb < 1.0)
    • 一直运行,直到被中断(默认)
步骤 2:创建分支和状态文件
git checkout autoresearch/<goal>-<date> 2>/dev/null || git checkout -b autoresearch/<goal>-<date>

仔细阅读源文件。在编写任何内容前,深入了解工作负载。

创建三个文件:

autoresearch.md

持续更新的研究文档。一个没有上下文的新 Agent 应当能够阅读此文件并有效运行循环。花时间把它写好。

# Autoresearch: <goal>

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

## Metrics
- **Primary**: <name> (<unit>, lower/higher is better) — the optimization target
- **Secondary**: <name>, <name>, ... — independent tradeoff monitors

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

## Termination
<When to stop: experiment count, time budget, target metric, or run until interrupted.>

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

Bash 脚本(set -euo pipefail),用于快速预检查(语法错误检查耗时少于 1 秒)、运行基准测试,并将结构化的 METRIC name=value 行输出到标准输出。保持脚本快速。

对于快速、噪声较大的基准测试(耗时少于 5 秒),在脚本内多次运行工作负载并报告中位数。耗时较长的工作负载(机器学习训练、大型构建)则不必如此。

示例:

#!/bin/bash
set -euo pipefail

# Pre-check: syntax validation
python3 -c "import ast; ast.parse(open('train.py').read())" 2>&1 || { echo "SYNTAX ERROR"; exit 1; }

# Run the workload
output=$(uv run train.py 2>&1)

# Extract and output metrics
val_bpb=$(echo "$output" | grep -oP 'val_bpb=\K[0-9.]+' | tail -1)
echo "METRIC val_bpb=$val_bpb"
autoresearch.checks.sh(可选)

仅当用户的约束要求验证正确性时(例如,“测试必须通过”、“类型检查必须通过”)才创建此文件。Bash 脚本(set -euo pipefail),用于执行反馈检查。

#!/bin/bash
set -euo pipefail
pnpm test --run --reporter=dot 2>&1 | tail -50
pnpm typecheck 2>&1 | grep -i error || true
步骤 3:初始化 JSONL 并提交状态文件

初始化实验日志:

python3 autoresearch_helper.py init --jsonl autoresearch.jsonl --name '<goal>' --metric-name '<metric_name>' --direction <lower|higher>

提交所有状态文件:

git add autoresearch.md autoresearch.sh autoresearch.jsonl
git commit -m "autoresearch: initialize experiment session"
步骤 4:运行基线

运行基准测试并记录基线结果:

bash autoresearch.sh

解析输出中的 METRIC 行,然后将基线记录为保留项:

python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
  --commit $(git rev-parse --short=7 HEAD) \
  --metric <baseline_value> \
  --status keep \
  --description "baseline" \
  --asi '{"hypothesis": "baseline measurement"}'

这是第 #1 个实验,用于确定后续所有比较的起点。

实验循环

无限循环。 永远不要问“要不要继续?”——用户期待你自主工作。只有在以下情况才停止:

  • 满足设置中的终止条件
  • 用户中断
  • 你发现自己的上下文即将耗尽(参见下文“上下文管理”)
对于每个实验:
1. 选择尝试的方案

阅读 autoresearch.md(尤其是“已尝试的方案”)和 autoresearch.ideas.md(如果存在),以选择下一个假设。思考数据告诉了你什么。最好的想法来自深入理解,而不是随机变化。

2. 进行更改

编辑范围内的文件。让更改聚焦——每次实验只验证一个假设。

3. 运行实验

执行基准测试:

timeout 600 bash autoresearch.sh

捕获完整输出。从输出中解析 METRIC name=value 行。

如果运行崩溃或超时,将其记录为崩溃并还原更改。

如果 autoresearch.checks.sh 存在,且基准测试通过,则运行:

timeout 300 bash autoresearch.checks.sh

如果检查失败,将其记录为 checks_failed 并还原更改。

4. 评估结果

使用辅助脚本将主要指标与当前最佳结果(如果尚无保留项,则与基线)进行比较:

python3 autoresearch_helper.py evaluate --jsonl autoresearch.jsonl --metric <value> --direction <lower|higher>

该脚本会输出保留或舍弃的建议、置信度分数以及与基线的差值。

决策规则:

  • 主要指标有所改善 -> keep
  • 主要指标变差或不变 -> discard
  • 性能相同但代码更简洁 -> keep(性能相同的情况下,减少代码量就是胜利)
  • 微小收益却带来难看的复杂度 -> 通常应 discard
  • 次要指标很少影响保留或舍弃的决定。只有次要指标严重退化时,才舍弃主要指标有所改善的结果。
5. 记录结果

保留时:

先记录到 JSONL(这样该条目会包含在提交中):

python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
  --commit $(git rev-parse --short=7 HEAD) \
  --metric <value> \
  --status keep \
  --description "<what was tried>" \
  --asi '{"hypothesis": "<what you tried>"}' \
  # --metrics '{"compile_us": <value>, "render_us": <value>}'  # optional secondary metrics
  --direction <lower|higher>

然后提交所有更改(包括 JSONL 条目):

git add -A
git commit -m "<description>

Result: {\"status\": \"keep\", \"<metric_name>\": <value>}"

舍弃/崩溃/检查失败时:

先记录到 JSONL(还原更改前记录,以保留条目):

python3 autoresearch_helper.py log --jsonl autoresearch.jsonl \
  --commit "0000000" \
  --metric <value_or_0> \
  --status <discard|crash|checks_failed> \
  --description "<what was tried>" \
  --asi '{"hypothesis": "<what you tried>", "rollback_reason": "<why it failed>"}' \
  # --metrics '{"compile_us": <value>, "render_us": <value>}'  # optional secondary metrics
  --direction <lower|higher>

然后还原更改,并备份状态文件,以免 git clean -fd 将其删除:

# Backup state files
cp autoresearch.jsonl autoresearch.jsonl.bak 2>/dev/null || true
cp autoresearch.md autoresearch.md.bak 2>/dev/null || true
cp autoresearch.ideas.md autoresearch.ideas.md.bak 2>/dev/null || true

# Revert all changes
git checkout -- .
git clean -fd 2>/dev/null

# Restore state files
cp autoresearch.jsonl.bak autoresearch.jsonl 2>/dev/null || true
cp autoresearch.md.bak autoresearch.md 2>/dev/null || true
cp autoresearch.ideas.md.bak autoresearch.ideas.md 2>/dev/null || true
rm -f autoresearch.jsonl.bak autoresearch.md.bak autoresearch.ideas.md.bak
6. 更新研究日志

每进行几次实验(或取得重要发现后),更新 autoresearch.md 中的“已尝试内容”部分。包括:

  • 哪些方法有效,以及原因
  • 哪些方法无效,以及原因
  • 应避免的死路
  • 当前最佳结果及其实现方式
7. 维护想法待办列表

发现有潜力但暂缓实施的优化时,将其作为项目符号追加到 autoresearch.ideas.md。不要让好想法被遗忘。清理过时或已尝试的条目。

8. 循环

返回步骤 1。

状态文件参考

文件格式用途
autoresearch.jsonlJSON Lines仅追加的实验日志。每行一个 JSON 对象。
autoresearch.mdMarkdown持续更新的研究文档。包含目标、已尝试内容和当前最佳结果。
autoresearch.ideas.mdMarkdown假设待办列表。记录值得尝试的想法。
autoresearch.shBash基准测试脚本。输出 METRIC name=value 行。
autoresearch.checks.shBash可选的正确性检查(测试、类型检查、lint)。
JSONL 架构

autoresearch.jsonl 中的每一行都是配置标头或实验结果:

配置标头(第一行或重新初始化时):

{"type": "config", "name": "...", "metricName": "...", "metricUnit": "...", "bestDirection": "lower|higher"}

实验结果:

{
  "run": 1,
  "commit": "abc1234",
  "metric": 1.234,
  "metrics": {"compile_us": 4200, "render_us": 9800},
  "status": "keep|discard|crash|checks_failed",
  "description": "what was tried",
  "timestamp": 1711600000000,
  "segment": 0,
  "confidence": 2.1,
  "asi": {"hypothesis": "...", "rollback_reason": "...", "next_action_hint": "..."}
}
ASI(可执行的辅助信息)

每次实验都要记录 ASI。至少包含:{"hypothesis": "what you tried"}。舍弃或崩溃时,还要包含 rollback_reason 和 next_action_hint。添加其他能够记录经验的键值对,例如死路、意外发现、错误详情和瓶颈。

ASI 是还原更改后唯一能够保留的结构化记忆。没有它,后续迭代就会浪费时间,重新发现相同的死路。

置信度评分

进行 3 次或更多实验后,辅助脚本会使用中位数绝对偏差(MAD)计算置信度分数:

置信度含义
>= 2.0x改善很可能是真实的
1.0-2.0x高于噪声,但幅度有限
< 1.0x处于噪声范围内——考虑重新运行以确认

该分数仅供参考——不会自动舍弃结果。如果置信度低于 1.0x,可考虑重新运行同一实验以确认,然后再决定是否保留。

上下文管理

Droid 会话的上下文有限。为妥善处理这一点:

  1. 跟踪当前会话中的实验次数。进行约 15 次实验后,上下文会变得臃肿。
  2. 主动保存状态——所有状态都保存在文件中(jsonl、md),因此新会话可以立即继续。
  3. 上下文即将耗尽时:更新 autoresearch.md,记录当前发现,提交状态文件,然后停止。下一会话会读取这些文件并继续。
  4. 恢复时:读取 autoresearch.md、autoresearch.jsonl 和 git log --oneline -20,了解当前进展。检查当前状态:
python3 autoresearch_helper.py status --jsonl autoresearch.jsonl

循环规则摘要

  • 永远循环。 绝不要问“要继续吗?”
  • 首要指标至上。 有所改进 -> 保留。变差或持平 -> 丢弃。
  • 为每次运行添加 ASI 注释。 记录你的收获,而不仅仅是你做了什么。
  • 关注置信度分数。 < 1.0x 表示结果处于噪声范围内——重新运行以确认。
  • 越简单越好。 性能相同但代码减少 = 保留。
  • 不要反复折腾。 如果反复撤销同一个想法?尝试结构上不同的方案。
  • 崩溃: 如果修复很简单,就修复;否则记录下来并继续。
  • 卡住时多思考。 重新阅读源文件,研究数据,推理实际发生的情况。最好的想法来自深入理解。
  • 恢复时: 读取 autoresearch.md + git log,继续循环。

最终整理

实验循环结束时(达到终止条件、用户中断或上下文耗尽),将结果整理到清晰且易于审查的分支中。这是自动研究会话的最后阶段。

第 1 步:总结结果
python3 autoresearch_helper.py summary --jsonl autoresearch.jsonl

查看 git log,了解实际提交:

git log --oneline --stat $(git merge-base HEAD main)..HEAD
第 2 步:分组变更

将保留的实验归入逻辑变更集。每组应:

  • 代表一项连贯的优化或变更
  • 与其他组不共享修改过的文件(以便各分支可以独立合并)
  • 清楚说明实现的效果和指标改进

向用户展示拟议的分组以供批准:

Group 1: "Reduce model depth from 8 to 6"
  Files: train.py (DEPTH, HEAD_DIM, N_EMBED)
  Metric improvement: val_bpb 1.15 -> 1.08 (-6.1%)
  Experiments: #3, #7, #12

Group 2: "Switch to cosine LR schedule"
  Files: train.py (lr_schedule, warmup_steps)
  Metric improvement: val_bpb 1.08 -> 1.05 (-2.8%)
  Experiments: #15, #18

等待用户确认后再继续。在任务工作者模式下,无需等待确认,直接采用最佳分组继续。

第 3 步:解决文件冲突

如果各组共享文件,请在创建分支前解决:

  • 将相关的组并为一组(如果变更彼此相关)
  • 更细致地拆分文件变更(如果它们确实是对不同部分的独立修改)
  • 询问用户应优先处理哪一组

各组不得共享文件——每个分支都必须能够独立合并。如果所有变更都涉及同一个文件且无法拆分,则创建一个包含所有改进的最终分支。

第 4 步:创建干净的分支

对每组执行:

merge_base=$(git merge-base HEAD main)
git checkout -b autoresearch/finalize/<group-name> $merge_base
git checkout autoresearch/<session-branch> -- <file1> <file2> ...
git commit -m "<group description>

Autoresearch results:
- Metric: <name> improved from <baseline> to <best> (<delta>%)
- Confidence: <score>x noise floor
- Experiments: <count> total, <kept> kept"
第 5 步:验证并报告

对每个最终分支运行基准测试,确认改进仍然成立;如适用,运行相关检查,并确认其能与 main 干净地合并。

向用户提交摘要:

Created 2 clean branches from 20 experiments:

  autoresearch/finalize/reduce-depth
    val_bpb: 1.15 -> 1.08 (-6.1%)
    Ready for review

  autoresearch/finalize/cosine-schedule
    val_bpb: 1.08 -> 1.05 (-2.8%)
    Ready for review

Original experiment branch preserved: autoresearch/<session-branch>

原始实验分支始终会保留——最终整理会创建新分支。

任务工作者模式

作为任务工作者运行时,功能描述会指定优化目标、终止条件、涉及的文件和约束。请仔细阅读,遵循上述相同的循环流程,并遵守终止条件。达到条件后,执行最终整理,并在交接中报告结果。

评论

支持 Markdown