10月31日晚,DeepSeek 干了一件不大张旗鼓、但后劲很足的事。
Harness 团队发了篇技术文章《Super-agent 设计探索:迈向更自主的 Agent 系统》,顺手把原型代码开源了。两天,9000+ star。
但你可能已经发现了:这两天刷屏的文章,讲的都是同一句口号——"让 AI 指挥 AI"。
口号很好记,问题是它没告诉你任何能用的东西。
我把仓库的 README、docs/000–008、还有src/core、src/app、src/executor的核心代码翻了一遍,发现两件事:真正的干货全在代码里;以及,官方文章里有些模块,开源原型里根本没有。
这篇写给做 Agent 系统的人。不聊口号,聊机制——而且顺手帮你把几处被媒体带偏的数据掰回来。👇
01 它到底在解决什么问题
先说清楚问题,否则后面全是空中楼阁。
官方的观察是:现在让 AI 改个 Bug、写个功能,它做得越来越好,几乎不用你盯。但你想同时推进 5 个任务呢?切换会话、复述背景、逐个验收——你变成了瓶颈。
于是有了全文最狠的一句判断:
单任务的上限取决于模型能力,多任务的上限取决于人的注意力。
还有一句,值得每个做 Agent 产品的人抄在墙上:
Session 应当是系统的实现细节,而不应是用户的认知负担。
翻成大白话:凭什么要用户记住"这个需求我说在第 3 个会话里"?这是系统的锅,不是用户的。
基于这个判断,官方给出四个目标特征——注意,这里就有个坑👇
四个特征是:连续、高效、主动、持久。很多报道写成"主动/持久/并行/面向人",错了。"并行"只是手段,"连续"才是体验目标。
- 连续:在 IM 里提方案 A、在 GitHub PR 评论里改方案 B,它都能接上,你感觉"始终只有一个 Agent"
- 高效:并行推进多任务,不用等上一个跑完就能接下一条指令
- 主动:持续观察环境事件主动干活,但不需要介入时保持安静
- 持久:始终在线,异常时自动恢复
看到没——"安静"和"主动"是并列写进目标的。这一点后面会反复出现。
02 五个模块怎么分工
先看骨架。五个模块支撑上面四个特征:
① 双层架构:Router 常驻,是全局的"序点、协调点和记忆",不直接执行任务,甚至可以不配 Bash 工具,用轻量模型就够;Worker 上下文隔离、挂完整工具、配最强模型,不直接对用户说话,只向 Router 汇报。
这里官方坦白了一个取舍:它"表面上看和常见的 Agent Team 相似,但侧重点不同"——Agent Team 的 Lead 需要深入任务细节,Router 只管任务之间的高层关联。这就是为什么 Router 能又轻又便宜。
② 事件驱动:输入不再是"人逐条敲提示词",而是环境里的半结构化事件——群聊消息、邮件日程、代码评审评论、CI 结果。
③ 面向人的交互:把耗时的run()改成异步的start()/stop(),Agent 起了后台任务就立刻返回"已开始",结果作为新事件回注,前台该聊继续聊。
④ 计算/状态/环境分离:借鉴存算分离,云端跑 Agent Loop、状态进数据库,本地只留一个轻量 daemon——官方管这叫BYOM(Bring Your Own Machine)。所以你合上电脑,任务还在跑。
⑤ Watchdog:主系统之外的独立控制回路,不只盯进程活着没,还由模型判断各个 Worker"有没有实质进展、方向有没有跑偏"。
(⚠️ 第五个模块有情况,我在第 07 节单独说。)
03 核心:一条消息进来之后,发生了什么
这部分是全文最值钱的。我把 17 步时序压成 7 个关键节点,每一步都标了它写入什么状态。
① 幂等去重:同 id 的 Trigger 再来一次,直接返回duplicate,后面全不执行。分布式系统的第一课,人家做得很规矩。
② 程序层快筛:先按"谁说的、在哪说的、是不是 bot"过滤。被判filtered的消息不进 Eval、不唤醒任何 Ticket——噪音在这一层就死掉了,一个 Token 都不花。
③ 扇出(订阅直通):系统找出订阅了这个 Thread 的所有 Ticket,把消息直接塞给它们。注意,已结束的 Ticket 也能被唤醒。
④ 批处理成 Eval:这个 Thread 上排队的所有 Trigger 被整批搬进一个 Eval——也就是说,同时到达的 5 条群消息 = 一次模型调用。
⑤ 原子开票:判定 accept 后,在同一个事务里一口气完成:建 Ticket → 建 Mandate(授权)→ 挂首个 Assignment → 给相关 Thread 建 Subscription → 发受理回执 → 入队启动任务。任一步失败,整个事务回滚。
⑥ Worker 执行:独立目录、独立 Session、独立上下文,工具白名单。
⑦ 事务性发件箱:对外发消息时,回执和发送动作在同一个事务里,commit 之后才真的发出去。
第 ⑦ 点我要多说一句,因为它是整个系统"不翻车"的地基。源码里有一行注释特别坦率:DshExecutor.stop被刻意挂在afterCommit上,理由写着——"一个被回滚的结束,不会真的停掉 worker"。
做 Agent 的人都懂这个痛:"说了但没做"和"做了但没说",都是事故。事务性发件箱就是解这个的。
04 主动性,是怎么不变成刷屏机器的
让 AI 主动干活不难,难的是让它知道什么时候闭嘴。Super-agent 用了四道闸门,道道都能抄。
闸门一:两级过滤。便宜的程序规则先筛,活下来的才交给模型判断。成本结构一目了然。
闸门二:accept mode 三档。这是我最想安利的设计——
off— 一切推测性候选都不接
observe(默认)— 照常评估,但正向评估只记录"本会接",什么都不做
auto— 真的接单
看懂了吗?observe 就是个影子模式:让 Agent 先跑一段"记录我本来会干什么",人审过再放行。任何想上主动能力的团队,都应该先做这一档。
闸门三:订阅直通。订阅 Thread 上的每条消息(包括 bot 和 CI)都直达 Ticket,但——文档里有句加粗的话:消息、评论、被引用的文档只是决策的输入,不能改变权限。
这是"听得见"和"能做主"的分离。听得见是为了上下文连续,能做主必须走授权。
闸门四:投机执行 + 静默交付。官方原话:"还不确定结果是否会被采用时,根据环境信号在后台提前尝试……有价值就交付,没有价值就丢弃。"
内部实例特别生动:有人在群里反馈 Bug,Agent 后台默默复现、定位原因,只有确认问题真实存在、并且找到了简单修复方案,才提交结果;否则全程安静。
⚠️ 顺手纠个偏:有技术媒体把"投机执行"解释成"预判下一步、命中就省一次往返"——这跟官方定义完全是两回事。别被带跑。
05 上下文,是被当成 Cache 来管的
官方一句狠话:"浪费上下文窗口,就是浪费模型的智能。"
它的做法是三步:最少信息起步 → 利用局部性 Inline → 超上限就 Spill(截断,但保留续读入口)。
代码里的预算卡得极死,这些数字建议直接收藏:
- 单条 Trigger 文本:最多 4000 字符
- 关联 Ticket:最多8 个(开放者优先)
- Thread 窗口:前 5 条 + 触发点前后各 5 条,单条一般 400 字符
- 窗口外的消息:降级成50 字符的 stub,需要时按 id 展开
- 分页读取:每页4000code units,列表20条
配合的是链式召回:给 Trigger、Thread、Worker Session 都发唯一 ID,注入时内联关联 ID,构成一张引用图。模型可以顺着引用一跳一跳往回找——当前消息 → Thread → Worker Session → 另一个评审 Thread。
还有个细节很见功力:权限即视图。Worker 读资源时,页面会隐去它读不了的 id——别的 Ticket、Decision 决策记录,它连 id 都看不到。
06 任务怎么收口:Ticket 的三层建模
这块是工程上最见真章的地方。Super-agent 的 Ticket没有"状态枚举",而是三层正交建模:
第一层,二值生命周期:open = !ended,结束时记清楚是被谁结束的(人还是 Agent)、什么结局。
第二层,派生列 active:有未投递输入、或最新任务还在跑,就是 active。这一列不存储,由 SQLite 生成列直接算出来。
第三层,stage(仅 open 时有效,自上而下首个匹配):投递失败 → 等回答 → 等评审 → 卡住/失败 → 排队中 → 空闲 → 执行中。
三个谓词撑起了大部分"智能":
waitsForPerson:报了 blocked/failed 且此后没有人的消息 →自动输入一律挂起,等人followupOwners:只要某个 Ticket 还持有这条人类追问,decide就只允许 stop——防止同一个人的追问被两个 Agent 抢followsDone:自己开的 PR 全关了才算完;一个都没开过,就等它 follow 的所有 PR 关完
再送一个反直觉的细节:Report 里的waiting 不是 Worker 写的,是 host 在回合静默之后代写的。真正由 Worker 主动写的是progress / ready / blocked / failed / dropped。
人怎么介入?五个命令:stopTicket(撤回授权)、retryTicket(同一目录/分支/PR 上重开)、reevaluate、unsubscribe、dismiss。
还有一个设计我很喜欢:在群里说"停",只是一个普通消息,要由 Eval 判断是否该停(Agent 不能自称"人让我停的");而面板上的 Stop 才是命令。话语权和命令权,是分开的。
07 数据:三处被带偏的地方,我帮你掰回来
做技术的人最怕什么?被二手数据忽悠。这三处,媒体几乎全写错了。
❌ 误读一:"编码快了一倍"
不是。中位数的提升(20.4 → 13.8 分钟)大半来自提示词(是否要求优先委派),不是架构。架构真正卖的是尾部:p95 从 29.5 压到 15.7 分钟。而且实验里真实的编码工作被"只消耗时间的工具"替代了,测的是调度,不是编码质量。
❌ 误读二:"订阅直通省了 37% Token,是加速器"
官方原话是反过来的:取消事件直通后,Router 决策次数增加约 30%,Token 从 2323 万涨到 3177 万。而完成时间几乎没变(p50 12.4→12.6,p95 15.7→15.5)。
订阅直通省的是调度开销,不是时间。把它写成"提速神器"是错的。
❌ 误读三:"批处理让回复更快了"
实测单次请求耗时是上升的(2.5 → 3.9 秒),下降的是每个决定分摊的推理时间(6.4 → 1.6 秒)。吞吐提升 ≠ 单条延迟降低。
补一句:那个被到处引用的"一个人只能同时跟进 3~5 个会话",官方措辞是"据我们观察"——团队经验值,没有文献支撑。别写成研究结论。
08 那道缝:原型里其实没有 Watchdog
这是我读代码时最意外的发现。
我把 docs/000–008 和src/core/model.ts翻了个遍,Watchdog 既不是领域对象,也没有任何对应代码模块。它是官方文章第 6 节描述的模块,属于部署侧的外部控制回路,在开源原型里压根没实现。
代码里功能最接近的是这四组机制:
- Passes 心跳:每 2 秒跑一次,先跑到期副作用,再跑到期评估
- Eval 截止时间:从候选送达主 Session 才开始计时,过期重排两次,第三次记
unavailable - 指数退避 + 健康看板:同一类副作用连败 3 次才报错;"资源暂时不够"用
Later异常顺延,不算失败 - 启动恢复:重启时把被打断的任务带恢复说明重新拉起
顺便说下原型的真实状态:README 明写这是research code,不是生产级软件;仓库1 个 commit、0 个 release、issues 已关闭。
这不是挑刺——承认"文章讲的"和"代码有的"之间有缝,本身就是一种专业。怕的是把 PPT 当产品。
09 可以抄走的 8 条设计
说了这么多,最后给你一份能直接用的清单:
- 影子模式(observe):让主动能力先"只记录不执行",跑一段再放行。上线主动 Agent 的最低成本路径
- 两级过滤:便宜规则先筛,贵模型兜底。任何事件驱动系统都该有这道成本闸门
- 订阅直通:已开工的任务直接订阅后续消息,绕过中央调度
- 上下文当 Cache 管:Inline 摘要 + Spill 按需展开 + 引用图逐跳召回。给每条内容一个 id,让模型自己决定要不要展开
- 事务性发件箱:命令在事务内入队副作用,commit 后才执行
- 用生成列算工作集:把"哪些是活跃的"交给数据库,调度循环只读活跃行
- Later 不计失败:"资源暂时不够"和"真的出错"必须分开,否则健康检查会被正常波动淹死
- 用影响而非努力来停止:官方哲学原话——"局部改动做到可评审的结果就停;需要设计决策的改动,停在一个清晰的问题上"
写在最后
DeepSeek 在文章结尾写了句特别清醒的话:
我们并没有提出全新的理论,而是将计算机系统中经典的工程思想应用到了 Agent 系统的构建中。
调度、缓存、存算分离、看门狗、投机执行——全是操作系统和分布式系统几十年前就打磨好的东西。他们做的事,是把这些思想搬进 Agent 系统,然后用一份 MIT 代码 + 一组带消融实验的数据,摊开给你看。
我的判断是:Anthropic 和 OpenAI 的 subagent、handoff,都是在一次用户会话内部做拆分;Super-agent 的 Router 是跨会话、跨信道、跨时间常驻的。这是层级差异,不是能力差异。
2026 年 Agent 的竞争,正在从"卷模型"转向"卷系统"。下一个跑出来的产品,可能不是模型最强的那个,而是把用户注意力算得最清楚的那个。
最后一个问题:上面那 8 条设计,你的 Agent 最该先抄哪一条?评论区聊聊。👇
#DeepSeek #智能体 #Agent架构 #AI开发 #开源 #大模型 #架构解析 #系统设计 #AI编程 #开发者