- AI 技能
- AI 插件
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,115+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
导读
多任务队列(multi-task queues)是 Aider Delegate 委托模式中把多个有界编码任务串成一条可控流水线的核心方法论:一次只跑一个任务,任务之间由编排者(orchestrator)亲自审查并提交,把此前任务中已经定下的接口、模式与边界显式传递下去,最后对整个任务区间做一次完整的一致性复查。本文基于 agentic-awesome-skills 仓库中 aider-delegate 技能族的 multi-task-queues.md 展开,结合同技能族的简报、派发与审查文档,讲清楚为什么队列必须顺序执行、约束如何跨任务存活、进度文件怎么写,以及什么时候该停下来回到人类决策。
一、什么是多任务队列
先给队列下一个严格的定义:队列是几个有界任务通过同一个循环逐个运行、一个接一个,任务之间由你(编排者)审查。
这句话里有三个不可省略的限定:
- 有界:每个任务必须能被一个独立的简报(brief)完整描述,有明确的起点、终点和验收标准;
- 逐个运行:同一时刻只有一个 Aider 实例在工作树里修改代码;
- 中间有审查:任务 N 完成后,你检查 diff、跑门禁(gates)、决定提交,然后才派发任务 N+1。
尤其要注意:队列不是把一个大任务拆成多片并行派发的方式。并行拆分会把"审查单个任务的 diff"这件事直接摧毁——后面会详细解释为什么。它与 writing-the-brief.md 中"一任务一简报"(One task per brief)的原则严格对应:多个任务被捆绑进一次派发,产生的 diff 无法被干净地审查,某一半失败还会拖累另一半,因此正确做法就是把它们排成队列逐个处理。
在 Aider Delegate 的整体流程中,队列的每一次迭代都对应 SKILL.md 中定义的五步循环:写简报 → 派发(relay)→ 等待完成 → 审查 → 提交落地。队列只是把这五步循环重复 N 次,并在 N 次之间加上跨任务的约束管理和收尾检查。
二、顺序运行,每任务一个提交
队列的第一条铁律:派发任务 N,审查它,提交它,然后才派发任务 N+1。这看起来慢,但原因完全是实践性的,而不是教条。
原因一:每个任务需要一个干净的基线
审查一个 diff,本质上是在读"这个任务到底改了什么"。如果两个运行同时在同一个工作树里编辑文件,touchedFiles(由 relay 在 result.json 中通过git status --porcelain报告)就再也说不清哪一行是谁改的。touchedFiles报告的是 git 看到的所有东西,而不仅仅是 Aider 写的;一旦并发运行污染了工作树,这个字段就失去了"任务归因"的能力,你的审查就失去了起点。
原因二:Aider 的聊天历史是按仓库存的
Aider 没有会话 ID,它的恢复单元是存放在仓库里的聊天历史文件.aider.chat.history.md。--resume-last在 relay 中对应 Aider 的--restore-chat-history,恢复的就是这个文件;--history-file则可以钉住某个特定的历史文件。
这意味着:同一个工作树内的并发运行会共享并互相覆盖这一个历史文件。两个 run 同时--resume-last,后写的会把先写的冲掉,两边都会读到对方半途的状态。所以真正的并行必须满足一个条件——每个运行有自己的工作树,也就是自己的.aider.chat.history.md、自己的可审查 diff。
原因三:失败保持隔离
顺序执行的第三个好处是失败被装进一个小的盒子里。一个坏的任务 N,最多就是一个需要检查的提交,而不是一团纠缠不清、无法归因的改动。你可以单独回退它、单独修补它,而不是在混战里捞线头。
真正需要并行时:git worktree
如果你确实需要并行,SKILL.md 和本队列文档给出的方案是git worktree:
git worktree add ../feature-a -b feature-a git worktree add ../feature-b -b feature-b这样每个运行都获得:
- 自己的树(各自的
--cd目标); - 自己的
.aider.chat.history.md(互不干扰,--resume-last语义天然按 worktree 隔离——review-and-land.md 明确指出"resume 是按 worktree 的,不是按用户的:同一个项目的两个 clone 并不共享它"); - 自己的可审查 diff。
顺带一提,worktree 在 Aider Delegate 里还有一个安全用途:当某个改动"绝对不能碰"某些东西时,文件作用域(--file、--read)只是聊天上下文控制,不是安全边界,真正的边界必须来自 Aider 外部——容器、虚拟机,或只包含任务允许看到内容的临时git worktree(详见 writing-the-brief.md)。
三、把已定下的约束向前传递
Aider 每次非恢复运行(没有--resume-last)都从零开始,对上一次任务毫无记忆。这是队列设计里最容易踩的坑:你在任务 1 里定下的东西,任务 3 的 Aider 一无所知。
因此在任务 3 的简报里,必须显式重申任务 1 中已经决定、并且对任务 3 有约束力的内容:
- 名字、签名和接口:之前敲定的函数名、参数、返回类型、公开 API;
- 选定的模式:例如"这里用的是仓储模式(repository pattern),请沿用",Aider 会遵守它能看到的约定;
- 守住的边界:例如"仍然不要碰
migrations/目录"。
为什么必须这样做?因为简报就是全部契约——writing-the-brief.md 说得非常直白:Aider 看到的只有你发送的文本加上它编辑作用域内的文件,没有聊天历史、没有共享上下文、没有把你引到这里来的任何推理过程。任何你留作隐式的内容,Aider 都会替你自己做决定。
一个不把约束向前传递的队列,最终产出的是 N 个各自局部合理、但彼此对不上的改动:任务 1 用了ValueError,任务 3 却按 clamp 的语义写调用方;任务 1 定了接口签名,任务 3 又按自己的理解微调了一遍。每个任务单独看都没错,合起来却是碎片。
同时记住"简报冻结"(premises freeze)原则:你在简报里断言的一切,在派发的那一刻就冻结了。如果运行期间你学到了会改变前提的信息(门禁命令写错了、接口挪了位置),不要让运行落在一个错误的基础上——停掉它,或者丢弃结果、用修正后的简报重新派发。
四、维护一个进度文件
任何超过三个任务的队列,都应该在仓库之外维护一个小的进度文件,逐行跟踪四类信息:任务、状态、提交 sha,以及任何后续任务依赖的决策。
文档给出的示例格式如下:
1. reject negative windows done a1b2c3d ValueError, not clamp 2. propagate through scheduler done e4f5g6h callers let it raise 3. document the new behavior pending follow decision from 1这个文件的价值有两层:
- 它能在丢失会话后存活。编排者的上下文窗口是有上限的,一次中断、一次回滚、一次进程重启,都会抹掉你对"队列进行到哪了"的记忆。文件不会。
- 它就是你要带进每个简报的东西。任务 3 的简报不是凭空写的——它应该由进度文件里"任务 1 的决策"+"任务 3 自己的目标"拼接而成,这正是上一节"约束向前传递"的具体落地工具。
从 Aider Delegate 的实现角度看,进度文件与 relay 的产物模型完全互补:relay 把每次运行的产物(brief.txt、final.txt、stderr.txt、result.json)写到运行目录(默认在系统临时目录下,仓库保持干净),其中result.json里的status、touchedFiles、finalMessage等字段是每次任务的"结构化事实";而进度文件把这些跨运行的结构化事实压缩成一行行的队列状态。两者配合,即使编排者丢失了 relay 的输出,运行目录里依然有完整证据(git diff是最终真相,因为 relay 从不提交)。
五、收尾做一次一致性检查
单个任务各自正确,加起来仍然可能是不连贯的。这是队列模式特有的风险:任务 1 到任务 N 逐个审查时都通过了,但作为整体看,接口可能已经悄悄漂移。
所以在最后一个任务之后,把整个区间当作一个 diff 来复查:
git diff <sha-before-queue>..HEAD<sha-before-queue>是队列开始前最后一个提交的 sha——这正是进度文件里应该在任务 0 就记录下来的锚点。
在这次全区间复查中,重点寻找四类"接缝"问题:
- 接口在任务之间漂移:任务 2 用了任务 1 定下的签名,任务 4 却改掉了它;
- 重复引入的辅助函数:两个任务各自实现了一个功能相同的 helper,因为它们互相不知道对方;
- 描述旧迭代的文档:文档还停留在任务 2 的行为描述,任务 5 已经改了行为;
- 被后续任务留下的死代码:任务 3 删除了某路径,任务 4 的代码却还在引用它。
在宣布队列完成之前,把这些接缝修好。这与 review-and-land.md 中的"实现者清扫"(implementer sweep)清单一脉相承:改名或删除后全仓库 grep 旧名称(包括文档、配置、生成代码)、迁移要回滚验证、留意"顺手重构"造成的静默范围蔓延、警惕只断言实现本身的新测试、以及被 try/except 吞掉的错误。
另外注意一个容易误判的点:Aider 默认开启--auto-lint,它可能在编辑后自己跑 linter 并修正自己的报错——那是 Aider 的 lint,不是你的门禁。全区间一致性检查里,要把这些 lint 驱动的额外编辑当作 diff 的一部分来读,并且无论如何都要亲自重跑项目的真实门禁。
六、什么时候该停下来询问
队列不是一条蒙眼跑到底的传送带。以下四种情况出现时,停下列队,回到人类:
- 同一原因连续失败两次:两次失败指向同一个根因,说明简报本身错了,而不是实现者不行。继续派发第三次只是用更贵的成本重复同一错误。此时应该改写简报,而不是给实现者更多机会。
- 任务揭示出计划本身是错的:某个任务做不下去,暴露了后续任务在逻辑上已经不成立。这时候继续执行后面的任务没有意义。
- 正确完成需要范围变更:需要碰
DO NOT TOUCH清单里的文件、修改公开接口、引入新依赖。这是 review-and-land.md 中"范围变更即停止"(scope change stops the loop)规则的队列版本——不要在实现者授权之外擅自扩大委托范围。 - 队列的假设已经过时:现实在队列运行期间移动了——依赖升级了、接口被外部改动了、需求变了。队列是建立在派发时冻结的前提之上的(见上文"简报冻结"原则),前提失效,队列就该终止。
文档给出的最终判断标准非常直接:在一个错误前提上完成队列,比在队列中途停下来更糟。半途停止只是浪费了已经投入的成本;错误前提下的"完成"会把一整串基于错误假设的改动合并进主干,让审查和回滚的成本都变成全体承担。
七、队列与委托全流程的关系
把上面的每一条放回 Aider Delegate 的整体循环中看,队列并不是孤立的一套规矩,而是对以下既有机制的显式编排:
| 队列机制 | 依赖的既有实现 |
|---|---|
| 顺序执行、每任务一提交 | relay 强制传入--no-auto-commits与--no-dirty-commits,Aider 编辑工作树、编排者负责提交(SKILL.md) |
| 约束向前传递 | 每次非恢复运行无记忆;--resume-last恢复仓库内的.aider.chat.history.md,且按 worktree 隔离(dispatch-and-poll.md) |
| 进度文件 | result.json的status/touchedFiles/finalMessage为每任务提供结构化事实(dispatch-and-poll.md) |
| 收尾一致性检查 | 提交边界:门禁通过 + diff 匹配简报 + 未要求之事已上报,三者齐备才提交(review-and-land.md) |
| 停止询问 | "一任务一简报"原则的延伸——任务粒度就是队列粒度的前提(writing-the-brief.md) |
需要说明的是,本仓库中的 aider-delegate 技能为文档导入形态:根据 SKILL.md 的 Limitations 部分,可执行的scripts/relay.mjs未随仓库捆绑(docs-only import),运行时需要自行安装aiderCLI(python -m pip install aider-chat)、Node 18+ 与 git。队列文档描述的 relay 行为(--resume-last、--timeout看门狗、result.json原子写入、绝不提交等)是对上游运行时语义的准确转述,落地使用时应以实际安装的 relay 版本为准。
结语
多任务队列的正确姿势可以浓缩为一句话:慢的、可审查的顺序执行,永远胜过快的、不可归因的并发。每次派发一个任务、审查一个 diff、提交一个 commit,把跨任务的约束显式写进每个简报,用一个仓库外的进度文件扛住会话丢失,最后用git diff <sha-before-queue>..HEAD对整个区间做一次一致性复查——并且永远保留在四种明确场景下停下来的勇气。这样得到的不是一个"看起来都做完了"的工作树,而是一串每个提交都可解释、可回退、可审计的干净历史。
- AI 技能
- AI 插件
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,115+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
相关推荐
Antigravity 委派队列实战:基于 agy-delegate 的顺序多任务编排、进度追踪与收尾一致性检查
Antigravity 委派队列实战:基于 agy delegate 的顺序多任务编排、进度追踪与收尾一致性检查 导读 当委派任务从单次变为批量(跨层删除拆分、
AI 技能AI 插件Rewrite进阶:如何用TensorBoard可视化字体训练过程与损失变化?
Rewrite进阶:如何用TensorBoard可视化字体训练过程与损失变化? 在深度学习项目中,监控训练过程是确保模型收敛和优化性能的关键步骤。对于中文字体风
cppcodec vs 其他编解码库:为什么它是C++项目的最佳选择?
cppcodec vs 其他编解码库:为什么它是C++项目的最佳选择? 在C++开发中,数据编解码是一项常见任务,而选择合适的库往往直接影响项目效率与稳定性。c
序列化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考