DeepSeek Harness 专栏开篇:学习路径总览
专栏:DeepSeek Harness · 第 1 / 14 篇这是 DeepSeek Harness 专栏的第 1 篇,也是整个专栏的路线图:先讲清楚 dsh 是什么、为什么值得读它的源码,然后给出一条由浅入深的六阶段学习路径。后续文章会沿着这条路径一篇篇展开。
dsh 是什么
DeepSeek Harness(简称 dsh)是 DeepSeek 开源的 agent harness(智能体框架)——就是驱动 coding agent 那类产品的”骨架”:负责会话管理、prompt 组装、工具执行、权限审批、沙箱隔离、subagent 委托这些模型之外的全部脏活。
它有两个让我决定开这个专栏的特质:
- 一切皆插件。dsh 构建在 Cordis 框架之上:模型适配器、工具注册表、会话日志、甚至 agent loop 本身,都是可替换的插件。不存在”需要打补丁的特权内核”——扩展它的方式是把新插件挂载到旧插件旁边。这套架构的论文背景是 A Programming Paradigm for Spatiotemporal Composability。
- 文档质量罕见地高。仓库里 50 个包每个都有 README 契约,
docs/下还有架构总览、事件时序图、能力 seam 图、扩展实操手册,中文齐全。这意味着它是我见过最适合用来学习”agent 产品如何被工程化”的开源代码库之一。
另一个阅读理由:agent harness 是当前 AI 应用工程里模式最密集的一层。读透一个 dsh,再看同类产品的公开资料(Claude Code、Codex 等)会有强烈的”原来都一样”的既视感——dsh 的 hooks 包甚至在字面意义上桥接了 Claude Code / Codex 的线协议。
:::note 专栏定位与新手须知
本专栏是进阶源码拆解:逐行分析一个生产级系统的实现。前置课程:① 没接触过 agent 的读者,请先读「Agent 工程」专栏的前六篇(特别是第 4 篇手写循环);② TypeScript 工程基础薄弱的读者,请先读「TypeScript 与 Node 地基」专栏;③ 想彻底读懂”一切皆插件”的机制,请读「Cordis 插件框架」专栏——逐行讲解 vendored 源码。前置课完成后,这里会事半功倍。
先解释几个贯穿全专栏的名词:
| 术语 | 大白话解释 |
|---|---|
| Harness(鞍具) | 给模型套上的”工程骨架”——会话、工具、审批、沙箱这些模型之外的全部设施 |
| Cordis | dsh 底层的插件框架:每个功能都是可插拔的插件 |
| ctx | 插件之间共享的”上下文对象”,服务都挂在它身上(如 ctx.tools) |
| fiber | 一次插件运行的实例,卸载时自动撤销它注册的一切 |
| seam(接缝) | 可替换能力的设计模式:接口/实现/消费三方分离,换实现不动调用方 |
| waterfall 事件 | 一层层”洋葱式”监听器,可以改写结果也可以直接拦截 |
| 仅追加日志(append-only) | 只往日志末尾写、永不修改删除——历史可完整回放 |
| profile / patch | 启动配置的组装方式:基础配置 + 你的覆盖层,改配置不改代码 |
| TUI | 终端里的图形界面(Cursor 式的键盘操作体验) |
:::
环境与前置知识
- 语言:TypeScript 为主(约 2500 个源码文件),另有 Python SDK(
python/sdk) - 框架:Cordis(插件化运行时),pnpm monorepo
- 运行:
npx @deepseek-ai/dsh web即可体验,默认起在http://127.0.0.1:3080;从源码跑则是pnpm install && pnpm run build && pnpm dsh web - 源码:https://github.com/deepseek-ai/deepseek-harness(MIT,开发者预览阶段,接口可能破坏性变更)
不需要你是 Cordis 专家——阶段二专门补这块。但建议你对 agent 的基本工作方式(模型 + 工具循环)有直觉。
源码地图
读源码前先认清地形。packages/ 下的包按能力分组,每组 README 是该系列的权威地图:
| 位置 | 内容 |
|---|---|
packages/core/ | 产品主干:session(事件日志)、system-prompt(提示词组装)、tools(工具注册与执行流水线)、agent + agent-loop(agent 抽象与默认循环)、scope |
packages/llm/ | LLM 消息/流式词汇表 + 各模型提供方适配器 |
packages/shell/ fs/ sandbox/ subprocess/ terminal/ | 执行世界:shell、文件系统、进程限制(bwrap/Landlock/Seatbelt)、PTY |
packages/subagent/ skill/ web/ lsp/ compaction/ todo/ plan/ jobs/ | 面向模型的能力工具包系列 |
packages/interaction/ credentials/ settings/ | 人机协作平面:审批、权限预设、凭据、设置 |
packages/host/ client/ | Web GUI 的两半:宿主 API 网关 + 浏览器端 |
packages/bundle/ preset/ boot/ | 组装层:profile、组合包、启动粘合 |
apps/cli/ apps/web/ | 两个可执行应用 |
docs/ | 架构文档、子系统说明、cookbook(本文的路线大量参考这里) |
学习路径总览
整条路径按”先跑起来 → 打地基 → 读主干 → 抓设计思想 → 看产品化 → 动手改”推进,规划 6 个阶段约 14 篇:
阶段一:跑起来,建立直觉(第 2~3 篇)
目标:不读任何核心代码,先会用、会看。
- 第 2 篇 · 10 分钟跑通 dsh:
npx起服务、Web UI 各功能区、headless 一次性运行、dsh --profile web --dump-config看启动配置树。产出:一个能玩的本地环境。 - 第 3 篇 · 从源码构建:
pnpm install/pnpm run build的产物结构、apps/cli的入口做了什么、调试怎么挂。产出:能改一行代码并看到效果。
阶段二:地基——Cordis 与组装机制(第 4~5 篇)
目标:看懂”插件如何变成一个产品”。
- 第 4 篇 · Cordis 入门:插件向共享上下文贡献服务、类型化事件、可逆副作用;
ctx键是什么;对照docs/cordis-primer读最小例子。 - 第 5 篇 · Profile 与组合包:
dsh-base→dsh-web-app的分层叠加、patch 文件如何按 id 替换条目、五种随附 profile(web/headless/sdk/sdk-minimal/acp)的差异。产出:用--dump-config解释你机器上实际生效的插件树。
阶段三:核心主干——一个轮次的完整旅程(第 6~9 篇)
这是专栏的重头戏。跟着轮次流程图把一次用户输入到回复落地的路径走通:
- 第 6 篇 · Session:仅追加的事件日志:
SessionEventMap、“模型可见即已记录”不变量、deriveMessages()如何从日志投影出模型历史、会话格式与迁移。 - 第 7 篇 · agent-loop:循环本体:turn/step 生命周期、事件瀑布(
agent/pre-step/agent/request/llm/stream/tools/*)、inbox 与唤醒。对照源码packages/core/agent-loop/src/agent.ts读。 - 第 8 篇 · system-prompt:提示词组装:片段注册、工具 schema 如何进入 prompt、上下文注入(
agent.inject())。 - 第 9 篇 · tools:带把关的执行流水线:作用域化注册表、
pre-execute → execute → post-execute、取消与错误恢复。产出:能徒手画出一次工具调用的完整时序。
阶段四:设计思想——能力 seam(第 10~11 篇)
目标:从”读懂”升级到”会欣赏”。
- 第 10 篇 · seam 三角色:Service Definition / Service Provider / Consumer 的分工;为什么”换一个文件系统提供方 = 换掉整个执行世界”;
ctx.shell、ctx.fs、ctx.sandbox实例拆解。 - 第 11 篇 · LLM 适配器与流式:
ctx.llm的消息/流式词汇表、适配器 seam、assistant-stream 的提交语义、模型可见的 wire 扩展。
阶段五:产品化——模型之外的一切(第 12~13 篇)
- 第 12 篇 · 人机协作平面:审批流、权限预设、凭据与
ask_user;沙箱后端(bwrap/Landlock/Seatbelt)如何限制进程。 - 第 13 篇 · 三种产品形态:Web GUI 的 host/client 分工、headless 与 SDK(TypeScript JSON-RPC + Python SDK)、subagent 与后台任务(
jobs)。
阶段六:实战——写自己的插件(第 14 篇收尾)
- 第 14 篇 · 扩展实操:对照
docs/cookbook(adding-a-tool / adding-an-llm-adapter / adding-a-package)从零写一个工具插件并挂进 profile。走到这里,这个专栏的目标就完成了:你能自信地改它,而不只是读它。
学习方法建议
- 文档先行,代码验证。dsh 的文档可信度很高(CI 里有文档新鲜度门禁),先读文档建立预期,再去代码里找对应实现,效率远高于直接扎进 2500 个文件。
- 让
--dump-config当导游。任何”插件树现在长什么样”的疑问,dump 一下就有答案;再配合ctx键表反查包,几乎不会迷路。 - 沿着一条事件走。读循环类代码最忌横向铺开。选定”用户发一条消息”这条主线,从
turn/start一路追到turn/end,中途遇到的每个包只记录职责、不展开。 - 笔记输出成专栏。我自己就是按这个路径边读边写——每篇的草稿都是阅读笔记的整理。如果你也在读,欢迎用 RSS 订阅本专栏同行。
dsh 处于开发者预览阶段,本文基于 2026-09 的 main 分支(d347e70)。接口后续可能变动,思路不变。
参考资料索引
- 仓库:https://github.com/deepseek-ai/deepseek-harness
- 官方文档站:https://deepseek-harness.github.io/deepseek-harness/
- 架构论文:A Programming Paradigm for Spatiotemporal Composability
- Cordis 框架:https://github.com/cordiverse/cordis
- 仓库内关键文档:
docs/architecture.zh.md、docs/agent-lifecycle.zh.md、docs/tool-execution-pipeline.zh.md、docs/capability-seams.zh.md、packages/README.zh.md