生命不息,折腾不止。单兵再强也怕活多——今天让 dsh 里的 Agent 学会「组队」,把大任务拆给几个子 Agent 并行干。

前两篇我们把 dsh 从「装上」玩到了「能写插件」。但真正干活的场景里,一个 Agent 从头盯到尾有个致命问题:上下文越滚越长,到最后模型大半注意力都在考古——三十轮之前的对话跟当前这步基本没关系,却一直占着 token。DeepSeek Harness 给出的答案是「多 Agent」:主 Agent 当项目经理,把活拆给几个子 Agent 各干各的,最后收拢结果。

这篇就带你把 dsh 的多 Agent 体系跑起来。先说明一点:dsh 的「多 Agent」不是一个开关,而是一组可组合的工具,搞清楚每把工具的用途,比背命令重要得多。

一、先分清:dsh 的「多 Agent」其实是五套工具

翻 dsh 的文档会发现,「委派」这件事被拆成了五组独立的插件工具,职责泾渭分明:

工具 干什么 一句话理解
subagent / subagent_fork 派活 创建子 Agent 干活
subagent-control 管理 send_message / interrupt_agent / list_agents
jobs 统一后台 job_list / job_output / job_kill
workflow 编排 agent() / pipeline() / parallel()
ralph 有界迭代 一轮轮换新会话,只传交接报告

底层支撑它们的是一个叫 subagent seam 的机制:ctx.subagents 注册了六个命名 provider——spawn-in-process(默认,同进程建子 Agent)、fork-in-process(一次性前台)、acp(跨进程/跨机器)、codexclaude-codedsh-sdk。模型看到的接口永远一样,背后跑的是谁可以随便换。这套东西在 Standard 模式里默认就挂好了,不用额外装。

二、两个「派活」工具:subagent 和 subagent_fork

最常用的是这两个,区别一句话就能记住:

  • subagent:创建的是可续聊的后台子 Agent(continuable)。它默认在后台跑,有自己的「收件箱」,干完通过 report 工具把结果推回主 Agent。你中途还能再给它发消息追加要求。
  • subagent_fork一次性前台。它带着主 Agent 当前的会话历史起步,跑完直接把结果返回来,没有收件箱、不能追加,发出去就完事。

选择规则也很直白,官方社区给了个口诀:

fork when the context IS the task, spawn fresh when the task is separable.

翻译成人话:如果子任务本身就依赖你当前已经聊出来的上下文(「顺着这个思路,换个修法再试」),用 subagent_fork;如果子任务可以独立拆出去(「去把这三十个文件读一遍,告诉我结果」),用 subagent 新建。

三、上手:让主 Agent 同时派三个子 Agent 干活

不用写代码,直接开 Web UI 就能体验。流程如下:

1
2
3
# 1. 启动 dsh(已装好环境的话)
npx @deepseek-ai/dsh web
# 浏览器打开 http://127.0.0.1:3080

新建会话,模式选 Standard(子 Agent 和工作流都在这套模式里)。然后给主 Agent 布置一个「要拆解」的任务,比如:

1
2
3
4
5
帮我调研「本地优先的 AI Agent 运行时」这个话题:
1. 找 DeepSeek Harness 的架构特点
2. 找 LangGraph 的架构特点
3. 找两者在多 Agent 协作上的差异
三个方向并行调查,最后汇总成一份对比表格。

主 Agent 会自己判断:这个任务能拆,于是连续调用 subagent 开出三个后台子 Agent,各自去查各自的方向。子 Agent 干完,用 report 把发现推回来——子 Agent 的 report 有两个投递模式

  • wakeup(默认):报告一到,唤醒主 Agent 开一个新回合接着干;
  • quiet:只把结果塞进主 Agent 上下文,不打断它正在做的事。

如果子 Agent 跑偏了,主 Agent 还有三个管理工具兜底:list_agents 看看哪些还活着(状态分 running 干活中 / idle 空闲 / ready 只在存储里可恢复),send_message 给某个子 Agent 补一句要求,interrupt_agent 叫停一个跑偏的家伙。这才是真正的消息传递,不是发出去就撒手不管。

