本节摘要:委派解决"一次派几个兵",看板解决"一个兵团怎么长期作战"。kanban 多 Agent 工作队列以一块 SQLite 看板(
~/.hermes/kanban.db)为唯一事实源:任务卡在 triage→todo→ready→running→review→done 九态间流转,dispatcher 进程认领 ready 卡片、为每卡 spawn 一个独立 worker 进程(各自 git worktree、各自技能与模型);claim 锁与租约防双认领,心跳与连续失败断路器管崩溃恢复,review 工人复核产出。tools/kanban_tools.py(2480 行)把看板操作做成结构化工具给 worker 用(而非 shell 命令——后端可移植、免引号坑、错误可推理)。swarm 模式在看板上写标准拓扑:并行专家 + verifier + synthesizer。MoA(mixture-of-agents,agent/moa_loop.py2453 行)则是另一种混合:/moa 标记一个回合,多个参考模型并行出意见、聚合器综合成终答。最后以 cron 自然语言定时补齐"时间维度的协作",并总结委派/队列/混合三种协作模式。
内容来源:原项目源码
tools/kanban_tools.py、hermes_cli/kanban_db.py、hermes_cli/kanban.py、hermes_cli/kanban_swarm.py、agent/moa_loop.py、cron/jobs.py、tools/cronjob_tools.py。
⚠️ 注意:普通
hermes chat会话的 schema 里一个 kanban 工具都没有——工具只在两种情形注册:dispatcher 派生的 worker(环境变量HERMES_KANBAN_TASK已设)或显式启用 kanban 工具集的 orchestrator profile。人类继续用 CLI(hermes kanban …)、dashboard 与斜杠命令操作看板,三者都绕过 agent。
阅读完本节,你应当能够:
hermes kanban(三条理由)。hermes_cli/kanban_db.py(约 4800 行)定义内核。合法状态一目了然:
kanban_db.py:102 VALID_STATUSES = {"triage", "todo", "scheduled", "ready", 103 "running", "blocked", "review", "done", "archived"}
主流转:triage(人工分拣)→ todo(排队,依赖未满足)→ ready(依赖齐备可认领)→ running(worker 持有)→ review(待复核)→ done;异常侧线有 blocked(分类型阻塞:缺依赖还是断路器熔断,路由不同)与 scheduled。tasks 表(kanban_db.py:1333)把作战所需的字段全部建进去,三个最要紧的列:
-- kanban_db.py:1333 CREATE TABLE IF NOT EXISTS tasks ( claim_lock TEXT, -- 认领锁持有者 claim_expires INTEGER, -- 锁租约到期时间 consecutive_failures INTEGER NOT NULL DEFAULT 0, -- 连续失败计数 worker_pid INTEGER, last_heartbeat_at INTEGER, -- worker 心跳 current_run_id INTEGER, -- 当前 run(task_runs 表外键) skills TEXT, -- 强制预载技能(JSON)
认领靠锁加租约:ready 卡被 worker 以带过期时间的锁占有,进程崩溃后租约自然过期、release_stale_claims 回收再派。崩溃恢复靠三信号:心跳(heartbeat_current_worker_from_env,kanban_tools.py:301)、连续失败计数(spawn 失败/超时/崩溃都 +1,仅成功完成清零,超限触发断路器熔断成 blocked)、run 历史(task_runs 表存每次执行的完整重试史)。每张卡可带 workspace(默认 scratch,可绑 project 的 git worktree)、强制技能清单、per-task 模型覆盖——任务卡就是一份完整的执行规格。

tools/kanban_tools.py 的模块头回答了"为什么是工具不是 shell":
kanban_tools.py:17 Why tools instead of just shelling out to ``hermes kanban``? 19 1. **Backend portability.** A worker whose terminal tool points at Docker 20 / Modal / Singularity / SSH would run ``hermes kanban complete …`` 21 inside the container, where ``hermes`` isn't installed and the DB 22 isn't mounted. Tools run in the agent's Python process ... 24 2. **No shell-quoting footguns.** 26 3. **Better errors.** Tool-call failures return structured JSON ...
工具面覆盖 show/list/complete/block/unblock/comment/attach/attach_url/attachments/create/link/heartbeat 与 orchestrator 专属的 request_review/request_changes。操作纪律刻在守卫函数里:_reject_delegated_child_mutation(kanban_tools.py:85)禁止 delegate_task 子代直接改板——"子代把发现汇报给父,板上的变更必须由 dispatcher worker 或显式配置的 orchestrator 执行",因为同进程子代身上的环境变量证明不了所有权;_enforce_worker_task_ownership 确保 worker 只能动自己名下的卡。request_review 把卡推入 review 态并触发复核工人(图 kanban-09 展示了 drawer 里的 pipeline review 视图),复核工人可 complete(过)或 request_changes(打回 todo 重做)——验证引擎(上节 /review 的思想)在看板上的制度化。

kanban_swarm.py 明言"intentionally does not introduce a second scheduler"——swarm 只是往现有看板内核写一张标准任务图:
kanban_swarm.py:7 planning root (completed immediately) 8 ├─ parallel specialist workers (ready) 9 └─ verifier (todo until all workers done) 10 └─ synthesizer (todo until verifier done)
根卡立即置 done 充当锚点;专家卡 ready 先行;verifier 卡靠依赖门(所有父卡 done 才从 todo 升 ready)等待;synthesizer 再等 verifier。共享黑板也是"deliberately low-tech":根卡上的结构化 JSON 评论([swarm:blackboard] 前缀),不引入新服务——dashboard、通知、dispatcher 全部照常工作。
MoA(agent/moa_loop.py)换一个维度混脑:它不是委派,模块头强调"The slash command is deliberately not a model tool. It marks one user turn as MoA-enabled; the normal Hermes agent loop still owns tool calling and turn termination"。流程:/moa 标记回合 → 每次模型迭代前,_run_references_parallel(moa_loop.py:795)线程池并发调多个参考模型(auxiliary 槽位配置,便宜模型)→ aggregate_moa_context(moa_loop.py:1233)把各家输出拼成带标签的参考块附进聚合器的输入 → 聚合器(主模型)综合出终答。隐私过滤器是亮点:参考输出可能回显用户贴过的邮箱/电话/凭据,_redact_reference_text 先走中央脱敏器再叠加 MoA 专属的邮箱与分隔电话号码正则——注释详细论证了为什么 10 位裸数字不能匹配(会误伤日期、SHA、IP)。与委派的本质区别:参考模型没有工具、没有会话、只出意见,工具调用与回合终止始终归主循环;MoA 是"多顾问单执行官",委派是"多执行官"。
协作还包括"与未来的自己协作"。cron/jobs.py 的 parse_schedule(jobs.py:732)把人话翻成结构化调度:
jobs.py:742 Examples: 743 "30m" → once in 30 minutes 745 "every 30m" → recurring every 30 minutes 747 "0 9 * * *" → cron expression 748 "2026-02-03T14:00" → once at timestamp
四种形态:一次性延时(30m/2h)、循环间隔(every 30m)、标准 cron 表达式(croniter 校验)、ISO 时间点。用户对 agent 说"每天早上九点把 HN 头条发到我 Telegram",agent 调 cronjob 工具(tools/cronjob_tools.py,压缩成单一 action 型工具防 schema 膨胀)落库,调度器到期触发独立 cron 会话,结果经第 7 章的 DeliveryRouter 投递 deliver=telegram。cron 会话同样跑标准内循环——它的产物也进外循环沉淀。
三种模式各有其位:委派(delegate_task)适合一次性扇出——父在场等待、秒级生命周期、结果直接回流;队列(kanban)适合长任务流——任务卡生命周期可达数小时数天、崩溃恢复、人类可随时插板、复核制度化;混合(MoA/swarm)适合提升单步质量——多模型对冲单一模型的盲区。三者可以嵌套:kanban worker 内部可以 delegate,delegate 子可以调 cron,cron 会话可以 /moa——因为它们共享同一套内循环与工具注册表。
💡 循环要点:kanban 的深刻之处在于把多 agent 协作的状态外置到一块普通 SQLite——不是消息传递、不是中央编排器,而是"共享数据库 + 状态机 + 认领锁"。这带来三个外循环红利:任务卡强制携带技能与模型规格(经验的容器化)、每次 run 的重试史沉淀为可复盘数据、review 工人让"验证"从父子关系升级为组织制度。军团作战的每一步,都变成可积累的作战记录。
下一章进入粮草官:37 个模型 provider 插件、国内模型全家桶、5 种 API 适配器与 profile 路由。