Back to home@pbwheel

dsh-agency-market

把 agency-agents 中的 273 个专业智能体装进 DeepSeek Harness,类似 workbuddy 中的专家

Stars
0
Language
JavaScript
Created
Sep 1, 2026
Updated
Sep 1, 2026
GitHub repo

Introduction

DSH Agency Market

装进 DeepSeek Harness 的专家市场:273 位专家,一键安装,随时召唤

English · 许可证

License: MIT Bundled experts DSH Web Plugin No build

dsh-agency-market 是社区维护的 DeepSeek Harness(DSH)插件,不是 DeepSeek 官方产品。 273 位专家人格全部导入自开源项目 agency-agents(MIT)。

它是什么

一个装在 DSH Web 里的「专家」市场:浏览专家卡片,一键把专家安装为用户级 agent preset。装好的专家有两种用法——新建会话时选预设直接开聊;或在任意已有会话里让模型召唤(market_experts / summon_market_expert 两个模型工具),随时换专家。

设置 → 专家市场 → 挑一张卡片 → 安装 ─┬→ 新建会话选预设 → 与专家开聊
                                     ├→ 任意会话里让模型召唤(market_experts / summon_market_expert)
                                     └→ 输入框「召唤专家」按钮 / @ 菜单 → 生成召唤指令草稿(不自动发送)

主会话始终保留任务上下文、判断与最终答复;被召唤的专家子代理只提供专业视角,且不能再召唤其他专家(防递归)。

特性

  • 市场页(设置 → 专家市场):registry 式名录——全宽搜索、领域分类 chips、超大领域的二级分组 tab、已装过滤、行内移除确认、骨架加载,卡片中英文双语,搜索跨语言命中。
  • 一键安装:安装即走 roster 认可的预设编写路径(复制底座 → 改写元数据 → 换 persona → 挂载校验),绝不写部署自带的 preset;卸载只删用户级条目。
  • 会话中途召唤market_experts() 列出可召唤专家,summon_market_expert(expert, task) 把一个自包含任务委派给专家——一次性子代理带着完整专家人格跑完任务并返回答复,同一会话可以给不同任务换不同专家。
  • 三个召唤入口:模型自己调工具、输入框「召唤专家」按钮、@ 菜单触发源;后两者只起草指令草稿,不自动发送
  • 273 位专家 × 18 个领域:学术、设计、工程、财务、游戏开发、GIS、医疗、营销、付费媒体、产品、项目管理、研究、销售、安全、空间计算、专业垂直、支持、测试。
  • 零构建、零运行时依赖、不执行任何安装脚本:纯 ESM JavaScript + JSON 数据,node scripts/smoke.mjs 一条命令离线自检。

前置条件

  • 一套可用的 DeepSeek Harness Web 安装,dsh 命令可用(Node.js 22+;dsh 不在 PATH 时可用 npx --yes @deepseek-ai/dsh 代替)。
  • 示例均使用 web profile,按需替换为目标 profile。

安装

方式一:让另一个 agent 帮你装

本插件运行在 DeepSeek Harness Web 里。把下面这句话粘给 DSH(或 Codex、WorkBuddy 等会装 npm 包的 agent),让它替你装进本地 web profile:

从源码安装 DSH 插件 https://github.com/pbwheel/dsh-agency-market 到我的 web profile:clone 该仓库,进入目录运行 dsh plugin --profile web add .,然后运行 dsh --profile web --dump-config 确认 dsh-agency-market 已挂载,并提醒我重启 DSH Web 和强刷浏览器。

方式二:从源码安装(调试或未发布改动)

git clone https://github.com/pbwheel/dsh-agency-market.git
cd dsh-agency-market
dsh plugin --profile web add .
dsh --profile web --dump-config

dsh plugin ... add 会读取包元数据与 cordis.patch.yml,把 host 半边接入组合层(dsh.profile.bundles 自动登记,无需手改)。配置输出里应能看到 dsh-agency-market

然后重启 dsh web(bundles 列表只在启动时读)并强刷浏览器。本插件无构建步骤、无运行时依赖、不执行任何安装脚本,克隆目录就是插件源码目录,不要只拷贝 src

