DeepSeek Harness

按照「先用起来、再理解、后深入」的三阶段路径学习

npx @deepseek-ai/dsh web 或 pnpm dsh web 开始
经历了一系列精心编排的步骤,把一组离散的插件组装成一个可运行的 Agent 实例。

第一步是解析命令行参数,确定要启动的 Profile(默认是 web 或 headless)。
Profile 是存储在 Harness home 中的命名组合,它列出了要堆叠的 Bundle。
第二步是 Cordis Loader 介入,读取 Profile 指定的 Bundle 列表,
解析每个 Bundle 的 cordis.yml 配置行,确定要加载的插件及其配置。

启动流程
const ctx = new Context(); // 创建插件树根
ctx.provide('dshHomePath', dshHomePath); // 注册第一个服务
await ctx.plugin(Loader); // 挂载配置加载插件
await mountRootInclude(ctx, configPath); // 展开配置成插件树
await assertEntriesActivated(ctx, binName);// 审计:谁没激活就报错

组件不仅须声明"我需要什么",还须声明"我会改变什么";
agent loop
agent-loop,理解 claim、step、turn 的调度逻辑

vendor

vendor/
├─ cordis # 核心框架 @deepseek‑ai/cordis
├─ cosmokit # 基础工具库 @deepseek‑ai/cosmokit
├─ schemastery # 配置校验模式库 @deepseek‑ai/schemastery
├─ loader # 插件加载器插件
├─ include # 配置文件包含/合并插件
├─ group # 插件分组管理
├─ hmr # 热模块重载(配置热更新)
├─ timer # 定时任务插件
└─ logger‑console # 控制台日志插件

运行时核心 cordis

vendor/cordis
├── src
│ ├─ context.ts # 上下文 Context,插件通信、服务注入核心
│ ├─ fiber.ts # ✅核心:Fiber(协程),插件生命周期管理器
│ ├─ service.ts # Service 服务定义,单例可注入组件
│ ├─ registry.ts # 插件注册表,插件注册、元信息存储
│ ├─ effect.ts # Effect:副作用自动回收机制
│ ├─ events.ts # 事件系统,on / off / emit
│ ├─ util.ts # 工具函数,异步工具、错误处理
│ └── index.ts # 对外导出入口
├── package.json
└── tsconfig.json

核心源码

fiber.ts
export const enum FiberState { PENDING, LOADING,ACTIVE,FAILED, DISPOSED,UNLOADING,}
readonly ctx: Context disposables

JS-TS

了解ts的异步编程 -异步逻辑:连接数据库、初始化 LLM 客户端、启动后台轮询任务
Promise await State

了解 ts的代理 extend/isolate/intercept
ctx.xxx 动态解析意味着属性不是在编译时固定的,而是在运行时根据已安装/激活的插件解析的
拦截属性的 get 操作来实现“按需加载”和“动态解析
new Proxy(target, handler),带有 get 和 set 陷阱
const self = new Proxy(this, ReflectService.handler)

Service 是 Cordis 的可注入全局单例组件抽象
静态 inject + @Inject() 装饰器

读取类上静态字段、装饰器元数据、解析依赖列表、提取插件配置 schema。给 loader、registry、schemastery 提供反射能力

registry.ts:存储解析出来的插件元数据 registry “应该加载什么

ctx.plugin() 手动加载插件,此时完全不需要 yaml。
根实例直接就是根 Context + 根 Fiber,
Context.new():内部直接构造根 Fiber,就是整个框架的根
bin.js(命令行入口)
// 1. 创建根上下文(根fiber)
const ctx = Context.new()
// 2. 手动挂载 loader 插件
await ctx.plugin(loaderPlugin)
// 3. loader 插件读取 ./cordis.yml,解析配置,写入 registry,applyDiff,加载全部业务插件

工程判断力

从"怎么实现"到"要实现什么,什么不该做
场景 : 重复、可验证、有明确成功标准的流程的
如果插件化成为共识,那么社区的力量将集中在开发高质量插件上,而非重复造框架

DSH

Pi 的哲学是“最小核心 + 按需扩展”,适合终端工作流,强调可控、低噪音、高缓存命中

