§20从delegate_task到Kanban平台

From delegate_task to a Kanban Platform

今年4月Hermes的多Agent能力只有一个函数。到6月它变成了一整套SQLite支撑的持久看板平台,§07里你已经用它接力跑完过三张卡。有意思的是,源码里躺着一份白纸黑字写着「只是设计、不许动核心」的宣言,而最后落地的东西,把这份宣言喂胖了一倍不止。

旧书时代:一个工具就是全部家底

翻回4月的第一版,Hermes的多Agent那一章其实挺单薄。它只有一个原语,叫delegate_task 。

机制很好懂:父Agent fork出一个短命的子Agent,把任务丢过去,然后阻塞着等返回。子Agent在隔离的会话里跑完,吐一段summary回来,然后就消失了。当时最多三个并发。能让不同子Agent用不同模型,推理用强模型、搜索用快模型,也就到此为止了。

(这个函数自己后来也长了:v0.22默认最多10个子Agent并发,可以丢到后台跑、中途插话改方向或者叫停,子Agent单独有250轮的上限。但它的本质没变,还是一次调完就忘的函数调用。)

这是个标准的fork-join结构。适合短的、自包含的推理子任务。但它撑不起社区里越来越常见的那几种活:一个要跑几小时的工程流水线、一个每天早上自动出日报的循环、一个你想给它起个名字、养上几个月的持久助理。这些都需要「活过单次API调用」的东西,delegate_task 给不了。

那份写着「DESIGN ONLY」的设计文档

2026年4月25日,Nous Research在仓库里放了一份PDF,叫Hermes Kanban v1 spec。我第一次读到它的扉页时,是有点意外的。

扉页的Abstract上,几句话写得斩钉截铁:

设计文档原文(扉页):Status: DESIGN ONLY. No implementation accompanies this document. / The kernel requires no changes to run_agent.py, no new core tools.

翻译过来:这只是设计,没有任何实现跟着它。这个内核不需要改动run_agent.py 一行,不需要任何新的核心工具。

整份spec的调性都是这种克制到近乎洁癖的极简主义。它把内核的边界画得清清楚楚,恨不得用尺子量过:

维度v1设计文档的承诺
状态机恰好6个状态:todo / ready / running / blocked / done / archived
数据库表原文写「exactly four tables」,恰好4张
新增核心工具零。一个都不许加
CLI命令一个子命令
其余一个skill、一个cron job,完事

spec里那个dispatcher(调度器)也被设计得故意「笨」。它只干三件事:重新算哪些任务ready了、用CAS原子地认领一个任务、spawn出一个worker进程。不做智能路由,不做预算,不做审批。所有聪明的活都推给上层的profile和插件去干。

这是一份很漂亮的设计。问题是,它没能管住自己。

反转:104个PR,把宣言喂胖了

到了v0.16.0,我把实际shipped出来的代码和这份spec逐条对了一遍。落差大到有点好笑。

推荐不推荐
设计文档说:6状态 · 4张表 · 0新工具 · 1个CLI子命落地代码是:9状态 · 7张表 · 一整套kanban_*工具
令集 · 30+个CLI子命令(到v0.22.2一级子命令47个,算
上二级56条)

每一条都被突破了。状态机多出了三个:triage (人随手丢个粗想法进来)、scheduled (等时间不等人的任务)、review (评审门控)。表从4张涨到7张,光是核心那张tasks 表的列数就从十几列暴涨到三十列左右。

最打脸的是那句「no new core tools」。实际代码里,dispatcher每spawn一个worker,就把kanban_show 、kanban_complete 、kanban_block 这一整套工具直接塞进它的schema里。这恰恰就是新的核心工具。

那个里程碑发生在v0.15.0,官方自己的release notes写得很直白:「Kanban grew into a real multi-agent platform — 104 PRs」。一份极简主义的设计宣言,被现实需求在104个PR里一口一口喂成了一个平台。

核心建议

这条「设计文档 vs 落地实现」的落差,本身就是观察开源项目演化最好的样本之一。它说明一件事:克制是一种姿态,但真实用户的工作形态会持续往内核里灌东西。能写出「exactly four tables」的团队,几周之后照样会因为有人真的要拿它管50个Instagram账号,而把表加到7张。这不是设计失败,是设计在和现实谈判。

delegate_task没死,它降格了

有人可能会问:Kanban这么强,那delegate_task 是不是被淘汰了?

没有。它还在,源码里反复强调kanban的worker在自己一次运行内仍然可以调delegate_task 。变的是它的位置。它从「多Agent的全部」降格成了「函数调用级」的子能力,而Kanban成了「队列级」的协作底座。两者共存,分工被官方写死成一句话。

这条分界线值得记住,它干净利落:

维度delegate_taskKanban
形态RPC调用(fork→join)持久消息队列 + 状态机
父Agent阻塞到子返回fire-and-forget,建完即done
子身份匿名子Agent,无持久自我有名profile,自己的记忆/skill/历史
可恢复无,失败就是失败block后能unblock重跑;崩溃自动回收
人能不能插手不行,全程headless随时comment/block/reassign
每任务Agent数一次调用一个任务一生N个(重试/评审/跟进)
审计父上下文一压缩就丢SQLite行永久留存

怎么选?官方给了一句判据,特别适合背下来:这个交接,需要活过单次API循环、并且对别人可见吗?需要就上看板,不需要就用delegate。一句话就把两个原语的边界划干净了。

用大白话讲:delegate_task 是一次函数调用,调完就忘;Kanban是一个持久工作队列,每一次交接都是一行任何profile(或者你这个人)都能读、能改的数据。

从「函数」到「基础设施」

把这个反转串起来看,Hermes多Agent从4月到6月的演化路径其实很清楚。

delegate_task v1 spec

104个PR

Kanban

一个函数极简宣言喂胖持久看板平台一个SQLite支撑、跨进程、能扛住单点失败的看板平台。它有自动任务分解、有swarm拓扑、有定时任务、有按任务覆盖模型、有断路器重试、有多租户、有多看板。v0.22又补了一层抗故障:模型服务商报429、5xx这类错误时,卡片会带着上下文重新排队,失败的卡片在面板上直接显示worker最后的输出。这些后面几节会一个一个拆开讲。

但这一节我只想让你先记住这个反转本身。旧书最弱的一章,现在成了全书最有料的Part。而它之所以这么有料,恰恰是因为那份spec一开始想得太克制。克制给了它一个干净的内核,现实又逼着它在这个内核之上长出了一整个平台。

下一节我们钻进这个平台的内核,看看那个被设计成「笨」的dispatcher,到底笨在哪、又为什么这种笨反而是它能扛住生产环境的原因。