dsh-agent-studio
简体中文 · English · 在线文档
一个 DeepSeek Harness 图形化插件:可视化地精确配置 Agent 的提示词(prompt)、工具(tools)、可见技能(skills)。
模型每一轮看到的东西就三份:系统提示词、工具目录、技能目录。随着插件、工具、MCP 越装越多,这三份只会越来越大,拖累模型表现。另外 DSH 目前给子代理的配置极其简陋,没法单独配它的提示词、工具、技能、模型和思考强度。
本插件就是来解决这个的。它把 Agent 拆成可随意拼装的积木:提示词、工具、技能、模型拼成一个完整 Agent,子代理也一样能高度定制;预设可以随手新建;兼容官方 PTC 模式。
它不写、不删、不改宿主的任何预设文件,卸载即恢复原状。
可以搭配 dsh-context 一起用,查看模型这一轮实际收到的提示词、工具和 skill 到底长什么样。
它解决什么
| 你可能遇到过的问题 | 平台的默认行为 | 装上之后 |
|---|
| 系统提示词越堆越长,关不掉也用不上 | 预设里注册了哪些段就投递哪些段 | 按 agent 编一份白名单,名单外的段不进上下文 |
| 工具越装越多,同类工具一大堆,模型挑不准 | 工具面按已装的插件全量下发 | 挑出这个 agent 要用的,其余收起来 |
| 技能多了不好管 | 所有 modelInvocable 的 skill 都进目录 | 勾哪些就给哪些,不勾的模型看不见 |
| 每个 step 都塞一段运行时快照 | 官方按 step 动态注入,没有开关 | 代理级开关,关掉就不用再收 |
| 子代理只能整套继承主代理,占用大量上下文 | 官方 subagent 既没有条目标识,也没法按角色裁剪 | 每个子代理独立配:模型 / 提示词 / 工具 / 技能 / 后台模式 |
| PTC 模式下创建的子代理也是 PTC | 官方默认继承主代理的模式 | 子代理走传统模式还是 PTC,你说了算 |
| 干不同的活想用不同的提示词、工具、Skill,切来切去很麻烦 | 预设只管提示词组合,工具和 skill 是全局一套,换个预设照旧全量下发 | 给预设挂的 Agent 一切换即可 |
| 本地部署模型上下文紧张,根本对话不了几轮 | 做不到提示词全清,只能创造模式自己建一个 | 创建一个什么都不挂的Agent,给预设绑上就行,真 · 0提示词 |
面板预览
界面有浅色、深色两套:
Agent 详情:预设绑定、Agent 身份与 Agent 模式
Agent 详情(深色)
Agent 完整详情
提示词集:段清单、PTC 专属标记、自定义与平台预设
工具集:按来源分组的工具候选,带必配标记
技能集:按来源分组,同名 skill 的优先级写在下面
| 区域 | 做什么 |
|---|
| 左侧「Agent 池」 | 每个 agent 一条:绑哪个预设、装哪些集、Agent 模式、子代理名册 |
| 左侧集库 | 提示词集 / 工具集 / 技能集三类列表:新建、复制、改名、删除、导入导出 |
| 右侧详情 | 选中集 → 编成员;选中 agent → 装载集、配模型与后台模式、挂子代理、切快照开关 |
| 顶栏 | 全量导入 / 导出(导出的是草稿,含未保存的改动) |
| 底栏 | 保存改动;池级导入 / 导出 |
改 id 之前会先列出谁在引用它,改的时候把所有引用一并同步,不留悬空引用。
四个池,互相独立
四类配置对象各管各的,可以多对多引用。集建好之后,能被多个 agent 装载。
| 池 | 干什么用 |
|---|
代理 Agents | 指定绑给哪个预设;配 Agent 模式(传统 / PTC)、提示词、工具、skill、子代理名册,以及被当子代理时的模型与思考强度 |
提示词集 promptSets | 有序的提示词清单,顺序可调 |
工具集 toolSets | 工具名清单,插件的和 MCP 的都在里面 |
技能集 skillSets | Skill 清单,决定哪些能被 AI 自主调用 |
- 装载:把集挂到 Agent 上。同一个 Agent 装载的集之间不允许有重叠成员,界面和写入端点各拦一道。
- 绑定:把某个预设绑到一个 Agent 上,这个预设就交给它管了。
语义边界
绑定之后,这个预设就归这个 Agent 管。三面一个规矩:没装就是空的。
| 概念 | 规则 |
|---|
| 绑定预设 | 被绑定的预设,提示词、工具、skill、子代理全部交给这个 Agent;解除绑定即恢复原样 |
| 提示词集 | 一个都不装 = 投递空提示词 |
| 工具集 | 一个都不装 = 一个工具都不给 |
| 技能集 | 一个都不装 = 一个 skill 都不暴露;装了就只看勾的 |
安装
从 npm
dsh plugin --profile web add dsh-agent-studio
从源码
git clone https://github.com/thissensen/dsh-agent-studio.git dsh-agent-studio
cd dsh-agent-studio
pnpm install # 只装 devDependencies;peer 是宿主包,不走 registry
node scripts/link-deps.mjs web # 把宿主的 @deepseek-ai/* 链进本项目的 node_modules
dsh plugin --profile web add "link:<本目录的绝对路径>"
装完重启一次 DSH,在 设置 → Agent 中心 看到面板就成了。
link: 装法下改 lib/ 立即生效;改面板(client/parts/panel.js)刷新页面就行,不用重启。
- 改
package.json 的入口类字段(main / exports / dsh.*)后必须重启。
--profile 填 web(纯 Web 版)或 desktop(桌面版)。桌面版就是 Web 版加一层 Electron 壳,host 半边一行不用改。
卸载
dsh plugin --profile web remove dsh-agent-studio
卸载后宿主配置里不留任何痕迹。预设从没被改过,其余配置都在插件自己的数据里。
快速上手
- 打开面板:设置 → Agent 中心。左边是 Agent 池和提示词、工具、Skill 三个集库,右边是详情。
- 建一个提示词集,往里加提示词段。段有两种:
- 平台预设:引用平台自己注册的段,正文跟着平台升级走,面板里只读;
- 自定义:自己写正文,支持平台注册的
{{变量}} 插值。写了平台没注册的变量名,这次请求会直接失败。
- 建一个工具集,勾你要留下的工具。
skill 是必配项,没有它 AI 没法自主调用 Skill。
- 建一个技能集,勾要暴露给模型的 skill。候选按来源分组,可折叠,也可以整组勾选。
- 建一个代理:填名字,装上前面那些集,选 Agent 模式(跟随预设 / 原生 / 强制 PTC)和后台模式(可续接 / 一次性 / AI 自行决定)。子代理名册也在这里挂。
- 绑定:把这个代理绑到一个平台预设上。
- 保存。只有点了保存才落盘,别忘。
保存之后,用这个预设开个新对话就生效了。
配置与数据
配置存在插件自己的 settings 命名空间 agent-studio 下(在用户配置文件 settings.yaml 里)。模型是四个键加一份绑定:
agent-studio:
agents: # 代理池
- id: reviewer
name: 代码评审
model: { provider: deepseek, model: deepseek-v4.1-flash, reasoningEffort: medium }
background: foreground # always-background | foreground | model-decides
toolPresentation: follow # follow | native | ptc
promptSets: [review-sections] # 有序:集在这里的顺序就是段的投递顺序
toolSets: [read-only]
skillSets: [review-skills]
children: [tester] # 可以派出去的子代理名册
promptSets: # 提示词集:有序段清单;带 text = 自定义,不带 = 引用平台预设
toolSets: # 工具集:工具名清单
skillSets: # 技能集:skill 名清单
runtimeContextOff: [reviewer] # 名单里的代理不再收到官方的 runtime 快照
bindings:
presets: [{ presetId: standard, agentId: reviewer }] # 预设 → 主代理
这些列表全是数组,不是字典。 设置服务的合并语义是「对象递归、数组整体替换」,用字典的话界面永远删不掉一个成员。代价是 id 唯一性得自己保证,由界面和写入端点把关。
兼容性
- 目标环境:纯 Web 版 DSH(
dsh --profile web),社区桌面版也支持。
- 依赖的宿主服务(
peerDependencies,全部 optional):dsh-agent-presets / dsh-scope / dsh-settings / dsh-system-prompt / dsh-tools / schemastery。官方 DSH 升级导致某个服务缺席时,逐项降级,不抛错。
- 界面语言与主题跟随平台,自带中文 / English 两套文案,深色浅色都能看。
- client 半边零构建:
client/index.js 是壳(启动时加载),client/parts/panel.js 是面板(由 host 路由运行时按需伺服)。
已知边界
- 极简类预设(
minimal)的段面改不动。 这类预设的 persona 段带了 complete: true 标记,意思是「我就是完整的提示词,别再拼别的」。平台会在装配瀑布跑完之后把段清单强制换回那一段,插件在瀑布里算出来的白名单因此被盖掉——最终投递的永远是那一段。这是平台设计,不是插件的缺陷,而且它本来就只剩一段,损失有限。工具面、技能面没有这道后处理;standard / code / cordis 这类常规预设的段面也一切正常。
- 派活用插件自带的工具:
studio_list_subagents 现算子代理名册,studio_delegate 派活。配了名册的预设里,官方 subagent 会被停用,界面行内标出了替代方案。
- 同时派多个一次性子代理时,身份是按先后顺序配对的。 平台在
agent/created 事件里不告诉插件「这次创建是哪一次派活触发的」,插件只能按队列顺序推定:先创建的配先调用的。实测中顺序一致,但平台没承诺过这一点。可续接(Resumable)子代理不受影响,它在启动前就拿到了预生成的 childId,配对是精确的。
- 工具候选有冷启动。 没有会话时,宿主进程里根本没有那些工具注册,问谁都问不出来。所以观察结果会按预设落盘缓存,冷启动时面板拿它兜底。
目录结构
lib/ host 半边产物(npm 包的实际入口,tsc 从 src/host/ 生成)
index.js 入口:挂观察层 + 路由 + 生效层 + 派活工具
config.js 四个池的 schema + 装载重叠校验(数据模型的唯一真源)
preset.js 「当前 agent 跑在哪个预设上」的唯一出口
observe.js 装配期只读观察层
cache.js 观察结果的磁盘缓存(冷启动时面板的候选来源)
apply.js 装配期生效层(主代理拼装 + 子代理创建窗口挂钩)
delegate.js 派活工具 + 认领映射与待认领队列
presets.js 预设管理(列表 / 复制 / 删除,走官方服务)
models.js 模型目录(provider / 模型 / 推理档位)
attribution.js 工具来源归因(注册时刻记「谁注册的」,best-effort)
sdk-strip.js PTC 的 tools:sdk 声明正文裁剪
api.js host 侧路由分发
http-guard.js HTTP 请求围栏与响应工具
client/ client 半边产物
index.js 壳:注册模块 + 运行时加载面板 + 失败兜底卡片
parts/panel.js 面板实现(host 运行时伺服;改它刷新页面即生效)
src/host/ src/client/ 源码真源(tsc → lib/,vite → client/)
types/ 宿主类型声明
assets/ README 用的截图
scripts/ 依赖链接 + 三个离线自检
tests/ client 侧自检(vitest + 真 React + testing-library)
开发与自检
pnpm build # tsc → lib/;vite → client/(壳 + 面板)
pnpm typecheck # host 与 client 两个 tsc,都要零错误
node scripts/verify-host.mjs # 110 项:挂载 / schema / 服务缺席降级 / 注册回滚 / 来源归因
node scripts/verify-apply.mjs # 120 项:段过滤与工具收窄 / SDK 裁剪 / 异常边界
node scripts/verify-api.mjs # 118 项:HTTP 围栏 / 配置写入 / 预设增删
npx vitest run # 263 项:client 侧(真 React + testing-library)
合计 611 项,改完必跑。先 pnpm build 再跑,自检跑的是 lib/ 和 client/ 的产物,忘了构建会出假 pass。
client 侧的断言挂在真 React 上,能重渲染并断言「点一个按钮之后界面变成什么样、打出去的请求对不对」。client 代码跑在浏览器里,看不到控制台,这套断言是它唯一的防线。
文档
对外技术文档正在整理,将在 docs/ 下发布。当前可参考的权威来源是
DeepSeek Harness 官方仓库与官方文档站。
License
MIT