mcpField
M
ml-autoresearch

ml-autoresearch

github.com/gaasher数据与数据库17839 次安装17 周前更新
代码仓库

关于 ml-autoresearch

ML Autoresearch Loop 是用于开放式 ML 实验的技能,每次修改都以对模型行为的分析为依据。它每轮只测试一项改动,并可选择结合已有文献来制定实验。

主要功能

  1. 01依据分析规划实验
  2. 02每轮仅做一项改动
  3. 03按指标保留或撤销
  4. 04快照或分支策略
  5. 05可选文献依据
  6. 06实验与发现记录表

适用场景

  1. 01围绕标量指标迭代改进模型
  2. 02根据诊断结果检验假设
  3. 03参考已发表研究制定 ML 改动

安装

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

$npx skills add https://github.com/gaasher/agent-loop-skills --skill ml-autoresearch

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples/
run.example.yaml
roles/
research-subagent.md
schemas/
literature_schema.json

详细介绍

ML 自动研究循环

此循环以分析优先:每次实验后都会进行诊断,检查模型内部发生了什么;下一步改动是基于这些证据提出的假设,而非猜测。反馈信号是从运行日志中读取的 <metric>;分析是决定改动方向的主线。<literature> 开关(on/off)可选地通过同级的 literature-search 技能,依据已有研究为每次改动提供依据。每次迭代只做一项改动,因此每次指标变化都能归因于该改动。

你是研究人员。循环启动后,无需暂停并征求许可。

适用场景

适用于开放式、自主运行的 ML 研究活动,且你希望每项改动都由对模型实际行为的分析来推动。设置 <literature> = off,进行独立的分析与评分循环;设置 <literature> = on,则还会依据科学文献为改动提供依据(论文搜索、证据评级、可复用的研究发现待办清单)。不适用于单次训练、固定范围的参数扫描,或没有可衡量标量指标的任务。默认设为 off,除非用户希望参考文献,或这是一个已有大量公开研究、采用既有方案会有帮助的问题。

设置

以交互方式确定各项绑定。 如果工作目录中存在 loop.run.yaml,则加载该文件并跳转至循环。否则:在 Claude Code 上(可使用 AskUserQuestion 工具——记录 <host> = claude-code),根据项目推断每项绑定的可能值,并将其作为推荐选项呈现;在其他宿主上(<host> = other),将每项内容作为带引号的纯文本提示询问。然后写入 loop.run.yaml(格式:examples/run.example.yaml),并且在创建任何其他文件之前,先与用户确认每项值。 对于 branches 策略,创建 git checkout -b autoresearch/<run_tag>(标签取自当天日期;分支必须尚不存在)。对于 time 限制,将 <sandbox_root>/run_with_timeout.sh 写入 timeout $(( <budget> * 60 )) <entrypoint> "$@",并将其用作运行命令;在 2 × <budget> 分钟时强制终止。对于 epochs,修改 <editable_files> 文件中的 epoch 上限。

绑定含义默认值推断方法
<metric> / <metric_direction>要优化的标量 + minimize/maximize—扫描可编辑文件和 README,查找指标名称
<run_cmd> / <entrypoint>端到端运行单次实验的命令—pyproject.toml / .venv / README
<editable_files>可编辑的文件(评估框架除外)—模型 / 配置 / 训练脚本;排除数据、日志、环境、框架
<sandbox_root>存放快照和记录表的位置./sandbox可编辑文件所在目录附近
<iter_strategy>snapshots 或 branchessnapshots工作目录是否为干净的 git 仓库?
<gate> / <budget>time(分钟)或 epochs,以及限制—配置中的现有时间 / epoch 设置
<literature>on = 以文献为依据;off = 仅分析off用户是否希望参考论文?
<research_scale> (仅限 on)深度选项 low/medium/high/x-highmedium参见 roles/research-subagent.md
<domain> (仅限 on)用一个短语描述问题领域;仅用于构造查询措辞,绝不用于筛选—根据数据 / 模型 / 任务推断
<lit_skill_dir> (仅限 on)literature-search 技能的安装目录此循环所在目录的同级目录~/.claude/skills/literature-search/(根据宿主调整)
<lit_py> (仅限 on)用于文献辅助脚本的 Python ≥3.9 解释器(仅使用标准库)python3与 <run_cmd> 相互独立

