mcpField
S
swe-loop

swe-loop

github.com/gaasher开发17836 次安装17 周前更新
代码仓库

关于 swe-loop

swe-loop 是在代码库中按计划逐项实现编码任务的技能。Engineer 与 QA 子 Agent 分别负责代码和测试,并通过回归与代码质量门槛反复验证每项改动。

主要功能

  1. 01按依赖顺序执行任务
  2. 02分离源码与测试修改
  3. 03Engineer 与 QA 迭代审查
  4. 04运行完整测试套件检查回归
  5. 05依据量规和阈值检查代码质量
  6. 06支持堆叠、单个或不创建 PR

适用场景

  1. 01根据编码提示实现代码库改动
  2. 02以经过测试的增量完成多项任务
  3. 03准备按任务划分的提交与 PR

安装

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

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

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

包含的文件

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

examples/
run.example.yaml
roles/
engineer.md
qa.md
rubrics/
quality-rubric.md
schemas/
change.schema.json
verdict.schema.json
tools/
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.jsonplan-loop 在 Phase 0 中生成
<test_command>项目的测试运行方式—tasks.json.environment.test_command;否则根据仓库推断(pytest、npm test、…)
<sandbox_root>计划、迭代产物和记录所在的位置./sandbox—
<iter_strategy>branches(每项保留的任务对应一个 git 提交)或 snapshots(文件夹副本)branchesbranches 需要仓库干净
<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_loc8 / 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),而不是继续改进无效方案。

评论

支持 Markdown