Deepseek harness
一个内核加一套协议的味道 重新定义了封装的边界,把复杂性拆成模块,再把修改权交给你
为了自进化打好基础,进化什么,怎么进化?
Harness primitives(Harness 原语)。二是组合这些原语的能力。
1. Plugin
2. capability seam 能力接缝:Service Definition / Provider / Consumer
3. append-only log Trajectory
4. Profile 和 Bundle 机制, 以声明式方式组合插件
Bundle → Profile → Patch → Overlay 进行分层
apps/ # 可运行应用(web、headless 等)
apps 是面向最终用户的可运行应用入口,如 Web UI 和 headless 模式
packages/ # 核心工作区(50+ 个 @deepseek-ai/dsh-* 包) Capability Seam(能力接缝)
dsh 启动
packages/boot/app-boot/src/index.ts
packages/boot/cmdline/src/index.ts
new Context() 创建插件树的根。Context 既是服务仓库,也是树节点——每个插件挂载后有自己子 context,父卸载时子树跟着卸载
ctx.provide() 注册第一个服务。把值挂到 ctx 上,全局可读
ctx.plugin(Loader) 程序化挂载插件。Loader 负责读 YAML 配置
mountRootInclude() 把 cordis.yml 交给 Loader,声明式展开成整棵插件树
Capability Seam (能力接缝) 挂载和启动是两个分离的动作

一个能力被拆成三个包:契约包(Definition)定义服务本身,实现包(Provider)提供实现,消费方包(Consumer)使用能力。

复杂的运行时管理(如配置文件监听、插件热更新),Cordis 提供了 @cordisjs/plugin-loader 这个官方插件。它维护了一个 EntryTree(入口树)

app-boot 管理“如何启动”,而 cmdline 管理“应用能识别哪些参数”。它们是启动流程中分工明确的上下游关系
「组合优于配置」:通过 Profile 和 Bundle 机制,让用户以声明式方式组合插件,而非编写胶水代码。
:每项能力拆分为服务定义、提供者、消费者三角色,通过 ctx 键解耦,独立演进。
「服务定义」与「服务实现」的分离
component observability(组件可观测性)

DeepSeek Harness

Node.js 原生支持的一种运行 TypeScript 文件的方式,
它通过 --import 参数加载 tsx 包作为模块加载器,从而让 Node.js 能够直接执行 .ts 或 .tsx 文件,无需预先编译
scratch-plugin/src/hello-plugin.ts

DSH_CLIENT_COMMIT_HASH=b150a551b8d465e31e418e1b2eaf5e79bbb7d28e
离线本地部署的情况下,会出现报错,定位在scripts文件中 git rev-parse --verify HEAD
https://github.com/deepseek-ai/deepseek-harness/discussions/3510

优先读取 DSH_CLIENT_COMMIT_HASH 环境变量。
如果变量不存在,则执行 git rev-parse HEAD 来获取当前 Git 提交哈希。
当你从源码包(而非 git clone)构建,或 .git 目录缺失时,git rev-parse HEAD 命令会失败,从而导致整个构建过程报错

采用 pnpm workspace 管理的 Monorepo(单体仓库),其编译和打包流程围绕 TypeScript 和 Turborepo 构建
继承根目录的 tsconfig.json

typescript

nvm:Node.js 版本管理器,切换不同 node 版本(类似 pyenv)
NVM_IOJS_ORG_MIRROR
NVM_NODEJS_ORG_MIRROR
node.js
node‑pty:node.js 的伪终端库
node-gyp:官方跨平台命令行工具,专门用来为 Node.js 编译 C++ 插件模块
gyp编译错误
node-vXX.X-headers.tar.gz Node的headers
主流包管理器
n :轻量、命令极简,全局软链接切换 node N_NODE_MIRROR
npm(官方原生,Node.js 自带)Node.js 默认安装,配套 package.json、package-lock.json
使用npm init命令来初始化一个新的Node.js项目,这会创建一个package.json文件,其中包含项目的基本信息、依赖项等
--nodedir参数指定Node.js源代码目录
node_modules 是项目的依赖包管理机制
npm 会根据 package.json 文件中的 dependencies 和 devDependencies 字段列出的依赖,逐步完成以下步骤:
解析依赖树 :分析 package.json 和可能存在的 package-lock.json 文件,明确需要安装的依赖版本。
下载依赖 :从 npm 的注册服务器下载必要的包,并存储在 node_modules 文件夹中。
完成后处理 :包括生成或更新 package-lock.json 文件,以及运行任何必要的安装脚本。

pnpm(极速磁盘存储,当前行业首选,对标 uv) Rust 优化,硬链接节省磁盘,安装速度远超 npm/yarn

npm config set registry https://test.com/repository/npm-public/

DSH

Cordis --> Capability Seam --> Profile / Bundle / Patch
Cordis
Plugin: Context Service Inject Event effect
Seam: Capability Family(官方文档叫 capability seam)= 标准化抽象接口 / 插槽
Service Definition/Service Provider/Consumer
能力是什么 能力谁来实现 谁来使用这个能力
此前习惯的:Tool Skill Agent Workflow 各自拥有完全独立扩展体系
Marketplace 主要负责分发: Capability
DeepSeek Harness: 一套 Runtime 组合方案,能力如何组成不同类型的 Runtime
从它的架构模式推导出的自研 Harness 设计
llm/ — LLM capability family
fs/ - filesystem capability family
面向接口编程和单一职责原则:
Definition 定义层确保上下层解耦; packages/fs/fs
Provider层的叠加(Local + Sandbox) 实现了“能力与策略分离”; packages/fs/fs-local packages/fs/fs-sandbox
Consumer层(tool-fs) 只专注模型交互,不碰底层API; packages/fs/tool-fs
中间件(Policy) 以非侵入方式增强可靠性

