Skip to content

Latest commit

 

History

70 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Adg 多智能体模式(DSH agent preset)

一份 DSH 自建 agent preset:一个调度智能体 + 一组专家智能体(当前名册见下面的「专家名册」一节)。你把需求说给调度智能体,它判断范围后分派给对应的专家,专家做完把结果交回来由它汇总;专家之间不能直接互相转交。

另外三件一起装的东西:

  • browser/ —— 默认无头的 Chromium 系浏览器驱动(Chrome / Brave / Edge 探测)+ 最小 CDP 驱动,零第三方依赖,是 agent_browser 实际用的工具链;
  • notify/ —— 仓库内部第一方子插件 adg-notify,注册工具 notify_user(Windows 桌面提醒,单向不阻塞);
  • skills/adg-add-agent —— 让你在任何模式(含创造模式)下说一句「给 Adg 加一个智能体」就能新增专家。

要看怎么改这个仓库(命令、红线、模块地图、质量门)请看根 AGENTS.md;本文是给人看的:怎么装、怎么用、怎么排错。

安装

最快路径:把仓库地址交给 AI

把仓库地址发给 dsh 里的 AI,说一句「按仓库 README 装到本机」。本文的「给 AI 的安装指令」一节就是写给它看的。

手动安装

git clone <repo-url> ~/adg-multi-agent
sh ~/adg-multi-agent/install.sh                     # macOS / Linux
git clone <repo-url> $HOME\adg-multi-agent
powershell -ExecutionPolicy Bypass -File $HOME\adg-multi-agent\install.ps1   # Windows

要求 Node ≥ 22。

安装脚本的参数(两边行为等价,只是写法不同):

参数 作用
不带参数 对**每个"能装 preset 的 profile"**逐个注入组探测,各自决定拿哪一份生成物
位置参数(sh install.sh web desktop;PowerShell 用 -Profiles web,desktop) 只装指定的 profile 子集
--billion-context=auto|on|off(PowerShell:-BillionContext) on / off 是整体覆盖该注入组的探测结果,覆盖与探测不一致时脚本会多打一行黄字警告
--save-token=auto|on|off(PowerShell:-SaveToken) 同上,管另一个注入组

auto(缺省)的语义是"装了什么才注入什么":脚本对每个 profile、每个注入组各探测一次,装着那个插件才把它的全局工具名注入专家的 allow,并给它挑对应的那一份生成物。不传参数时它只挑 dsh.profile.bundles 里含 @deepseek-ai/dsh-web-app 的 profile —— 判据是 preset 注册服务由那个 bundle 声明,往缺它的 profile 里塞声明行会让该 profile 启动失败。

装完必须重启 dsh

preset 的改动按"重启 + 新会话"验收,别赌热重载。 装完重启 dsh,然后在新建对话里选「Adg 多智能体模式」。重启之前 Adg 模式仍在用旧组合运行,不要拿它做验证。

(browser/ 是例外:重跑一次安装脚本即生效,不用重启。)

装到哪里

${DSH_HOME:-~/.dsh} 是你的 dsh 用户根。

仓库里的路径 安装到 生效方式
preset/(preset 的源文件) 先由 tools/gen-preset-bundle.mjs 生成 bundle(生成物落在被 .gitignore 排除的 bundle/adg-<味道>/,产物不入库、不许手改),再按味道拷到它的稳定目录 ${DSH_HOME:-~/.dsh}/bundles/dsh-adg-preset(以及 ...-bili / ...-save-token / ...-bili-save-token),并把包名 dsh-adg-preset 写进目标 profile 的 dsh.profile.bundles 重启 dsh + 新会话
skills/adg-add-agent/SKILL.md ${DSH_HOME:-~/.dsh}/skills/adg-add-agent/SKILL.md 用户技能根是热加载的,立即生效
browser/ ${DSH_HOME:-~/.dsh}/browser/ 重跑安装脚本即生效,不用重启
notify/ 稳定副本 + dsh plugin --profile <p> add "file:<稳定副本>" 重启 dsh + 新会话

味道:一份源文件,四种生成物