四、用 workflow 写编排脚本:从「手动派活」到「自动流水线」

单个任务手动派活够用,复杂编排就得靠 workflow 工具了。它的思路很硬核:模型写一段 JavaScript,引擎在 worker_threads 里跑。脚本里有三个原语:

1
2
3
4
5
6
7
8
9
10
11
12
// 一个 workflow 脚本(模型生成,执行前先做 meta 校验)
const researcher = await agent({
description: '调研 DeepSeek Harness 架构',
prompt: '查清 Cordis 内核、subagent seam 和会话日志机制,输出要点',
});

const writer = await agent({
description: '汇总成文',
prompt: `根据这份调研写一段 300 字总结:${researcher.result}`,
});

return { summary: writer.result };

agent() 建单个子 Agent,pipeline() 让每个条目依次流过所有阶段(条目 A 走到第三阶段时,条目 B 可能还在第一阶段,互不等待),parallel() 则是栅栏——所有任务全部完成才继续下一步。两者的选择也很简单:只有当后面的阶段真的一次性需要前面所有结果(比如全量去重、决定要不要继续)时才用 parallel(),否则用 pipeline() 更快,它耗时等于「最慢的那条链」,而不是「所有阶段之和」。

防失控有三道保险:maxTotalAgents 限制单次运行最多能 agent() 出多少个子 Agent;signal(AbortSignal)可以中途取消;meta 在执行前先校验,引擎绝不靠「跑一下脚本」来提取元信息。

五、Ralph loop:长任务不掉链子的秘诀

还有个大杀器叫 Ralph loopralph 工具),专门治「长会话考古病」。它的规则很死:

  1. 目标不可变(immutable objective):一轮轮跑,目标不许漂移;
  2. 每轮一个全新子会话:不继承父会话、也不继承上一轮的对话;
  3. 跨轮只传一份「交接报告」(handoff):{ status, summary, evidence, nextSteps, blockerText }

所以 Ralph 每轮都把考古垃圾扔掉,只保留一份有界的结构化交接——上下文永远跟眼前这步的活成正比。适合「写一篇长文」「分阶段重构代码」这种有终点、但一轮干不完的活。它和 workflow 的区别在于:workflow 是通用编排(模型写任意 JS),Ralph 是固定策略(新子会话 + 交接报告),拿不准就先 workflow,要跑长迭代任务再上 Ralph。

六、避坑指南

  1. 先确认工具真挂上了。子 Agent、workflow 这些全是插件,挂没挂取决于你的模式和 profile 堆的 bundle。设计编排之前,先跑 dsh --profile web --dump-config 看一眼有哪些工具,别对着一个没挂载的工具空想编排。

  2. fork 别滥用,会浪费 tokensubagent_fork 会把当前会话历史一起塞给子 Agent,如果子任务根本不需要这些上下文,纯属白烧 token。可分离的任务一律用 subagent 新建。

  3. 子 Agent 不是拿你的工具副本。子 Agent 有自己独立的 scope,工具可以被裁剪或替换——比如可以配一个「只读、绝不写文件」的审查员。这正是预设(preset)能实现「只读审查者」的机制。

  4. list_agents 有范围参数。默认 scope: 'children' 只列直系子 Agent;scope: 'descendants' 会按序走完整棵子树,并标注每个节点的父会话和深度。send_message 只能发给深度 1 的子 Agent,再深层的只能 interrupt_agent

  5. 多模型换着来更省钱。多 Agent 场景天然适合「什么活配什么模型」:研究型子 Agent 用 DeepSeek V4,需要强写作的子 Agent 换 Claude——dsh 一个 key 就能把多家模型接上,多模型对接、价格还便宜,折腾阶段尤其划算(中转站配置见前几篇,ai.aklibk.com)。

五套工具串起来,dsh 就从「单兵 Agent」进化成了「能组队、能调度、能交接的项目经理」。下一篇我们换个角度:不再只用一个模型干到底,而是把 settings.yaml 玩明白。

生命不息,折腾不止。下一篇:《DeepSeek Harness 配置调优与模型切换实战》——settings.yaml 深入、多 provider 配置、按场景给不同 Agent 配不同模型,敬请期待。