文件编辑防护:在任何时候(设置或循环期间)接触任何文件之前,先确认该文件属于 <editable_files>;因为其他所有内容都是只读的基础事实(评估框架定义了 <metric>)。无一例外。

文献工具链(仅当 <literature> = on 时)

论文搜索通过同级的 literature-search 技能进行(仅使用标准库,无需安装): <lit> = <lit_skill_dir>/tools/lit_search.py(注意包含 tools/)。在子命令后追加 --cache-dir <sandbox_root>/literature/.cache,以复用同一缓存。子命令会输出 JSON; 失败时会输出 {"error","fallback"} 并以非零状态码退出——此时降级使用主机的 WebSearch/WebFetch(绝不捏造引文)。设置时对 <lit> --help 进行冒烟测试;如果缺少此技能,请告知用户并提出安装选项(cp -r <repo>/loops/literature-search ~/.claude/skills/),或在降级模式下继续。对于入门配置和 API 密钥(均为可选;建议使用免费的 S2_API_KEY),运行 <lit> keys --init——它会管理项目根目录下共享且被 git 忽略的 keys.env,并以布尔值报告密钥是否存在(密钥绝不会进入聊天)。将当前启用的层级持久化到 loop.run.yaml。

初始化沙盒

创建目录结构(仅当 <literature> = on 时才额外创建 literature/ 目录树),并写入账本表头:

<sandbox_root>/
├── loop.run.yaml       ← resolved bindings (written now)
├── results.tsv         ← experiment ledger, header only (written now)
├── literature/         ← (on only)
│   ├── corpus.tsv      ← findings ledger, header only (written now)
│   ├── .cache/         ← lit_search on-disk cache
│   ├── pdfs/           ← fallback PDF reads
│   └── text/           ← extracted LaTeX section text
└── iter1/              ← created at loop start

results.tsv 表头(制表符分隔;仅当 <literature> = on 时才包含 literature_basis 列):

iter	<metric>	status	analysis_summary	[literature_basis	]description

循环(无限循环——直到中断)

第 1 次迭代始终是未经修改的基线:跳过变更规划和调研(目前还没有可用于指导变更的诊断结果),但仍要编写基线 plan.md 并运行强制分析——它会生成第一个实证锚点,作为第 2 次迭代的依据。<editable_files> 中的所有内容都可以修改(架构、优化器、超参数、数据流水线、损失函数);唯一的限制是代码能够正常运行且在 <budget> 内完成。简洁性标准:其他条件相同时,越简单越好——增加 20 行杂乱代码只换来 0.001 的提升,不值得;通过删除代码获得 0.001 的提升(或指标持平),则应当 keep。

每次迭代都复制这份清单,并勾选已完成的项目:

  • 1. 查看状态。 分支模式:git log --oneline -5。快照模式:确认 iter<N>/ 不存在。阅读第 N-1 次迭代的分析摘要;(如果有)略读 corpus.tsv,查找尚未实现的保留项。
  • 2. 规划一项变更(第 1 次迭代:跳过——运行未经修改的基线)。以第 N-1 次迭代的分析为依据。参见下文的规划变更;(如果有)此步骤还会运行文献调研。
  • 3a. 创建快照/提交,然后应用这一项变更。 快照模式:创建 iter<N>/{code_snapshot,analysis,results}/,将每个 <editable_files> 复制到 code_snapshot/,将 loop.run.yaml 复制到 iter<N>/,然后应用变更。分支模式:应用变更,然后运行 git commit -am "<desc>"。实现已发表的技术/库中的技术时,应以真实、当前的示例或仓库中的实际库为依据(先阅读);切勿凭记忆编写 API。
  • 3b. 在运行前编写分析计划,并添加所需的任何检测代码。参见下文的分析计划。
  • 4. 运行实验,将所有输出重定向到文件(绝不要使用 tee):<entrypoint> > <sandbox_root>/iter<N>/<run_log> 2>&1(或者在受时间限制时使用 run_with_timeout.sh)。如果超时,终止进程并将其视为崩溃。
  • 5. 读取指标:grep '^<metric>:' <sandbox_root>/iter<N>/<run_log>。如果结果为空,运行 tail -n 50 <run_log>,阅读追踪信息,并尝试一次简单修复(拼写错误/导入错误);如果问题根本无法修复,记录为 crash 并继续。
  • 6. 分析结果——这是强制步骤,会生成实际的文件产物。参见下文的分析。
  • 7. 记录到台账(不跟踪——绝不要提交)。参见台账。
  • 8. 保留或还原(本次迭代运行的变更)。若 <metric_direction> 所示方向有所改善 → keep,并更新当前最佳结果。持平/变差/崩溃 → discard/crash;分支模式运行 git reset --hard HEAD~1,快照模式从 iter<N>/code_snapshot/ 恢复 <editable_files>。记录 discard 前先应用简洁性标准。发生崩溃/OOM 时,使用保留原意的最小变更进行修复(OOM → 减小批次大小,并通过梯度累积保持有效批次大小)——绝不要把实验改成计划中未要求的内容。
  • 9. 转到第 1 步——第 6 步的分析是下一个假设的主要依据。
