关于 alpha-evolve
alpha-evolve 是面向可编辑模型或程序代码的种群式进化搜索技能。它并行评估多个变体,并通过跨岛屿的 MAP-Elites 存档保留高性能且多样化的候选项。
主要功能
- 01种群式程序搜索
- 02SEARCH/REPLACE 差异修改
- 03级联式评估运行
- 04跨岛屿 MAP-Elites 存档
- 05跟踪复杂度与多样性
- 06岛屿迁移与检查点
适用场景
- 01并行探索多种模型代码变体
- 02保留多样的高性能候选项
- 03在固定训练运行预算内搜索
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gaasher/ agent-loop-skills --skill alpha-evolve安装后在 Claude Code 中输入/alpha-evolve确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/run.example.yamlroles/Mutator.mdschemas/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。