为每个 DSH 会话附加一个独立评审模型,按 nit/concern/blocker 三档严重度给主会话提建议,仅建议不阻断。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add dsh-advisor在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-advisor:先查看仓库 https://github.com/omdsh-dev/dsh-advisor 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
为每个 DSH 会话附加一个独立评审模型,观察主会话 transcript 后按 nit / concern / blocker 三档严重度注入带前缀的 user-role 建议;advisor 仅作为旁路评审,不会替主 agent 批准、否决或执行任何动作。
核心能力
- 按会话独立评审:每个会话拥有独立的
AdvisorRuntime与有界积压队列(默认 32,满时丢最新),主循环始终不被阻塞。 - 三档严重度建议:nit(轻微风格/清晰度提示)/ concern(值得权衡的实质风险)/ blocker(明显浪费工作的方向错误);缺失或非法 severity 默认按 nit 处理。
- 按严重度分级送达:nit 通过
agent.inject(不打断),concern/blocker 通过agent.steer(唤醒主 agent),但immuneTurns冷却窗口内的打断性建议会自动降级为 inject。 - 会话级命令控制:在会话里输入
/advisor [on|off|status|config]可临时开关、查看运行态、查看合成配置;这些切换只作用于本会话,从不修改持久化配置。 - 三路径配置合成:同一组配置键可经 web Settings 卡片(设置 → 插件配置 → Advisor)、dsh-tui
/settings屏幕的 Advisor 分节、或 profile 的cordis.patch.yml编辑,全部写入同一个advisorsettings namespace,无需重启即可热应用。 - 零工具 + 自审隔离:评审者只是一个普通模型调用,没有任何 advisor 工具;advisor 注入的消息带专属
source.kind标记,下次 delta 自动排除,advisor 永远不会读回自己的建议。
技术实现
- 语言: TypeScript(ESM,主包 + 浏览器客户端两套入口)
- 关键依赖:
@deepseek-ai/cordis(插件 fiber 框架)、@deepseek-ai/dsh-llm(llm.stream流式调用)、@deepseek-ai/schemastery(配置 schema 校验)、@deepseek-ai/dsh-session/dsh-agent(session/event 与 agent 生命周期订阅) - 架构模式: 纯挂载 bundle。
cordis.patch.yml只在 profile 根插入一行id: advisor,所有配置通过 settings namespace 合成(schema 默认 → 插件行 base → user layer),web 客户端走/api/advisor/get|set自有网关通道读写同一个 namespace;不修改宿主源码,没有 postinstall 脚本。 - 入口文件:
src/index.ts(主包入口,导出apply/Config/ 类型)+src/client/index.ts(浏览器入口,注册 web Settings 卡片)
适用场景
希望给 DSH 会话加一道旁路质量评审,但又不想让评审干扰主 agent 的常规工作流:典型场景是长时间跑任务的会话中,由独立的便宜模型定期检查每个主回合的产出,提示潜在问题(如测试缺失、原地打转、与显式指令矛盾等)。advisor 只发带标签的注入消息,主 agent 自行判断是否采纳,不会让会话失控。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.1-rc.2+ | peerDependencies 钉住 @deepseek-ai/dsh-* 全家桶 ^0.1.1-rc.2,由宿主扁平 profile 模块解析,无需手动安装 |
| Node.js | ^22.19 或 >=24 | engines.node 强制约束,本地构建时需要 |
| 平台 | 跨平台 | 未声明 os / cpu 限制 |
| 原生模块 | 无 | 没有 node-pty / node:sqlite / FFI 等原生依赖 |
安装方式
dsh plugin --profile web add github:omdsh-dev/dsh-advisor
配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
enabled | 布尔 | 总开关。关闭时插件不观察任何会话。 | false |
provider | 字符串 | 评审模型所属 provider 路由。enabled: true 时必须非空,否则被显式门禁挡下(绝不发起调用)。 | 未设置 |
model | 字符串 | 评审模型 id。enabled: true 时必须非空,否则被显式门禁挡下。 | 未设置 |
systemPrompt | 字符串 | 自定义评审 prompt,覆盖内置的三档严重度 + JSON 帧输出契约。留空 = 用内置。 | "" |
immuneTurns | 整数 ≥ 0 | 一次真实的 concern/blocker 唤醒送达后,下 N 个完成的主回合内不允许再发唤醒性建议;窗口内自动降级为 inject。 | 3 |
maxDeltaMessages | 整数 ≥ 0 | 送进评审模型的转录增量窗口。超出部分以「earlier messages omitted」标记截断;0 = 无上限。 | 60 |
常见问题
Q: 启用后 advisor 会替主 agent 决定下一步该做什么吗?
A: 不会。advisor 只通过带 [advisor:{severity}] 前缀的 user-role 消息表达建议,主 agent 收到后自行权衡;advisor 不会批准或否决任何动作,也不会冒充主 agent 发命令。
Q: advisor 模型调用失败会卡住主会话吗?
A: 不会。每次 advisor 调用都有 60 秒超时;transient 错误 1 次重试后丢弃,连续 3 次丢会清空自身积压,quota/rate-limit 进入暂停态(需 /advisor on 手动恢复),永久错误进入 halted(需 /advisor on 重建)。主循环在任何情况下都不会被阻塞。
Q: 已经在 Settings 里勾了 enabled,为什么 advisor 还是没动静?
A: 必须是 enabled: true 且 provider 与 model 都填了非空字符串才会真正发起模型调用;缺一个就会被显式门禁挡下,状态显示 disabled-with-reason(/advisor status 看原因)。Settings 卡片会在保存时阻止这种不合法组合。
Q: advisor 会不会把自己发出的建议再读回去循环评审?
A: 不会。advisor 自己注入的消息带 source.kind === 'advisor' 标记,转录增量渲染器会从下次 delta 里排除这类消息,advisor 永远读不回自己的建议。
Q: 如何在 quota 耗尽后恢复被暂停的 advisor?
A: 在会话里发 /advisor on 即可手动恢复;被永久错误 halt 的会话,发 /advisor on 会销毁当前 runtime 并新建一个。这些切换只影响当前会话,不会改持久化配置。
Q: 配置文件改完要重启 dsh 才生效吗?
A: 不需要。Settings 卡片、TUI /settings 屏幕或 cordis.patch.yml 的更改通过 settings namespace 的 live 源读取并实时重新应用;只改 immuneTurns / maxDeltaMessages 等数值时连在途调用都不会被打断。
Q: 卸载这个插件需要做什么?
A: 插件是纯挂载——安装时只通过 cordis.patch.yml 插入一行 id: advisor,没有 dsh 源码补丁也没有 postinstall 脚本。卸载时把那一行从 profile 的 patch 文件里删掉,重启 dsh 即可。
上手难度
进阶 — 需要理解 provider / model 路由、明白 advisor 与主 agent 的边界,并能在 Settings 卡片或 YAML 三路径(patch 层 / settings.yaml / TUI)中至少选一种配置。
已知问题与限制
- 单会话仅一个 advisor:没有并行评审者名单或外部文件监听机制(计划中)
- advisor 没有任何工具:评审者只是普通的模型调用,无法自行验证主张(计划中)
- 没有会话内 advisor 面板:建议只以带标签的注入消息出现;web 卡片是配置面,不是会话视图(计划中)
- 没有转录持久化与成本统计:没有可恢复的 advisor 历史或成本可观测性(计划中)
- delta 内容不做密钥混淆:主会话 transcript 中出现的密钥会原样到达评审模型,请选用可信的评审模型来缓解
- 不隔离不安全的 advisor 输出:行为异常的 note 可能携带指令性文本,JSON 帧校验 + 自我描述前缀是仅有的缓解,note 会原样送进主会话(路线图)
- 没有 backlog 追赶等待:积压过多的 advisor 不会等主循环,背靠背的 backlog 会被丢弃,建议可能晚于下一个主回合到达(路线图)
- 长会话上下文有界:
maxDeltaMessages限制单次评审的输入窗口,compaction 后 advisor 可能丢失早期上下文(计划中)
A standalone dsh (DeepSeek Harness) plugin bundle porting the omp "advisor" subsystem: a per-session independent reviewer model that observes the primary transcript, reviews each stepped turn with an explicitly configured model (provider + model are required), and injects severity-ranked advice (nit / concern / blocker) back into the session — without polluting or recursively reviewing itself.
Advisory only. The advisor never approves or rejects the primary agent's actions, and never issues commands as if it were the primary agent. Every delivered message is self-described advisory content, and a misbehaving reviewer is bounded end to end (emission guard, immuneTurns cooldown, failure policy) so it can never stall or pollute the primary loop.
Works in both dsh front ends: the web profile (Settings → 插件配置 → Advisor card) and the dsh-tui terminal profile (/advisor + /advisor config).
Quick start
Install
dsh plugin --profile web add dsh-advisor # web profile (Settings → Advisor card)
dsh plugin --profile dsh-tui add dsh-advisor # dsh-tui terminal profile
Same plugin, either front end — the only difference is the --profile flag. Pin a version with @<version> (e.g. [email protected]). A registry install fetches the published tarball, which ships the built artifacts (lib/ + cordis.patch.yml) — nothing builds on the target machine, and runtime dependencies (@deepseek-ai/cordis, @deepseek-ai/schemastery, @deepseek-ai/dsh-* peers) resolve through the dsh installation's flat profile module fallback — no extra install step. Registry / git / tarball / local-directory variants (local-dir from a built checkout: dsh plugin --profile web add . or dsh plugin --profile dsh-tui add .), web Settings exposure, uninstall, and --dump-config verification → docs/install.md.
Configuration
Add an advisor: section to the global dsh settings document (default $DSH_HOME/settings.yaml — shared across profiles; the web Settings card writes to this same file):
advisor:
enabled: true # master switch (default false) — set explicitly to enable
provider: deepseek-official # REQUIRED when enabled
model: deepseek-v4-flash # REQUIRED when enabled
systemPrompt: "" # optional; "" = built-in reviewer prompt
immuneTurns: 3 # int ≥ 0, default 3 — cooldown after a delivered steer
maxDeltaMessages: 60 # int ≥ 0, default 60 — delta window; 0 = unbounded
The advisor is off by default. When enabled, provider and model are mandatory: enabled: true without both is a hard gate — the advisor never starts a model call and reports a disabled-with-reason status; unknown config keys are rejected.
The same keys compose across three surfaces (later layers override earlier ones; every surface shares the same key set and the same hard gate, with the host-side gate as the final line of defense on every path):
- Plugin-row config — the profile patch layer (
$DSH_HOME/profiles/<profile>/cordis.patch.yml). This is the composition base. - dsh web Settings page — the "插件配置" (Plugin Configuration) page — the Advisor card (namespace key
advisor) with the enabled toggle, provider / model selects restricted to system-configured providers and their models, and the optional fields. Saving writes into theadvisorsettings namespace and applies to new sessions immediately — no restart. The card requires a current dsh web build whose shell declares thesettings.plugin.itemcard slot and loads packages that declaredsh.client; it reads and writes the namespace through the officialGatewayServiceRPC channel (/api/advisor/get+/api/advisor/set), which is not gated by the settings exposure allowlist. It additionally blocks saving while enabled with a required field empty. /advisorcommand — per-session and ephemeral: it flips a session override, never the persisted config (see Verify).
In a dsh-tui profile the same five keys are editable in the TUI /settings screen: run dsh --profile dsh-tui, open /settings, and edit the Advisor section (enabled / provider / model / immuneTurns / maxDeltaMessages, each with zh/en label + hint). Edits are staged and written on save through the revision-fenced settings.mutate into the same advisor namespace user layer the web card writes, and re-apply live without a restart. systemPrompt is NOT a TUI field (the TUI text control is single-line; a multi-line prompt would be truncated) — edit it via the web card or $DSH_HOME/settings.yaml. The section requires dsh-tui ≥ v0.8.0 (shipped in the dsh-tui-settings-sections row of the v0.8.0+ bundle); older dsh-tui versions no-op it cleanly and the two file paths — profile patch layer + global $DSH_HOME/settings.yaml — remain the edit paths. /advisor config stays a read-only readback whose edit hint names the /settings screen when the seam is mounted. Save behavior differs from the web card: the TUI seam has no cross-field validation, so a save may set enabled: true with empty provider/model — the explicit model gate resolves that to disabled-with-reason at runtime (visible via /advisor status and /advisor config); the web card blocks such a save outright. Full reference → docs/configuration.md.

Verify
dsh --profile web --dump-config # shows a "# == dsh-advisor" layer with the advisor row
With the advisor installed and enabled, control it in-session with the /advisor command (available when a command registry is composed):
/advisor toggle the advisor for this session
/advisor on enable the advisor for this session
/advisor off disable the advisor for this session
/advisor status show state, model, runtime status, pending count, last activity
/advisor on|off|toggle are session-scoped and ephemeral: they flip a per-session override, never the persisted config. Enabling a session whose config lacks provider/model starts no model call — /advisor status (and the /advisor on reply) shows the gate reason: the advisor runs only when enabled with both configured. /advisor on is also the manual recovery path: a session advisor paused by a quota/rate-limit (quota_exhausted — no auto-resume timer) resumes in place, and a halted advisor (permanent model error, e.g. invalid credentials) is rebuilt fresh for the session.
In a dsh-tui profile, /advisor config additionally reads back the composed configuration — read-only, with edit hints naming the real write paths: the TUI /settings screen (Advisor section, dsh-tui ≥ v0.8.0), the profile patch layer, and the shared $DSH_HOME/settings.yaml advisor: section. The /advisor / on|off|status|config commands are listed in the TUI / menu with subcommand completion (command discovery requires the dsh-tui-command-trees row — the shipped dsh-tui bundle has it).
Features
-
Independent reviewer per session: a separate model call observes the primary transcript and reviews each stepped primary turn; advisor messages are excluded from later deltas, so the advisor never reads its own advice back.
-
Severity-ranked advice with inject/steer semantics: at most one note per review — nit (a minor style, clarity, or quality suggestion; delivered via non-waking
agent.inject, consumed at the next pre-step boundary), concern (a material risk or clearly better direction to weigh before continuing; delivered via wakingagent.steer, subject to theimmuneTurnscooldown), blocker (continuing clearly wastes work — contradicts an explicit user instruction, going in circles, fundamentally unsound; delivered viaagent.steer). Delivered messages carry the[advisor:{severity}]prefix and are self-described advisory content:[advisor:concern] extract the helper into a module and unit-test it -
Explicit model gate:
enableddefaults to off;enabled: truewithoutprovider+modelnever starts a model call — status reports disabled-with-reason. Unknown config keys are rejected. -
Zero-tool minimal start: the reviewer is an independent model call only — no advisor tools, nothing it can do to the session besides advisory messages.
-
No-stall failure policy: a failing or quota-limited advisor only drops its own bounded backlog — it can never park or pollute the primary loop.
-
Session-scoped controls:
/advisor on|off|status|configwork per session; the toggles are ephemeral overrides, never persisted config.

Mount-only (no dsh modification)
The plugin installs as a pure mount: bundle insert + client card (web Settings 插件配置) + its own gateway channel (/api/advisor/get|set, claimed by the host's typertGateway — the same mechanism the dsh goals service uses, not gated by the settings exposure allowlist) + the /advisor commands — no dsh patches, no postinstall step, and dsh upgrades never require re-patching.
Limitations & roadmap
The MVP deliberately drops full omp parity. Accepted gaps (tracked in the harness iteration roadmap):
- Single advisor per session — no parallel advisor roster or WATCHDOG-style file discovery (next iteration).
- No advisor tools — the reviewer is an independent model call only; it cannot verify claims itself (next-next iteration).
- No in-session advisor panel — advice surfaces only as tagged injected messages; the web Advisor card is a config surface, not a session view (next-next iteration).
- No transcript persistence or cost stats — no resumable advisor history or cost observability (next-next iteration).
- No secret obfuscation of delta content — secrets present in the transcript can reach the advisor model; mitigate by configuring a trusted reviewer model.
- No quarantine of unsafe advisor output — a misbehaving note can carry directive text; the JSON frame + validation + advisory-only framing are the only mitigation, and the note is delivered as-is (roadmap).
- No
syncBacklogcatch-up wait — a far-behind advisor does not wait for the primary loop; its backlog is bounded and dropped, so notes may arrive after the next primary turn started (roadmap: context-maintenance batch). - Bounded advisor context — long-session full replays are truncated (
maxDeltaMessages), so the advisor may lose early context after compaction (roadmap: next-next iteration).
Documentation
| Doc | Content |
|---|---|
| docs/install.md | profile install (web + dsh-tui) / registry / git / tarball / local-directory variants / web Settings exposure / uninstall / --dump-config verification |
| docs/configuration.md | full advisor namespace reference: keys & defaults, explicit model gate (S4), settings surfaces (web card / patch layer / global settings.yaml), example YAML, live re-apply behavior |
| docs/consumer-api.md | developer consumption contract: package-root library API, dsh-advisor/client entry, /advisor command surface, export inventory, lifecycle |
| docs/verification.md | verification records: test matrix (16 files / 319 cases), typecheck/build, CI contract, real-environment steps |
| docs/release.md | release process: PR-driven Release prep + Release workflows, OIDC trusted publishing, version strategy, rollback |
License
Released under the MIT License — see LICENSE. The LICENSE file is authoritative for copyright and license terms.
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-advisor)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。