乐于分享
好东西不私藏

理解DeepSeek Harness的插件架构

理解DeepSeek Harness的插件架构
LEARNING · 实战笔记2026.08

框架文档看不懂?

我用一天啃下

DeepSeek Harness

的插件架构

从五个核心概念到 Hello World · DeepSeek Harness 实战

DeepSeek Harness

AI AGENTCORDIS

📦 4 Parts + Conclusion

👉 滑动

PART 01

五个概念

剥开外衣

PART 02

启动链路

一行命令

PART 03

架构全景

四层关系

PART 04

Hello World

亲手跑通

PART ///

写在最后

我的理解

这是一篇真实的踩坑笔记 ——

看不懂文档,不代表跑不起来

我是一个 CS 基础还行、但对 TypeScript 不熟 的人。最近想搞懂 DeepSeek 开源的 AI 智能体运行时 DeepSeek Harness,结果一打开它的 Cordis 入门页,就被「五个核心概念」整懵了。

每个词都认识,连起来完全不知道在说啥。好在我换个学法——不硬啃术语,而是把框架当「操作系统」去理解,再一层层往下钻。一天下来,居然把第一个插件跑起来了。

01

PART

啃不动的那页文档

THE FIVE CONCEPTS

先给一句总纲:Cordis 是个插件框架。插件往一个共享容器里塞能力,声明自己需要什么,彼此用类型化事件通信,而且所有注册都能干净撤销。下面把五个概念逐句剥开。

① 插件是实现 Service 的对象

插件就是给系统装的「功能模块」。两种写法:函数式 apply(ctx),或类式 extends Service。生命周期由框架管,你不用自己 new / delete。

② 上下文是服务的容器

Context 是个按名字存能力的大柜子。每个能力占一个稳定的位置,比如 ctx.tools、ctx.llm。插件之间不互相 import 具体类,而是去 ctx 上按名字取——这就把「用的人」和「做的人」解耦开了。

③ 通过 inject 声明服务依赖

别手动排启动顺序,而是说「我需要 ctx.llm」。框架等这些服务就绪了才启动你。加载顺序从依赖图自动涌现,不用你写启动序列。

④ 类型化事件用于通信

插件之间靠事件总线协作,事件是「类型化」的。分发有四种模式:emit 广播、waterfall 包裹、parallel 并行、serial 串行。

⑤ 注册是可逆的副作用

提示词、工具、监听器都通过 ctx.effect() 安装,返回一个撤销函数。热重载安全靠的就是这条——重加载时自动清理,不会重复注册。

一句话:插件是安装工,ctx.X 是装好的设备

02

PART

一行命令,牵出一整条启动链

THE STARTUP CHAIN

真正让我开窍的,是把那条启动命令拆开看。比如这条:

CMDpnpm dsh web --patch ./scratch-plugin/cordis.yml

web 是名叫 web 的 profile(一组插件的集合);--patch 是在最顶层叠加一份配置清单,里面列的那个插件才是真正被加进来的。

再往里钻,Cordis 自己有个极薄的引导文件 bin.js,它只做一件事:把内核跑起来,然后把加载权交给 cordis.yml。

bin.js

const ctx = new Context()

ctx.baseUrl = pathToFileURL(process.cwd()).href + '/'

await ctx.plugin(Loader)

await ctx.loader.create({

 name: 'cordis-plugin-include',

 config: { path: './cordis.yml' },

})

看明白了吗:new Context() 建容器 → baseUrl 设成当前目录 → 装出 ctx.loader → 让它去读 cordis.yml 拉起真正的业务插件。bin.js 只是个引导层。

03

PART

插件架构全景图

ARCHITECTURE

我之前一直以为 cordis.patch.yml 就是 Profile 文件,结果搞反了。Profile 是个目录,里面 package.json 点名要叠哪些 bundle,cordis.patch.yml 只是它自带的一份覆盖层。

Profile

目录:点名叠哪些 bundle

Bundle

组合包:列若干插件

Plugin

插件:真正的能力

再加一个数据根:$DSH_HOME(你的个人配置与产物,独立于程序)

启动时的层叠顺序(从低到高优先级,后者盖前者):

bundle

dsh-base → dsh-web-app

profile patch

场景预设

home patch

个人覆盖(更高)

--patch

最高(临时)

一个关键区分:程序安装目录是「能跑的程序」,人人一样;$DSH_HOME 是你的「个人数据根」,升级程序它也不动。两者刻意分离。

04

PART

动手:跑出第一个 Hello World

HELLO WORLD

STEP 01

启用 pnpm 并克隆仓库

本机只有托管 Node,没有系统 Node。先启用 pnpm,再克隆仓库(国内用镜像,GitHub 直连会超时)。

CMDgit clone https://ghfast.top/https://github.com/deepseek-ai/deepseek-harness.git

STEP 02

装依赖 + 编译

用国内镜像装依赖、跳过 postinstall 钩子,再编译库和前端。约一分钟装完、几十秒编译好。

STEP 03

写插件 + 装进 profile

插件必须是 npm 包结构。核心就是一个 apply(ctx) 函数,挂载时打印 Hello World。

hello-world.ts

export const name = 'hello-world'

export function apply(ctx) {

 console.log('🎉 Hello, World!')

}

CMDpnpm dsh plugin --profile web add ./scratch-plugin/hello-world-pkg

STEP 04

启动,看输出

terminal

╔════════════════════════════╗

║ 🎉 Hello, World!      ║

║ hello-world 已挂载到 ctx! ║

╚════════════════════════════╝

dsh web: http://127.0.0.1:3081

!踩坑提示 🕳

本地插件必须先 dsh plugin add 装进 profile,--patch 只能引用已安装的包名;而且你自己的终端若无 Node,要先 export PATH 指向托管 Node 的 bin 目录。

///

LAST

写在最后:我现在的整体理解

MY UNDERSTANDING

把一天的理解收成五句话:

DeepSeek Harness 是开源 AI 智能体运行时

类似 Claude Code 那一类,最大特点是 Cordis 驱动的「一切皆插件」。

Cordis 五个核心概念是施工规范

插件 = 安装工,服务 = 装好的能力,上下文 = 共享世界。

插件逐层叠加:bundle → patch → --patch

home 级在 profile 级之上,--patch 最高。

看不懂术语没关系,把它当操作系统去理解

从「五个概念看不懂」到「亲手跑通插件」,关键不是 TS 多熟,而是换个类比。下一步我打算让插件真正干点活——比如注册一个自定义工具给 agent 调用。路还长,慢慢来。

我是 AI小帅超会玩,带你解锁更多 AI 黑科技!🤖✨

既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。

点赞
在看
转发

THANKS FOR READING