bernardleex526 / oh_my_deepseek_harness

Listed

DeepSeek Harness 多智能体编排模式 — 灵感来自 oh-my-opencode-slim

mainOther View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:bernardleex526/oh_my_deepseek_harness

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 1de0cc9Synced Aug 17, 2026

oh_my_deepseek_harness

DeepSeek Harness 多智能体编排模式 — 灵感来自 oh-my-opencode-slim

Orchestrator 为控制平面,调度 Explorer / Librarian / Observer / Oracle / Designer / Fixer 六个职责严格隔离的专职子代理,在 DeepSeek Harness 中实现“调查 → 判断 → 执行 → 验证”的完整工作流。

本插件是一个 DSH agent preset(可切换的模式):安装后可在 Web 界面 的 Agent preset 选择器中与 standard(标准模式)、codeminimalcordis 并列选择,随时切换,互不影响。

⚠️ 最终版声明(FINAL RELEASE):因开发者没有 Money 承担 DeepSeek 的 API,本项目自 v0.1.6(2026-08-17) 起停止功能迭代,这是最后一版。 后续问题请自行解决;欢迎 fork / PR,但作者不再承诺响应 issue 或发布新版本。


更新记录(简要)

详细变更见 CHANGELOG.md。自 6a252cd 起共六轮更新,v0.1.6 为最终版

  • v0.1.6(2026-08-17) — 审查修复批次:自定义角色真正可见且可写(单写者锁同步)、并行委派预算预留、workspace fingerprint 内容哈希、持久化状态即时可读、broker_status 输出 receipt 详情、Linux CI 修复。
  • v0.1.5(2026-08-16) — 轨迹计数器客户端插件(We need… vs Let me…): 在 composer dock 实时显示首行轨迹分布,bundle 可复现构建与单测覆盖。
  • v0.1.4(2026-08-16) — 融合 dsh-anchored-standard 的锚定首请求: 新会话首个模型请求仅暴露控制平面工具,首个信号后自动晋升完整委派面; $DSH_ORCHESTRATION_BOOTSTRAP 可关闭/自定义。
  • v0.1.3(2026-08-16) — 完成门禁 + 审查闭环 + pytest 分层减量 + broker_route 路由工具:任务状态自动派生 (PLANNED → RUNNING → IMPLEMENTED → VERIFIED → COMPLETE),Oracle 复审 BLOCKED 机械阻断该任务后续委派;测试 receipt 支持 [risk=R0-R3,exit,counts,fail] 注解、同 fingerprint 重复验证机械标记、 每任务 receipt 预算;Fixer 内置 R0-R3 风险分层 / 变更测试选择 / 失败分类 规则,Observer 不再重跑 Fixer 已验命令。
  • v0.1.2(2026-08-16) — P1/P2:ArtifactStore 持久化(结果/状态落盘, 崩溃恢复与任务 replay)、workspace fingerprint、测试 receipt 提取与去重 查询、自定义角色注册(roles.json)、预算环境变量配置、 npm run status / npm run metrics CLI。
  • v0.1.1(2026-08-15) — 机械编排运行时(OrchestrationBroker):单写者 锁改为 workspace 粒度并修复 ask 审批洞、TASK_ID 协议、每任务预算机械 强制、envelope 结果门禁(坏信封被 block)、broker_status 报告工具; 构建/安装适配(YAML 安全、force 整目录替换)。

更新细则(v0.1.6)

本版本为最终版,主要修复上一轮审查发现的问题:

  • 自定义角色运行时可见:新增 runtime-catalog.mjs;dist 构建复制内置目录, npm run build:localroles.json 重新生成。orchestration.mjs 从该目录 展开 Orchestrator allow-list,自定义 subagent_<id> 不再被根代理边界隐藏。
  • 自定义 executor 可写roles.json 的权限现在支持显式 write / edit 布尔开关;声明后可获得写工具,并自动进入单写者锁集合。
  • 并行预算预留:broker 在 tools/pre-execute gate 阶段即预留任务总委派、 每 specialist 尝试、连续失败容量;settle / 取消 / deny / throw 路径按 token 释放,并行委派无法再绕过 12/3/3 机械上限。
  • workspace fingerprint 内容哈希git status --porcelain 从长度改为 sha256 哈希;Observer / 非 writer settle 时重新采样,外部改动不会再被 误判为“同一 workspace”。
  • 持久化即时可读broker_status / snapshot() 会先加载 $DSH_ORCHESTRATION_HOME 下的持久化状态,进程重启后无需先触发委派即可查看。
  • broker_status receipt 详情:现在输出每个 receipt 的 risk / exit / success / fingerprint / result,Fixer 与 Observer 跑测试前可据此决定是否跳过。
  • 测试与 CI 修复:Linux 下 tests/artifacts.test.mjs 不再失败; renderComposition(root) 尊重传入 root;路由表头不再重复渲染。
  • CLI 兼容自定义角色:持久化状态记录 writerToolsstatus / metrics CLI 对自定义 executor 的状态推导一致。

灵感来源

本项目是对 oh-my-opencode-slim (opencode 平台的精简多智能体套件)在 DeepSeek Harness 上的移植与适配。