有两个可选的外部插件会往全局工具层注册工具,而它们给模型看的指令与通知只看自己的配置、不看这个请求到底有没有那些工具 —— 所以本 preset 必须按"这个 profile 到底装没装它"决定给不给专家那几个名字。这样一组东西在仓库里叫构建期注入组(清单只有一份,写在 tools/flavors.mjs):

  • billion-context:把会话上下文折叠进 pack,注册 compress / decompress / search_context / acp_status(同属该插件的 acp_cache 故意不注入 —— 它是给调度者做诊断用的,给每个专家只会加长它们每次请求的固定前缀)。它激活时还要关掉 preset 自己的自动压缩(给 compaction-basic 注入 config: {auto: false}):有 bili 在折叠上下文时,让 dsh 自带的自动压缩同时上工会两套压缩抢同一段历史。auto: false 的语义是「关掉自动压缩与溢出恢复,手动 /compact 仍可用」,不是把这一行禁用。
  • save-token(dsh-plugin-save-token):在工具结果进入历史的那一刻把大输出换成 [save-token #id] … 通知,并注册 save_token_expand 让人把原文取回来。通知正文会直接点名那个工具,而被委派的专家确实收得到它,所以装了就必须注入,否则专家会去调一个不存在的工具。

所以口径是"源文件中立、生成物按探测决定":

味道键 稳定目录($DSH_HOME/bundles/) 注入专家的工具名 compaction-basic 的 config.auto
plain dsh-adg-preset 无 不写(这些 profile 里 dsh 自带的自动压缩是唯一的压缩手段)
bili dsh-adg-preset-bili compress / decompress / search_context / acp_status false
save-token dsh-adg-preset-save-token save_token_expand 不写
bili+save-token dsh-adg-preset-bili-save-token 上面五个名字 false

四份生成物的 package.json 逐字节相同、包名都是 dsh-adg-preset(所以 dsh.profile.bundles 那一行四种味道通用),只有 cordis.patch.yml 不同;每个 profile 的 node_modules/dsh-adg-preset 只链接它该拿的那一份。目录名不要写死,以 tools/flavors.mjs 的 dirNameFor(key) 为准(味道键里的 + 换成 -)。手动生成不带旗标 = plain:忘带旗标只是少个能力,不会装坏。

真实挂载验证

静态自检证明不了挂载 —— 只有真实挂载算证据。 node tools/check-preset.mjs 是逐行文本扫描器、不是 YAML 解析器:exit 0 只说明"这些硬约束在文本上没被破坏"。做法:重启 dsh 后在新对话里选 Adg 多智能体模式,再挂一个注入 agentPresets 的临时插件读运行期状态(读法见 skills/adg-add-agent/SKILL.md),判据是这几条:

  • agentPresets.resolve('adg') 的 .broken 为空 —— 它是"这份组合能不能用"的唯一判据,报的是具体哪一行起不来;
  • agentPresets.list() 里能看到 adg。
  • compositionInventory() 报的启用专家行与你预期的名册一致,且没有 tool-subagent-fork 行。判据要写准:它报的是模块名,所以 @deepseek-ai/dsh-tool-subagent 出现的次数 = 专家行数 + 两条 enabled: false 的 codex / claude-code 行,按"出现次数 = 专家行数"去断言会误报失败。

专家名册

本文档里逐专家枚举只有这一处:新增 / 删除一个专家,只改这里的一行(连同 preset/agent.cordis.yml 的专家行与顶部调度 persona 的名册)。每行的「组」写的是它覆盖的能力带(不带个数),「本环境的边界 / 缺口」一栏写的是本环境的真实实现口径,不是宣传语:

专家(toolName) 组 何时派他 越界时找谁 本环境的边界 / 缺口
agent_file 文件与文档 检索定位、深入阅读与问答、批量整理归类、格式转换与文档生成;包括图片内容理解(read_image) 要改文件内容找 agent_coder;系统级操作找 agent_computer;公网资料找 agent_search 图片内容理解走 read_image(需要模型路由支持图像输入);文本类文档(PDF / Word / Excel / PPT)用本机已有工具提文本。OCR、人像/场景检索、跨设备传输取决于本机工具链:先探测可用工具,缺什么就直说「本机缺少 X,无法完成」并给替代方案,不允许假装完成
agent_computer 系统与应用 系统与硬件信息、设置修改、优化清理、故障排查、进程与服务控制;桌面软件启停/安装卸载与命令行调用、Android 模拟器上的 App、微信小程序 先按 persona 明写的去向:不整理用户文档 → agent_file;不改工作区代码 → agent_coder;不做网页交互 → agent_browser(以及任何不可逆 / 高风险的系统状态改动:先停下写明需要用户确认,由调度者转达) 不依赖模拟点击的 Windows API 路线可用(PowerShell / CIM / P-Invoke);软件侧只能走 CLI / adb / winget / 软件自带接口 —— GUI 视觉识别 + 模拟点击在 DSH 没有对应工具,「看界面点按钮」类需求必须明说不具备并给替代。会改变系统状态的操作要先说明影响与回退;不可逆或高风险操作必须先停下、写明需要用户确认
agent_browser 网页 登录态下的站点操作、多步表单、点击与下拉选择、多页跳转抓取 系统设置找 agent_computer;整理本地文件找 agent_file;只取静态内容的公开页可找 agent_search 本会话必须是「完全权限」(danger-full-access)—— 硬约束(理由见下一节);走 browser/ 工具链(默认无头;需要人进去操作时才升级成有头窗口,登录态跨会话复用);工具链不可用或目标本来就静态可取时降级成 web_fetch 单次抓取(只能取静态内容、不能交互),并在回答里说明是降级执行;撞上登录墙 / 验证码 / 二次验证时把有头窗口开好、停手如实报,由调度者转达你。截图可以用 read_image 自己看
agent_search 检索 多轮联网检索与多源资料综述,结论要带来源链接 先按 persona 明写的去向:读本地文件 → agent_file / agent_researcher;改代码 → agent_coder;操作软件或系统 → agent_computer;在网页上执行交互 → agent_browser 只联网:工具面里只有 web_search / web_fetch,本地文件与系统级请求被硬性排除(这不是偏好)。天气、汇率、股价这类简单事实、以及一两次抓取就能答完的已知 URL 定点核对由调度智能体直接回答,不派给它
agent_researcher 检索 在本仓库/本机文件里定位实现、配置与出处 先按 persona 明写的去向:公网发现式调研 → agent_search;要落成改动 → agent_coder;要替用户做方案决策 → agent_reviewer 硬只读 —— 工具面里没有 write / edit / pwsh,真的改不动东西
agent_coder 代码 按已确定的方案改动工作区代码,并运行编译/测试自证 先按 persona 明写的去向:需要查外部资料 → agent_researcher;需要对抗性审查 → agent_reviewer;需要系统级操作 → agent_computer;需要普通文档整理 → agent_file 只在当前工作区内改动文件;不做需求解读、方案设计与系统级运维
agent_reviewer 代码 对已有改动做对抗性审查 报告的问题要改由 agent_coder 动手;事实出处不清找 agent_researcher 只报告、不修改被审对象与任何既有文件。它手上的 write 只有一种用途:把程序化验证用的临时脚本写进平台临时目录、用完删除;read_image 让它能直接看截图做视觉核对;验证仍以只读命令或测试为主

"专家之间不能直接互相转交"是能力边界,不是偏好:每个专家的可见工具目录恰好等于它那一行的 allow 名单(连 preset 自己注册的工具一起被裁),任何专家行的名单里都没有别的 agent_* 名册行。

浏览器专家需要完全权限

结论先说: agent_browser 要做真正的浏览器自动化,必须让本会话处于 danger-full-access(界面 Permissions 选择器里 id 为 danger-full-access 的那一项,或 /permission danger-full-access)。在 workspace-write / read-only 下,本机的 Chrome、Edge 与 Brave 三家都起不来,而且无头不改变这个结论 —— 有头与无头在受限令牌下同形失败。

根因(实测到这一层):沙箱在 Windows 上用受限令牌运行子进程,而该后端自己的文档把这条边界写在「已知限制」里 —— 受限孙进程的管道 stdio 捕获不可用(libuv 的管道 stdio 用有名管道,client 端打开所请求的写访问时没有任何 restricting SID 被授予)。Chromium 的 Mojo IPC 同样走有名管道,于是浏览器在进程初始化阶段就死掉,三家浏览器各有自己的失败签名(签名本体不在这里复述:三条签名的文本与判读口径见 browser/AGENTS.md 的「红线」一节)。同一批命令在 danger-full-access 下全部转绿。换 stdio 救不了浏览器(它要的是进程内部 IPC,不是它自己的 stdout),--no-sandbox / --single-process / --no-zygote、把 profile 放进工作区或临时目录都试过、全部无效。

这条约束无法从 preset 侧修掉,逐条原因(都是源码级事实):

问题 结论
父智能体能否给子智能体指定权限范围? 不能。子代理工具行的实例配置里根本没有沙箱相关项
能否用 preset 文件改默认权限范围? 不能。沙箱模式、权限预设、审批三行都在宿主的部署文件里;模式解析是"请求 > 会话事件 > 部署默认",没有 preset 侧入口
子代理能否自己升权(带 sandbox_permissions + 用户批准)? 不能。委派时子会话的审批策略被钉成 never,策略 never 对审批请求直接判拒、不弹窗
父级切换权限后,已经在跑的子代理会跟着变吗? 不会。权限在委派那一刻就被捕获并写进子会话 ⇒ 新权限只对"切换之后新开的子代理"生效

唯一能把子代理送进完全权限的路径是:你在会话里把权限切到 danger-full-access。 切完之后要新建委派(旧的先停掉再重派),不要等它原地变得能用。

处置是调度侧的两道闸门(提示级,不是权限强制 —— 它靠 persona 被遵守):

  1. 派发前问权限:调度者先读自己上下文里那行 Current DSH file policy:,不是 danger-full-access 就先问你,选项是「已切到完全权限,继续派发」/「改用降级方案:只做静态抓取(不能交互)」/「暂不做这项网页操作」。你答已切换后它会先确认那行真的变了再派发;没变就如实说没切成功。
  2. 派发前第二问:模式:同一次问你里让它定这次走有头还是无头(需要问权限时并进去,不分两轮),问题里写清可能访问哪些网站与这次要做什么。定完之后它把模式原文写进委派 —— 专家问不了你,委派里没写模式它就只能按工具默认(无头)开工,这道闸门也就空转了。同一条委派的续派 / 重派、以及沿用的同一个实例都用已定模式,不在流程中途换(换模式=优雅关掉旧实例再同 profile 同端口重开:磁盘 cookie 留住,内存里的未提交表单与页面状态会丢)。你已明说模式、或已说过不必再问 → 照办不再问,并在交付里写明这是你的要求。工具层的默认值没改:不给旗标仍是无头,变的只是谁来决定这一次用哪种模式。

刻意没做的事:本可以把这道闸门做成确定性拒绝(dsh-tools 的 tools[].pre-execute 钩子真实存在,非放行的判定会带 reason 变成一次工具错误)—— 没这么做,是因为它会把一条"流程提醒"升级成硬拦(连你想降级执行也会被一并挡掉),而要做对就得再起一个包、一条部署路径与一套测试,收益与体积不成比例。

登录墙与验证码:人工介入协议

能让你手动去登录/过验证码,而且这是默认路径,不是失败。 需要登录态才拿得到目标时,调度者就该照常派发、请你手动登录一次 —— 它不许在派发前就禁止专家登录,也不许为了回避登录先降级成静态抓取;只有你明确说过「不想登录/不想验证」时才走收手那条路。分工是:专家把有头窗口开好并停下来说明 → 调度者用 ask_user_question 转达你的选择 → 按你的回答决定「重派/换方式/收手」。撞上登录墙时专家还会先用 notify_user 给你发一条单向提醒(写清卡在哪、你要做什么;不阻塞、不等回话)。

为什么专家问不了你(源码级事实):ask_user_question 按 preset 注册给调度者,而用户提问服务在带上调用者 agent 时只认 live runtime root;被委派的子代理会拿到 DELEGATED_CALLER,那句错误文本自己就规定了做法 —— 「human interaction is unavailable while the calling agent is owned by another live agent; include the unresolved question or decision in the child agent's final result」。所以不要把 ask_user_question 加进专家的 allow(加了也不解决任何问题)。

你的回答 调度者做什么 专家做什么
「我去手动登录/过验证,已完成」 重新派发同一个 agent_browser,带上专家上一轮报的「CDP 端口 / profile 目录」与「用户已完成」 CDP 重连那个已有实例继续,不新开浏览器(登录态在旧实例的 profile 里)
「不想登录或验证」 停手,如实汇总「因为未登录,X 拿不到」 停手;不绕过、不换路径再试、不拿别的来源冒充
「试过了还是被挡」 停手,把结论交回你换方案(想再试就照常重派 —— 默认不设次数上限) 停手,报「人工验证未通过」并说明还能换的方式;不自己反复催、也不换路径偷试
「换种方式」 走降级路径(静态抓取/换来源),或按你的替代方案改派其它专家 说明这次拿不到哪些内容

人工介入没有次数上限。 需要你本人做的事 —— 登录/验证码/二次验证/切换会话权限/要你拍板的选择/要你在本机某处操作 —— 想做几轮就几轮,这条口径对所有专家、所有任务都适用(不只浏览器)。它买的是"别把还能请你帮忙错判成已经没救了",否则智能体会过早放弃、甚至事前就禁掉某条路径。唯一例外是你自己提出的:说过「不要打扰我 / 别问我」→ 需要介入时直接如实报「因为没有打扰你,X 拿不到」,不许换路径偷试;说过「只介入一轮」→ 该任务最多请你介入一次。真正该收手的判据只有两个:你说不想做,或你自己试过仍被挡。

同一份信息默认只在一个站点取。 浏览器操作很贵,而在两个以上站点取同一份信息基本等于把同一份材料买了 N 次。所以调度者默认不会要求同一个信息在两个以上站点各取一遍 —— 除非 ① 你明确要多源 / 对比 / 交叉验证,② 那个站点拿不到、或各站数据互相矛盾,③ 交付物本身就是跨站点比较(比价、同款选型)。真要多源时它会让一个 agent_browser 在一条委派里串行跑完再合并。

浏览器工具链与登录态资产

agent_browser 用的不是"每个任务现写一个脚本",而是仓库里的工具链:一个入口 cli.mjs、零依赖(只用 Node 内建 + 全局 fetch / WebSocket,要求 Node ≥ 22)、默认无头(不抢焦点、不弹窗)、实例活着就复用。装完之后它在 ${DSH_HOME:-~/.dsh}/browser/:

node "$env:DSH_HOME\browser\cli.mjs" help        # 契约以它为准(选项、输出行、退出码)
node "$env:DSH_HOME\browser\cli.mjs" profile     # 排错第一站:profile / 端口 / 浏览器可执行文件 / 默认模式
node "$env:DSH_HOME\browser\cli.mjs" launch --url "https://example.com/a"     # 默认无头;活着的是同一种模式就复用(STATE=REUSED)
node "$env:DSH_HOME\browser\cli.mjs" status      # 活着吗、什么版本、现在哪种模式、开着哪些页
node "$env:DSH_HOME\browser\cli.mjs" launch --headed --url "https://example.com/login"   # 需要人登录时才用:优雅关掉无头实例,同 profile 同端口换成有头(STATE=SWITCHED)
node "$env:DSH_HOME\browser\cli.mjs" text --url "https://example.com/a" --out page.txt
node "$env:DSH_HOME\browser\cli.mjs" eval --file probe.js --match example.com
node "$env:DSH_HOME\browser\cli.mjs" tabs        # 看现在开着哪些页(清理前先看这个)
node "$env:DSH_HOME\browser\cli.mjs" close-tab --match hotels.ctrip.com   # 收掉自己开的那些页
node "$env:DSH_HOME\browser\cli.mjs" close       # 唯一让登录态落盘的动作

默认模式为什么是无头:日常自动化根本不需要人看窗口,而有头窗口会抢焦点、在任务里弹到你面前。模式不是猜的 —— /json/version 的 User-Agent 里有没有 Headless 就直接决定了它是哪种模式(三家浏览器都成立,无需额外的状态文件)。想全局改默认值用环境变量 ADG_BROWSER_MODE=headless|headed(写别的值直接报错,不静默回落);单次覆盖用 --headless / --headed。

登录态是资产,不是每任务重来的消耗品。 profile 固定在 ${DSH_HOME:-~/.dsh}/browser-profile、与会话工作区无关(工作区一换 profile 就换,正是"浏览器代理经常被登录拦住"的成因)。于是流程变成:第一次撞登录墙 → 你在那个有头窗口里登录一次 → 每次任务收尾 close(cookie 落盘)→ 之后同一个 profile 免登录。要沿用别处已有的 profile 就传 --profile <绝对路径>,不要复制目录。

五条不变的行为(不变量见 browser/design.md):

行为 为什么
launch 幂等:端口活着、模式也一致就 STATE=REUSED,不重启 重启会丢内存里的会话态,而"你刚登录完"正是最不该被打断的时刻
换模式只能显式要求:--headed / --headless 才动手,且只有"活着的正好是另一种模式"时才换;换法唯一=优雅关掉旧实例 → 等端口落下 → 同 profile 同端口重开 静默统一模式会砸掉你刚登录的窗口;而"直接起第二个实例"根本不成立(同 profile 的第二个有头实例会把启动请求转交给活着的那个再自己退出,无头第二个直接硬失败)
任务进行中不 close;只有本轮交互全部完成、你不再需要在窗口里操作时才 close close 会关掉那个窗口;你可能正登录到一半
选页必须命中:--match / --tab 不命中就报错,不随便挑一页 静默挑错页会让"读到的内容"与"以为在读的内容"不一致
标签页不堆积:text/eval/shot --url <新地址> 自己开的临时页读完自己收(--keep 才留);存量用 close-tab 点名清;不点名不关、也不许关到只剩 0 个页面 "读得越多、页越乱"会留下成堆标签页;而关到 0 个页面等于绕过 close,你开着登录表单的页更绝不能被自动关掉

边界(不做的事):不代填账号密码、不读取 profile 的 cookie 库、不做验证码识别与指纹伪装、不加 --no-sandbox 之类降权旗标、不引入 playwright / puppeteer;不判断哪一页"已经不需要了"。登录永远由人在窗口里完成 —— 注意无头模式没有可操作的窗口,所以这一步的前提是先把模式升级成有头(同 profile 同端口,登录态留在原地);无头与有头在受限令牌下同样起不来,所以升级模式并不能绕开"需要完全权限"那条硬约束。

怎么用

  1. 新对话选择 Adg 多智能体模式,直接说需求。
  2. 调度智能体自己负责意图理解、任务拆解、调度与汇总,先判断范围再派发:

派给谁按本文「专家名册」一节那张表逐行对(专家名册、岗位、何时派他、越界时找谁都在那一张表里,本节不逐个专家列)。只举三个对应关系示意:文件与文档(检索、整理、转换、生成)→ 名册表里的文件与文档那一行;系统 / 硬件 / 设置 / 清理 / 故障排查、软件与 App 操作 → 系统与应用那一行;网页登录 / 填表 / 点击 / 多页抓取 → 网页那一行(需本会话为完全权限,不是的话调度者会先停下来问你;默认无头,要人工登录或过验证时才换成有头窗口)。

  1. 需要多个专家时(实体不同或性质不同才拆),它在同一条回复里并行启动多个委派,而且一律以后台方式派出 —— 只有后台的可续跑子代理才能被你在界面上发消息、随时停掉,也才能被调度者复用;阻塞调用会把这次委派降级成一次性运行,复用与"省重读"当场失效。后台不等于结果丢了:子代理结算时会带着收尾正文唤醒调度者,后续步骤照常接上,没有可以阻塞的例外。
  2. 同一个代码库 / 文档库 / 站点的多个"方面"不会各派一个子代理,而是合并成一条委派、让一个专家一次通读并分节产出;同一实体的后续任务优先接给已经读过它的那个专家(复用它的会话,省掉重读)。它接之前要看那个专家的状态:专家还在跑时发消息等于插进它当前任务那一轮,所以只有"修正/补充同一件事"才该现在发,"另一件事"要等它结算后再接给同一个它。
  3. 每条委派都必须带验收标准与本次不做,而且派发前要过必要性闸门:答案不会改变交付物、又不在验收标准里的旁路不派子代理,只在最终答复里挂号「未纳入本次:X(可能影响 Y,未调研)」—— 省钱但不隐瞒。交付时它按证据落点(命令与退出码、文件位置锚、URL)逐条判定验收标准,不拿专家的"已完成"自报当达标;未达标的要么返工,要么在交付里写明哪条没达标、缺什么。
  4. 专家的返回值只是给调度智能体汇总用的中间材料,不是给你的最终答复;最终交付由调度智能体整理后给出。
  5. 它做的大产出会分段交付(先给结论 / 证据位置 / 未验证的梗概,再分段给大正文):子代理的单条输出有上限,截断是正常结局(不是失败),被截断时调度者会把同一个子代理接回来续写,而不是重做一遍。

为什么不设 token 预算:本 preset 不压低任何体积旋钮 —— 上下文压缩阈值、单条工具结果的截断长度、检索与抓取的上限一律用插件出厂默认值,persona 里也不写"你能读多少 / 结论写多长"。理由:截断会把工具已经取到的事实切掉(模型只能重取、换查询或拿残缺证据下结论,三者都比不裁更贵);提前压缩不可逆(过了压缩点一切只能基于摘要);写在 persona 里的预算会把专家的注意力从"把事情做对"挪到"别写太多"。成本控制改放在编排层(同一实体 + 同一性质合并成一次委派、后续任务接给已经读过它的专家、大材料走 digest、派发前过必要性闸门)与输出纪律(不回贴工具输出原文、同一结论只说一次、不转述中间过程、"未验证 / 未纳入"必填块不许为求简短省略 —— 没有字数上限)。这两层约束的是"派给谁、派几次、材料怎么中转、写下来的东西怎么组织",不是"单个专家能读多少、能写多少"。

怎么加一个智能体

在任何模式里说,例如:

给 Adg 加一个智能体:文档员,负责把内部笔记改写成对外口径,只能读不能改文件,需要改动时报告需要 agent_coder。

AI 会加载技能 adg-add-agent,一次问清岗位 / 能力范围 / 越界时报告需要谁,然后改三处(preset/agent.cordis.yml 的新增专家行 + 同文件顶部调度 persona 的名册 + 本文「专家名册」一节的新增一行)。改完在仓库里跑一次自检:

node tools/check-preset.mjs

通过(exit 0)即可,重启 dsh 后生效。自检还会核对承载体积旋钮的那三行是否完好(行在、包名对、没被关掉、config: 里没有插件不认识的键);本 preset 刻意不覆盖任何旋钮,所以它打印出来的是插件出厂默认值。

故障排查

症状 先看这里
装完没有「Adg 多智能体模式」可选 重启 dsh 了吗?装的是能装 preset 的 profile 吗(判据:该 profile 的 dsh.profile.bundles 含 @deepseek-ai/dsh-web-app)?
模式在,但某次委派直接报 names unknown global tool "…" 那个 profile 拿错了味道(生成物里的注入名与它实际装的插件不匹配)。重跑 install.* 让它按探测重选,或显式用 --<组>=on|off 覆盖
专家收到"去调 compress / save_token_expand"却没有这个工具 同上,反方向:该 profile 装了那个插件,却拿了 plain 味道。重跑 install.* 并确认 node_modules/dsh-adg-preset 链接的是哪一份稳定目录
resolve('adg') 的 .broken 非空 它报的就是起不来的那一行;最常见的是 composition 里的 @deepseek-ai/* 包名随 dsh 升级改了名(用旧名会报 … never started)
改了预设但行为没变 preset 改动必须重启 dsh + 新会话;browser/ 才是"重跑安装即生效"
浏览器起不来(命中 browser/AGENTS.md 的「红线」一节那三条沙箱失败签名里的任意一条) 本会话不是完全权限。切到 danger-full-access,并新建委派(已在跑的子代理拿不到新权限)
浏览器专家说没有可操作的窗口 当前是无头实例:需要你操作时用 launch --headed 换成有头(同 profile 同端口,登录态留在原地)
提示 names unknown global tool 只出现在某一个 profile 那是该 profile 自己的味道选错,不是全局配置问题 —— 四种味道本来就允许共存
装的时候 pnpm 报文件被占用 dsh 正在运行。要真正装/换依赖先关掉 dsh;脚本会如实报告并继续
install.ps1 在 Windows PowerShell 5.1 上直接解析失败 检查文件前三个字节是否仍是 EF BB BF:这个脚本必须保留 UTF-8 BOM,没有 BOM 时 5.1 会按系统 ANSI 代码页读它、中文变乱码
想知道某个结论"量过没有" 先看本文末尾的「未观测」一节与各模块的 **未观测**: 条目;都没有的就是还没量过,别当成实测

许可

preset 的包清单(preset/bundle.package.json)与 notify/ 的包清单都声明 MIT。仓库里没有单独的 LICENSE 文件;以包清单里的字段为准。

未观测

未观测就地写在它所属模块的文档里,本文不留副本、也没有集中台账:要判"这条量过没有",就去该模块的 design.md / testing-guide.md 里搜 **未观测**:,命中处紧跟的一行就是它的量法。跨模块的那几条(编排层规则是否被遵守、子代理 running 时会不会被插话、截断后是否接回续写、交付端是否逐条判定验收标准、不确定时是否先问用户)不按单个模块切分,所以就地写在 preset/design.md 与 preset/testing-guide.md 里。

现行规范(引用任何结论前先看):未观测不许写成实测,也不许写成"不可观测" —— 每条未观测都必须给出量法与可复跑的判据。引用别人记载的实测必须写明来源,不得写成自己验证过。版本区文档只描述当前项目状态,不写变更叙述 —— 变更史由 git 提交历史承担。

给 AI 的安装指令

  1. git clone <repo-url> <tempdir>
  2. 生成 bundle:node <tempdir>/tools/gen-preset-bundle.mjs bundle/adg-plain(plain;--with-billion-context = bili、--with-save-token = save-token、两个旗标叠加 = bili+save-token)。输出目录是位置参数;不传位置参数才落到缺省 <tempdir>/bundle/adg-preset/,两种写法别混。它读 preset/preset.yml(显示元数据)+ preset/agent.cordis.yml(插件条目列表)+ preset/bundle.package.json(包清单模板),写出 {cordis.patch.yml, package.json}。bundle/ 是构建产物(在 .gitignore 里),任何情况下都不要手改生成物 —— 要改就改 preset/ 下的源文件再重跑。目标 profile 装着哪个注入组就装哪个味道的产物(手工装的时候别只装 plain);生成完顺手 node <tempdir>/tools/check-bundle-flavor.mjs <那份文件> <味道键> 验一遍。
  3. 判断每个 profile 该拿哪个味道:先 node <tempdir>/tools/has-bundle.mjs "$DSH_HOME/profiles" <profile> 逐组问一遍(缺省探测 billion-context,换组加 --package=dsh-plugin-save-token),再用 node <tempdir>/tools/resolve-flavor.mjs --<组> … 翻成"味道键 / 稳定目录名 / gen 旗标"。每个 profile 只装它该拿的那一份,不要把多份都链接进同一个 profile。
  4. 装 bundle:用 plugin_manager 的 install_bundle,target 给 bundle 目录的绝对路径 —— 包安装与 dsh.profile.bundles 选中由它自己完成,不要用 shell 命令复刻这两步。想让"仓库被删/被挪也不影响已装好的 dsh",先把生成物整个拷到它自己的稳定目录(${DSH_HOME:-~/.dsh}/bundles/ 下;目录名不要写死,以 tools/flavors.mjs 的 dirNameFor(key) 为准),再拿那个稳定目录当 target(install.ps1 / install.sh 就是这么做的)。装完 list_bundles 里应能看到 dsh-adg-preset。
  5. 复制 <tempdir>/skills/adg-add-agent/SKILL.md → ${DSH_HOME:-~/.dsh}/skills/adg-add-agent/SKILL.md。
  6. 装 notify/ 子插件:把 notify/ 拷到一个稳定副本,然后 dsh plugin --profile <p> add "file:<稳定副本>",并读回该 profile 的清单确认它真的在(install.* 的第 2b / 4c / 4c-1 步做的就是这个)。
  7. 校验(只有真实挂载算证据):挂一个注入 agentPresets 的临时插件,按「真实挂载验证」一节那三条判据核 —— .broken 必须为空、list() 里能看到 adg、compositionInventory() 的启用专家行与名册一致且没有 tool-subagent-fork 行。也可以直接 node <tempdir>/tools/check-preset.mjs(exit 0 表示通过),但它只是文本扫描器,上面那条真实挂载的校验不能省。
  8. 明确告诉用户:preset 改动仍按"重启 dsh + 新会话"验收(已挂载的会话不会中途换组合)。重启后在新建对话里选择「Adg 多智能体模式」。
  9. 如果用户还需要在创造模式里说「给 Adg 加一个智能体」被识别,确认第 5 步的技能已就位 —— skills 是用户技能根,两种模式都会扫描且热加载。

About

DSH agent preset: one dispatcher agent routes tasks to nine capability-scoped specialist agents, with a bundled CDP browser toolchain and an add-agent skill.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages