mcpField
A
alpha-evolve

alpha-evolve

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

关于 alpha-evolve

alpha-evolve 是面向可编辑模型或程序代码的种群式进化搜索技能。它并行评估多个变体,并通过跨岛屿的 MAP-Elites 存档保留高性能且多样化的候选项。

主要功能

  1. 01种群式程序搜索
  2. 02SEARCH/REPLACE 差异修改
  3. 03级联式评估运行
  4. 04跨岛屿 MAP-Elites 存档
  5. 05跟踪复杂度与多样性
  6. 06岛屿迁移与检查点

适用场景

  1. 01并行探索多种模型代码变体
  2. 02保留多样的高性能候选项
  3. 03在固定训练运行预算内搜索

安装

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

$npx skills add https://github.com/gaasher/agent-loop-skills --skill alpha-evolve

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

包含的文件

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

examples/
run.example.yaml
roles/
Mutator.md
schemas/
result.schema.json

详细介绍

Alpha-Evolve

参考资料(如需了解算法细节,请阅读):AlphaEvolve — https://arxiv.org/abs/2506.13131 · OpenEvolve(开源实现)— https://github.com/algorithmicsuperintelligence/openevolve

围绕一个程序运行的基于种群的进化循环。可编辑的模型代码是产物;子代是针对一个父代的、经过分析后提出的一个 SEARCH/REPLACE 差异;反馈信号则是级联评估的训练运行(<metric>,从 smoke 到 full)。子代会被放入跨岛屿的 MAP-Elites 存档(复杂度 × 多样性轴),因此子代凭借更优或更新颖即可留存,而不必只靠性能更优。该机制确保:多样性得到保留,而非坍缩——表现优异且各具多样性的个体可以共存,而不是由某个局部最优一枝独秀。你负责控制流程:抽样选择父代和灵感来源,启动并行 Mutator 来提出和评估子代,将其放入存档,在岛屿间迁移,并创建检查点。循环运行至计算预算耗尽或被中断。

适用场景

适用于针对模型或程序开展并行且保留多样性的搜索:多个变体同时探索,存档则持续记录已发现的前沿。默认应广泛覆盖各岛屿;如果质量提升停滞,就偏向利用顶尖精英;如果覆盖范围停滞,就偏向选择空单元。不适用于顺序式 autoresearch 循环(一次只做一项更改),也不适用于修复已知异常。

(此文件夹中的)参与角色:roles/Mutator.md 负责生成并级联评估一个子代(即生成步骤);schemas/result.schema.json 是 Mutator 返回的结果。

设置

交互式解析绑定项。如果工作目录中存在 loop.run.yaml,则加载该文件,用一行确认各项值,然后跳转到循环。否则:在 Claude Code 上(AskUserQuestion 工具可用,<host> = claude-code),推断每个绑定项的可能值,并将其作为推荐选项;在其他宿主上(<host> = other),针对每项以引用的纯文本提示提问。然后写入 loop.run.yaml(格式:examples/run.example.yaml),并在创建任何其他文件之前确认各项值。<host> 还决定执行方式:Claude Code 并行启动真正的 Agent Mutator(上限为 <concurrency>);其他宿主则降级为按顺序运行一代中的子项(算法相同)。

先探测设备(必须——测量,不要假设 <concurrency>)。 记录并报告:

  • CPU 核心数 → <cores>:python3 -c "import os; print(os.cpu_count())"。
  • RAM → <ram_gb>:macOS 上使用 sysctl -n hw.memsize;Linux 上使用 grep MemTotal /proc/meminfo。
  • 加速器 → <accelerator>/<vram>/<gpu_count>:NVIDIA 使用 nvidia-smi --query-gpu=name,memory.total,count --format=csv;否则检查 macOS Apple GPU/MPS;再否则仅使用 CPU。
绑定项含义默认值推断方式
<metric> + <metric_direction>要优化的标量;最小化/最大化—询问;扫描评估输出,查找报告的指标
<run_cmd> / <entrypoint>单次训练运行的命令(评估器)—检查 pyproject.toml/.venv/uv/README
<editable_files>要演进的程序(例如 model.py、config.yaml);绝不能是测试框架或数据—明确询问——这是会被变异的代码;不要设为默认值(Claude Code 上使用多选)
<sandbox_root>创建 lae/ 的位置./sandbox—
<gate> + <budget>一次完整运行的规模:time/epochs + 数量;应用于每个程序的固定评估预算—现在确定时长键(例如 train.epochs),以便控制器覆盖它
<total_budget>总计算量 = 完整训练运行的次数(或墙钟时间分钟数);唯一的成本调节项—询问
<concurrency>并行评估数 C根据探测结果得出仅 CPU → max(1, <cores>//4);单 GPU/MPS → 1(询问 <vram> 是否足以容纳更多);多 GPU → <gpu_count>(将每个子项绑定到一块 GPU)

num_generations 为推导值:ceil(<total_budget> / <concurrency>)。级联参数根据 <budget> 推导(不询问):smoke = 约 1 个 epoch / 小规模子集,full = <budget>,gate = 子项的 smoke <metric> ≥ 父项的 smoke。<budget>/<metric>/评估拆分均为固定值——绝不能作为变异目标(子项不能为了看起来更好而“训练更久”);更改这些值意味着要重新运行整个循环。

高级选项(自选)。 提出一个是/否问题:“使用进化设置的默认值,还是自定义?”默认值遵循 AlphaEvolve/OpenEvolve——使用默认值,不再询问其他内容。只有在用户选择“自定义”时,才逐项询问以下设置(并显示推荐的默认值):num_islands(4)、num_top(3)、num_diverse(2)、num_bins(10)、migration_interval(5)、diversity_reference_size(10)、pop_per_island(40)、seed(42)。固定坐标轴:复杂度 × 多样性。结构示例见 examples/run.example.yaml。

输出解析后的绑定项、探测结果和推导出的 num_generations,并且在用户确认之前,不得创建文件或启动运行。确认后初始化沙盒(仅写入表头行;在评估子项时创建 programs/):

<sandbox_root>/lae/
├── archive.tsv     ← current elites = program database + checkpoint
├── history.tsv     ← append-only record of every child
├── leaderboard.md  ← rendered UI
└── programs/       ← one self-contained dir per program

控制器(循环)

你负责维护 archive.tsv 中的 num_islands 个 MAP-Elites 映射、只追加的 history.tsv、各坐标轴的运行中百分位统计,以及 leaderboard.md。所有共享日志均只能由你写入——Mutator 只返回结果,因此不会发生写入竞争。复制此检查清单并逐项勾选:

  • 完成设置:已记录探测结果、确认绑定、初始化沙箱,并推导出 num_generations。
  • GEN 0 — 在每个岛中创建基线程序(复制 <editable_files>),并可选择创建一些随机变体;进行级联评估;放入档案。
  • 每一代:恰好构建 <concurrency> 个任务(按轮询方式分配岛、使用按种子规则选出的父代、选取排名靠前的 num_top 个灵感来源和差异最大的 num_diverse 个灵感来源);通过复制父代程序和测试框架来创建每个子代目录。
  • 运行 C 个变异器(生成或降级),为每个变异器提供 roles/Mutator.md、父代代码、灵感来源、父代产物、子代目录,以及冒烟测试和完整测试的预算。
  • 对每个返回的子代:追加一行 history.tsv 记录;如果已完成评估,则计算其生态位 → 单元,并仅在 <metric> 更优时将其放入岛屿地图(kept=y);记录 smoke_dropped/crash,但不放入地图。
  • 重新生成 leaderboard.md;保存检查点(archive.tsv 即为检查点);打印状态行。
  • 每隔 migration_interval 代:将排名靠前的精英从岛 k 环形迁移至岛 k+1。
  • 达到 <total_budget> 时停止(为合成留出少量预算),然后合成最终报告。

生态位计算(由你根据子代沙箱完成):

  • complexity = 可训练参数数量(备用方案:可编辑文件中代码行总数 + 子代新增的任何文件中的代码行数),按 log10 缩放。
  • diversity = 程序拼接代码(可编辑文件 + 新增文件)与其所在岛随机抽取的 diversity_reference_size 个程序之间的平均归一化编辑距离(岛中程序很少时,则与基线比较)。值越高 = 越新颖。
  • 使用滚动第 5/95 百分位数对每个轴进行归一化(而非原始最小值/最大值,避免单个离群值压缩整个范围):scaled = clamp01((v − p5)/(p95 − p5));bin = min(num_bins−1, int(scaled × num_bins));cell = (complexity_bin, diversity_bin)。当百分位数变化足以使边界移动时,重新分箱现有精英(发生冲突时保留 <metric> 更高者;档案规模较小)。

变异器的提示词(采样器): 父代代码 + 灵感来源 + 父代渲染产物(<metric>、各类别准确率、损失曲线、stderr)+ 要求返回一个 SEARCH/REPLACE 差异的指令。仅使用一个测试框架模型,不使用 LLM 集成。变异器在子代目录中应用其差异,在固定的 <budget> 下进行级联评估(控制器会在运行命令中注入/限制时长键),并返回一个根据 schemas/result.schema.json 验证的结果:

{"child_id": "g3-i1-a2", "parent_id": "g1-i1-a0", "approach_summary": "add BatchNorm after conv2",
 "sandbox_path": "<sandbox_root>/lae/programs/g3-i1-a2", "status": "evaluated",
 "smoke_metric": 0.61, "metric": 0.71}

status ∈ {evaluated, smoke_dropped, crash};除非状态为 evaluated,否则 metric 为 null。变异器不计算档案相关的任何内容——控制器会根据沙箱推导出每个生态位。

程序沙箱。 并行种群无法映射到分支,因此每个程序都必须是一个独立、可完整运行的目录 <sandbox_root>/lae/programs/<child_id>/;档案通过 id 引用该目录。通过复制真实文件来构建每个子代目录(父代的 <editable_files>,然后应用差异,再加上其导入的测试框架/入口点代码),并从该目录内部进行评估(cd <child_dir> && <entrypoint>)。只对大型只读数据使用符号链接,绝不要链接入口点或任何导入的 .py 文件:Python 会将符号链接脚本的 __file__ 解析为链接目标,因此 sys.path[0] 会指向原始目录,子代的 model.py/dataset.py 就会被基线版本悄悄覆盖——所有架构/数据变异都会变成无效操作(典型迹象:不同“架构”的损失曲线完全相同)。**隔离健全性检查:**测试框架会记录参数数量/代码指纹;如果某个子代的代码发生变化,但其指标/损失曲线与父代相同,则将其标记为异常(文件被覆盖),并在放入档案前修复沙箱。绝不修改仓库工作树。

最终合成。 报告全局最佳程序及其 lae/programs/<id>/ 路径、已照亮的复杂度×多样性地图(覆盖范围 + 各区域的胜出者)、每个岛的最佳程序,以及 2–3 个特别多样的候补程序。

台账

所有三个日志都位于 <sandbox_root>/lae/ 下,使用制表符分隔,自由文本中绝不使用逗号。 控制器是唯一写入者;如果中断,请根据 archive.tsv + history.tsv 恢复。

archive.tsv — 当前精英 + 检查点。表头 island cell metric child_id parent_id sandbox_path complexity diversity:

island	cell	metric	child_id	parent_id	sandbox_path	complexity	diversity
0	(2,7)	0.7100	g4-i0-a1	g2-i0-a3	lae/programs/g4-i0-a1	2.1M	0.71

history.tsv — 每个子代的记录,只追加不修改。表头 gen island parent_id child_id smoke_metric full_metric status kept cell:

gen	island	parent_id	child_id	smoke_metric	full_metric	status	kept	cell
4	0	g2-i0-a3	g4-i0-a1	0.61	0.71	evaluated	y	(2,7)
4	1	g2-i1-a0	g4-i1-a2	0.40	-	smoke_dropped	n	-

leaderboard.md — 每代重新生成:全局最佳项 + 各岛覆盖情况 + 按 <metric> 排名的档案。停止时报告最佳程序(而非最后一个)、档案覆盖情况,以及几项具有多样性的备选项。让 lae/ 保持未跟踪状态。

约束

  • 子代只能在自己的 lae/programs/<child_id>/ 目录中工作——可以编辑复制来的 <editable_files> 并在该目录中创建新文件,但绝不能修改该目录以外的任何文件(仓库、只读测试框架、数据及其他程序目录都是真实依据或共享状态)。
  • 控制器是 archive.tsv/history.tsv/leaderboard.md 的唯一写入者,因此并行的 Mutator 不会争抢日志写入。
  • <concurrency> 由探测结果和用户确认决定——绝不猜测机器的能力;多 GPU 时每个 GPU 固定运行一个子代;如果运行出现 OOM 或争用加剧,就降低 C 并说明原因(不要改写子代配置来适配),因为机器的限制是真实存在的,改写子代会破坏比较结果。
  • <budget>(轮数/时间)、<metric> 和评估/测试集划分均为固定值,不得更改。 控制器会在每次运行时注入 <budget>,覆盖子代设置的任何时长,因此“训练更久”、更改指标或更改测试集都不可能胜出。应改进模型/优化器/数据流水线,而不是计算量或评分方式;程序之间的可比性取决于此。
  • 绝不要将入口文件或任何导入的 .py 符号链接到子代目录(它会通过 sys.path[0] 遮蔽子代代码);复制测试框架代码,只对数据使用符号链接,并在放置子代前运行隔离健全性检查——代码被遮蔽时得到的结果只是幻象。
  • 不要安装新软件包或修改评估测试框架——<metric> 是真实依据。
  • 不要停下来询问“要继续吗?” 一直运行到 <total_budget>(为综合归纳预留少量预算)或收到中断;如果覆盖范围停滞,就优先填补空单元;如果质量停滞,就利用顶尖精英。超出运行门限的子代会被终止并记录为 crash。

评论

支持 Markdown