DeepSeek Harness 源码版:从下载到第一个插件开发完整指南
DeepSeek Harness 源码版:从下载到第一个插件开发完整指南
日期:2026-08-22
环境:macOS 15.7.9 (Intel x86-64)、Oh My Zsh、node@24
DSH 版本:0.1.0-rc.8(源码版)
前言
DeepSeek Harness(简称 DSH)是 DeepSeek 开源的 AI Agent 框架,支持插件扩展。本文记录从源码下载、构建、启动,到开发并验证第一个插件的完整过程,包括所有踩过的坑和解决方案。
适用人群:想基于 DSH 开发插件、或想深入了解 DSH 源码的开发者。
一、环境准备
1.1 系统要求
- macOS / Linux / Windows
- Node.js v22.13+(关键!v20 不够)
- pnpm(通过 corepack 自动管理)
- git
1.2 Node.js 版本管理(最容易踩的坑)
DSH 源码构建需要 Node.js v22.13+,因为:
- pnpm 11 需要 node v22.13+
- 代码中使用了
node:sqlite等较新的内置模块
检查你的 node 版本:
node --version
如果低于 v22.13,需要安装新版本。以 macOS Homebrew 为例:
# 安装 node@24
brew install node@24
# 验证安装
/usr/local/opt/node@24/bin/node --version
# 输出:v24.x.x
二、第一步:下载源码
2.1 克隆仓库
选择一个工作目录,克隆 DSH 源码:
# 创建工作目录
mkdir -p ~/workspace/DSH
cd ~/workspace/DSH
# 克隆源码
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
2.2 目录结构概览
deepseek-harness/
├── apps/ # 应用入口
│ └── cli/ # CLI 命令行工具
├── packages/ # 核心包(200+ 个子包)
│ ├── boot/ # 启动引导
│ ├── core/ # 核心功能(agent、session、tools 等)
│ ├── client/ # 前端 UI 组件
│ ├── llm/ # LLM 提供商适配
│ ├── shell/ # Shell 工具
│ └── ...
├── vendor/ # 第三方依赖(cordis、loader 等)
├── docs/ # 文档
├── package.json # 根 package.json(monorepo)
├── pnpm-workspace.yaml
└── tsconfig.json
DSH 是一个 monorepo 结构,包含 200+ 个子包,用 pnpm 管理。
三、第二步:安装依赖
cd ~/workspace/DSH/deepseek-harness
# 用 node@24 安装依赖
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm install
💡
corepack pnpm会自动按package.json里的packageManager字段下载对应版本的 pnpm,不需要全局安装 pnpm。
安装完成后,目录大小约 1.7GB(含所有依赖)。
四、第三步:构建源码(重点,有坑)
4.1 为什么必须构建?
DSH 用 TypeScript 编写,运行时需要编译成 JavaScript。克隆下来的源码只有 .ts 文件,没有编译产物,直接启动会报错:
Error: Cannot find module '.../typert.host.js'
Error: client bundles not found; run `pnpm run build` before launch
4.2 构建命令
cd ~/workspace/DSH/deepseek-harness
# 用 node@24 构建(关键!用 v20 会失败)
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm run build
构建过程约 20-30 秒,会编译全部 200+ 个子包。
4.3 构建失败的常见原因
错误 1:node:sqlite 模块找不到
Error: Cannot find module 'node:sqlite'
原因:用了 node v20,node:sqlite 是 node v22+ 才有的内置模块。
解决:确保用 node@24 运行构建命令(加上 PATH 前缀)。
错误 2:pnpm 版本要求 node v22.13+
ERROR: This version of pnpm requires at least Node.js v22.13
原因:同上,node 版本太低。
解决:同上。
4.4 验证构建结果
构建完成后,检查之前缺失的文件是否生成:
# 检查 typert.host.js
ls -la packages/context/session-reference/lib/typert.host.js
# 检查 4 个 client 包
for pkg in ui-renderer ui-brand-official ui-attachment ui-reference; do
ls -la packages/client/$pkg/lib/client.js
done
所有文件都存在,说明构建成功。
五、第四步:启动验证
5.1 查看版本
cd ~/workspace/DSH/deepseek-harness
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh --version
# 输出:0.1.0-rc.8
5.2 启动 Web 模式
cd ~/workspace/DSH/deepseek-harness
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web
启动成功后,日志会显示访问地址(通常是 http://127.0.0.1:3080/)。在浏览器中打开,确认 Web UI 正常加载。
按 Ctrl+C 停止服务。
六、第五步:开发第一个插件
6.1 插件目录结构
在工作目录下创建插件项目:
~/workspace/DSH/dsh-plugins/
└── hello-plugin/
├── package.json # 包配置
├── cordis.patch.yml # 插件注册配置(关键!)
├── README.md # 说明文档
└── src/
└── index.ts # 插件源码
创建目录:
mkdir -p ~/workspace/DSH/dsh-plugins/hello-plugin/src
6.2 package.json
{
"name": "dsh-hello-plugin",
"version": "0.1.0",
"description": "DeepSeek Harness Hello World 示例插件",
"type": "module",
"main": "src/index.ts",
"author": "your-name",
"license": "MIT",
"keywords": ["dsh", "deepseek-harness", "plugin"],
"dsh": {
"bundle": true
},
"peerDependencies": {
"@deepseek-ai/cordis": "*",
"@deepseek-ai/dsh-tools": "*",
"@deepseek-ai/schemastery": "*"
}
}
关键字段说明:
"type": "module":ES Module 模式"main": "src/index.ts":入口文件(源码版支持直接加载 .ts)"dsh": { "bundle": true }:DSH 插件标记,告诉 DSH 这是一个插件包
6.3 src/index.ts(插件核心代码)
/**
* Hello World 示例插件
*
* 演示:
* 1. 基本插件结构(name + apply)
* 2. 注册自定义工具(Tool)
* 3. 事件监听
* 4. 配置项
*/
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
import Schema from '@deepseek-ai/schemastery'
// 插件名称(唯一标识,建议用 kebab-case)
export const name = 'hello-plugin'
// 声明依赖:需要 tools 服务来注册工具
export const inject = ['tools']
// 插件配置接口
export interface Config {
/** 问候语前缀 */
greeting: string
/** 是否启用调试日志 */
debug: boolean
}
// 配置 Schema(用于校验和在 UI 中生成配置表单)
export const Config = Schema.object({
greeting: Schema.string().default('你好').description('问候语前缀'),
debug: Schema.boolean().default(false).description('是否启用调试日志'),
})
/**
* 插件加载时调用
* @param ctx 上下文对象,通过它注册各种能力
* @param config 插件配置(从 settings.yaml 或 patch 读取)
*/
export function apply(ctx: Context, config: Config) {
if (config.debug) {
console.log(`[hello-plugin] 插件加载,配置:`, config)
}
// ========== 1. 注册自定义工具 ==========
const greetTool = defineTool({
name: 'greet',
description: '向用户打招呼,返回个性化问候语',
// 工具参数定义
input: Schema.object({
name: Schema.string().required().description('用户的名字'),
excited: Schema.boolean().default(false).description('是否用激动的语气'),
}),
// 工具执行逻辑
async execute({ name, excited }) {
const punctuation = excited ? '!!!🎉' : '。'
const message = `${config.greeting},${name}${punctuation}`
if (config.debug) {
console.log(`[hello-plugin] greet 工具被调用: ${message}`)
}
return { result: message }
},
})
// 注册到工具注册表
ctx.tools.register(greetTool)
console.log('[hello-plugin] 工具 "greet" 已注册')
// ========== 2. 事件监听 ==========
// 监听 DSH 就绪事件
ctx.on('ready', () => {
console.log('[hello-plugin] DSH 已就绪')
})
// 监听会话创建事件
ctx.on('session/create', (session) => {
if (config.debug) {
console.log(`[hello-plugin] 新会话创建: ${session.id}`)
}
})
// ========== 3. 可撤销的副作用 ==========
// 用 ctx.effect() 包裹的副作用,插件卸载时会自动清理
ctx.effect(() => {
console.log('[hello-plugin] 插件已激活')
// 返回清理函数
return () => {
console.log('[hello-plugin] 插件已卸载,清理完成')
}
})
}
插件核心概念:
name:插件唯一标识inject:声明依赖的服务(如tools)Config:配置 Schema,定义插件可配置项apply(ctx, config):插件入口函数,加载时调用ctx:上下文对象,通过它注册工具、监听事件、执行副作用config:插件配置对象
6.4 cordis.patch.yml(插件注册配置)
这是加载插件的关键配置文件:
# cordis.patch.yml
# 插件注册配置文件
# 通过 dsh web --patch 此文件来加载插件
- insert:
- # 插件 ID(唯一标识)
id: hello-plugin
# 插件入口文件的绝对路径
# 注意:必须是绝对路径,指向插件的主文件
name: '/Users/claw/workspace/DSH/dsh-plugins/hello-plugin/src/index.ts'
# 插件配置(可选,会覆盖 settings.yaml 中的配置)
config:
greeting: '你好呀'
debug: true
⚠️ 重要注意事项:
insert必须是数组格式(- insert:下面跟- id: ...),不能写单个对象,否则会报Spread syntax requires ...iterable[Symbol.iterator]错误name必须是绝对路径,指向插件入口文件config里的字段要和插件代码里的ConfigSchema 对应
七、第六步:配置插件加载
DSH 有两种加载插件的方式:
方式 A:通过 --patch 参数临时加载(推荐,开发阶段用)
启动时指定 patch 文件:
cd ~/workspace/DSH/deepseek-harness
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web \
--patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml
优点:不需要修改全局配置,灵活切换,适合开发调试。
方式 B:通过 dsh plugin add 永久注册
# 添加插件到指定 profile
dsh plugin --profile web add /path/to/your-plugin
# 查看已安装插件
dsh plugin --profile web list
# 移除插件
dsh plugin --profile web remove <plugin-id>
⚠️ 注意:
dsh plugin命令必须带--profile参数。
八、第七步:启动并加载插件
8.1 用源码版启动(推荐,支持 .ts 插件)
cd ~/workspace/DSH/deepseek-harness
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web \
--patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml
九、第八步:验证插件
9.1 验证配置解析(不启动服务)
/usr/local/bin/dsh --profile web \
--patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml \
--dump-config | grep -A 10 "hello-plugin"
预期输出:
- id: hello-plugin
name: /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/src/index.ts
config:
greeting: 你好呀
debug: true
能看到这个输出,说明配置文件格式正确,dsh 能解析。
9.2 验证启动日志
启动 dsh web 后,观察终端日志,应该能看到:
[hello-plugin] 插件加载,配置: { greeting: '你好呀', debug: true }
[hello-plugin] 工具 "greet" 已注册
[hello-plugin] 插件已激活
[hello-plugin] DSH 已就绪
看到这些日志,说明:
- ✅ 插件被正确加载
- ✅ 配置被正确读取
- ✅
greet工具注册成功 - ✅ 插件生命周期正常
9.3 验证 Web UI 工具调用
- 打开浏览器,访问 dsh web 地址(启动日志里会显示)
- 进入对话界面
- 在输入框里输入:“用 greet 工具向张三打招呼,要激动一点”
- AI 会调用
greet工具,传入参数name="张三",excited=true - 返回结果应该是:“你好呀,张三!!!🎉”
验证点:
- 工具列表里能看到
greet工具 - AI 能正确调用工具并传入参数
- 返回结果符合预期(问候语前缀 + 名字 + 标点)
9.4 验证配置生效
在 cordis.patch.yml 里修改配置:
config:
greeting: 'Hello' # 改成英文
debug: false # 关闭调试日志
重启 dsh web,再次调用 greet 工具,返回结果应该变成:
"Hello,张三。"(问候语变了,标点也变了因为 excited=false)
说明配置项生效。
十、常见问题与解决方案
Q1:构建时报 node:sqlite 找不到
A:用了 node v20。确保用 node@24 运行构建:
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm run build
Q2:启动时报 client bundles not found
A:源码没构建。先运行 pnpm run build。
Q3:npm 版 dsh 加载 .ts 插件报 Unknown file extension ".ts"
A:npm 版不支持直接加载 .ts。用源码版 dsh,或把插件编译成 .js。
Q4:cordis.patch.yml 报 Spread syntax requires ...iterable[Symbol.iterator]
A:insert 格式错了。必须写成数组格式:
# ✅ 正确
- insert:
- id: hello-plugin
name: '/path/to/plugin'
# ❌ 错误(单个对象)
- insert:
id: hello-plugin
name: '/path/to/plugin'
Q5:改了插件代码后不生效
A:dsh 启动时加载插件,运行中修改不会热更新。重启 dsh web 即可。
Q6:启动后看不到 [hello-plugin] 日志
排查:
- 确认
cordis.patch.yml里的name是绝对路径 - 确认用的是源码版 dsh(npm 版不能加载 .ts)
- 确认
debug: true开了 - 检查有没有报错信息
Q7:怎么关闭 dsh 服务?
A:
- 前台运行:按
Ctrl+C - 后台运行:
pkill -f "dsh web",或ps aux | grep "dsh web"找到 PID 后kill <PID>
十一、快速命令速查
# ========== 环境 ==========
# 用 node@24 运行命令
PATH="/usr/local/opt/node@24/bin:$PATH" <命令>
# ========== 源码操作 ==========
cd ~/workspace/DSH/deepseek-harness
# 安装依赖
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm install
# 构建源码
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm run build
# 查看版本
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh --version
# 启动 web(不带插件)
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web
# 启动 web(带插件)
PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web \
--patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml
# ========== 插件验证 ==========
# 验证配置解析
/usr/local/bin/dsh --profile web \
--patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml \
--dump-config | grep -A 10 "hello-plugin"
# 插件管理(npm 版)
dsh plugin --profile web list
dsh plugin --profile web add <plugin-path>
dsh plugin --profile web remove <plugin-id>
# ========== 便捷别名(加到 ~/.zshrc)==========
# alias dsh-dev='cd ~/workspace/DSH/deepseek-harness && PATH="/usr/local/opt/node@24/bin:$PATH" corepack pnpm dsh web --patch /Users/claw/workspace/DSH/dsh-plugins/hello-plugin/cordis.patch.yml'
十二、关键路径总结
| 项目 | 路径 |
|---|---|
| DSH 源码 | ~/workspace/DSH/deepseek-harness/ |
| DSH 工作区 | ~/workspace/DSH/dshworkspace/ |
| 插件开发目录 | ~/workspace/DSH/dsh-plugins/ |
| 示例插件 | ~/workspace/DSH/dsh-plugins/hello-plugin/ |
| DSH 配置目录 | ~/.dsh/ |
| DSH settings.yaml | ~/.dsh/settings.yaml |
| DSH profiles | ~/.dsh/profiles/ |
| node@24 路径 | /usr/local/opt/node@24/bin/node |
| npm 全局 dsh | /usr/local/lib/node_modules/@deepseek-ai/dsh/ |
十三、总结
本文完整记录了 DSH 源码版从下载到第一个插件开发验证的全过程,核心要点:
- Node 版本是关键:必须用 v22.13+,推荐 node@24
- 源码必须构建:克隆后先跑
pnpm run build,否则启动报错 - 插件开发用源码版:npm 版不能直接加载 .ts 插件,源码版用 tsx 支持
- cordis.patch.yml 格式要对:
insert必须是数组,name必须是绝对路径 - 验证三步走:配置解析 → 启动日志 → Web UI 工具调用
掌握了这个流程,你就可以开始开发更复杂的 DSH 插件了。DSH 的插件体系基于 Cordis 框架,支持注册工具、事件监听、UI 扩展、子 Agent 等丰富能力,值得深入探索。
参考资源
- DSH 官方仓库:https://github.com/deepseek-ai/deepseek-harness
- DSH 插件开发文档:https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/index.md
- Cordis 框架文档:https://cordis.js.org/
- 源码内中文文档:
~/workspace/DSH/deepseek-harness/docs/cordis-primer.zh.md
更多推荐



所有评论(0)