快速运行

运行deepseek harness 源码运行

1
2
3
4
5
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

image

配置apiKey

image

常用路径解析

dsh运行时会在本机用户下的目录新建一个.dsh

image

路径 目的 应用场景 截图
.dsh Harness 主目录 处理配置,会话。插件注册等 image
.dsh/profiles/web 以web模式启动的工作目录 插件挂载,依赖安装,cordis.patch.yml image
.dsh/sessions 当前的会话日志
image
.dsh/.env 环境变量配置

.dsh/settings.yaml 全局运行时设置(默认模型路由、权限预设等) 配置模型,设置权限,主题设置等 image

认识dsh cli

deepseek harness 的简称为dsh。 dsh cli则是这套harness的命令行入口,在本项目中是最顶层的命令行解析,也可以叫做 launcher入口(启动器)。由它给到launcher参数,launcher根据一套预设来组织启动,注入相应的依赖,插件以及执行顺序等。

整体概念搭建

dsh 基于 Cordis 微内核,所有功能均拆分为可插拔插件,通过事件总线协同完成 Agent 完整执行循环。Launcher 作为启动器,扫描发现插件,读取配置,参照插件注册表按依赖顺序实例化插件并启动内核;dsh CLI 作为入口,向 Launcher 指定配置与插件组合,最终编排为可运行的服务。

[!IMPORTANT] ❗ 重点
dsh 顶层命令行是整个项目的启动器,它的职责:

  1. 扫描目录,发现插件(本地插件 / 远程插件)
  2. 读取全局 + 用户自定义配置
  3. 按照插件依赖顺序实例化插件
  4. 启动 Cordis 微内核,把插件挂载到内核事件总线
  5. 拉起最终服务(web 服务 /cli 任务)

image

dsh cli 核心指令理解

  • 名词解释

    profile : 一套【命名好、独立隔离、可直接启动的插件组合配方】 ,保存在 $DSH_HOME/profiles/<profile名称>/ 目录里

命令 作用 截图 讲解
dsh --profile <名称> 启动位于 $DSH_HOME/profiles/<名称> 的指定 profile。dsh根据这个的profile,得知并加载相应的Bundle、顺序以及patch文件按这份配方把插件树组装出来、拉起 Cordis 内核。 image 官方内置了两套profile1. web dsh --profile web2. headless其中headless 主要服务于不想开界面,直接跑一个任务拿结果的任务,属于shell脚本,不开启端口,它会把命令行剩余部分,提交成一个普通用户消息,跑完把最后一段非空助手文本写到 stdout 退出。dsh --profile headless "把当前目录的测试跑一遍并汇总结果"
dsh plugin --profile 指定为某一个profile进行插件的管理事务 plugin 把参数原样转发给 pnpm,在 profile 目录执行;只接受 pnpm 能识别的源(纯 git 源、link: 等)。 dsh plugin --profile web add <plugin插件名称> 为web 安装插件 dsh plugin --profile web remove <plugin插件名称> 为web移除插件
dsh --help 查看启动器自己的帮助指南 image
dsh --profile <profileName> --help 查看profile该应用的帮助指南 image
dsh <profileName> --dump-config 查看带patch的配置以及组件树(叠加所有层之后的结果) image
dsh <profileName> --dump-default-config 查看内置默认配置(未叠加任何 patch) image

最重要的规则:参数顺序

启动器只解析自己的 flag,从第一个无法识别的 token 开始,后面全部属于应用参数。

1
2
3
4
5
6
7
8
9
10
11
# ✅ 正确:启动器参数在前,应用参数在后
dsh --profile web --port 8080 # --port 是 web 应用的参数
dsh --profile tui --resume <id> # --resume 是终端应用的参数
dsh --profile headless "run tests" # 任务文本是应用参数

# ❌ 错误:应用参数跑到了启动器前面
dsh --port 8080 --profile web # 启动器看不到 --profile

# 看帮助的区别
dsh --profile web --help # 看 web 应用自己的参数
dsh --help # 看启动器的参数

认识DSH的配置逻辑

配置优先级以及理解

DSH 配置是分层叠加的:bundle 层 → profile 层 → 用户 patch 层,后者覆盖前者;运行时用户可改的东西在 settings.yaml。

其实所有的分层都是同一套配置的方式,但是意义不一样

bundle层是以 npm 包形式分发的预制能力包,每个 bundle 自带 patch,作为最底层基座(可以是官方 / 第三方写好的)

profile层是本机自定义的启动模板,它选定一组 bundle,同时 profile 自身可以附带一份专属 patch,用来对 bundle 的基础配置做修改

用户patch则提供了一个本机最高优先级的启动期补丁,在内核启动前合并,覆盖前面两层;即profile下的cordis.patch.yml。

image

1. bundle层

bundle 是 DSH 的标准化可分发能力包(npm 包) ,bundle 层就是 profile 里列出的所有 bundle,按顺序叠加出来的【底层默认配置基座】,是整套配置树的起点。它具体是npm包+dsh.bundle声明。如图

image

image

image

image

具体讲解:

  1. 读取当前 Profile 的清单,拿到 dsh.profile.bundles 数组(bundle 加载顺序就是数组顺序,前面先加载,后面覆盖前面)
  2. 调用 pnpm:检查包是否安装,缺失就自动安装;pnpm-lock 用来锁定版本
  3. 逐个遍历 bundle 数组:
    • 在 node_modules/pnpm-workspace 找到该包的目录
    • 读取包内 package.json
    • 判断是否含有 dsh.bundle 字段,确认是合法 bundle
    • 读取 dsh.bundle.patch 指向的 yaml 文件
    • 将这份 patch 合并进全局 Cordis 配置树(下层,被后续 profile patch、全局 patch 覆盖)

[!IMPORTANT]
总的来说:

  • 定义

    Bundle就是 开发者写好、打包发布、多人共享的能力单元(可版本管理,npm 安装),是带 Cordis 配置补丁的 npm 能力包。,也是dsh配置体系的最底层基座。通常通过npm等方式安装。

  • 执行逻辑

    Launcher 读取 profile 里的 bundle 列表,借助 pnpm 安装并定位 node_modules / pnpm-workspace 下的依赖包;读取包内 package.json 中的dsh.bundle标识,识别为 bundle 层,加载其指定的 patch 配置,依次合并进配置树。

当经历 bundle层之后,就相当于我们的工具箱里面加载了各种各样的工具,比如 螺丝刀、锤子、钳子….

2. profile/patch层

Profile 是本地目录模板,由它提供 bundle 清单;Launcher 先加载完清单内所有 bundle,再加载 profile 自带的 patch,在 bundle 合并结果之上做覆盖,构成 profile 层;profile 只存在本机,不作为 npm 包分发。换句话来说,我们的工具箱里面已经有了很多工具,现在我们要在这些工具里面挑选我们的工具组合(编写profile),用这些组合去解决问题。

对于launcher来说,

  1. CLI 指定 --profile xxx,Launcher 去 $DSH_HOME/profiles/xxx/ 找到 profile 目录
  2. 读取 profile 目录里的 package.json,识别到 dsh.profile,确认这是 profile
  3. 取出 dsh.profile.bundles 数组 → 进入 bundle 加载阶段(上一节的逻辑)

    ⚠️ 注意顺序:profile 先提供 bundle 列表 → 加载全部 bundle 并合并

  4. Bundle 层全部加载完毕后,回到 profile 配置,读取 dsh.profile.patch 指向的 yaml
  5. 将这份 profile 的 patch 合并到当前配置树:覆盖 bundle 层里相同 key((用户patch层操作)

image

dsh web默认模板中patch为空。

1
2
3
4
5
6
7
~/.dsh/profiles/web/
├── cordis.yml # 入口文件(空列表,勿编辑;每次启动被重写为空基座)
├── cordis.patch.yml # 用户挂载层:插件的 insert/覆盖都写这
├── package.json # 依赖 + dsh.profile.bundles(bundle 层列表)
├── pnpm-lock.yaml
├── pnpm-workspace.yaml # 离树插件所需
└── node_modules/

3. setting.yml

setting.yml 位于 ~/.dsh 文件夹中,它与之前的不同的是,之前的是部署开发人员静态写好的配置文件,而settings.yml作用于启动后、运行时可改的配置(由 dsh-settings-file 热发布,用户可在 UI 改)。例如在设置那里配置的apiKey就会修改setting.yml

image