Introduction¶
A common pain point when orchestrating agents is that experts’ personas, responsibilities, and escalation rules are scattered across prompts and code, so changing the review lineup requires updating the engine. dsh (DeepSeek Harness) follows the principle of “everything is a plugin,” and libinyam/dsh-experts extends this idea into a user-writable data directory for an “expert team”: each team is automatically registered as a model-routable skill (experts-<team name>), decoupling the engine from the lineup. This post covers its design, installation, and usage.
What is this¶
dsh-experts is a dsh multi-expert plugin maintained by libinyam under the MIT license. In one sentence: it turns expert persona lists into native dsh skills — team discovery, validation, and workflow protocols live in the plugin, while expert personas and escalation routing live in the team directory. The design references the product form of Qoder Expert Teams / WorkBuddy Expert Teams, and the collaboration protocol inherits from the author’s earlier github-project-review-skill (escalation routing matrix, data-gated decisions, layered output depth), built on dsh native capabilities (skills provider, resumable child, nested subagent, message and report channels).
How it works¶
The plugin scans team directories by rank, with same-name teams overridden by the lowest rank (closest source):
- Project
.dsh/experts/(rank 100) config.teamDirs(rank 300)<dshHome>/experts(rank 400)- Bundled
teams/(rank 600, sample teams)
After discovery, it strictly validates each team’s team.json (fail loud). Once passed, it assembles the workflow template, roster, persona cards, and escalation matrix. Then experts-<team name> appears in the skill directory, and the model can route to that team.
Runtime actions have two steps: the current session first starts a real lead child, then lead dynamically starts specialist children based on the task — only relevant experts are started, and they can be continued or additionally dispatched.
If you want to modify the official sample, the standard approach is to copy the bundled sample directory into <dshHome>/experts/ and edit it there; a same-name team at the project level will automatically mask the bundled version.
Writing a team directory¶
A team is a directory:
my-team/
├── team.json # 机器接线:名称/描述/工作流/专家/升级路由
├── TEAM.md # 团队级约定(可选,注入技能 body)
└── experts/ # 人设卡,由 lead 在 specialist prompt 中全文注入
├── lead.md
└── coder.md
Key fields in team.json:
experts[]: 1–8 experts,{id, role: coordinator|specialist, card, modelHint?}; exactly one coordinator is started as the lead child;escalations[]: escalation routing{from, to, when, priority(P0|P1|P2)}, wherefrom/tomust reference expert IDs and must not be self-referencing;TEAM.md: team-level conventions, optional, injected into the skill body;experts/*.mdpersona cards are fully injected by lead into specialist prompts;reportLanguage:zh(default) oren.
Validation is fail loud. The following are rejected outright: unknown fields, path escapes (../, absolute paths, drive letters, symlinks escaping the directory, NUL bytes), dangling escalation references, multiple coordinators, free text containing line breaks or pipe characters (to prevent Markdown structure injection), cards containing 4 or more backtick fences, TEAM.md exceeding 64KB, and so on. Error messages include precise file paths and field names. Same-name teams are first deduplicated by name, then the winner is fully validated — a valid lower-rank team can mask a bad same-name team; without masking, any bad team causes an error across this provider, and fixing that team restores service.
Installation and enabling¶
The recommended way is to add it to a dsh profile: add this package to dependencies and bundles in the profile’s package.json.
{
"dependencies": {
"dsh-experts": "github:libinyam/dsh-experts"
},
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-experts"]
}
}
}
For local development, you can use "dsh-experts": "file:<path to this repo>".
The second method is manual placement: clone this repository into the profile’s node_modules/dsh-experts, and append "dsh-experts" to the bundles list. The plugin has no external dependencies and no installation step is required.
Environment requirements: Node ≥18; zero runtime dependencies, zero devDependencies; plain ESM JavaScript, no build step.
Typical usage¶
After installation, the skill directory contains the built-in sample team experts-web-review (5 experts: coordinator tech-lead + frontend + backend + testing + security). Tell dsh:
Use experts-web-review to assess the launch readiness of owner/repo
Create your own team using the companion script by copying the built-in web-review sample:
node node_modules/dsh-experts/scripts/new-team.mjs --name my-team
By default it copies to <dshHome>/experts/my-team. Edit my-team/team.json (description, experts, escalation routing) and the experts/*.md persona cards, then validate offline:
node node_modules/dsh-experts/scripts/validate-team.mjs <dshHome>/experts/my-team
Once validation passes, experts-my-team is automatically added to the skill directory. Note that v0.1 has no file watcher; after adding or changing a team, reload the plugin to refresh the directory.
Common developer-side commands:
npm test # 全量测试(单元 + 守护)
npm run guard # 只跑宪法守护测试
npm run validate-team teams/web-review # 校验内置示例团队
Configuration¶
Configuration is written in cordis.patch.yml; all keys are optional:
| Key | Default | Description |
|---|---|---|
providerName |
dsh-experts |
Provider name in the skills registry |
includeDefaultRoots |
true |
Whether to scan project/user roots (when disabled, only teamDirs + bundled) |
dshHome |
$DSH_HOME or ~/.dsh |
Override the dsh home directory |
teamDirs |
[] |
Extra team roots (rank 300) |
includeBundledTeams |
true |
Whether to expose bundled sample teams |
Equivalent environment variables: DSH_EXPERTS_PROVIDER_NAME, DSH_EXPERTS_INCLUDE_DEFAULT_ROOTS=0, DSH_HOME, DSH_EXPERTS_TEAM_DIRS (semicolon/comma-separated), DSH_EXPERTS_INCLUDE_BUNDLED_TEAMS=0.
Known issues (v0.1)¶
- No file watcher: adding or modifying teams requires reloading the plugin.
- Each
list()rescans and revalidates all teams from scratch (no caching); with thousands of teams, directory refresh overhead is noticeable. - Only the
reviewworkflow template is available; thedeveloptemplate (patch-based output + green-light gates + manual PR) is on the roadmap. - Roots in the
.agentsfamily are not scanned. modelHintis only a template hint and does not force routing to a model.
Use cases and notes¶
This is suitable for agent developers who need multi-expert review workflows in dsh, want the lineup to be versionable and modifiable as data, and do not want to modify the engine to change personas.
Before using it, keep the following in mind:
- A bad team (without a same-name lower-rank mask) causes an error across this provider. This is fail-loud design; fix it according to the error message and service is restored.
- When subagent or report tools are unavailable, the plugin explicitly marks the team as runtime-unavailable rather than pretending an expert is working.
- Troubleshooting entry: check dsh console logs for
skills.registerProviderrelated errors, or runscripts/validate-team.mjs <directory>to locate issues offline. - The plugin runs with the permissions of the current dsh process. Before installing, review the source code and license yourself (MIT).
Conclusion¶
The value of dsh-experts is turning “changing the lineup” from code changes into directory changes: strict validation catches low-level errors, rank-tiered override supports in-place customization, and automatic skill registration lets the model route as needed. Repository and directory page:
- GitHub: https://github.com/libinyam/dsh-experts
- Directory page: https://www.skillhub.cn/plugins/libinyam/dsh-experts (community site, no official affiliation with DeepSeek / High-Flyer)