DeepSeek Harness: 组合包 bundle 与 profile
最后更新:2026-08-31
一个 DSH 项目可能需要多种运行配置——Web UI 开发用一套、Headless 部署用一套、CI 测试用一套。Profile 是具名的组装方案,Bundle 是可分发的配置+代码包。两者组合,让 DSH 的部署像切换频道一样简单。
📋 前置知识:已完成 12-local-plugin.md,理解 cordis.yml 配置
1. 你将学到
- profile:具名组装(web/headless)
- bundle:配置+代码的分发格式
- dsh.profile 与 dsh.bundle 字段
- dsh-base / dsh-web-app / dsh-headless
- 配置层组合顺序
- patch overlay 机制
2. profile:具名组装
(1) profile 概念
profile 是一组预设的插件组合方案,用名称标识:
web profile: → 包含 Web UI 插件、交互式工具
headless profile: → 无 UI,纯 API + 脚本执行
ci profile: → 最小插件集,仅测试所需
(2) 配置 profile
在 package.json 中声明 profile:
{
"name": "my-dsh-project",
"dsh": {
"profiles": {
"web": {
"description": "Web UI mode for interactive development",
"plugins": [
"@deepseek-ai/dsh-web-app",
"@deepseek-ai/dsh-plugin-tools-interactive"
]
},
"headless": {
"description": "Headless mode for automation",
"plugins": [
"@deepseek-ai/dsh-headless",
"@deepseek-ai/dsh-plugin-tools-basic"
]
}
}
}
}
(3) ▶ 示例 3
# 使用 web profile
pnpm dsh web --profile web
# 使用 headless profile
pnpm dsh headless --profile headless
(4) profile 的组成
| 组成 | 说明 |
|---|---|
| 插件列表 | 包含哪些插件 |
| 描述 | profile 的用途说明 |
| 默认配置 | 插件的默认参数 |
3. bundle:配置+代码的分发格式
(1) bundle 概念
bundle 是 profile + 配置 + 代码的打包格式,可以像 npm 包一样分发:
profile: 选哪些插件
bundle: 插件 + 配置 + 版本锁定 → 可分发的包
(2) ▶ 示例 2
dsh-bundle-my-team/
├── package.json ← dsh.bundle 字段
├── cordis.yml ← 默认配置
├── plugins/
│ ├── team-tools/ ← 内置插件
│ └── team-lint/ ← 内置插件
└── profiles/
├── web.yml ← web profile 配置
└── headless.yml ← headless profile 配置
(3) ▶ 示例 3
{
"name": "@my-team/dsh-bundle",
"version": "1.0.0",
"dsh": {
"bundle": true,
"profiles": {
"web": "./profiles/web.yml",
"headless": "./profiles/headless.yml"
},
"baseConfig": "./cordis.yml",
"plugins": [
"./plugins/team-tools",
"./plugins/team-lint"
]
}
}
(4) 安装 bundle
# 从 npm 安装
pnpm add @my-team/dsh-bundle
# 使用 bundle 的 profile 启动
pnpm dsh web --bundle @my-team/dsh-bundle --profile web
4. dsh-base / dsh-web-app / dsh-headless
(1) 内置 bundle
DSH 提供三个内置 bundle:
| bundle | 说明 | 包含的核心插件 |
|---|---|---|
| dsh-base | 最小基础集 | core, llm, sessions, trajectory |
| dsh-web-app | Web UI 完整版 | dsh-base + web-ui, interactive-tools |
| dsh-headless | 无 UI 版 | dsh-base + headless-runner, basic-tools |
(2) 依赖关系
graph TB
BASE[dsh-base<br/>core + llm + sessions] --> WEB[dsh-web-app<br/>+ Web UI + 交互工具]
BASE --> HEADLESS[dsh-headless<br/>+ Headless runner + 基础工具]
(3) 默认行为
不加 --bundle 参数时,DSH 默认使用 dsh-web-app:
# 等价于 pnpm dsh web --bundle dsh-web-app
pnpm dsh web
(4) 选择基础 bundle
# 最小 bundle(仅核心)
pnpm dsh web --bundle dsh-base
# Web UI bundle(默认)
pnpm dsh web --bundle dsh-web-app
# Headless bundle
pnpm dsh headless --bundle dsh-headless
5. 配置层组合顺序
(1) 多层配置叠加
DSH 的最终配置由多层叠加而成,从下到上优先级递增:
graph TB
L1[Layer 1: Bundle 默认配置<br/>cordis.yml] --> L2[Layer 2: Profile 配置<br/>profiles/web.yml]
L2 --> L3[Layer 3: 项目配置<br/>项目 cordis.yml]
L3 --> L4[Layer 4: Patch 配置<br/>cordis.patch.yml]
L4 --> L5[Layer 5: CLI 参数<br/>--patch, --config]
(2) 叠加规则
Bundle 默认: { plugins: [core, llm], port: 5173 }
Profile: { plugins: [+web-ui], debug: true }
项目配置: { plugins: [+my-tool], port: 8080 }
Patch: { plugins: [+debug-tool] }
最终: { plugins: [core, llm, web-ui, my-tool, debug-tool],
port: 8080, debug: true }
(3) 插件列表合并
| 操作 | 效果 |
|---|---|
| 新插件 | 直接追加 |
| 同名插件 | 后层覆盖前层 |
$insert |
追加到列表末尾 |
$replace |
替换同名插件 |
(4) 配置值合并
低层: { a: 1, b: { x: 1, y: 2 } }
高层: { b: { y: 3, z: 4 }, c: 5 }
结果: { a: 1, b: { x: 1, y: 3, z: 4 }, c: 5 }
嵌套对象深度合并,标量值直接覆盖。
6. patch overlay 机制
(1) cordis.patch.yml
patch 文件是最高优先级的配置覆盖,适合开发时临时调整:
# cordis.patch.yml
plugins:
debug-tools:
$insert: ./dev-plugins/debug-tools
llm:
config:
debug: true
logRequests: true
(2) --patch 参数
# 应用 patch 层
pnpm dsh web --patch
# 不应用 patch
pnpm dsh web
(3) 多环境 patch
config/
├── cordis.yml ← 基础配置
├── cordis.patch.dev.yml ← 开发环境 patch
├── cordis.patch.staging.yml ← 预发布 patch
└── cordis.patch.prod.yml ← 生产 patch
切换环境:
# 开发
cp config/cordis.patch.dev.yml cordis.patch.yml
pnpm dsh web --patch
# 生产
cp config/cordis.patch.prod.yml cordis.patch.yml
pnpm dsh web --patch
(4) CLI 直接覆盖
最高优先级的配置方式:
# 直接覆盖端口
pnpm dsh web --config.port=8080
# 直接覆盖 LLM 模型
pnpm dsh web --config.plugins.llm.config.model=deepseek-reasoner
❓ 常见问题
dsh.bundle 字段,告诉 DSH 如何加载配置和插件。--dump-config 查看最终配置: bash pnpm dsh web --patch --dump-config 这会显示所有层叠加后的结果,方便定位冲突来源。--bundle dsh-base 只加载最小核心集,然后通过 cordis.yml 自行组装。.gitignore 排除 cordis.patch.prod.yml。 ---📖 小节
- profile 是具名的插件组装方案(web/headless/ci 等)
- bundle 是 profile + 配置 + 代码的可分发包
- 内置三个 bundle:dsh-base(最小)、dsh-web-app(Web UI)、dsh-headless(无 UI)
- 配置五层叠加:Bundle → Profile → 项目 → Patch → CLI,后层覆盖前层
- cordis.patch.yml 是最高优先级的配置文件,
--patch启用 --dump-config查看最终合并配置,是排查冲突的利器
📝 作业
1. ⭐ 基础题:在项目的 package.json 中添加 dsh.profiles 字段,定义 web 和 headless 两个 profile。分别用两个 profile 启动 DSH,对比加载的插件列表。
2. ⭐⭐ 进阶题:创建一个 cordis.patch.dev.yml,在开发模式下加载 debug-tools 插件并开启 LLM 请求日志。用 --patch 启动,用 --dump-config 验证 patch 层的覆盖效果。
3. ⭐⭐⭐ 挑战题:创建一个完整的 bundle 包,包含一个自定义 profile、两个内置插件、一份默认配置。发布到本地 npm registry(或用 file: 协议引用),从另一个项目安装并使用这个 bundle 启动。