规划变更(第 2 步——第 2 次及后续迭代)

最新分析确定了方向;它是每次迭代的主要依据。请明确只选择一个改进杠杆,并以第 N-1 次迭代的分析为依据。其他经过验证的想法应排入队列,不要捆绑到同一次运行中。

实施前,请明确说明:

  • 这一项变更,以及它涉及哪些 <editable_files>;
  • 实证依据——第 N-1 次迭代 results/ 中能支持此变更的具体文件和数值/模式。除简化以外的每项变更都必须引用实证依据;仅有理论推理并不足够。架构转向也必须有依据(例如,遇到上限/结构性问题的发现:“该类别在 X 处达到瓶颈,仍有提升空间”,或“恰好在需要 Y 的案例上失败”),而不能只基于局部问题。
  • 预测会发生什么,以及这一发现为何支持该预测。

**当 <literature> = off 时:**该实证依据就是全部依据——直接根据分析选择变更。编写计划前,请扫描先前的分析(ls <sandbox_root>/iter*/analysis/*.py),避免重复诊断;若有对比理由,则不在此限。

**当 <literature> = on 时:**确定实证依据后,还需以文献研究为变更提供依据——

  • 2a. 先处理方向漂移,再将积压项作为缓存查阅。如果上一次保留的变更改变了架构类别(例如,CNN→transformer),请将所有尚未实施、且 scope 为不匹配架构标签的保留项设为 result=stale;scope=agnostic 的保留项(调度、权重衰减、数据增强、初始化理念)仍可保留。然后检查 corpus.tsv,寻找以分析方向为目标且尚未实施的 keep 项——仅当它根据当前架构通过了门槛(2c)的重新验证时,才可复用;不再适用的发现应作废,而不是强行套用。
  • 2b. 研究该方向(除非 2a 已找到仍有效的改进杠杆,否则这是默认做法)。将分析中的局限转化为问题(明确将局限与问题对应起来),记录在 iter<N>/questions.md 中,然后按 roles/research-subagent.md 的说明派遣研究子 Agent(生成或降级:在 Claude Code 中启动真正隔离的子 Agent,否则就在当前上下文中直接开展研究),并遵循拨盘设定的深度/投入度(<research_scale> 见该文件的拨盘表)。 第 1 级 = 高层研究(架构适配性、以往方法、文献是否显示有效);先进行第 1 级研究——若由此发现有说服力的新方向,则将其作为改进杠杆。第 2 级 = 具体微优化(初始化、权重衰减动态、针对序列长度的注意力/缓存、归一化位置、调度)。**防止陷入固定套路:**某项保留项若约 3 次迭代都未被采用,或已不属于任何当前方向,就应作废(result=stale),避免它再次出现。
  • 2c. 证据门槛(重新验证;需参考历史记录)。只有同时满足以下所有条件,才可保留/复用某项发现:evidence.strength 为 moderate/strong(而非 weak);applicability_to_our_setup 适用于当前数据/模型/预算;每个 files_to_edit 都在 <editable_files> 范围内,且符合 <budget>;并且它与 corpus.tsv 中已记录为 no-effect/hurt/crashed 的变更没有实质相同之处(除非该发现说明了为何当前情况有所不同)。为每项保留的发现标注 scope(agnostic 或当前架构标签),以便通过机制处理方向漂移。将每项发现(无论保留还是拒绝)都记录在 corpus.tsv 中;已保留但未选中的发现应留在队列中(implemented=n、result=pending)。
  • 2d. 选择单一改进杠杆:从保留项(积压项和新发现)中选择证据强度 × 适用性 × 单位复杂度收益最高的一项。除上述明确说明外,还要补充文献依据(保留的发现及引用),若是纯粹由分析驱动的简化/消融,则写 none;并补充验证待办事项(从该发现的 how_to_verify 中选择用于判断是否有效的指标/日志/分析)。文献依据是补充性依据,绝不能取代实证依据。
分析计划(步骤 3b——运行前编写)

将 <sandbox_root>/iter<N>/analysis/plan.md 写成交付物表格,而不是散文——每一行都是一项明确承诺:你将编写并运行的脚本、该脚本生成的确切输出文件、它要回答的问题,以及每种结果会是什么样:

脚本输出文件要回答的问题如果改动有效,预期结果如果无效,预期结果

计划必须至少包含一个此前任何迭代都未测量过的诊断维度(历史扫描会对此进行检查);“如果无效,预期结果”这一列为必填项(它会迫使你在看到结果之前定义证伪条件)。当 <literature> = on 时,还要包含第 2d 步中的 verify-todo,并定期(以及每当考虑大幅调整时)进行一次上限/提升空间探测——当前架构是否接近极限?(训练/验证平台期、表征崩塌、结构性失效)。

仪表化(需要时必须执行)。 如果计划中的测量需要当前尚未生成的指标/日志(例如逐层梯度范数、逐类别准确率,或同时记录 val_loss 和 val_acc),且生成该数据的脚本位于 <editable_files> 中,现在、运行前就添加日志记录。 先写计划正是为了强制做到这一点——不要等到分析时才发现所需数值没有记录。

分析(步骤 6——必须执行;生成实际产物)

这是整个循环的核心。在 plan.md 中每一行都在 iter<N>/results/ 下对应一个非空文件之前,不要进入步骤 7。 没有写入文件的分析就等于没有进行。

  • 6a. 执行计划。 对每一行,在 iter<N>/analysis/ 中编写脚本并运行,将输出重定向到 iter<N>/results/。可选诊断维度(根据假设和结果选择,而非固定轮换):梯度范数/流动、激活统计/饱和度、嵌入(PCA/CKA/崩塌)、错误与混淆分析、损失动态与提升空间、权重/参数统计、数据分析(审查数据本身是收益最高的诊断之一)、计算资源分析。
  • 6b. 检查清单。 对照 plan.md 检查 ls iter<N>/results/;现在编写并运行所有缺失的交付物。
  • 6c. 根据计划解读。 对每一行,结果符合“如果有效,预期结果”还是“如果无效,预期结果”?不匹配也是信息,而非失败。
  • 6d. (启用时)检查第 2d 步中的 verify-todo——改动是否达到了文献所预测的效果?这将决定步骤 7 中该发现的 result。
  • 6e. 机会式跟进。 如果出现意外情况(异常的损失曲线、某个类别持续预测错误、某层表现异常),再编写一个脚本追查——最有新意的发现往往来自这里。

编写一份简洁的分析摘要(3–8 条要点):检查了什么、最重要的一项发现(无论是否符合预期)、(启用时)架构是否接近上限,以及促使下一份计划制定的具体实证依据(文件 + 数值/模式)。

实证依据门槛。 进入步骤 7 之前,你必须能够用真实文件引用和具体数值/模式补全以下句子——不能只给出理论论证:

“下一步将进行 X 改动,因为分析显示 Y(来自 results/<file>,数值/模式为 Z)。”

如果做不到,就返回 6a,继续运行分析,直到能够给出为止。缺少实证依据就继续推进,正是这个循环要防止的失误。

面向后续的仪表化。 分析后,问自己:“我希望当时记录了哪些内容?”——如果生成相关数据的脚本位于 <editable_files> 中,现在就添加相应记录(最佳 epoch 检查点、额外的逐 epoch 诊断),以便后续分析更有价值。单独一次仪表化改进也可以作为一轮迭代。

Ledger

<sandbox_root>/results.tsv,使用制表符分隔,自由文本中不得包含逗号。仅当 <literature> = on 时,才会有 literature_basis 列。状态 ∈ {keep, discard, crash};发生崩溃时,指标使用 0.000000。对于 branches,第一列是 7 位字符的提交标识,而不是迭代编号。

iter	<metric>	status	analysis_summary	literature_basis	description
1	0.6320	keep	grad norms clean; no pathologies	none (baseline)	baseline
2	0.7050	keep	overfit on small data per val/train gap	Dosovitskiy 2020 ViT — aug+warmup	add RandAug + 3-ep warmup
3	0.7010	discard	warmup ok but LR too high; unstable	Loshchilov 2017 — decoupled wd	switch to AdamW wd=0.05

<sandbox_root>/literature/corpus.tsv(仅当 <literature> = on 时;使用制表符分隔):经审核的研究发现积压列表,可在多轮迭代中复用,而不必重新研究。编排器(而非子 Agent)负责写入该文件并执行最终证据门槛检查,以确保不同问题的判定一致。

iter	level	paper_id	title	scope	relevance	verdict	implemented	result
2	649def…	1	An Image is Worth 16x16 Words	vit	high	keep	y	helped
3	a1c2…	2	Decoupled Weight Decay Regularization	agnostic	high	keep	y	no-effect
4	7d9e…	1	ConvNeXt blocks	cnn	low	keep	n	stale

列:level ∈ {1,2};scope = agnostic 或架构标签(用于决定是否因架构漂移而退役);relevance ∈ {high,med,low};verdict ∈ {keep,reject};implemented ∈ {y,n};result ∈ {helped,no-effect,hurt,pending,stale}(stale = 因漂移/过期而退役)。最后一行:CNN 的一项保留发现,在架构迁移至 ViT 后退役;agnostic 的权重衰减发现则不受漂移影响,仍然有效。

总结进展时,报告最佳迭代(不一定是最后一次)。不要将 results.tsv 或 literature/ 提交到 git —— 保持未跟踪状态。

约束

  • 只能编辑 <editable_files> 中的文件——每次编辑前都要确认,因为其他所有内容都是只读的事实依据,且评估框架定义了 <metric>。
  • 每轮迭代只做一项更改,这样每个指标变化都能归因于单一因素。
  • 每轮迭代都必须进行分析,并在 results/ 中生成实际文件(plan.md 中的每一行都必须对应一个非空输出文件)。没有分析支撑的更改不允许——这会使迭代变成盲目尝试(启用时则会变成盲目遵循方案,最终停滞)。
  • 所有非简化类更改都必须引用该分析中的实证依据(文件 + 数值/模式);启用时,文献依据只能作为补充,不能替代实证依据。两者都要记录在 results.tsv 中。
  • 不要安装项目尚未提供的软件包或添加依赖;辅助脚本(包括文献辅助工具)必须仅使用标准库。
  • 始终将训练输出重定向到 <run_log>;不要使用 tee。沙箱是独立的——不得通过 ../ 越界。
  • (启用时)绝不要打印或提交 API 密钥——keys 只报告密钥是否存在;keys.env 位于项目根目录,必须保持在 gitignore 中。如果文献工具返回 {"error","fallback"},请改用 WebSearch/WebFetch;绝不要捏造引用——每篇引用的论文都必须来自真实的工具结果。

停止条件

此循环会无限运行,直到人类中断——不要暂停并询问“要继续吗?”或“现在停下来是否合适?”。人类可能不在场,并期望任务无限期自主运行。取得可用结果,就意味着开始下一轮迭代,而不是结束。如果想不出新思路:重新阅读范围内的文件,寻找遗漏的切入点;深入分析(梯度/激活/嵌入/错误总能揭示问题);结合 results.tsv 中先前接近成功的尝试;尝试更激进的更改——启用时,回到文献中继续探索:深入追踪引用关系图,阅读近期引用你所用方法的研究之方法论,从 corpus.tsv 中挖掘排队待用的保留发现,并组合不同论文中的方案。

评论

支持 Markdown