Skip to content
源码版本47f9438 (dsh@0.1)

架构总览

deepseek-harness(简称 dsh)是 DeepSeek 开源的 AI agent harness,仓库 README 第一句就给出了它的设计主张:

DeepSeek Harness (dsh)… It uses an architecture where everything is a plugin, and is powered by Cordis

这句"一切皆插件"不是宣传话术,而是仓库结构层面的工程约束。本页先给一张全景,再逐层下沉到后续章节。

分层全景

dsh 是一个 pnpm monorepo,自上而下分五层:

  • CLI(apps/cli):解析 dsh 命令行参数,按模式(profile/plugin/dump-config)动态启动。入口在 apps/cli/src/bin.ts:27-52
  • Web UI(apps/web):浏览器的 React 半,通过 RPC 与 host 半通信,展示会话、工具调用、Cordis 插件面板。
  • Cordis 框架(vendor/cordis):运行时核心,七个模块构成全部公共面 vendor/cordis/src/index.ts:1-14
  • 能力插件(packages/*):每个能力域(fs/shell/llm/mcp/session/… )都是独立 pnpm package + Cordis 插件,共 360+ 个包。
  • 模式补丁层(packages/bundle/*):用 YAML patch 把插件组合成"开箱即用的 bundle"——base 是地基,headless/web-app 是变体。

"一切皆插件"在仓库结构上如何体现

关键证据在 dsh-base bundle 的 patch 文件里。以下能力看似"核心",实则都是 patch 行:

packages/bundle/base/cordis.patch.yml:15-45dsh-base bundle 的 insert 列表开头——timer/hmr/llm/session/typert/agent-default-model/jobs/settings 全部以 - id: <stable> 形式挂载,没有任何"特权模块"。

更直白的是"每个模式都挂载的五行"packages/bundle/base/cordis.patch.yml:420-451:tools/system-prompt/agent-loop/fs-sandbox/llm-deepseek 是所有模式必挂的基础能力,其余能力在此之上 overlay。这意味着你可以 fork 任何一个 dsh-* 包替换它,而无需动其他包——没有"核心服务"硬编码在二进制里。

profile:用户私有的插件组合

dsh 不把插件列表写死在代码里,而是落在用户私有的 profile 目录:

  • initProfile 在用户目录下建一个 pnpm workspace(pnpm-workspace.yaml)。
  • dsh plugin add <pkg> 实际执行 pnpm add,把包写入依赖 apps/cli/src/plugin.ts:120-158
  • pnpm 跑完后 reconcilePlugins 对照 before/after,新依赖若声明了 dsh.bundle.patch 就 push 进 dsh.profile.bundles 层栈;依赖移除或新版不再声明 bundle 则 splice 出 apps/cli/src/plugin.ts:59-91
  • 如果新包带 dsh.bundle.patch,会被当成一个 bundle layer 加入层栈 apps/cli/src/plugin.ts:36-45

所以"装一个插件"=装一个 npm 包 + 对账 bundle 层栈,完全复用 pnpm 的依赖管理。

patch 的层叠顺序

cordis.patch.yml 不是普通配置,而是按层叠合并的 patch:

每条 patch 行有 id/name/config/disabled 四个字段。其中 disabled: !!js <expr> 是唯一被插值的元数据字段,每次挂载决策时对 loader context 求值——平台/环境差异(如 process.platform === 'win32')在此分流。!!js 表达式由 @deepseek-ai/cordis-plugin-include 在挂载时插值,允许 process.env/dshHomePath(...) 注入。

Cordis 框架的来源

Cordis 不是 DeepSeek 自己重写的,而是从 cordiverse/cordis vendor 进来的——即 Koishi 作者 Shigma 的 Cordis 框架,版本 4.0.1(上游 4.0.0-rc.7)。DeepSeek 把它 rescope 到 @deepseek-ai/cordis,并做了 18 处本地修改,文档化在 vendor/README.md 里,主要包含:

  • cordis/src/fiber.ts 的生命周期硬化(修补了三个 reentrant disposal 漏洞)
  • 所有 package.json / tsconfig 重新生成
  • include/src/index.tsapplyEntryPatches 抽出 + durable debounced writes
  • hmr/src/index.ts 移除 i18n YAML 依赖
  • loader/src/config/entry.tsdisabled: !!js 插值

同时 vendor 了 cosmokit/schemastery/loader/include/group/timer/hmr/logger-console 等上游 Cordis 生态包。这意味着理解 dsh 的运行时,本质是理解 Cordis 的 context/registry/service/fiber 模型——这正是后续 Cordis 框架 三章要讲的。

接下来读什么