概念oh-my-opencode-slim(opencode)本项目(DeepSeek Harness)
模式/Agent 定义opencode.json + markdown 模式文件agent.cordis.yml 组合文件 + prompts/*.md
子代理内置 task 工具 + 模式切换@deepseek-ai/dsh-tool-subagent 委派工具 × 6
权限隔离每模式 allow/deny 工具列表每子代理 toolFilter → 编译为 tools.restrict()
委托深度限制角色内配置宿主 maxDepth 机制
模型混用每 Agent 指定 modelagentOptions(provider/model/maxTokens)
宿主opencodeDeepSeek Harness(零侵入,纯增量 preset)

设计文档中的角色分工(Orchestrator 路由、信息生产者/决策者/执行者分离、 envelope 返回协议)均与 oh-my-opencode-slim 一脉相承,并利用 DSH 的 原生能力做了机械化的权限强制。


特性

  • 🎛️ Orchestrator 控制平面:理解目标、拆解任务、路由调度、整合结果、向用户汇报
  • 🔍 Explorer:仓库静态事实(文件、符号、调用链、结构、已有模式)
  • 📚 Librarian:外部知识(官方文档、第三方库、API、版本、标准)
  • 👀 Observer:运行事实(测试输出、日志、已有截图、UI 输出、复现)
  • 🧠 Oracle:深度技术推理(根因、架构权衡、并发、安全、性能)
  • 🎨 Designer:视觉/交互判断(UI/UX、布局、可访问性、规范输出)
  • 🔧 Fixer:执行修改(唯一拥有 write/edit 的代理)
  • 🛡️ 权限隔离:工具面由 toolFilter 机械强制,非仅提示词约束。只有 Fixer 拥有 write/edit 工具;Explorer 与 Observer 仍保留可执行 shell(bash/pwsh),因为 DSH 权限层无法表达只读 shell——它们“只读”完全依赖 prompt 纪律,并非权限层强制。所以不要用无条件的“只有 Fixer 能修改”来描述:可执行 shell 的代理在技术上仍可经 shell 写文件,只是被 prompt 禁止
  • 🚫 禁止代理图maxDepth: 1 + 过滤器双重保证 specialist 无法再生成代理
  • ⚙️ 模型混用:每个 specialist 可独立配置 provider / model / maxTokens
  • 🔌 零侵入:不修改宿主任何文件,卸载即删目录
  • 🧮 机械编排运行时(OrchestrationBroker):workspace 粒度单写者锁(审批期间保持)、每 TASK_ID 预算(12 委派 / 3 尝试 / 3 连续失败硬停)、envelope 结果门禁(坏信封被 block)、broker_status 只读报告——全部在真实工具链上机械强制
  • 完成门禁 + 审查闭环:broker 按记录自动派生任务状态 PLANNED → RUNNING → IMPLEMENTED → VERIFIED → COMPLETE;完成前必须 Fixer SUCCESS + Observer SUCCESS +(咨询过 Oracle 时)Oracle SUCCESS;Oracle 复审 BLOCKED 会机械阻断该 TASK_ID 的全部后续委派
  • 🧭 broker_route 路由工具:Orchestrator 可随时把子问题文本交给与提示词同源的评分模型,拿到建议角色与候选(advisory,不强制)
  • 锚定首请求(anchored bootstrap):融合 dsh-anchored-standard 的机制——新会话的第一个模型请求只暴露控制平面工具(read/grep/glob/ask/todo/broker_*,8 个),首个回复或首次工具调用后自动晋升完整 16 工具面(含全部委派工具),首轮成为干净的"理解任务"回合;恢复会话与 one-shot 子代理恒不锚定。$DSH_ORCHESTRATION_BOOTSTRAP=0 关闭,JSON 数组自定义
  • 🧾 测试 receipt 分层与去重:VERIFICATION/OBSERVED 支持 [risk=R0-R3,exit,counts,fail] 注解;Fixer/Observer 先查 broker_status 避免重跑相同命令;同 fingerprint 的重复验证被机械标记;每任务报告式 receipt 预算(默认 12 条);风险分层/变更测试选择/失败分类规则内嵌 Fixer prompt
  • 💾 持久化(可选):设置 $DSH_ORCHESTRATION_HOME 后,每次委派的结果全文与解析元数据、会话状态(预算/结果/receipts/fingerprint/任务状态)自动落盘——支持崩溃恢复、任务 replay 与质量统计
  • 🧩 自定义角色(本地构建)roles.json 声明新 specialist(write/edit 显式开启后可成为真正可写 executor),npm run build:local 合并为额外的委派工具并同步进 Orchestrator allow-list 与单写者锁,隔离保证与内置六角色一致
  • 📊 状态/指标 CLInpm run status / npm run metrics 从存储渲染运行状态(含任务状态与 receipt 分层)与历史质量指标
  • 🎛️ 多模型子代理:每个 specialist(含自定义角色)可经 model-routing.json 独立配置 provider / model / maxTokens——Explorer 用轻量快模型、Oracle/Fixer 用强模型,互不影响

快速开始

环境要求

  • DeepSeek Harness(Web 界面,默认 http://127.0.0.1:3080)
  • Node.js ≥ 22(仅构建/安装脚本需要,运行时不需要)

安装

方式一:直接使用已构建的 preset(推荐,无需构建)

# 把 preset 目录复制到 DSH 用户目录
$dsHome = if ($env:DSH_HOME) { $env:DSH_HOME } else { "$env:USERPROFILE\.dsh" }
Copy-Item -Recurse .\preset\orchestrator "$dsHome\.agent-presets\orchestrator"

方式二:通过脚本安装(自动构建 + 复制)

node scripts/build.mjs        # 从 src/ + prompts/ 生成 preset/orchestrator/
node scripts/install.mjs      # 复制到 $DSH_HOME/.agent-presets/orchestrator/

方式三:npm 包(需先将包发布到 npm registry 后方可使用)

npm pack dsh-multi-agent-orchestrator   # 或 clone 仓库
tar -xzf dsh-multi-agent-orchestrator-*.tgz
node package/scripts/install.mjs

启用与切换(Web 界面)

安装后无需重启,Web 界面实时读取 $DSH_HOME/.agent-presets/。两种启用路径:

  1. 按会话启用:打开“新会话”界面(composer 上方),在 Agent preset 选择 chip(位于 workspace 选择旁边)中点击,选择 多智能体编排, 然后开始会话。该选择只影响这一个会话。
  2. 设为默认:设置(Settings)→ General → Agent preset → 选择 多智能体编排 → 点击 Set as default。之后新建的会话默认使用该模式。

切换回标准模式:同样路径选择 标准模式(standard) 即可。

注意:preset 在会话创建时固定。已产生内容的会话不能中途切换 preset (工具目录会与历史日志不一致);空白会话可在创建后、首次输入前切换。

卸载

$dsHome = if ($env:DSH_HOME) { $env:DSH_HOME } else { "$env:USERPROFILE\.dsh" }
Remove-Item -Recurse "$dsHome\.agent-presets\orchestrator"

删除目录即完成卸载,宿主恢复原样,不影响任何其他模式。

验证安装

node scripts/validate.mjs     # 真实 loader 方言解析 + 行名解析 + 过滤器校验
node --test                   # 测试套件(含真实挂载集成测试)
node scripts/smoke-mount.mjs  # 真实启动 harness 并挂载 preset 的集成验证

使用指南(速查)

完整步骤见上文的“快速开始”与下文的“详细使用说明”;这里是常用命令速查。

场景命令 / 操作
直接安装已构建 preset复制 preset/orchestrator/$DSH_HOME/.agent-presets/orchestrator/
重新构建标准版(不读本地配置)node scripts/build.mjs
重新构建本地版(读 model-routing.json / roles.jsonnpm run build:local
安装 / 覆盖安装node scripts/install.mjs --force
启用模式Web 会话的 Agent preset chip 选择“多智能体编排”,或在 Settings 设为默认
验证安装npm run validatenpm testnpm run smoke
配置多模型子代理复制 model-routing.json.examplemodel-routing.json,再 npm run build:local
配置自定义角色新建 roles.json + prompts/<id>.md,再 npm run build:local
开启结果/状态持久化设置 $DSH_ORCHESTRATION_HOME,用 npm run status / npm run metrics 查看
覆盖预算设置 $DSH_ORCHESTRATION_BUDGETS='{"maxDelegationsPerTask":20,...}'
关闭/自定义锚定首请求设置 $DSH_ORCHESTRATION_BOOTSTRAP=0,或给 JSON 工具数组
日常委派纪律每次委派首行写 TASK_ID: <id>;重试沿用 id,新子问题换新 id
查询任务状态Orchestrator 调 broker_status;Fixer/Observer 跑测试前先查 receipt

客户端插件:轨迹计数器(We need… vs Let me…)

融合 dsh-anchored-standard 的测量口径后,会话的「首行轨迹」现在可以直接在 界面上看到:

  • 位置:与宿主状态行(10 轮 · 396 步 | LLM … | 首 token 平均 … | 缓存命中 … | 输入/输出 tok同一条 composer dock,紧随其后渲染;
  • 内容We need… 12 (63%) · Let me… 3 (16%) · 其他 4 (21%),绿/琥珀/灰 圆点区分,hover 显示完整明细;随会话实时更新;
  • 口径:当前会话每条 assistant/message首行分类 (We need/We've/We're… → we;Let me/Let's… → let;其余 → other), 与 dsh-anchored-standard 的轨迹测量一致——直接观察锚定/晋升后的风格分布;
  • 实现client/trajectory-counter/(npm 包 dsh-trajectory-counter): 客户端插件(dsh.client 声明 + __ModuleLoader__ bundle),注册到 conversation.composer.dock 槽(id trajectory-counter,order 10,紧随 宿主 stats 之后);分类逻辑在 src/classify.js(纯函数,单测覆盖), bundle 由 scripts/build-client.mjs 生成(可复现,测试门禁)。

安装客户端插件

npm run build:client                        # 生成 client/trajectory-counter/client/client.js
node scripts/install-client-plugin.mjs      # 复制包到部署的 node_modules(支持 --checkout 指定)

然后(宿主只为已注册的 loader 条目服务客户端 bundle):

  1. 在部署中注册 dsh-trajectory-counter 插件条目(部署的插件管理 / dsh plugin,或启动配置加一行);
  2. 重启 DeepSeek Harness
  3. 验证 boot manifest 出现 /plugins/dsh-trajectory-counter/client.js
  4. 打开会话,composer dock 的状态行旁即可看到计数。

槽名 conversation.composer.dock 与 rc.6 运行实例的 conversation 包逐字核对 一致(该槽即宿主 StatsLine 的注册位置)。若未来宿主升级改名,只需同步 src/component.cjs 中的槽名并重新 build。

详细使用说明

1. 工作流

Orchestrator 强制执行:

facts before decisions
decisions before actions
actions before verification
verification before completion
  1. 理解 — 复述目标,仅对用户拥有的选择提问
  2. 调查 — 并行委派 Explorer / Librarian / Observer
  3. 决策 — 根因/设计复杂时,先把证据交给 Oracle(技术)或 Designer(视觉)
  4. 执行 — 目标明确后委派 Fixer(携带问题、文件、根因、期望行为、约束、验收标准、验证步骤)
  5. 验证 — Fixer 完成后由 Observer 或测试确认
  6. 汇报 — 总结发现、变更、验证、不确定性、下一步

2. 委派协议(envelope)

每个 specialist 返回统一信封:

STATUS: SUCCESS | PARTIAL | BLOCKED | NOT_APPLICABLE
SUMMARY:
FINDINGS:
EVIDENCE:
UNCERTAINTIES:
RECOMMENDED_NEXT_STEP:
  • Fixer 追加 CHANGES: / VERIFICATION:
  • Observer 追加 OBSERVED: / EXPECTED: / DIFFERENCE:
  • Designer 输出可交给 Fixer 的 SPECIFICATION:(组件、当前问题、期望 行为、布局、间距、排版、响应式规则、交互、无障碍、验收标准)
  • 信息不足返回 UNKNOWN/BLOCKED,禁止编造;Fixer 发现根因与输入不符时 停止扩大修改并以 STATUS: BLOCKED 返回,附 REASON: 字段说明为何被阻塞

3. 权限矩阵

每个代理的工具面(allow 列表;未列出的一律不可见):

AgentReadSearchWebShellEditJobsAsk user
Orchestratorread, read_imagegrep, globweb_searchask_user_question
Explorerread, read_imagegrep, globbash/pwsh*
Librarianweb_search
Observerread, read_imagegrep, globweb_searchbash/pwsh*job_*
Oracleread, read_imagegrep, globweb_search
Designerread, read_imagegrep, globweb_search
Fixerread, read_imagegrep, globweb_searchbash/pwshwrite, editjob_*

* Explorer 与 Observer 的 shell 是“只读纪律”:DSH 无法在权限层表达只读 shell(属已知限制),它们的 prompt 硬性限制为非变更/观测命令;可变更工具 (write/edit)在权限层被移除。Designer 与 Oracle 无 shell。

要点:

  • 只有 Fixer 拥有 write/edit 工具;Explorer 与 Observer 拥有 shell,但 仅凭 prompt 纪律保持只读(DSH 权限层无法表达只读 shell,属已知限制); 只有 Orchestrator 拥有 subagent_* 委派工具与 ask_user_question
  • 边界安装失败时 fail-closedagent/created 监听内同步 throw 会否决 该代理发布——工具注册表不可用时拒绝创建根代理,绝不 fail-open 运行
  • 所有过滤器均为 allow 白名单(deny-by-default)
  • bash 仅在非 Windows 注册、pwsh 仅在 Windows 注册;含 shell 的过滤器 生成 !!js process.platform === 'win32' ? [...] : [...] 表达式,由 loader 激活时求值,避免 tools.restrict() 对未注册工具名抛错
  • Orchestrator 自身被边界行(orchestration.mjs)限制为控制平面集合, 不能写文件、不能跑 shell、不能直接执行

4. 路由策略

Orchestrator 的 prompt 内嵌路由表(由 src/routing/policy.js 渲染, 测试与提示词共享同一来源):

Specialist何时使用
Explorerwhere / which file / implementation / call chain / repository structure / existing pattern / configuration
Librariandocumentation / third-party library / framework behavior / API / version compatibility / standards
Observerscreenshot / runtime behavior / UI rendering / test output / console / network / logs
Oraclemultiple solutions / high-risk change / complex root cause / architecture tradeoff / concurrency / security / performance
DesignerUI / UX / layout / interaction / accessibility / visual consistency
Fixer仅当修改目标/根因/验收标准明确时

核心纪律:模糊的 bug 报告先调查后修复(route() 对无明确目标的任务回退 到调查代理);信息代理之间冲突时,证据交给 Oracle 而非自行裁决。

5. 为不同 Agent 配置不同 provider / model

model-routing.json.example 复制为 model-routing.json 并修改,然后 用本地构建模式重新构建安装(见下方要点:普通 npm run build 的 dist 模式故意忽略本地的 model-routing.json):

Copy-Item model-routing.json.example model-routing.json
# 编辑 model-routing.json:为每个 specialist 指定 provider / model / maxTokens
node scripts/build.mjs --local     # 或等价的 npm run build:local
node scripts/install.mjs --force
{
  "explorer":  { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 8000 },
  "librarian": { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 4000 },
  "observer":  { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 8000 },
  "oracle":    { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 16000 },
  "designer":  { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 8000 },
  "fixer":     { "provider": "deepseek-official", "model": "deepseek-v4-flash", "maxTokens": 12000 }
}

要点:

  • model-routing.json 已在 .gitignore 中(可包含密钥相关配置);示例文件 model-routing.json.example 随仓库分发
  • provider 必须已在宿主中注册(如 deepseek-official,或通过 Settings → Models 配置的 pi-ai 等适配器),model 必须是该 provider 提供的 模型名。未配置的 specialist 保持继承 Orchestrator 的路由
  • 三个字段(provider / model / maxTokens)全部必填——这是 dsh-tool-subagent 的 schema 要求,缺失会构建失败
  • maxTokens 是该 specialist 单次输出的上限;oracle 这类深度推理角色建议 给更大预算,librarian 这类短查询角色可以收紧
  • 构建模式区分(重要)npm run build(dist 模式)刻意不读取任何 model-routing.json——它生成的是随仓库提交、CI 验证的标准继承 preset (所有 specialist 继承 Orchestrator 的 provider/model)。只有 npm run build:local(即 node scripts/build.mjs --local)才会读取本地的 model-routing.json,把 agentOptions 写入每个委派行,用于个人按 specialist 定制路由。本地模式不会改变 dist 构建产物,两者互不影响
  • 因此:配置完 model-routing.json 后必须用本地构建再安装;否则沿用 文档命令 npm run build(dist)时,你的路由配置不会生效,specialist 仍 全部继承 Orchestrator 的路由

6. 自定义提示词与权限

  • 提示词:编辑 prompts/*.md(七个代理各一个),然后 node scripts/build.mjs && node scripts/install.mjs --force
  • 权限:编辑 src/permissions/agent-permissions.js(每个代理的 allow 列表),然后重新构建安装
  • 路由规则:编辑 src/routing/policy.jsROUTING_RULES 数组), 路由表会自动渲染进 Orchestrator 的 prompt
  • Agent 目录:编辑 src/agents/catalog.js(工具名、persona 文件、 委派参数)

7. 项目结构

preset/orchestrator/          # 生成的可安装 preset(可直接复制使用)
├── agent.cordis.yml          # 组合文件:Orchestrator persona + 六个委派工具 + 边界行
├── preset.yml                # 显示元数据(选择器中的名称/描述)
└── orchestration.mjs         # 边界行:agent/created 时收紧根代理的工具面
prompts/                      # 七个代理的系统提示词(Orchestrator + 6 specialists)
src/
├── agents/catalog.js         # 六个 specialist 的定义(工具名、persona、过滤器)
├── config/                   # schema 校验、默认值、模型路由、组合 loader
├── orchestration/orchestration.mjs  # 边界行(根代理工具收窄;零依赖)
├── permissions/agent-permissions.js # 每代理权限矩阵(唯一事实来源)
└── routing/                  # 路由规则 + scoreTask/route + envelope 模板
scripts/                      # build / install / validate / smoke-mount
tests/                        # 测试套件(node:test)
.github/workflows/ci.yml      # GitHub Actions:build + validate + test

8. 架构说明

  • 模式 = DSH agent preset:DSH 原生机制,会话代理的工具、提示词、能力 由 preset 组合文件决定;Web UI 有原生选择器
  • specialist = 委派工具实例:每个 specialist 是 @deepseek-ai/dsh-tool-subagent 的一个实例,自带专属 persona、toolFilter、maxDepth;子代理通过宿主 ctx.subagents 生成,上下文完全隔离(spawn,不继承父对话)
  • maxDepth: 1:Orchestrator(深度 0)可生成 specialist(深度 1); specialist 再试图生成任何代理会被宿主拒绝(深度 2 > 1)——加上过滤器 不暴露 subagent_* 工具,双重机械保证
  • 边界行 orchestration.mjs:监听 agent/created,只对根代理调用 agent.ctx.tools.restrict(...),把 Orchestrator 收窄为控制平面
  • 零侵入:不修改宿主行、不覆盖 provider/MCP、不动 shipped 预设、 不写 profile patch 层

9. 测试

node --test
测试文件覆盖
routing.test.mjs路由策略:模糊任务不直接路由 Fixer
permissions.test.mjs权限矩阵:Explorer 不能写、Librarian 仅 web、Fixer 可写且唯一、Designer 无 shell、任何 specialist 看不到 subagent_*
delegation.test.mjs六个委派工具 spawn 语义、maxDepth 1、边界行只收窄根代理、preset 行只导入同目录兄弟模块
model-routing.test.mjs每 Agent 模型路由配置的加载与校验、agentOptions 的 YAML 安全引号发射
envelope.test.mjs信封状态与字段校验(v2 多行协议):parseEnvelope/isKnownStatus/extractTaskId 接受四个标准状态与 TASK_ID,拒绝未知/缺失/重复字段,多行 CHANGES/VERIFICATION/SPECIFICATION 段完整捕获,缺可选 section 给 warning
handoff.test.mjshandoff 委派提示词渲染:role-specific 约束 + 每个委派首行声明 TASK_ID + 内嵌信封模板
broker.test.mjsOrchestrationBroker 单元:workspace 键写锁与所有权、TASK_ID 门禁、每任务预算/重试/连续失败、envelope 门禁(含角色证据段)、receipt 注解解析与重复验证检测、workspace fingerprint、持久化恢复、任务状态派生与 Oracle 审查阻断、rootSessionKey、预算 env 解析
artifacts.test.mjsArtifactStore 单元:落盘/读取/列表/内容哈希、启用语义(仅 $DSH_ORCHESTRATION_HOME)、损坏状态降级、会话枚举
roles.test.mjs自定义角色:roles.json 加载/校验(id 冲突、toolName 派生、权限键)、dist 不读 / local 合并、隔离配置一致
orchestration.test.mjs控制平面运行时机制:fail-closed 边界安装 + 单写者守卫(workspace 粒度、ask/deny 保持锁、throw 释放、完成/错误路径解锁)
harness-compat.test.mjs无 host patch 层、不改宿主行、无 provider/MCP 行、确定性构建、工具结果裁剪预算(20000/12000/3000)
mount.test.mjs真实集成:启动 harness、挂载 preset、断言组合激活与边界生效、真实工具链探针(并发 Fixer 被拒、坏 envelope 被 block、ask 审批期间锁保持)

暂存问题 / 限制与已知问题(v0.1.6 最终版)

以下问题在最终版中暂存(pending),不再安排官方修复。由于开发者已无 Money 承担 DeepSeek API,请自行解决或 fork 处理。

暂存问题速览

  1. Explorer / Observer 的 shell 不是权限层只读——理论上可经 shell 写文件; 在 approval=never 且 sandbox=workspace-write 的部署中风险更高。
  2. 无跨进程全局锁——单写者锁与 broker 状态均为进程本地,多进程同项目仍可能并发写。
  3. Observer 不能截图 / 驱动浏览器——只能读已有图片、日志、测试输出。
  4. 无 continuable / 后台委派——六个 specialist 均为 one-shot,并行靠同消息多工具调用。
  5. web_fetch 未启用——保持宿主默认 SSRF 防护;且无法经 toolFilter 下发给子代理。
  6. 无真实模型端到端测试——CI 只验证挂载 / 权限 / 工具链探针,不跑付费 LLM 回合。
  7. 工具结果整体裁剪——pruner 无字段排除,长结果连同 envelope 一起裁剪。
  8. 动态模型选择 / Web 运行面板未实现——模型路由为构建期静态 agentOptions

以下限制都是如实记录,而非未支持的借口——它们来自当前 DSH rc 版本的真实 能力边界,或是有意的架构取舍。

版本兼容性(DSH 与 npm 生态)

  • 本项目构建并测试于 @deepseek-ai/dsh@0.1.0-rc.6dsh-basedsh-tool-subagentdsh-compaction-tool-result-pruner 均为 0.1.0-rc.6)。rc 阶段的 API 具有波动风险:任一底层包的接口调整都 可能影响本 preset,升级前请先跑 npm testscripts/smoke-mount.mjs
  • 更早的 0.0.1-rc.1 / rc.3 这条线无法从公共 npm 安装(依赖树损坏), 因此不在支持范围内。请使用 0.1.0-rc.x 及以上。

运行时调度是“模型跟随 + 机械门禁”

  • 路由表 + ROUTING PRECEDENCE(风险门 → 明确目标 → 信号强度 → 默认 Explorer)是内嵌在 Orchestrator prompt 里的纪律。route() / scoreTask() 是 CI 验证的参考实现,不是运行时钩子——它们不参与实际 分发决策。
  • 机械门禁由 orchestration.mjs + broker.mjs 在真实工具链上强制(在 tools/pre-execute / tools/execute / tools/post-execute 瀑布中):
    • TASK_ID 协议:每次委派 prompt 必须以 TASK_ID: <id> 开头;缺失即 在门前被机械 DENY。
    • 每任务预算:每个 TASK_ID 最多 12 次委派、每个 specialist 每任务最多 3 次尝试、每任务 3 次连续非 SUCCESS 后机械停止;换新 TASK_ID 即重置。
    • envelope 门禁:每次委派返回后,结果文本被机械解析并校验 (多行 CHANGES / VERIFICATION / SPECIFICATION / OBSERVED 等段均支持); STATUS / SUMMARY / TASK_ID 缺失、TASK_ID 与 prompt 不一致、重复段、 SUCCESS 但缺少角色证据段(Fixer 的 CHANGES+VERIFICATION、Observer 的 OBSERVED、Designer 的 SPECIFICATION)都会被 block 并以错误形式返回 给 Orchestrator,不会当作成功结果。
    • broker_status 工具:Orchestrator 可随时读取每任务预算、尝试次数、 连续失败数与最近结果。
  • parseEnvelope() / renderDelegationPrompt() 不再是纯参考工具:解析器 已接入 post-execute 真实执行路径(上述 envelope 门禁),委派提示词模板 也内嵌 TASK_ID 协议。route() / scoreTask() 仍只供 prompt 渲染与测试。

TASK_ID 协议

  • 每个子问题一个 TASK_ID(如 t1t2…),重试/追问沿用同一 id, 新子问题开新 id。broker 以 (session, taskId) 为键记录预算与结果; envelope 必须原样回显 prompt 里的 TASK_ID,否则被机械拒绝。
  • 这是“任务边界”的机械近似:id 分配纪律仍由 prompt 约束(滥用同一 id 会合并预算;换 id 绕过预算属于违规用法)。

子代理皆为 one-shot

  • 六个 specialist 均为 one-shot:每次调用都把上下文重新转录给子 代理,子代理不保留跨调用会话。
  • 未开启 continuable 会话。DSH 的 continuation 机制把跟随子代理的 send_message 工具注册在一个 continuable 子代理开始之后,而 Orchestrator 的 allow-list 边界在会话设置时就安装完毕;tools.restrict() 在 restrict 时就对当前未注册的名字抛错(dsh-tools/lib/index.js:2777-2785), 且 restrictableNames 只覆盖继承/全局层工具(dsh-tools/lib/types/index.js:504-508)。 因此 send_message 无法被加入 Orchestrator 的 allow-list,continuable 子代理 将无法被 Orchestrator 触达——这是架构性限制,未实现
  • 并行是通过一条消息内多个 one-shot 工具调用实现的(见 prompt)。

工具结果裁剪预算

  • 结果裁剪预算为 thresholdChars 20000 / headChars 12000 / tailChars 3000, 对**整个结果(含 envelope)**生效。DSH 的 pruner 没有字段排除机制 (无法只保留 envelope 而裁剪正文),因此六个 specialist prompt 都被指示 保持简短输出、把 envelope 与关键证据放在 head 窗口内(详见各 prompt 的 Brevity 小节)。

单写者(single-writer)

  • Fixer 委派由机械守卫 + prompt 规则双重串行orchestration.mjstools/pre-execute规范化 workspace(会话 cwd,大小写折叠)取锁、 tools/executefinally 解锁(tools/post-execute 兜底),保证同一 项目上任意时刻最多一个写能力的委派在途;两个会话打开同一项目也会互相 串行,不同项目互不阻塞。
  • 锁在 ask 审批期间保持持有:DSH 的 tools/pre-execute 每次执行只跑 一次,审批通过后直接 dispatch、不会重跑 pre-execute(dsh-tools lib/index.js:3098-3130),因此审批中的 Fixer 也必须占住锁。拒绝/取消/ 通过后的释放均由 execute-finally 或 post-execute 按 token 所有权完成, 不会悬挂也不会被无关调用误释放。此行为由 smoke 真实链探针验证。
  • 不存在自动 workspace 回滚。Fixer 按 TRANSACTION RULES 返回完整 diff 并在 PARTIAL / BLOCKED 时给出明确的 keep-vs-revert 决策(可回滚则 git checkout -- <files>,否则列出遗留修改的文件与原因),由 Orchestrator 决定保留还是回滚——这是文档化的显式策略,不是自动能力。

预算(经费)是机械强制 + prompt 分配纪律

  • 每 TASK_ID 最多 12 次 specialist 委派、每个 specialist 每 TASK_ID 最多 3 次尝试(1 次初始 + 2 次重试)、每 TASK_ID 3 次连续非 SUCCESS 即机械停止——由 broker 在 tools/pre-execute 机械 DENY(附原因), broker_status 可查当前计数。TASK_ID 的分配与“何时该停”仍由 Orchestrator 的 BUDGET & TERMINATION 提示词纪律决定。

web_fetch 限制

见下方 FAQ:由 preset 行注册在 agent 平面,无法经 toolFilter / restrict 下发给子代理。此处不重复。

stub 模型 / 评估说明

  • 完整的“真实模型调用”行为评估需要活的 provider。CI 验证 挂载 / 权限 / 路由 / handoff / envelope / 真实工具链门禁探针(用 stub 工具影子化 subagent_fixer 驱动真实 tools.execute())等机械机制; 不跑真实模型回合。
  • 仓库的 devDeps 中没有可用的 stub / mock LLM provider(已检查 node_modules/@deepseek-ai),因此未提供真实调用的集成测试。

持久化 / 可观测配置(P1/P2,可选开启)

  • $DSH_ORCHESTRATION_HOME:设置后启用 ArtifactStore——每次委派的结果 全文 + 解析元数据落到 <root>/artifacts/<session>/<taskId>/…,会话状态 (预算、结果、receipts、workspace fingerprint)落到 <root>/state/<session>.json;进程重启后 broker 自动恢复该会话状态 (崩溃恢复 / 任务 replay)。未设置时运行纯内存模式,不写盘。
  • $DSH_ORCHESTRATION_BUDGETS:JSON 覆盖预算上限,例如 {"maxDelegationsPerTask": 20, "maxConsecutiveFailures": 5}
  • $DSH_ORCHESTRATION_BOOTSTRAP:控制锚定首请求(默认开启)—— 0 / off 关闭;1 / on 用默认控制平面集(8 个工具);JSON 数组 自定义首请求工具(如 ["read","grep","ask_user_question"])。恢复的会话 与 one-shot 子代理不受影响。晋升时工具目录变化一次,KV 前缀缓存在该点 断开(与上游行为一致)。
  • npm run status [sessionId] / npm run metrics:从存储渲染单会话 状态(任务、结果、receipts、fingerprint、artifacts)或跨会话质量指标 (各 specialist 的 SUCCESS/PARTIAL/BLOCKED/ERROR 分布与成功率、协议 block 率、receipt 总数)。也支持 --home <path> 指定存储根。
  • 自定义角色:项目根放 roles.json(格式见 docs/audit-verification-and-modification.mdsrc/config/roles.js 头部注释),npm run build:local 会连同 model-routing.json 一起合并 出额外的委派工具行;dist 构建永不读取它们。

其余已知限制(如实记录)

  • 无跨进程全局锁:单写者锁与 broker 状态是进程本地的。同机多进程同时 打开同一项目时,进程间不能互相看到对方的锁;审计建议的 lockfile 方案 需要宿主支持,当前未实现。
  • 对话内仍受 pruner 裁剪:模型看到的结果仍整体经过 pruner (20000/12000/3000,无字段排除);但完整原文已由 ArtifactStore 保存 (开启 $DSH_ORCHESTRATION_HOME 时),broker_status --includeArtifactsnpm run status 可回看。
  • 根代理身份靠持久化的 parentSession 头判断:恢复/导入一个曾是子代理 的会话时,其头仍带 parentSession,会被当作子代理而不安装 Orchestrator 边界(即不会收窄工具)。这是 rc.6 宿主没有 “活根会话”信号导致的边界情况,已记录。
  • 没有机械的完成状态机:IMPLEMENTED → VERIFIED → REVIEWED → COMPLETE 的流转仍由 Orchestrator 模型执行;机械门禁只保证“坏结果进不来、预算 超不了、写不并发”。完整的任务图状态机需要宿主级调度器,超出 preset 范围。
  • Explorer / Observer 的 shell 只读仍是 prompt 纪律(DSH 权限层无法 表达只读 shell),它们理论上可用 shell 写文件,从而绕过 Fixer 写锁; 这是宿主的权限模型限制,README 与对应 prompt 均已明示。
  • 动态模型选择 / 运行状态面板未实现:按成本延迟动态换模型需要宿主 在 spawn 时解析路由(当前为构建期静态 agentOptions);Web 面板需要 宿主 client 插件集成。两者均超出 preset 范围,已记录。

常见问题

  • 选择器里看不到该模式? 确认 $DSH_HOME/.agent-presets/orchestrator/ 存在且包含 agent.cordis.yml;Web 端选择器实时读盘,无需重启
  • 改了 prompts 没生效? prompts 在构建时内联进 agent.cordis.yml, 改完运行 node scripts/build.mjs && node scripts/install.mjs --force--force 现在是整目录替换,旧版本残留文件不会存活)
  • 委派被 DENY 说“TASK_ID”/“budget exhausted”? 每次委派 prompt 首行 必须是 TASK_ID: <id>(同子问题复用、新子问题开新 id);预算按 TASK_ID 计数,broker_status 可查当前计数。超限后要么开新子问题的 新 id,要么停止并报告。
  • 结果被 block 说“envelope rejected”? specialist 未按协议返回信封 (缺 STATUS/SUMMARY/TASK_ID、TASK_ID 不匹配、Fixer SUCCESS 缺 CHANGES/VERIFICATION 等)。重新委派并明确要求完整信封;该次尝试已计入 预算。
  • 测试跑了两遍 / 想避免重复 pytest? Fixer/Observer 会先查 broker_status(传 taskId)再决定是否重跑相同命令;也可开启 $DSH_ORCHESTRATION_HOME 让 receipt 与结果全文落盘,用 npm run status 回看。
  • 如何开启持久化 / 自定义预算 / 自定义角色? 见上文“持久化 / 可观测 配置”:$DSH_ORCHESTRATION_HOME$DSH_ORCHESTRATION_BUDGETSroles.json + npm run build:local
  • 想要后台委派 / fork? 当前六个委派工具为前台 one-shot(并行通过一条 消息内多个工具调用实现)。continuable 会话因架构限制未启用:DSH 把跟随 子代理的 send_message 工具注册在 continuable 子代理开始之后,而 tools.restrict() 对当前未注册的名字在 restrict 时就抛错,send_message 无法被加入 Orchestrator 的 allow-list(详见上文“限制与已知问题”)
  • web_fetch 未启用? 与宿主默认一致(SSRF 防护);需要时在组合的 tool-web 行打开 fetch: true 并挂载相应 fetch provider。注意:DSH 的 web_fetch 由 preset 行注册在 agent 平面,无法通过 toolFilter/restrict 下发给子代理(restrict 只接受宿主/祖先层注册的全局工具名)
  • 如何贡献? 欢迎 PR:新 specialist、路由规则、权限调整、测试

最终声明

因开发者没有 Money 承担 DeepSeek 的 API,所以该版本为最后一版,有问题自行解决。

本项目自 v0.1.6(2026-08-17) 起停止维护:不再承诺新功能、修复、issue 响应或 API 适配。你仍可 fork 并自行修改,仓库采用 MIT 许可证。感谢使用。


许可证

MIT

致谢

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

TestsDetected
DocumentationDetected

Repository information

Language
JavaScript
License
MIT
Last updated
Aug 17, 2026, 7:11 AM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.