安装排障

  • 市场页 404 / 只有客户端按钮不工作:确认 ~/.dsh/profiles/web/package.jsondsh.profile.bundles 数组里有 "dsh-agency-market",改完重启 dsh web(bundles 只在启动时加载);客户端半边由 loader 自动扫描,刷新页面即可。
  • @ 菜单里没有「专家市场」分组:package.jsondsh.client.inject 组合变更由 loader 在启动时扫描,重启 dsh web 即可(按钮与市场页不受影响,判空降级不报错)。

使用

1. 挑专家安装

打开 设置 → 专家市场:按分类浏览或搜索(中英文关键词均可命中),点卡片安装。已装行盖 ✓ 印章,行内确认即可移除。

2. 新会话直接开聊(preset 模式)

新建会话时,预设选择器里选该专家(expert-<id>,显示专家名与简介),即可以专家人格开一场会话。

3. 任意会话中途召唤(tool 模式)

在任意进行中的会话里,直接让模型召唤,或点输入框左侧的「召唤专家」按钮 / 输入 @ 选专家——按钮与 @ 只把指令写进草稿,不会自动发送

召唤专家「Code Reviewer」(engineering-code-reviewer)处理以下任务:
审查当前工作区的改动,按严重程度列出可复现的问题。

模型侧的两个工具:

  • market_experts(category?) —— 列出当前可召唤(= 已安装)的专家:id、名称、描述、分类;不知道精确 id 时先调它。
  • summon_market_expert(expert, task) —— 把一个自包含任务委派给某专家;expert 支持 id(推荐)或名称(含中文名,模糊匹配,歧义时报候选列表),task 需完整自包含、上限 8000 Unicode 码点。调用等待专家跑完并返回答复。

未安装的专家召唤会报错并提示「请先在 设置 → 专家市场 安装」。

一个专家是什么

一个专家 = 一个用户级 agent preset(expert-<id>,装在 ${DSH_HOME:-~/.dsh}/.agent-presets/ 下):

