从跑通 Demo,到理解“一切皆插件”,再到真正读懂 Agent 是如何运转的。
DeepSeek Harness 开源之后,很多人的第一反应都是:
怎么安装?从哪个目录开始看?有没有教程?
这些问题当然重要,但我觉得,在打开源码之前,还有一个更关键的问题:
DeepSeek Harness 到底应该怎么学?
因为它不是一个学会几个 API、照着示例接上模型,就算掌握了的项目。
如果只是想体验,跑一条命令就够了;但如果想真正理解它,甚至基于它开发自己的 Agent,只盯着工具调用、Prompt 和模型适配器,很容易越看越乱。
DeepSeek Harness 真正值得研究的地方,不是“它又做了一个 Coding Agent”,而是它试图用一种彻底插件化的方式,重新组织 Agent 系统里的模型、工具、会话、循环、文件系统、沙箱和界面。
所以,学习它的顺序也应该随之改变。
这篇文章不打算逐行教你写代码,而是想给出一条我认为更合理的学习路线:先建立直觉,再理解设计哲学;先看系统如何组装,再看 Agent 如何运行;最后用一个插件验证自己是否真的理解。
一、先搞清楚:你学的不是一个“聊天机器人项目”
很多 Agent 项目都可以用下面这条链路来理解:
用户输入 → 模型推理 → 调用工具 → 返回结果 → 继续推理DeepSeek Harness 当然也有这条链路。
但它更关心另一个问题:
组成这条链路的每一部分,能不能被独立加入、替换、组合和卸载?
在 Harness 中,模型适配器是插件,工具系统是插件,会话存储是插件,Agent Loop 是插件,沙箱和文件系统也是插件,甚至 UI 本身也可以被视为插件。
这就是官方反复强调的那句话:
Everything is a Plugin.
它不是一句营销口号,而是理解整个代码库的入口。
因此,学习 Harness 时不要只问:
• 它有哪些工具? • 它支持哪些模型? • 它能不能替代 Claude Code 或 Codex?
还要继续追问:
• 这些能力是怎样注册到系统里的? • 插件之间怎样声明和获得依赖? • 插件被卸载后,它产生的事件监听、服务和其他副作用如何清理? • 同一套组件为什么可以组合成不同形态的 Agent?
当你开始问这些问题,才算真正进入 Harness 的学习语境。
二、第一阶段:先跑起来,但不要停在“跑起来”
学习任何大型项目,第一步都不应该是从源码第一行开始读,而应该先获得整体感受。
按照当前官方文档,安装 Node.js 后,可以直接运行:
npx @deepseek-ai/dsh web默认情况下,Web UI 会运行在:
http://127.0.0.1:3080这一阶段的目标不是测试模型有多聪明,也不是让它完成一个多复杂的任务,而是观察系统暴露出来的结构。
你可以重点看四件事:
1. 一个 Agent 由哪些能力组成; 2. 切换不同 Profile 后,工具和行为发生了什么变化; 3. 一次任务如何从用户输入进入模型,再进入工具执行; 4. 会话、权限、工具调用和运行状态如何呈现在界面中。
官方提供的不同运行模式,可以理解为几份已经组装好的“Agent 配方”:标准模式偏向完整使用,PTC 模式强调程序化工具调用,极简模式只保留基础能力,创造模式则更适合观察和调整插件组合。
这里最值得建立的第一个认知是:
Profile 不是给同一个 Agent 换一套皮肤,而是在重新决定“这个 Agent 由什么组成”。
这一阶段学到什么算过关?
不是“成功打开了 3080 页面”,而是你能够回答:
为什么同一个 Harness 可以通过不同配置,表现成不同类型的 Agent?
三、第二阶段:补上 Cordis,理解“一切皆插件”为什么成立
直接进入 Harness 的 packages/ 目录,很容易看到大量模块,却不知道它们为什么以这种方式组织。
要解决这个问题,需要先认识 Cordis。
官方 README 对两者的关系写得很清楚:DeepSeek Harness 采用“一切皆插件”的架构,而这套架构由 Cordis 提供支撑;Cordis 的设计,则来自论文《A Programming Paradigm for Spatiotemporal Composability》。
你不一定要一开始就把整篇论文逐页推导完,但至少应该抓住两个概念。
1. 时间可组合性
一个插件被加载时,可能会注册服务、订阅事件、修改上下文,或者启动某些任务。
问题是:当插件被移除时,这些影响能不能一起撤销?
如果插件表面上卸载了,监听器却还在,状态仍然残留,系统运行得越久就越不可控。
所谓时间可组合性,关注的正是组件在不同时间被加入和移除时,其副作用能否被正确追踪和恢复。
2. 空间可组合性
插件很少真正孤立存在。
一个工具可能依赖权限系统,一个 Agent Loop 可能依赖模型和会话,一个 UI 又可能依赖运行状态与事件流。
这些依赖不是简单的静态导入。插件出现、消失或被替换时,其他组件需要感知环境变化,并重新满足自己的依赖。
空间可组合性关注的,就是多个组件同时存在时,依赖关系如何声明、解析并动态维持。
Cordis 可以看作论文思想的工程落点:它负责上下文、插件生命周期、依赖关系和副作用管理;Harness 则在这套机制上组装出 Agent 所需的各种能力。
论文应该怎么读?
不要把目标定为“读完 88 页”。更有效的方式是带着三个问题读:
1. 普通插件系统在动态卸载时会遇到什么问题? 2. 可逆副作用和响应式依赖分别解决了什么问题? 3. 这些抽象在 Cordis 与 Harness 的代码里分别对应什么?
先读摘要、引言、核心定义和 Cordis 实现部分,再回到代码中寻找对应关系。遇到不理解的形式化内容,可以先放下;等你写过插件后再回来看,很多概念会突然变得具体。
这一阶段学到什么算过关?
你能够用自己的话解释:
“一切皆插件”为什么不只是把代码拆成很多包,以及插件卸载为什么是一个需要专门设计的问题。
四、第三阶段:不要按目录顺序读源码,要按“一次任务”读
Monorepo 最容易制造一种错觉:好像必须把每个 package 都看完,才能理解项目。
实际上,更好的方法是选一条完整链路,从头跟到尾。
对于 Harness,这条链路就是一次 Turn。
可以沿着下面的顺序追踪:
用户发出消息
↓
创建一次 Turn
↓
读取会话与运行上下文
↓
组织模型请求
↓
模型返回文本或工具调用
↓
执行工具并写入结果
↓
进入下一个 Step,或结束本轮任务这里要区分两个概念:
• Turn:围绕一次用户任务展开的完整处理过程; • Step:Turn 内的一次模型请求及其相关工具执行。
一个 Turn 可能只包含一个 Step,也可能因为多次工具调用而包含多个 Step。
沿着这条链路,再有选择地阅读核心模块:
• core/session:会话事实怎样被追加、存储与恢复;• core/agent:Agent 对外提供怎样的抽象;• core/agent-loop:默认运行循环怎样推进 Turn 和 Step;• llm/llm:消息怎样流向不同模型适配器;• 工具与事件相关模块:调用怎样被注册、观察、拦截和记录。
这样读代码,你看到的不是一堆孤立文件,而是一次任务如何穿过整个系统。
一个特别重要的观察:事件有不同职责
阅读时要留意两类信息:
• 需要成为长期事实、重启后仍能恢复的信息; • 只在当前运行过程中用于观察或干预的信息。
前者更接近会话日志,后者更接近飞行中的 Agent 事件。分清两者,才能理解 Harness 如何同时处理持久化、界面更新、运行控制与扩展能力。
这一阶段学到什么算过关?
你能从一次用户输入开始,画出它经过会话、Agent Loop、模型和工具系统的完整路径,并指出关键状态最终记录在哪里。
五、第四阶段:用 Profile 和 Bundle 学会“组装”,不要急着造轮子
理解运行链路之后,下一步不是马上开发复杂插件,而是先学会修改现有组合。
这是理解 Harness 最省力的一步。
Profile 是什么?
可以把 Profile 理解为一份命名的 Agent 组装方案。
它决定加载哪些插件、使用什么配置,以及最终向用户呈现出怎样的能力集合。
Bundle 是什么?
Bundle 更接近一组可以复用和分发的组合单元。它把相关插件与配置组织在一起,使一套能力能够被其他 Profile 或项目采用。
推荐的练习方式
不要一上来重写 Agent Loop。先做几个小实验:
1. 从一个现成 Profile 中移除某项能力; 2. 替换一个实现,观察其他模块是否仍能工作; 3. 通过配置叠加修改某个插件,而不改它的源码; 4. 比较两份 Profile 的插件树,解释它们行为不同的原因。
这个阶段会让你真正理解:Harness 的扩展性首先来自组合,其次才来自编写更多代码。
这一阶段学到什么算过关?
你可以在不修改核心源码的情况下,组合出一个能力明显不同的 Agent,并且知道每项能力来自哪个插件。
六、第五阶段:写一个“小到不能再小”的插件
直到这里,才适合开始写第一个插件。
第一个插件不需要接数据库,不需要调用复杂 API,更不需要做一个完整产品。一个能够注册服务、监听事件,并在卸载时正确清理的 Hello World 插件,反而更适合验证理解。
这个练习应该覆盖三个动作:
1. 向共享上下文贡献一个能力; 2. 使用或监听系统中的某个事件; 3. 卸载插件,确认相关副作用一起消失。
第三步尤其重要。
很多教程只验证“插件加载后能不能工作”,但对于 Cordis 和 Harness 来说,“卸载后是否不留痕迹”同样是核心能力。
之后再逐步增加复杂度:
• 写一个实用工具插件; • 为插件增加配置项; • 把多个插件组织成 Bundle; • 为某类任务制作专属 Profile; • 最后再研究自定义 Agent Loop、远程执行环境或多 Agent 编排。
这一阶段学到什么算过关?
你的插件不仅能加载和工作,也能被安全卸载;你能解释它依赖什么、贡献什么,以及生命周期结束时清理了什么。
七、一条更合理的 DeepSeek Harness 学习路线
把前面的内容压缩一下,我推荐的顺序是:
体验 Web UI
↓
比较不同 Profile
↓
理解 Everything is a Plugin
↓
阅读论文的核心问题
↓
理解 Cordis 的生命周期与依赖机制
↓
沿一次 Turn 追踪核心源码
↓
修改 Profile 和 Bundle
↓
编写并卸载第一个插件
↓
开发自己的 Agent 组合这条路线背后的原则很简单:
先看到系统,再理解抽象;先学会组合,再学习实现;先写小插件验证生命周期,再挑战复杂 Agent。
八、几条容易踩坑的错误路线
误区一:一上来就通读整个仓库
Harness 是一个规模不小、仍在快速变化的 Monorepo。没有问题意识地顺着目录读,很快就会迷失。
先选一条运行链路,再按需展开模块,效率更高。
误区二:只看 Prompt 和工具定义
Prompt、模型与工具很显眼,但它们不是 Harness 最独特的部分。
真正值得研究的是:能力如何进入上下文、依赖如何得到满足、状态如何被记录、插件如何安全退出。
误区三:把论文当作入门门槛
论文重要,但不意味着必须先完全读懂形式化推导,才有资格运行项目。
正确方式是“体验—论文—代码—再回论文”,让抽象概念和工程现象互相印证。
误区四:背当前 API,却忽略项目仍在快速迭代
官方目前将 DeepSeek Harness 标记为 Developer Preview,并明确提醒未来可能发生破坏兼容性的变化。
所以现阶段更值得沉淀的是稳定的思想:插件边界、生命周期、依赖、事件、会话与组合方式。具体命令、目录和配置字段,则应随时以当前官方文档为准。
结语:真正要学的,是 Agent 如何成为一个“可组合的系统”
如果只是想使用 DeepSeek Harness,跑起来、配置模型、选择一个合适的 Profile,可能已经足够。
但如果你想通过这个项目学习 Agent 工程,那么最值得追的并不是“它今天又多了什么工具”,而是这些更底层的问题:
• 一个复杂 Agent 应该如何拆分能力? • 插件之间怎样形成依赖,却不彼此绑死? • 运行时加入和移除组件,怎样避免残留副作用? • 会话、事件、工具和 Agent Loop 怎样组合成可观察、可替换的系统?
DeepSeek Harness 给出的是一套仍在演进中的答案。
而学习它最好的方式,也不是把源码从头读到尾,而是沿着一条清晰路线,逐层验证自己的理解:
先会用,再看懂;先组合,再开发;最后回到设计哲学。
接下来,如果继续深入,可以分别拆开讲:论文中的“时空可组合性”、Harness 的一次完整 Turn、Profile 与 Bundle 的配置方式,以及一个插件从加载到卸载的全部生命周期。
参考资料
• DeepSeek Harness 官方仓库 • 《A Programming Paradigm for Spatiotemporal Composability》
注:本文依据 2026 年 8 月的 Developer Preview 版本整理。项目迭代较快,具体命令、目录结构与接口请以官方仓库最新说明为准。
夜雨聆风