关于 optimize-loop
optimize-loop 是用于优化代码或 SQL 的 Skill,在保持行为和结果不变的前提下改进度量指标。它结合正确性门槛与优化指标,只保留通过门槛且指标改善的改动。
主要功能
- 01可配置正确性门槛与指标
- 02代码重构和 SQL 调优模式
- 03每轮只进行一项改动
- 04快照、回滚与记录追踪
- 05达到平台期或迭代上限时停止
适用场景
- 01在测试持续通过的前提下降低代码复杂度
- 02在结果集不变时缩短 SQL 查询耗时
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gaasher/ agent-loop-skills --skill optimize-loop安装后在 Claude Code 中输入/optimize-loop确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/refactor.run.yamlsql.run.yamltools/bench.pymetrics.py详细介绍
优化循环
一个评估器—优化器循环,配有可插拔的正确性门槛 + 待最小化指标。处理对象是某种可编辑内容(代码模块或 SQL 查询);反馈信号分为两部分:必须通过的绑定门槛(行为/结果保持不变)和必须降低的绑定指标(要最小化的成本)。每次进行一项更改,检查门槛、测量指标;只有门槛通过且指标改善时才保留更改,否则就还原。重复此过程,直到指标不再改善或预算耗尽。循环启动后,不要暂停等待许可。
tools/ 中附带两种现成绑定(均为 vendored,仅使用标准库):
- 代码模式 — 门槛:
<gate_cmd>(测试套件)以 0 退出;指标:tools/metrics.py输出complexity(主要指标)、max_nesting、loc(按字典序作为次级比较项)。数值越低越好。 - sql 模式 — 门槛:
tools/bench.py的结果集hash与基线匹配;指标:同一工具输出的median_ms。数值越低越好。
两种模式下,门槛都不可妥协:未通过门槛的更改属于回归,而非改进。绝不要编辑作为真实性依据的内容(代码模式下的测试/tools/metrics.py,sql 模式下的数据库/tools/bench.py)——修改用于衡量你的依据来改变数值,会破坏这个循环。
适用场景
适用于有明确正确性边界需要保持、同时有数值需要最小化的情况:重构通过测试套件的代码(降低复杂度),或调优结果集固定的 SQL 查询(降低延迟)。默认使用匹配的随附工具;也可绑定任意通过时以 0 退出的 <gate_cmd>,以及输出单个待最小化数值的 <metric_cmd>(例如,代码检查工具的问题计数,或非 SQLite 引擎的耗时 + 结果指纹)。不适用于添加功能或修复错误——这些操作意在改变行为,而此循环的设计目的正是禁止改变行为。
设置
以交互方式解析绑定项。 如果工作目录中存在 loop.run.yaml,则加载该文件,用一行确认各项值,然后直接进入循环。否则先选择 <mode>(它决定门槛和指标),然后在 Claude Code 中(可使用 AskUserQuestion 工具)推断每个绑定项的可能值,并将其作为推荐选项展示;在其他宿主环境中,逐项以引用格式的纯文本提示询问。随后写入 loop.run.yaml,并在创建任何其他文件前确认各项值。
<gate_cmd> 和 <metric_cmd> 是可插拔的核心:根据表格按 <mode> 进行绑定。在 sql 模式下,一个基准测试命令同时提供两者——其 hash 是门槛,其 median_ms 是指标。
| 绑定项 | 含义 | 默认值 | 推断方式 |
|---|---|---|---|
<mode> | code(测试中的重构)或 sql(结果固定的查询) | — | 处理对象的类型 |
<editable_files> | 循环可修改的文件 | — | code:源文件(不包括测试/配置/工具);sql:查询文件(可选索引文件) |
<gate_cmd> | 必须通过的绑定门槛,否则还原 | — | code:测试命令(通过时以 0 退出);sql:隐式——候选项的 hash 必须与基准测试命令生成的基线 hash 一致 |
<metric_cmd> | 输出待最小化数值的绑定指标 | — | code:python3 <skill_dir>/tools/metrics.py <editable_files>(→ complexity,其次为 max_nesting、loc);sql:python3 <skill_dir>/tools/bench.py --db <db> --query <query_file> --setup <indexes_file> --repeat 5(→ median_ms、hash) |
<sandbox_root> | 快照和日志存放的位置 | ./sandbox | — |
<budget> | 最大迭代次数(硬性上限) | 8 | — |
<patience> | 连续 N 次迭代未改善后停止 | 3 | — |
<skill_dir> 是此技能的安装目录;写入 loop.run.yaml 时,请替换为实际路径。
对于非默认引擎/语言,请绑定任何符合上述约定的 <gate_cmd>/<metric_cmd>。
两个配置示例:examples/refactor.run.yaml(code)和 examples/sql.run.yaml(sql)。
循环(直到进入平台期或达到 <budget>)
复制此检查清单并逐项勾选:
- 第 0 次迭代 — 基线:运行
<gate_cmd>(代码)——如果未通过,停止(循环需要通过的门禁来保护行为)。运行<metric_cmd>;将该指标记录为当前最佳值,在 sql 模式下,将基线hash记录为正确性参照。记录基线行。 - 将
<editable_files>中的每个文件快照到<sandbox_root>/iter<N>/,以便迭代可以回滚。 - 应用一项有针对性的更改(参见下方各模式的思路)——每次迭代只尝试一个想法,以便将每次指标变化归因于该想法。
- 检查门禁:代码模式——运行
<gate_cmd>;sql 模式——从<metric_cmd>读取候选项的hash。 - 如果门禁失败(测试返回非零 /
hash≠ 基线 / 工具出错),丢弃:从快照恢复,记录原因,然后继续。 - 测量指标并与最佳值比较:代码模式——按字典序比较三元组
(complexity, max_nesting, loc)(先比较 complexity;只有相同时才比较max_nesting,然后比较loc);sql 模式——比较median_ms,只有优势明显超过计时噪声时才保留(默认相对优势 ≥ 3%)。 - 如果指标严格优于最佳值,则保留(更新最佳值,文件保持原样);否则丢弃(从快照恢复)。
- 追加一行记录;在进入平台期(
<patience>)或达到<budget>时停止。
更改思路 — 代码模式: 将嵌套的 if/else 展平为守卫子句,用标准库调用(sum、min、max、statistics.*)替换手写循环,合并重复分支,删除无用代码。保持公开行为不变——名称、签名、返回形态、引发的异常;测试套件就是契约。
更改思路 — sql 模式: 在 <indexes_file> 中添加索引,涵盖用于筛选、联接或分组的列;重写查询(将相关子查询改为 JOIN + GROUP BY,提取重复计算,将 SELECT * 替换为所需列,将筛选条件提前,删除多余的 DISTINCT/排序)。hash 是对行的多重集计算的,因此无法捕捉行顺序的变化——如果 ORDER BY 属于契约的一部分,请仔细检查重写是否保留了顺序。
字典序保留示例(代码模式),当前最佳值 (18, 3, 64): (15, 3, 45) 保留(complexity 更低);(18, 2, 70) 保留(complexity 相同,嵌套更少);(18, 3, 61) 保留(相同,行数更少);(18, 3, 64) 丢弃(没有进展);(19, 1, 20) 丢弃(complexity 更高,不能由更简单的嵌套/loc 抵消)。
平台期计数: 每次未创下新最佳值的迭代都要增加无改进计数器——包括门禁失败、改动出错或指标提升不足而被丢弃的情况;每次保留时将其重置为 0。连续 <patience> 次迭代没有进展则结束运行;<budget> 是硬性上限。停止时,将工作文件恢复到最佳迭代的状态(如果最新一次是丢弃的结果),并报告:基线与最佳指标(sql 模式下还需报告加速倍数)、指标变化轨迹,以及胜出的更改集。如果在达到预算前就快想不出新思路,请深入挖掘,而不是提前停止。
记录表
<sandbox_root>/ledger.tsv,以制表符分隔,描述中不能使用逗号。status ∈
{keep、discard、baseline}。使用当前 <mode> 对应的列。
代码模式表头 iter complexity max_nesting loc status description:
iter complexity max_nesting loc status description
0 23 7 86 baseline unmodified module
1 19 5 78 keep flatten summarize guard clauses
2 19 5 80 discard extract helper (no complexity gain)
3 13 3 40 keep use statistics + min/max/median
SQL 模式表头 iter median_ms rows hash_ok status description(hash_ok ∈ {yes、no、-}):
iter median_ms rows hash_ok status description
0 1121.06 10 - baseline correlated subquery no index
1 6.82 10 yes keep rewrite correlated subquery as JOIN + GROUP BY
2 1.18 10 yes keep add index orders(customer_id, amount)
4 0.40 10 no discard drop ORDER BY — changed result set
报告最佳迭代,不一定是最后一次。
约束
- 只能编辑
<editable_files>中的文件——门禁的基准数据为只读:测试和tools/metrics.py(代码)、数据库和tools/bench.py(SQL)。修改用于衡量结果的内容以改变数值,会使本次运行失效。 - 正确性门禁不容妥协。 未通过门禁的改动(测试失败,或
hash≠ 基线)属于回归,而非优化——无论指标如何,都必须回退。行为改变后门禁仍通过,说明门禁不够严格,而不代表改动安全;与其信任薄弱的门禁,不如确保行为完全一致。 - 每轮只做一项改动,以便将每次指标变化归因于该改动。
- 每个候选改动都用相同方式测量(代码:使用相同的
<gate_cmd>;SQL:使用相同的--repeat);比较指标,不要只看一次有噪声的运行结果。 - 改动仅限于现有依赖集合;不要添加项目缺少的导入(标准库除外)。
- 沙盒是自包含的——不得通过
../路径越出指定的<sandbox_root>。 - 不要暂停循环询问是否继续;持续运行,直到达到平台期或预算用尽。