源码 :
packages/fs 目录下扮演着完全不同的角色,
分别负责包管理/依赖、编译配置和多语言文档生成。
package.json —— 包的“身份证”与“依赖清单” 是几乎所有 TypeScript 项目的标配,
tsconfig.json —— TypeScript 编译器配置 告诉 TypeScript 编译器(tsc)如何将 .ts 源码转译成 .js 文件
README.i18n.yaml 第三个则是该项目的特定配置。 i18n,Internationalization
记录和审计中英文文档是否同步更新的。“Both languages carry equal authority(两种语言具有同等权威性)
记录的内容:它存储了 README.md(英文)和 README.zh.md(中文)两个文件最近一次被人工确认为内容一致时的 Git Blob 哈希值

能力簇(seam) ctx 入口含义可替换实现插件示例
LLM ctx.llm 大模型适配器注册表 llm-deepseek / llm-replay / llm-pi-ai文件系统
File ctx.fs 文件读写、搜索 fs-local / fs-e2bShell
Shell ctx.shell 命令执行 bash-local / bash-sandbox / pwsh-local
不要预防性拆分:只有角色需要独立演进时,才使用不同包。简单的工具插件无需拆分。
Service Definition 拥有 Request/Result 类型:Service Provider 和 Consumer 只依赖 Service Definition 包

Profile / Bundle / Patch
启动时按顺序叠插件树」:profile 里列出 bundle,再依次应用 profile 补丁、用户主目录补丁、命令行 --patch 参数。
Profile 这次启动要叠哪些组合包、按什么顺序叠 dsh --profile web
组合包(bundle) 一组 Plugin 的组合与分发
把 Harness 配置从「改代码发版」变成了「分层声明 + 可观测组合结果」
其中包含一个 package.json(树外插件 dependencies,加上 profile manifest dsh.profile 及其有序的 bundles 层列表)
dsh.profile.bundles 名称(先从 dsh 安装目录,再从 profile 目录)

和用户自己的 cordis.patch.yml。
cordis.patch.yml | Cordis 框架配置补丁:DeepSeek‑Harness 内部装配系统,只修改插件配置树,不改源码,dsh 运行时加载执行
内置组合包从 dsh 安装目录解析;
树外(out-of-tree)组合包通过 dsh plugin --profile add
安装进 profile

packages

Runtime Core
ctx.sessions
ctx.systemPrompt
ctx.tools
ctx.agents
ctx.agentLoop
ctx.llm
Execution Capability / Agent Capability/ Runtime Infrastructure
Composition / Product Surface

Runtime Composition 中可以选择、提供、替换的服务
开发插件
--patch overlay 加载本地插件
dsh plugin add 安装进一个 profile,并解释决定组合后配置的层顺序
交付
交付 tarball:用 pnpm pack 打包;用户执行 dsh plugin add ./hello-plugin-0.1.0.tgz
发布到 npm,在

Everything is a Plugin

也会带来新的治理难题: Trust Allowlist Version
Everything needs Governance

从岗位看数据

预训练数据工程师
持续搭建和改进现有的数据生产管线,与数据上下游保持紧密合作
数据采集 pipeline 用独到的经验和品味,去发现问题、定义评测标准、改进训练数据,教大模型更好地写代码。
将审美判断转化为可度量的评测维度与数据规范;具备一定动手能力,能借助工具高效支撑数据生产与质量校验。
定义图文/视频数据集的采集方式、质量标准和筛选方法,多部门协作建设大规模自动化清洗、质量筛选与数据合成管线,从数据侧提高模型表现
从复杂、多源的数据中提炼信号,并将数据清洗、筛选与合成流程系统化、自动化
日常生产流水线,支持每日增量处理、任务调度、数据统计、质量回归、线上问题排查和稳定性保障。
优化大规模数据清洗系统的性能、稳定性和可观测性,完善日志、指标、监控、测试与调试工具

数据 pipeline

功能的实现:逻辑层
性能的优化:并发 分布式 单机提速 --指标(内存和时间)
可观测性和稳定性: 日志- 数据库记录
灵活性和可拓展性: 不使用硬编码的方式,agent的方式呢
skill mcp等方式--pipeline

参考

https://github.com/cordiverse/cordis
https://deepseek-harness.github.io/deepseek-harness/develop/practice/
https://deepseek-harness.github.io/deepseek-harness/develop/cordis-tutorial/01-first-plugin

posted on 2026-08-20 17:25  辰令  阅读(59)  评论(0)    收藏  举报