卡片字段落到哪里
name / descriptionpreset 的 preset.yml(预设选择器里显示的名字与简介;写入的是目录基字段/英文)
persona组合里 dsh-persona 行的 text(专家的系统提示词)
base被复制的底座预设(默认 standard,完整工具链)
avatar / tags / category市场页自己的展示字段(只在目录数据里)
中文 name / description / 分类名不进专家文件:放在 locale 覆盖层 data/i18n.d/zh.json,仅用于展示(见多语言

安装流程(宿主侧,全部走 roster 服务):

  1. agentPresets.copy(base, 'expert-<id>') —— 复制底座预设到用户根;
  2. 改写副本的 preset.yml(名字/简介);
  3. 用锚定替换把副本 persona 行的 text 换成专家 persona(锚不中则降级为底座 persona 并在 UI 提示,不会装出坏预设);
  4. agentPresets.standingKeyFor(id) 真实挂载校验,通过才算装好。

绝不写部署自带的 preset;卸载只删 trust: "user" 的条目。

行为与安全细节

  • 变更路由只接受同源 POST、请求体上限 4 KiB、同时只允许一个安装/卸载在进行;安装只是预设复制加两处文件改写,不执行任何构建/安装脚本
  • 防递归:子代理的 toolFilter deny 掉两个召唤工具名;系统提示词 section 在子会话(header 带 parentSession)返回空串,被召唤的专家学不会再召唤。
  • 专家子代理以 stopReason !== 'completed' 结束时报错(携带 diagnostic 与部分输出),run.dispose() 在 finally 里必定执行。
  • persona 里 {{model}} / {{cwd}} / {{provider}} 是宿主注册的提示词变量,原样透传、不做 sanitize;导入时会把其余完整 {{…}} 组拆开({{{ {),未注册变量会让子代理启动失败,因此按字面文本处理。
  • 所有副作用(路由、工具、提示词 section、插槽、样式)收集 disposer 统一释放,插件卸载即全部撤销。

目录数据

目录分三层,加载逐文件合并、逐文件隔离:某个文件 JSON 损坏或校验不过(id 不合法 / 缺 persona / id 重复)只跳过该文件并把原因放进 /api/state 返回的 warnings[],不会拖垮整个目录;头文件损坏也一样降级,只有全部不可用时才报错。

文件作用
data/experts.json头文件:version + categories(18 个领域)
data/experts.d/每位专家一个 JSON,按领域分子目录(273 位 × 18 领域)
data/subgroups.json二级分组覆盖层:超大领域的子分组(见下)
data/i18n.d/locale 覆盖层:展示层翻译(见多语言

一位专家的完整定义:

// data/experts.d/engineering/engineering-code-reviewer.json
{
  "id": "engineering-code-reviewer", // [a-z0-9-],安装后 preset id 为 expert-engineering-code-reviewer
  "name": "Code Reviewer",           // 卡片标题 + preset.yml name
  "avatar": "👁️",                    // ← agency-agents frontmatter emoji
  "category": "engineering",         // 头文件 categories[].id(= 领域)
  "tags": ["Engineering", "agency-agents"],
  "description": "卡片一句话简介 + preset.yml description",
  "base": "standard",                // 底座预设,缺省 standard
  "persona": "# Code Reviewer Agent\n\nYou are **Code Reviewer**…"  // = md 正文
}

二级分组(subgroups):engineering 一个领域装了 59 位专家,单层 tab 挑不动。二级分组刻意做成独立覆盖层而不是写进专家文件——上游 agency-agents 没有分组信息,--replace 重导入会清空重写 experts.d/,而覆盖层与 i18n 一样原样幸存:

// data/subgroups.json
{
  "categories": {
    "engineering": [
      { "id": "ai-ml", "label": "AI & Machine Learning",   // label 为基字段(英文)
        "experts": ["engineering-ai-engineer", /* … */] }, // 数组顺序即子 tab 顺序
      // …frontend-client / backend-architecture / data-database /
      // ops-reliability / cms-platform / practices-quality,共 7 组覆盖全部 59 位
    ]
  }
}

加载分两步、逐条降级:先按形状校验(坏 id / 空 label / 畸形 experts / 重复组跳过并告警),再与目录对账(目录里已不存在的过期 id、挂错分类的 id、被两个组重复认领的专家、成员掉光的空组,逐条跳过并告警)。当前覆盖四个超载领域:engineering(59 × 7 组)、specialized(58 × 6)、marketing(36 × 4)、game-development(21 × 6);其余领域规模小(≤13 位),保持单层。给新领域加二级分组只需照抄该文件 + zh 覆盖层,代码零改动。

重新导入:agency-agents 上游更新后重跑 scripts/import-agency-agents.mjs

node scripts/import-agency-agents.mjs --replace   # --repo <path> 指定仓库位置,--dry-run 只校验

多语言(locale 覆盖层)

页面静态文案走客户端 locale 服务(zh/en 双语字典)。专家名称/描述/领域与二级分组标签的多语言走独立的 locale 覆盖层 data/i18n.d/:每种语言一个 <locale>.json,纯展示元数据叠加在目录之上——experts.d/ 里的专家文件(含 persona)一个字节都不改,--replace 重导入也不会碰覆盖层:

// data/i18n.d/zh.json(en 不需要文件:目录基字段本身就是英文,缺失即回退)
{
  "categories": { "engineering": "工程", /* …18 个领域 */ },
  "subcategories": { "engineering/ai-ml": "AI 与机器学习", /* …与 subgroups.json 一一对应 */ },
  "experts": {
    "engineering-frontend-developer": {
      "name": "前端开发工程师",
      "description": "专注现代 Web 技术、React/Vue/Angular 框架、UI 实现与性能优化的前端专家"
    }
    // …273 位专家
  }
}

生效链路:市场页把当前界面语言作为 ?locale=zh|en 传给宿主(切换语言自动重拉);宿主用覆盖层逐字段覆盖、缺啥回退基字段;召唤侧 market_experts 的输出、专家名称匹配(粘贴中文卡片标题也能解析到)同样吃覆盖层。市场页搜索是跨语言的——API 为每位专家附另一种语言的关键词,zh 界面输入英文照样命中。冒烟测试会强制校验 zh.json 覆盖全部目录专家,重导入新增专家后跑一次即可发现漏译;批量重译可用 scripts/merge-zh-overlay.mjs 合并片段,零星修订直接编辑 zh.json。

架构

浏览器                                DSH 宿主进程
──────                                ───────────
client/client.js                      src/index.js  (host 入口,双 inject)
  settings.section「专家市场」            ├─ inject webServer+agentPresets:
  名录行/分组/搜索   ──同源 fetch──────→ │    src/routes.js   /dsh-agency-market/api/*
                                         │    src/experts.js  catalog + 安装/卸载/状态
  conversation.input.left               ├─ inject tools+subagents+systemPrompt+agentPresets:
  「召唤专家」按钮    ──同源 fetch──────→ │    src/summon.js   market_experts / summon_market_expert
  (菜单选中 → setDraft 草稿)            │                    + 提示词 section(子会话为空)
  inputTriggers「@」触发源                ├─ agentPresets 服务(copy / remove / standingKeyFor)
  (candidates → /api/state)            └─ subagents 服务(spawn provider,按次 persona)
data/experts.json + data/experts.d/        ~/.dsh/.agent-presets/expert-<id>/
data/subgroups.json + data/i18n.d/<locale>.json(展示层翻译)
  • host 半边src/):纯 ESM JavaScript,无依赖无构建。三个路由:GET /api/state(目录+已装标记+告警)、POST /api/installPOST /api/uninstallsrc/summon.js 注册两个模型工具 + 一个提示词 section;工具名为 market 命名域,避免与其他专家插件(如 dsh-agency-agents 的 list_experts / summon_expert)在同 profile 重名。两段 inject 相互独立:市场页不依赖工具 seam,召唤也不依赖 web server。
  • client 半边client/client.js):手写的 harness 客户端 bundle 格式(window.__ModuleLoader__.load({ id, factory }),唯一 external 是 react),注册两个插槽条目——settings.section 渲染市场页、conversation.input.left 渲染「召唤专家」按钮——并在 inputTriggers 服务可用时注册一个 @ 触发源(服务不在组合里则判空跳过)。样式走主题 token(--dsw-alias-* 等)并带回退,明暗主题自适应,焦点环与 prefers-reduced-motion 降级齐备;<style data-plugin> 标签随插件卸载被 loader 清掉。
  • 安装边界:预设编写只发生在宿主 agentPresets 服务;路由层只解析请求、调服务、序列化 JSON。

已知边界

  • 安装写入 preset.yml 的是目录基字段(英文名/描述),预设选择器因此显示英文名;中文译名只出现在市场卡片、召唤菜单与 market_experts 输出里(按安装时语言写死元数据会随语言切换过期,故刻意不写)。
  • 召唤是一次性委派(one-shot subagent):专家答复返回主会话,不保留可续聊的专家子会话——「直开专家会话」是路线图项。
  • persona 替换依赖底座组合里 persona 行的锚定形状;底座漂移时降级为底座 persona 并在安装结果里给出 warning(不会装出坏预设)。

路线图

  1. 远端 registry:catalog 从远端 JSON 拉取,支持市场内更新;
  2. 直开专家会话:卡片按钮直接开一个可续聊的专家子会话,主会话随时 @ 它;
  3. 富卡片:使用次数 / 作者 / 版本 / 预览对话示例;卡片排序(热门/最新)。

开发

node scripts/smoke.mjs   # 离线冒烟:目录与覆盖层加载 + 安装/卸载/状态 + 召唤工具 + client bundle 加载与注册

无构建、无依赖、无 install 脚本。改完 host(src/)或 package.jsondsh.client.inject 后需重启 dsh web 才生效(bundles 与注入组合只在启动时加载);只改客户端半边(client/client.js)刷新页面即可。目录与脚本:

  • src/index.js —— host 入口(双 inject 编排);
  • src/experts.js —— 目录加载(头文件 + 分文件 + 覆盖层)与安装/卸载/状态;
  • src/routes.js —— 三个同源 HTTP 路由;
  • src/summon.js —— 两个召唤工具 + 提示词 section;
  • client/client.js —— 市场页 + 输入框按钮 + @ 触发源;
  • scripts/import-agency-agents.mjs —— 从 agency-agents 导入/重导入目录;
  • scripts/merge-zh-overlay.mjs —— 合并 zh 翻译片段;
  • scripts/smoke.mjs —— 离线冒烟。

许可证与致谢

  • 本插件的源码与文档以 MIT License 发布(Copyright (c) 2025 pbwheel)。
  • data/experts.d/ 下的 273 位专家人格导入自 agency-agents(MIT,Copyright (c) 2025 AgentLand Contributors),许可见 data/experts.d/LICENSE;二级分组与中文翻译为本项目新增。