关于 swe-loop
swe-loop 是在代码库中按计划逐项实现编码任务的技能。Engineer 与 QA 子 Agent 分别负责代码和测试,并通过回归与代码质量门槛反复验证每项改动。
主要功能
- 01按依赖顺序执行任务
- 02分离源码与测试修改
- 03Engineer 与 QA 迭代审查
- 04运行完整测试套件检查回归
- 05依据量规和阈值检查代码质量
- 06支持堆叠、单个或不创建 PR
适用场景
- 01根据编码提示实现代码库改动
- 02以经过测试的增量完成多项任务
- 03准备按任务划分的提交与 PR
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gaasher/ agent-loop-skills --skill swe-loop安装后在 Claude Code 中输入/swe-loop确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/run.example.yamlroles/engineer.mdqa.mdrubrics/quality-rubric.mdschemas/change.schema.jsonverdict.schema.jsontools/quality_check.py详细介绍
SWE Loop
prompt → plan → execute → debug 流程中的 execute 阶段:将编码提示词转化为可运行、经过测试且组织良好的代码。它运行 plan-loop,生成可执行的 tasks.json,然后按依赖顺序处理任务。每项任务由两个相互隔离的子 Agent 负责——编写代码的 Engineer,以及负责测试和质量标准的 QA——不断循环,直到满足关卡要求。反馈信号由两部分组成,与仓库中的其他评估循环类似:一个是客观关卡(任务测试通过、完整回归测试套件保持全绿,且 tools/quality_check.py 未报告任何阈值违规);另一个是定性关卡(QA 根据 rubrics/quality-rubric.md 对简洁性、可读性、注释规范、组织结构和风格匹配度进行评分)。每个外层步骤只处理一项任务;每个内层轮次只提出一项更改,因此每个差异都有明确的归属。
适用场景
当你想在真实仓库中实现提示词,并希望将工作拆解、构建和测试,而不是一次性完成时,使用此工具;同时,“完成”意味着下游工程师会接受结果:测试全绿,代码整洁。默认逐项执行 plan-loop 的 tasks.json 任务;只有确实存在计划缺陷时才可跳出,此时应将其作为 open_question 交由人工处理,而不是临时改道。越简单越好——如果某项更改为了通过测试而增加了复杂性,QA 会将其退回。此工具不适用于单纯规划(plan-loop),也不适用于优化已完成产物的某项指标(optimize-loop)。
设置
以交互方式解析绑定项。如果存在 loop.run.yaml,则加载它,用一行确认其中的值,然后跳转到循环执行。否则:在 Claude Code 中(可使用 AskUserQuestion 工具),为每个绑定项推断一个可能的值并给出建议;在其他宿主中,逐项以引用形式询问。然后写入 loop.run.yaml(格式:examples/run.example.yaml),并在开始构建前确认。
| binding | 含义 | 默认值 | 推断方式 |
|---|---|---|---|
<prompt> | 要构建的编码任务——文件路径或内联文本 | — | 用户的请求 |
<repo> | 要构建的项目;Engineer 会在其中编辑 | . | 当前正在处理的仓库 |
<tasks_file> | 循环要执行的 plan-loop 输出(由 plan-loop 的 validate_plan.py 验证) | <sandbox_root>/tasks.json | plan-loop 在 Phase 0 中生成 |
<test_command> | 项目的测试运行方式 | — | tasks.json.environment.test_command;否则根据仓库推断(pytest、npm test、…) |
<sandbox_root> | 计划、迭代产物和记录所在的位置 | ./sandbox | — |
<iter_strategy> | branches(每项保留的任务对应一个 git 提交)或 snapshots(文件夹副本) | branches | branches 需要仓库干净 |
<pr_mode> | 如何将保留的任务变为 PR(参见 拉取请求):stacked(每项任务一个 PR,依次基于前一个 PR——默认值)、single(整个运行只建一个 PR)或 none(本地提交,不建 PR) | stacked | 变更较小或没有堆叠 PR 工具时使用 single;离线或没有远程服务时使用 none |
<base_branch> | PR 最终要合入的分支 | main | 仓库的默认分支(git symbolic-ref refs/remotes/origin/HEAD) |
<task_budget> | 每项任务允许的 Engineer⇄QA 轮次数上限 | 6 | — |
<patience> | 连续 N 轮没有改进后停止任务 | 2 | — |
<quality_thresholds> | quality_check.py 的硬性限制:max_comment_block、max_comment_line_len、max_func_loc、max_nesting、max_file_loc | 8 / 100 / 60 / 4 / 400 | 根据仓库规范收紧或放宽 |
<skill_dir> 是此技能的安装目录;在 loop.run.yaml 中替换为实际路径。每轮的客观质量关卡如下:
python3 <skill_dir>/tools/quality_check.py <changed_files> \
--max-comment-block 8 --max-comment-line-len 100 --max-func-loc 60 --max-nesting 4 --max-file-loc 400
循环执行
阶段 0 — 规划(一次)
复制此清单并逐项勾选。
- 获取计划。 如果
<tasks_file>存在且 plan-loop 的validate_plan.py验证通过,则加载它, 用一行确认目标和任务数量,然后跳到执行阶段。否则,对基于<repo>的<prompt>运行plan-loop技能,生成<tasks_file>(以及plan.md),并在开始构建前与用户确认计划。 - 基线。 运行
<test_command>,记录当前通过的测试集合——这是后续每项任务都必须保持的 回归基线。记录基线台账条目。 - PR 预检(如果
<pr_mode> = none,则跳过)。确认存在远程仓库且gh已完成身份验证 (gh auth status);确定<base_branch>;根据今天的日期选择运行标签,并设置<run_branch>=swe/<tag>。绝不推送到你不拥有的分支,也绝不向其发起 PR;绝不强制推送。
每项任务(外层循环——按 tasks.json.order 中的任务顺序)
按依赖顺序处理每项任务 T;只有在其 depends_on 均已保留后才能开始:
- 检查点。 确保工作树干净且位于已知提交上(这是
T的还原点)。根据<pr_mode>选择分支模型:stacked → 从上一项已保留任务的分支(第一项任务则从<base_branch>)切出T的分支<run_branch>/<T>,让每项任务都叠加在其前置任务之上 (这有效,因为order是拓扑排序——每个depends_on都已位于祖先链中)。single/none → 保持在唯一的工作分支<run_branch>上(第一项任务时从<base_branch>切出)。在snapshots模式下,也将<repo>复制到<sandbox_root>/iter/<T>/before/。
内层循环(Engineer ⇄ QA——直到 pass 或达到 <task_budget>/<patience>)
- Engineer(启动或降级,
roles/engineer.md)。向其提供T、仓库,以及在优化轮次中 提供上一轮的verdict.json。它会阅读相邻代码,仅编辑源代码来实现T,并返回change.json(schemas/change.schema.json)。 - QA(启动或降级,
roles/qa.md)。向其提供T、Engineer 的变更、仓库和rubrics/quality-rubric.md。它会为T的acceptance_criteria补写缺失的测试(如果已覆盖, 则仅评估质量,并且只编辑测试),运行<test_command>执行完整测试套件(包括T的 测试和所有先前任务的测试),运行quality_check.py,按评分标准打分,并返回verdict.json(schemas/verdict.schema.json)。 - 记录本轮的台账条目。
- 保留或优化。 如果
verdict.pass→ 保留:提交T(分支模式)/提升工作副本 (快照模式)。然后按<pr_mode>打开或更新T的 PR(参见拉取请求):stacked→ 推送<run_branch>/<T>并打开 PR,目标分支 = 上一项任务的分支(第一项任务则为<base_branch>);single→ 仅提交(最后再打开唯一的 PR);none→ 不做任何操作。 此时回归基线包含T的测试;继续下一项任务。否则,将verdict.fixes提供给 Engineer 并继续优化。 如果连续<patience>轮未取得进展,或轮数达到<task_budget>,则停止该任务:还原T, 将其记录为blocked,记录一个open_question,然后停止——不要在未完成的任务之上构建后续任务 (也不要打开其 PR)。
当 order 中的每项任务都已保留(提示词已实现并测试)或某项任务受阻时,循环结束。
结束时,如果 <pr_mode> = single,则推送 <run_branch> 并打开唯一的 PR(目标分支为 <base_branch>),涵盖
所有任务。交付物包括构建完成的仓库,以及 plan.md、tasks.json、台账和 PR。
拉取请求(每项任务)
<pr_mode> 控制已保留的任务如何送达远程端。只有已保留的任务才会创建 PR(blocked 任务不会创建 PR)——PR 只是已通过任务的交付封装,因此互不重叠的范围检查保持不变。需要已完成身份验证的 gh 和远程端;如果工作树不干净或缺少远程端,则回退到 none 并告知用户。绝不要强制推送已推送的任务分支。
stacked(默认)——每项任务一个 PR。 每个任务分支<run_branch>/<T>都从上一个已保留任务的分支切出,其 PR 以该前置分支为目标,因此堆栈顺序与tasks.json一致:
保留时:执行<base_branch> ◄─ PR T1 (swe/<tag>/T1) ◄─ PR T2 (base = T1) ◄─ PR T3 (base = T2) ◄─ …git push -u origin <run_branch>/<T>,然后执行gh pr create --base <parent_branch> --head <run_branch>/<T> --title "<T.id>: <T.title>" --body "<what it delivers; Depends on #<parent PR>; tests N/N; quality minK>"。 从底部向上审查和合并;基础 PR 合并后,GitHub 会自动将子 PR 的目标分支改为<base_branch>(或重新变基整个堆栈)。每个 PR 都保持精简且可独立审查——这正是采用堆栈的目的。single——一个大型 PR。 所有任务都提交到<run_branch>;循环结束时,创建一个gh pr create --base <base_branch>,涵盖整个运行过程。适用于审查者希望一次审查全部内容,或无法使用堆栈工具的情况。none——仅限本地。 每项任务都提交,但不推送或创建 PR(原有行为)——适用于离线工作,或由人工自行创建 PR 的情况。
在账本的 change 备注中记录每个 PR 的 URL。
账本
<sandbox_root>/ledger.tsv,以制表符分隔,自由文本中不得使用逗号。列为
iter task phase tests quality pass note:
iter task phase tests quality pass note
0 - baseline 34/34 - - clean baseline; 34 passing tests
1 T1 engineer - - - implement config loader src/config.py
1 T1 qa 36/36 min4 yes authored 2 tests; rubric all >=4
2 T2 engineer - - - add retry to client.py
2 T2 qa 37/38 min3 no test_retry fails; backoff off-by-one
3 T2 qa 38/38 min2 no tests green but readability=2: nested 5 deep
4 T2 qa 38/38 min4 yes flattened; kept
tests 是完整测试套件的 passed/total;quality 是最低维度评分(min4 = 最低维度为 4);phase ∈ {baseline, engineer, qa, keep, blocked}。在被保留或受阻的任务处报告最终状态。
约束
- 写入范围互不重叠。 Engineer 仅编辑源文件;QA 仅编辑测试文件。这是循环的核心:代码生产者不能削弱评判其工作的测试,评论者也不能修改源代码以使测试通过。跨越范围的更改将导致硬性门禁失败。
- 一次只处理一项任务,并按依赖顺序进行,绝不要基于未保留的任务继续构建——未完成的依赖会使之后的所有结果都不可信。
- 门禁不可妥协。 只有当任务的测试通过、完整回归测试套件保持全绿,且符合质量标准时,才会保留该任务。测试全绿但代码糟糕,不算完成;代码整洁但有测试失败,也不算完成。
- 测试只能加强,且必须遵循计划。 QA 的测试必须验证任务的
acceptance_criteria;绝不要为了让更改通过而削弱、跳过或删除已通过的测试。 - 不要修改计划来逃避工作。
tasks.json是约定;其中确有缺陷时,应作为open_question提交给人工处理,而不是悄悄重写任务。 - 自主运行直至完成或遇到真正的阻碍;不要暂停询问“要继续吗?”。
角色
roles/engineer.md— 代码生产者。在 Claude Code 上使用真实的隔离子代理(Agent/Task 工具),否则以内联方式运行。编辑源文件,并返回schemas/change.schema.json。roles/qa.md— 测试编写者和质量评审者。同样使用子代理,无法使用时则降级处理。编辑测试,运行测试套件和tools/quality_check.py,依据rubrics/quality-rubric.md评分,并返回schemas/verdict.schema.json。
停止条件
此循环会自主运行,直到所有任务都已构建并保留,或某项任务在 <task_budget> 轮后受阻。遇到阻碍时,停止并报告任务、当前的 fixes 以及 open_question——指出真正的障碍,胜过强行提交一个只满足测试字面要求、却违背测试意图的更改。如果某项任务反复以相同方式失败,让 Engineer 改用不同方案(pivot),而不是继续改进无效方案。