Super-agent 架构图解

原文发表于 2026-10-31,是架构探讨,不是产品发布。下文的「文章」「作者」都指这篇原文。

单任务的上限取决于模型能力,多任务的上限取决于人的注意力。

作者观察到,一个人通常只能同时跟进 3 到 5 个活跃 Session。Super-agent 把 Session 变成系统内部的实现细节,用户始终只面对一个跨平台、持续在线的 Agent。文章列出四个特征,用五个模块支撑:

连续在 IM 提方案 A,再到 PR 评论改成 B,它都能接上。
高效不用等上一个任务完成,就能接下一条指令。
主动持续观察环境事件,值得处理才行动,否则保持安静。
持久始终在线,长期运行中遇到异常能自动恢复。

总图:跟一条事件走一遍

选一种事件,看它走哪条路、要不要调用模型。切到「公开原型」可以对照代码实际的做法。

视图
§5.1 云端无状态计算容器:可水平扩展、重启、替换 单机单进程:tmux + 目录锁,不是云端分离 §3 环境事件 Trigger §4.2 多信道 IM 群聊消息、话题 飞书事件流,默认关闭 GitHubPR、评审、CI轮询,默认 60 秒 邮件、日程往来、提醒本次检索未见 程序层策略§3.1 Fast Path 来源、群组、白名单不调用模型 Scope 过滤intake.ts 是否在监听范围不调用模型 丢弃大部分噪音止步于此 Thread 订阅表Ticket 订阅表 §3.2 程序查表 PR #12 → A B IM-7 → B 邮件-3 → C 其余:无人负责 Router 层 §2.1 常驻 Session,轻量模型,全局序点和记忆 主 Session orchestrator,配了 bash 和 read 语义层策略 LLM 按提示词判断 要不要行动 §3.1 Slow Path 分派与协调 新任务冷启动 跨任务协调 统一对外回复 Worker 层 §2.2 上下文隔离,完整工具,最强模型 Worker 每工单一个 Session,默认最多 3 个 Worker A隔离上下文PR #12 Worker B隔离上下文PR #12IM-7 Worker C隔离上下文邮件-3 IM≤100 词,低打扰 飞书100 词由代码强制 邮件、文档结构化摘要本次检索未见 GitHub结构化 PR 说明Worker 也直接发言 执行环境§5.2 留在原地 端侧 daemon开发机、云托管、间歇在线设备不存会话状态 本机目录git worktree 和主 Session在同一台机器daemon、BYOM本次检索未见 Session 数据库§5.1 持久化所有 Session 状态,计算容器换了任务也不丢 SQLite + JSONL 控制状态在 SQLite,Session 在 JSONL;能重启恢复 Watchdog Session§6 主系统之外 查基础设施故障,也判断任务有没有实质进展 Hourly check 只查服务状态并重启,要操作者自己配置 定时消息Control Loop 放行 未订阅Slow Path 全量观测仅通知 后续事件Fast Path 直通 订阅、退订、交回 创建 Worker、分派 汇报关键结论 统一回复 命令、结果本地执行 读写 Session 状态 读状态 介入修复status、restart ack、开 PR、回评审 Gate Engine 确定性控制面,状态唯一写入者(文章没画)
这张图比屏幕宽,可以左右滑动查看。
Fast Path:程序直达 Slow Path:进 LLM 外部控制回路 观测,不做决定 外部系统 程序层(不调模型) Router(轻量模型)主 Session Worker(最强模型)Worker 控制回路(主系统之外)控制回路 持久状态
    文章的总架构图把两级过滤画成 Router 之前的一个框,没有说语义层由谁运行,也没有说已订阅事件要不要过语义层。这里按公开原型的实际顺序来画:过了监听范围检查就查订阅,未订阅的才进 Router,语义判断在 Router 的 Session 里完成。

    §2双层架构:把连续性和吞吐量拆开

    所有事件进同一个 Session,上下文最连续,但会被单个 ReAct Loop 的串行速度卡住。每条事件新开一个 Session,吞吐最高,但结果彼此割裂。双层架构让两层各管一头。

    全进一个 Session

    事件 一个 Session A B A C B … 串行,细节混杂 用户

    上下文连续。任务耗时长、吞吐低,多任务的中间细节还会互相影响。

    每条事件一个 Session

    事件 Session 1 Session 2 Session 3 各自回复 用户

    并发最高。任务之间缺全局上下文,多个 Session 各说各的,交互混乱。

    Router + Worker

    事件 Router全局上下文 用户 一个声音 Worker 1 Worker 2 Worker 3

    Router 保持连续,Worker 并发执行。代价是多个会话带来更多 token 消耗(见 §7)。

    三种组织方式的差别在两处:事件进了几份上下文,用户听到几个声音。
    Router 层Worker 层
    职责人类交互、任务分派、跨任务协调,是全局的序点和记忆在独立上下文里专注完成单一任务
    模型较轻量的模型往往够用通常配能力最强的模型
    工具不直接执行任务,甚至可以不配 Bash完整执行工具,内部还能开 Subagent 或 Agent Team
    对外统一向用户回复不直接面对人,向 Router 汇报
    协作中转少数跨任务协同同层通常不直连,靠共同订阅 Thread 发现冲突

    和常见的 Agent Team 有什么不同:Team Lead 要深入单个任务、规划子任务、高频协调成员,自身推理负担很重。Router 只处理任务之间的高层关联,不介入单任务内部的拆解。这里的「双层」是逻辑划分,每层内部都可以再有结构。

    为什么单个 Router 没那么容易成为瓶颈

    事件平稳逐条进入 Trigger LLM 调用,1 条 LLM 调用,1 条 LLM 调用,1 条 单次响应延迟低 事件密集积压后合并 调用 1,1 条 调用 2,3 条一并注入 调用 3,4 条一并注入 单个决定分摊的推理时间更低
    示意图,长度不按比例。Router 每步通常是长输入、短输出,批量注入主要增加 Prefill,而 Prefill 是并行计算的,所以单次耗时的增长慢于 batch 大小。
    Router 压测(§7.2,Worker 用 Mock)约 1 条/分钟约 40 条/分钟
    平均 batch 大小1.02.8
    单次请求耗时2.5 秒3.9 秒
    单个决定分摊的推理时间6.4 秒1.6 秒

    看这组数字时注意:文章没有定义「分摊时间」,低负载下它是单次请求耗时的 2.5 倍,所以它不等于单次耗时除以 batch 大小。一种可能的解释是一个决定要用多次请求,这是调研时的推断。40 条/分钟是最高测试点,真正的上限没有测到。

    §3事件驱动:让环境推着 Agent 走

    驱动 Agent 的主要输入,从人类逐条键入的提示词,变成群聊消息、邮件、日程提醒、评审评论、CI 结果这类半结构化事件,统称 Trigger。一条 Trigger 的生命周期要回答四个问题。

    §3.1 过滤
    环境事件噪音高、触发率低。程序层用确定性规则筛掉大部分消息,语义层再由 LLM 判断。语义层的策略用提示词写,可以随时开关或新增。
    §3.2 路由
    同一个 PR、IM 话题或邮件串下的连续事件构成一条 Thread。Router 为新 Thread 创建 Worker 后,Worker 订阅这条 Thread,后续事件由程序直达。订阅是多对多的:共同订阅一个 PR 的多个 Worker 收到相同事件,不用点对点通信也有机会自行解决冲突。
    §3.3 注入
    把上下文窗口当 Cache 管。注入过多会稀释模型注意力,过少会迫使模型反复调用工具。下面这张图是它的完整机制。
    §3.4 提前行动
    借鉴投机执行,根据环境信号在后台先试,有价值就交付,没价值就丢弃。作者的内部群配了一条「静默复现并修复」策略:只有确认问题并找到简单修复才发声,否则全程安静。

    Inline & Spill 和链式召回

    Trigger #42当前事件,已注入窗口 前 50 字、相邻消息 thread_id: #08 worker_id: #03 Thread #08第 1 跳 近期事件摘要 trigger_ids: #39 #40 worker_ids: #02 #03 Worker #03第 2 跳 进度与状态摘要 thread_id: #15 Thread #15第 3 跳 关联的 Pull Request read_thread(#08) read_worker(#03) read_thread(#15) read_trigger(#42) Trigger #42 剩余内容Spill:留在窗口外,需要才读 read_trigger(#40) Trigger #40 详情同样遵循 Inline & Spill
    Inline 是把近期很可能用到的信息直接放进窗口,Spill 是把超出预算的内容留在窗口外、只留引用。对象一律带唯一 ID,并内联紧密关联对象的 ID,于是它们在底层连成一张引用图,模型可以顺着它走。这也是 Router 不用全量历史,却能在用户提起旧任务时找回上下文的原因。

    三步做法:从最少信息开始,只给 ID 和摘要;按局部性逐步 Inline,比如前 50 字、IM 的相邻消息、同一评审讨论里的相邻评论;超过上限就 Spill,一种简单做法是截断并保留续读入口。

    §4面向人的交互:前台不被后台卡住

    同一时刻到达 经典 ReAct半双工 用户消息 1 LLM 调用run() 同步阻塞,等工具返回 工具结果 回复消息 1 才处理消息 2 同步执行耗时工具 用户消息 2 只能等工具结束 异步 ReAct全双工 用户消息 1 LLM 调用start() Started 用户消息 2 立刻回复 完成事件 交付结果 后台异步执行耗时工具,模型可随时调用 stop() 终止 立即返回 完成后作为新事件投递
    用户消息 2 在两种模式下同一时刻到达。经典模式要等工具结束才能处理它(红线),异步模式在当前推理步结束后就处理。

    文章说这个异步机制「已在 DeepSeek Harness 中实现,但尚未默认开启」。核对公开代码:run_in_background 和超时转后台默认都是开的,也没有名为 start() / stop() 的工具。没有默认的是「耗时调用一律异步」:模型不主动放后台时,bash 仍在前台最多等 60 秒。把「未默认开启」理解成这一点是调研时的推断,也可能指未公开的内部配置。

    §4.2 输出要匹配信道

    信道风格规范
    IM 等即时通讯低打扰的轻量沟通,只在需要决策或验收时通知只问直接问题,给简短结论,单次回复不超过 100 词
    GitHub、邮件、文档结构化、高信息密度的异步交付PR 写完整的问题背景、改动说明和验证结果;邮件和文档给结构化摘要

    §5计算、状态、环境:分两步解耦

    现状:绑在一台设备上

    一台本地设备 Agent Loop(计算) Session(状态) 仓库、工具链(环境)

    设备休眠或离线,Agent 就停了,也访问不到其他设备上的环境。

    第一步 §5.1:计算与状态分离

    云端 Agent Loop无状态,可替换 Session 数据库持久化 环境怎么接? 执行环境未提交的修改、私有凭据、内网依赖

    Agent 摆脱单机生命周期,云端持久在线。但真实环境很难同步到云端。

    第二步 §5.2:计算与环境分离

    云端 Agent Loop无状态,可替换 Session 数据库持久化 命令、结果 开发机daemon 云托管环境daemon 间歇在线设备上线后再触发

    环境留在原地。端侧 daemon 只执行命令、返回结果,不存会话状态(BYOM)。

    第一步让 Agent 的生命周期不再依赖单台设备,第二步让它可以在多台设备之间切换,并接入间歇在线的设备。

    这个思路和 Anthropic 的「脑手分离」一致:brain 对应计算,session 对应状态,hands 对应环境。文章自己指出的区别是场景:Anthropic 讲托管服务里的沙箱和客户 VPC 资源,这里首先要接的是可能间歇在线的个人机器。

    调研时的推断:这个场景差异会改变故障恢复方式。Anthropic 的容器是可丢弃的 cattle,坏了就换一个;个人机器上有未提交的修改和本地凭据,没法重建。

    代价写在 §8.4:云端 Loop 一旦被入侵或被提示词注入攻破,它连接的全部设备都有被控制的风险。作者把这列为开放问题。

    §6Watchdog:主系统之外的控制回路

    许多异常不是进程崩溃,而是模型陷入无效循环或偏离目标。所以除了基础设施的存活,还要监控任务本身的进展。可以在总图里回放 Worker 跑偏的场景。

    进程存活探测、监控脚本Watchdog Session
    监控什么进程是否活着接口报错、状态恢复失败,以及每个 Worker 有没有实质进展、方向是否偏离整体目标
    谁来判断预设规则模型
    怎么介入告警或重启及时修复;遇到外部偶发故障就持续复查,直到恢复
    怎么用它看日志和看板用自然语言问故障原因,让它在线增删提示词、调整触发规则

    §7实验:用更多 token 换更短、更稳的完成时间

    作者用群聊和 GitHub CI 消息流驱动四种方案。每次约 300 条消息,其中约 20 条是工作请求,每种方案跑 5 次。编码工作用一个只消耗时间的工具替代,所以这里衡量的是调度能力,不是单任务执行能力。

    任务完成时间 P50 到 P95(分钟)

    P50P95

    单次实验读缓存 token(万,全部 Session)

     
    两种 Super-agent 方案的 P95 都在 16 分钟以内,两种单 Session 方案的 P95 都接近 30 分钟。代价是读缓存 token:Super-agent 是中性提示方案的 3.8 倍。
    方案P50(分钟)P95(分钟)读缓存 token
    Super-agent12.415.72323 万
    Super-agent,去掉直通12.615.53177 万
    单 Session + Subagent 工具,中性提示20.429.5605 万
    单 Session + Subagent 工具,提示优先委派13.829.01082 万
    • 单 Session 的问题在于靠提示词决定分不分工。中性提示下,5 次运行模型一次都没调用 Subagent。提示优先委派后有 4 次委派,剩下 1 次判断工作「很小」自己做,形成长尾。
    • 直通省的是 Router 开销。去掉直通后完成时间基本不变,但 Router 要做的决定多了约 30%,读缓存 token 从 2323 万增加到 3177 万,增幅约 37%。

    读这组数字要带上的限定

    • 作者声明实验基于合成负载和简化环境,结果仅作初步参考。
    • 累计完成曲线的图注写明消息间隔和工作时长按 1/4 缩放,模型调用耗时是真实值。表格没有单独说明,按同一组实验理解,分钟数不是真实耗时。
    • 每种方案只跑 5 次,没有给置信区间。提示优先委派方案的 P95 主要受 1 次长尾运行影响。
    • 正文说直通「不提高任务完成质量」,但编码被替换成只消耗时间的工具,实验里没有质量指标。
    • 公开仓库里没有实验负载和脚本,无法复现。

    公开原型实现了多少

    对照 dsh-superagent-prototype@6337fc8 的静态阅读结果,没有运行代码。它是一个面向单个 GitHub 仓库的主动编码 agent,README 明确写了「研究原型,非 DeepSeek 正式产品」。路由内核(§2 到 §4)基本都有,§5 和 §6 的主体在这个版本里没有看到。「本次检索未见」来自全仓多同义词检索,不代表内部版没有。

    代码里多出来的一层:文章没有画确定性控制面,原型却以它为核心。Engine 是 Trigger、Thread、Decision、Ticket 的唯一写入者,方法全部同步。LLM Session 负责决策,序点实际落在 Engine 上(后半句是调研时的推断)。读代码时注意术语:文章的 Router 在代码里叫 orchestrator,订阅的主体是 Ticket,Worker 是 Ticket 的执行者。

    机制状态原型里的样子证据
    Router + Worker 双层已实现单个常驻主 Session,每个 Ticket 一个 Worker Session,默认最多 3 个并发policy.ts:93
    两级过滤已实现程序层是 Scope 和 Gate,语义层就在主 Session 内。默认 observe 模式只研判、不接主动工作policy.ts:84
    订阅直通,多对多已实现一条消息扇出给所有订阅的 Ticket,发送者不需要通过权限检查intake.ts:34
    批处理已实现同一 Thread 的积压合并成一次研判;一次路由调用可带 1 到 20 个决定evals.ts:110
    main.ts:129
    Inline & Spill已实现Trigger 卡片 160 字符加总长和续读指针,研判窗口里的存根 50 字符cards.ts:8
    assessment.ts:37
    链式召回已实现统一走 orchestrator_read,中间跳是 Ticket。Worker 只能读自己的 Ticket,完整引用图只对 Router 开放resources.ts:24
    退订部分实现Worker 只能退后来挂上的 Thread,起源 Thread 和绑定的 PR 退不了tickets.ts:185
    投机执行部分实现没有专门机制,靠规则、auto 模式、静默接单和 dropped 组合。默认规则只有文案和视觉修复policy.ts:62
    多信道部分实现只有 GitHub(轮询)和飞书(默认关闭)。100 词是代码强制,比提示词约束更硬,但回复只对飞书生效outbox.ts:29
    Watchdog部分实现部署文档里的 Hourly check,由操作者在另一个 profile 配置,只查服务状态并重启。没有 Worker 进展判断006-deployment:133
    Router 工具集与文章不同配了 bash 和 read,「不读代码」只是提示词规则。文章说的是「甚至可以不配」007-architecture:507
    Worker 不直接对人与文章不同Worker 自己发 ack,自己开 PR、回评审。结果通知和提问才由 Router 发executor.ts:28
    Router 观测所有事件与文章不同只推放行的候选、人类跟进通知和 Worker 报告。人类跟进仍会唤醒 Router,名单外的 bot 和默认配置下的 CI 才真正绕过subscriptions.md:4
    异步 start / stop与文章不同没有这两个工具。前台命令等 5 秒转后台,用 job_kill 终止,语义相当、形态不同cordis.patch.yml:49
    云端无状态计算、状态分离本次检索未见单机单进程,SQLite 加目录锁。能重启恢复,但没有分离runtime.ts:93
    端侧 daemon、BYOM、间歇在线本次检索未见工作目录默认在本机 stateDir 下,和主 Session 同一台机器003-execution:25
    邮件、日程信道本次检索未见仓库只带 GitHub 和飞书两个 Source全仓检索
    Router 分片本次检索未见文章自己也把它列为未来方向全仓检索

    每个设计借用的系统思想

    作者的结论是,这里没有全新的理论,而是把计算机系统的经典思想用到了 Agent 上。这张表可以当记忆卡。

    系统思想在 Super-agent 里的对应章节
    Fast Path / Slow Path程序过滤和语义过滤;订阅直通和 Router 分派§3.1 §3.2
    序点 Sequence PointRouter 汇总所有跨任务的信息和决策§2.1
    批处理 Batching积压的 Trigger 合并进一次 LLM 调用§2.1
    水平切分 Sharding规模变大后切分 Router,用连续性换吞吐§2.1 §8.1
    Cache 与局部性把上下文窗口当 Cache,优先放时空相邻的信息§3.3
    Inline / Spill常用信息内联进窗口,其余留在窗口外只留引用§3.3
    投机执行后台提前尝试,有价值才交付§3.4
    半双工到全双工start() 立即返回,完成后投递新事件§4.1
    存算分离无状态 Agent Loop 加 Session 数据库§5
    Control Loop主系统外由定时消息驱动的 Watchdog§6

    §8作者自己列的开放问题

    • 怎么扩展双层架构。Router 何时切分、粒度多大,Worker 何时需要直接通信,都没有定论。运行周期拉长到跨月后,长程记忆是主要瓶颈。
    • 脱离 Session 后怎么协作。聊天窗口有路径依赖,交互可以更多发生在领域特化的界面里,比如 GitHub。用户中途介入和接管的方式还要探索。
    • 上下文边界和 A2A。共用一个实例就是共享上下文。多个隔离实例之间怎么安全通信,比如个人助手和团队 Super-agent 之间。
    • 安全与隐私。事件驱动带来更多不可信输入,云端和端侧的连接默认互相信任。作者认为,这个问题解决不好,Super-agent 只能在很小的可信范围内工作。

    全部文章