DeepSeek Harness(dsh)从零到全栈【1】认识 DeepSeek Harness:Agent、Harness 与“一切皆插件“

认识 DeepSeek Harness:Agent、Harness 与"一切皆插件"

文章目录

  • [认识 DeepSeek Harness:Agent、Harness 与"一切皆插件"](#认识 DeepSeek Harness:Agent、Harness 与"一切皆插件")
    • 学习目标
    • 正文
      • [1.1 从"会聊天的模型"到"会干活的智能体"](#1.1 从"会聊天的模型"到"会干活的智能体")
      • [1.2 为什么需要 harness:五个环节,五个事故现场](#1.2 为什么需要 harness:五个环节,五个事故现场)
      • [1.3 2026 年的 agent harness 格局](#1.3 2026 年的 agent harness 格局)
      • [1.4 DeepSeek Harness 是什么](#1.4 DeepSeek Harness 是什么)
      • [1.5 "一切皆插件"到底什么意思](#1.5 "一切皆插件"到底什么意思)
      • [1.6 论文导读:Spatiotemporal Composability(时空可组合性)](#1.6 论文导读:Spatiotemporal Composability(时空可组合性))
      • [1.7 技术栈与工程面貌](#1.7 技术栈与工程面貌)
      • [1.8 版本与生态现状(截至 2026-08)](#1.8 版本与生态现状(截至 2026-08))
      • [1.9 本系列学习路线图与使用方法](#1.9 本系列学习路线图与使用方法)
      • FAQ
    • 动手实验
      • [实验 ①:浏览仓库,找到"一切皆插件"的原文(约 5 分钟)](#实验 ①:浏览仓库,找到"一切皆插件"的原文(约 5 分钟))
      • [实验 ②:无 key 跑通 `dsh --help`(约 3 分钟)](#实验 ②:无 key 跑通 dsh --help(约 3 分钟))
    • 常见坑
    • 小结
    • 下一章预告
    • 参考资料

摘要 :本章从"模型只会输出 token"这一基本事实出发,厘清 Agent = Model + Harness 的本质,并系统拆解 harness 承担的五类工程职责(工具安全执行、上下文管理、状态持久化、权限审批、多轮编排)。随后对比 2026 年主流 agent harness 格局,引出 DeepSeek Harness(dsh)的四个差异点,深入解读其"一切皆插件"架构在源码层面的含义------不存在特权内核,模型适配器、工具注册表、会话日志乃至 agent loop 本身皆可配置替换,并由 capability seam 的三种角色(Service Definition / Provider / Consumer)承载。文章还导读支撑该设计的论文《A Programming Paradigm for Spatiotemporal Composability》,用 RAII、词法作用域与模块 import 类比解释 temporal / spatial composability,并介绍其可运行实现 Cordis 被 vendored 内嵌的工程决策。最后给出技术栈、版本生态现状、学习路线图、FAQ 与两个动手实验,帮助读者建立一张从概念到源码的准确认知地图。
本章导读:你大概已经用过不少 AI 编程工具,也听过"智能体(Agent)"这个词。但"agent harness(智能体框架)"到底是什么?为什么 DeepSeek 要开源一个,而且声称它"一切皆插件"?本章不写一行业务代码,只解决一个问题:让你建立一张准确的认知地图------模型、agent、harness 三者的边界,dsh 与同类工具的差异,以及支撑它的那篇设计论文到底在讲什么。

学习目标

  • 能用自己的话说出"模型只会输出 token"与"agent 能完成任务"之间的差距,并说出 harness 承担的五类职责;
  • 能说出 dsh 与 Claude Code、Codex CLI 等同类产品的四个差异点;
  • 能解释"一切皆插件"在源码层面意味着什么,并指出 capability seam(能力接缝)的三种角色;
  • 能用 RAII、词法作用域、模块 import 这三个静态世界类比,向同事转述论文中的 temporal / spatial composability;
  • 能独立完成两个动手实验:浏览仓库结构并定位架构文档,跑通 npx @deepseek-ai/dsh --help

正文

1.1 从"会聊天的模型"到"会干活的智能体"

  • 先把最基本的事实摆清楚:语言模型只会做一件事:给定一段文本,预测并输出后续 token 。你在 API 里调用 deepseek-chat,它不会打开文件、不会执行命令、不会记住上一次的对话(除非你把历史又发一遍)。它是一个纯函数式的文本进、文本出的机器。

  • 那你在 ChatGPT、Claude Code 或者别的"AI 助手"里看到的"它帮我改了文件、跑了测试"是怎么回事?因为模型外面套了一层软件:这层软件把用户的话塞进提示词,把模型输出的文本解析成"调用某个工具"的指令,替模型真正去执行那条命令,把结果再拼回上下文发回去,如此往复,直到任务完成。Agent = Model + Harness,这个等式里的 Harness(马具、挽具)就是这层软件:模型是那匹马力强劲但不知方向马,harness 负责套缰绳、递缰绳、防止它冲下悬崖。

  • 一个最小的 harness 循环长这样:

bash 复制代码
// 示例代码:最小 agent 循环(伪代码)
while (true) {
  reply = model(messages)          // 1. 请求模型
  tool_calls = parse(reply)        // 2. 解析模型想调用的工具
  if (tool_calls.length === 0) break
  for (call of tool_calls) {
    result = execute(call)         // 3. 真正执行(读文件、跑命令......)
    messages.push(result)          // 4. 把结果拼回上下文
  }
}
  • 二十行就能跑起来。那你可能会问:既然这么简单,为什么还需要一个"框架"?因为上面这个玩具循环在每个环节都是裸奔的,而每个环节都可能出事。这正是下一节的内容。

1.2 为什么需要 harness:五个环节,五个事故现场

  • harness 不是一个"循环库",它要同时回答五个工程问题。每个问题,我们都先看一个真实感十足的翻车现场。

一、工具安全执行。 反例:你让 agent"清理一下项目里的临时文件",模型输出的命令是 rm -rf /tmp/build,但如果模型的参数序列化出了偏差,或者干脆幻觉出一个 rm -rf ~呢?玩具循环会直接 exec(),你的家目录就此消失。一个合格的 harness 必须在模型输出的命令和真实操作系统之间加一道闸:参数校验、工作目录限定、沙箱(sandbox,把进程关进一个受限的"笼子"里执行)、以及最坏情况的兜底。dsh 里这条链路是工具注册表 → 执行流水线 → 沙箱/审批提供方,全部可替换。

二、上下文管理。 反例:任务做到第 40 轮,历史消息加工具结果早超过 128K 上下文窗口,API 直接报错;或者更糟,不报错,模型悄悄"忘了"你第 2 轮立下的规矩,开始自作主张。harness 需要决定每轮请求发什么:哪些历史保留、哪些压缩成摘要、哪些注入为隐形背景。dsh 的做法是"模型可见即已记录"------凡是发给模型的内容都必须能从会话日志重建(架构文档原话),这让上下文管理变得可审计、可回放。

三、状态持久化。 反例:进程崩溃或者你手一抖关了终端,刚才让 agent 跑了半小时的重构任务,没了,日志都没处找。harness 必须把每一轮对话、每次工具调用持久化成事件日志,重启后能原样恢复现场。dsh 的会话是一份仅追加(append-only)的 JSONL 事件日志,fork、回放、transcript(文本记录)导出都从这同一份日志派生。

四、权限审批。 反例:agent 在无人值守时决定"为了修好这个测试,我要改一下 CI 配置并且 curl 一个外部脚本下来执行"。谁批准的?没有人。harness 需要一个审批(approval)机制:敏感操作先弹给人类,人类点了允许才放行,并且每一次决定本身也要留痕。dsh 的审批记录是持久会话事件,事后可回溯谁在何时批准了什么。

五、多轮编排。 反例:一个"调研 → 写码 → 跑测试 → 修复 → 汇报"的长任务,中途用户插了一句"等等,别用那个库",玩具循环要么忽略插话,要么把整个上下文搞乱。harness 要处理输入排队(什么消息算新任务、什么算补充说明)、子任务委派(subagent,子智能体)、后台任务与定时续跑------这些在 dsh 里对应 inbox(收件箱)、turn(轮次)/step(步骤)分层、jobs 与 goals 等一整套机制。

这五件事没有一件是"模型能力"问题,全是工程问题。这就是 harness 存在的理由:它把"模型能干活的假设"变成"模型被约束着干活的现实"

⚠️ 常见误区 :很多人以为"harness 越强,模型越自由"。恰恰相反------harness 的核心价值是约束:它让模型的每次越界企图都先经过一道可配置、可审计的闸门。

1.3 2026 年的 agent harness 格局

harness 不是新概念,但 2025 年之后它才成为一类显性的软件品类。截至本章写作(2026-08),主流玩家大致是:

  • Claude Code(Anthropic):终端形态 agent harness 的破圈者,闭源,围绕 Claude 模型构建;agent 循环内置于产品,扩展主要通过 skills、MCP(Model Context Protocol,模型上下文协议)等方式。
  • OpenAI Codex CLI(OpenAI):同一赛道的终端 agent,围绕 OpenAI 模型体系,开源其 CLI 外壳但整体体验与自家模型绑定。
  • OpenCode:社区驱动的开源终端 agent,支持多家模型,但循环与扩展模型由项目自身固定。
  • Gemini CLI(Google):围绕 Gemini 的终端 agent,主打超大的免费额度与 Google 生态集成。

(以上定位概括以各家官方文档为准,一句话带过)重点是你该怎么选、dsh 凭什么不同。dsh 的差异点有四个:

  1. 一切皆插件:别家也讲"插件",但通常只有工具和 MCP 是插件;在 dsh 里,模型适配器、工具注册表、会话日志、乃至 agent loop 本身都是插件,都可以从配置替换------这句不是口号,架构文档原话如此(下一节引用)。
  2. MIT 许可:整棵树(包括它内置的框架层)都可以自由修改、二次分发、商用。
  3. 模型无关:官方适配 DeepSeek API,同时任何 OpenAI 兼容端点都能接------Claude、本地 Ollama、企业内网网关都在第 05 章的讨论范围内。
  4. 从框架层可定制 :产品不是"给你留了几个扩展点",而是"整棵插件树都暴露给你":组合包、profile(具名组装)、patch 文件层层叠加,dsh --profile web --dump-config 可以打印出你这台机器上实际组装出的整棵配置树,其中每个条目都能被你自己的 patch 替换。

一句话总结:别家是"一个带扩展槽的产品",dsh 是"一堆插件的预装组合"------后者在工程上更激进,代价是概念更多。

这对你的实际选择意味着什么,可以再说得直白些。如果你只是想要"开箱即用的终端助手",Claude Code、Codex CLI 这类产品到今天依然更省心------少配置、少概念、官方体验打磨得细。但当你出现以下任一需求时,dsh 的差异点就会开始变现:想把执行底座换成自己的沙箱或远程环境(换 provider);想接一家没有官方支持的内网模型网关(写一个模型适配器插件);想基于同一套能力做自己的产品形态(复用 dsh-base 组合包组装新 profile);或者就是想读懂一个现代 agent 的全部内部构造(整棵树都在仓库里,没有黑盒)。

  • 本系列假定你多多少少带着后面这几种动机而来。

1.4 DeepSeek Harness 是什么

  • 把官方 README 的信息浓缩成一段话:

DeepSeek Harness(命令名 dsh,npm 包 @deepseek-ai/dsh)是 DeepSeek AI 官方开发的开源 agent harness。 它构建于"一切皆插件"的架构之上,由 Cordis 框架驱动,设计思想来自论文《A Programming Paradigm for Spatiotemporal Composability》(arXiv:2608.25512),MIT许可。本章写作时的版本基准是 0.1.2-alpha.1 (根package.jsonversion 字段)。

  • 运行形态。一条命令即可起 Web UI:
bash 复制代码
# 来自 README.zh.md「运行」一节
npx @deepseek-ai/dsh web
  • 它默认在 http://127.0.0.1:3080 启动 Web UI,本机启动时会用默认浏览器打开页面;通过 SSH 启动时只打印宿主机 URL(本地转发由 SSH 客户端持有),--no-open 可仅运行服务器不开浏览器。深一层看,"形态"在 dsh 里不是硬编码的产品分支,而是五个随发行版交付的 profile 模板:
profile 形态 面向
web Web UI + HTTP 服务器(dsh web 日常交互使用
headless 不挂服务器的一次性运行器 脚本与流水线,如 dsh --profile headless "跑一遍测试"
sdk / sdk-minimal stdio 上的 JSON-RPC 服务器 TypeScript / Python SDK 程序化驱动
acp Agent Client Protocol 服务器 与编辑器等外部 agent 客户端对接
  • 前四种归并起来就是宣传里常说的"Web UI / CLI / SDK / ACP 四种运行形态";本质区别只是插件树多挂了哪几个组合包(dsh-base 是所有 profile 的共享第一层,架构文档对此有明确说明)。

预览期警告------这不是套话,必须原样转述。README 中文版写着:

DeepSeek Harness 处于 开发者预览 阶段,正在快速迭代。未来将出现破坏兼容性的变更。 运行本项目前,请阅读安全说明 SAFETY.zh.md(仓库根目录,本章末尾参考资料有路径)。

SAFETY.zh.md 说得更直接:

DeepSeek Harness 是实验性的开发者预览软件。它尚未接受安全审计,不得视为安全或可用于生产环境的软件。不要把 DeepSeek Harness 当作不可信工作负载唯一的安全控制措施。

  • "破坏兼容性"不是空话:仅 2026 年 8 月一个月内,就发生过 SQLite 存储格式不兼容变更(v0.1.0-rc.8,旧会话文件直接读不了)。

1.5 "一切皆插件"到底什么意思

现在拆解本章标题里的第三个词。先看两个原文引用:

  • 它构建于一切皆插件 的架构之上,由 Cordis 驱动。------ README.zh.md

  • 产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身,因此每个都可以从配置替换。不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边,而各项注册都是副作用,会在其插件卸载时撤销。------ docs/architecture.zh.md「Cordis」

  • 把「扩展系统」这件事建模成「对共享上下文做一系列可逆的副作用」。因为所有扩展动作都是副作用而非对内核的硬编码修改,所以它们天然对称------挂载是「施加副作用」,卸载是「撤销副作用」。这样整个系统就没有「改完就删不掉」的补丁,任何插件都能干净地装上、干净地卸下。

两段话里有三个关键词,值得逐个落到源码。

第一,"特权内核"的不存在。 传统软件的扩展是"内核 + 插槽":内核里有硬编码的主循环、硬编码的工具清单,扩展点之外的一切都改不了,想深度定制就得给内核打补丁(fork 后改源码,从此走上维护地狱)。dsh 的主张是反过来的:没有一个"dsh 核心 + 若干可选插件",只有插件 。你运行 dsh 时看到的一切能力,都是启动时一棵插件树组合出来的结果;组合方式暴露为配置,因此"改造产品"不需要改产品代码,改配置树就行。

第二,"从配置替换"。 承接这个主张的机制叫 capability seam(能力接缝,下文简称 seam)。seam 是一种包含三种角色的可替换能力(术语表 docs/glossary.zh.md 原文):

  • Service Definition(服务定义) :声明这项能力的接口,并占据一个稳定的 ctx.<key>(如 ctx.shell),注意它是一个 Cordis Service 类,而不是 TypeScript interface
  • Service Provider(服务提供方):实现该接口的具体行为,可以有一个或多个;
  • Consumer(消费方):使用这项能力的插件,通常是面向模型的工具。
  • packages/shell 是官方术语表点名的规范范例,目录结构如下:
bash 复制代码
// 真实目录结构:packages/shell/
packages/shell/
├── shell/              # dsh-shell:ctx.shell 服务定义(Service Definition)
├── bash-local/         # dsh-bash-local:本机 bash 提供方(Provider)
├── bash-sandbox/       # dsh-bash-sandbox:沙箱 bash 提供方(Provider)
├── pwsh-local/         # dsh-pwsh-local:Windows PowerShell 提供方
├── pwsh-sandbox/       # dsh-pwsh-sandbox
├── shell-env/          # dsh-shell-env:shell 环境信息
├── tool-bash/          # dsh-tool-bash:bash 工具(Consumer)
└── tool-bash-persistent/ ...
  • 那么"一堆插件的预装组合"预装了什么?架构文档列出的 dsh-base 组合包------所有主流 profile 的共享第一层------原文清单是:"模型适配器、工具、持久化、沙箱与审批策略、设置、凭据、遥测"。也就是说,你 npx 下来的那个"产品",本质上是这一层之上再加一层界面(dsh-web-app 加浏览器应用、dsh-headless 加一次性运行器)。看懂了这一点,你就看懂了 dsh 产品哲学的全部:界面可以换、组合可以换,底座清单每层都明码标价

  • 三个角色各占一个包。举例说明 seam 的威力 :把 bash-local 换成 bash-sandbox 提供方------改动只是配置树里的一行------整个产品的执行行为就变了:所有 bash 工具调用从此被关进沙箱执行,而 tool-bash 这个消费方一行代码都不用动,它根本不知道(也不需要知道)底下是谁在执行命令。架构文档对此有一句精辟总结:"seam 正是替换一个提供方就能改变整个产品的原因。" 更进一步:"文件系统与进程提供方共享同一个执行世界,因此把它们指向远程沙箱,也就把 Bash、PTY 和 LSP 一并搬了过去"------换提供方,等于给整个产品搬家。

💡 深挖 :想亲眼看看你这台机器上组装出了什么?运行 dsh --profile web --dump-config,它会打印组合包各层叠加上你自己的 patch 之后的完整配置树,并注释每一行来自哪个文件。架构文档原话:"它打印出的任何条目,都可以由你自己的 patch 替换。" 这条命令是本系列的核心调试手段。

第三,"挂载到其他插件旁边"。 没有内核,插件之间如何协作?答案是共享的上下文(Context) 。每个插件向当前上下文贡献服务、监听事件、安装副作用;上下文既是服务容器 (通过 inject 声明依赖,服务就绪后插件才启动),又是事件总线 (emit / waterfall / parallel / serial / bail 五种分发模式),还是副作用的登记处(登记的副作用在插件卸载时自动撤销)。这套机制的学名就是 Cordis------它从哪来、为什么可信,正是下一节的话题。

1.6 论文导读:Spatiotemporal Composability(时空可组合性)

  • dsh 与别的 harness 最深的差别不在功能清单,而在它先有一篇理论论文,再把理论落成了代码。论文全名《A Programming Paradigm for Spatiotemporal Composability》(arXiv:2608.25512,92 页,作者 Yifan Shi(北京大学 / DeepSeek-AI)、Wei Zhang、Tianyi Cui)。别被名字吓住,它其实只回答一个问题:一群随时装、随时卸的组件,如何共处而不互相留垃圾? 论文把这个问题拆成两个维度。

  • 时间维:temporal composability(时间可组合性)。 定义:当一个组件被移除时,它带来的所有副作用必须被完全回退,世界必须回到它到来之前的样子,不留监听器、不留注册项、不留后台任务。这不是新发明,静态世界里它早有对应物:

    • RAII(Resource Acquisition Is Initialization,资源获取即初始化):C++ 的约定------对象析构时自动释放它持有的资源。你 new 了一块内存、开了一个文件句柄,离开作用域时它们被如约归还。
    • 词法作用域:变量出了作用域就失效,不会"泄漏"到外面。
  • 动态世界(程序运行中随时装卸组件)的难点在于:静态世界里"作用域结束"是编译器保证的时刻,动态世界里"组件卸载"可能发生在任意时刻,甚至发生在它的初始化还没跑完的时候。要保证此刻"所有它登记的副作用被逆序撤销",需要运行时的簿记机制。

  • 空间维:spatial composability(空间可组合性)。 定义:组件之间的依赖以结构化方式声明 ,并且当依赖就绪时,依赖它的组件被响应式地激活 (反之,依赖缺失时保持等待,而不是带着空指针强行启动)。静态世界的对应物是模块系统的 import:你声明"我依赖 lodash",模块加载器负责解析、去重、按序加载------你从不手动编排"先加载 A 再加载 B"。

  • 统一:context paradigm(上下文范式)。 论文的贡献是把这两个维度塞进同一个原语------Context。同一个上下文对象,既是**effect(副作用)的作用域:组件在它上面注册的一切(监听器、服务、工具、定时器)都被登记,卸载时逆序回退------这是时间维;又是coeffect(协效果,即"对环境的依赖")**的声明处:组件声明"我需要 ctx.shell 就绪才能启动",上下文负责等待、注入、以及依赖变化时的响应式激活------这是空间维。

  • 为什么偏偏是 agent harness 需要这套理论?论文第 1 章的动机正是"自进化 agent harness":一个能为自己安装新能力(新工具、新策略)的 agent,意味着它的能力集合在运行时是可变的 。这恰好把两个维度的难题同时推向极端------运行时装上的组件必须能干净卸下(否则 agent 越跑越脏),运行时新增的组件必须能被现有组件声明和消费(否则装了也白装)。换一个不那么科幻的说法:只要你允许插件热加载、允许用户改配置不重启,你就已经活在"动态组合"的世界里了,区别只在于有没有纪律。论文先在第 2 章把effect/coeffect的预备概念摆正,第 3 章分别给出"可逆 effect"与"响应式 coeffect"的设计,第 4 章把规则形式化为一个动态组合演算,并证明了保持性(preservation)、时间可组合性、空间可组合性、进展(progress)、合流(confluence)等定理。

  • 这些定理翻译成人话是:在这套规则下,组件装卸不会留垃圾、不会死锁,最终结果与(满足依赖前提下的)装卸顺序无关。你不需要读懂证明,但需要知道"dsh 里每一个看似玄学的生命周期行为,背后都有定理背书"。

  • 实现:Cordis。 论文第 5 章介绍了这套理论的可运行实现------Cordis,一个 v4 元框架 。它并非 dsh 团队从零新写:Cordis 源自 Koishi(一个成熟的机器人框架)生态,作者是社区开发者 Shigma,已有多年生产服役史。dsh 的用法很特别:vendored(源码内嵌) ------把 Cordis 连同其基础库整体拷进仓库 vendor/cordis 目录,更名为 @deepseek-ai/cordis(上游版本在 vendor/README.md 清单中记录为 4.0.0-rc.7;本地 package.json 的 version 字段随同步演进可能更高,以你检出的源码为准)。

  • 为什么内嵌而不是 npm 依赖?vendor/README.md 给了两个理由,值得原文转述:一是让 harness 完全拥有框架层 (可审计、可打补丁、版本钉死),二是避免以上游名字发布导致 npm 注册表上的抢注(squatting)风险。内嵌不是原样照抄:vendor/README.md 逐条记录了 18 处本地加固改动------例如 fiber 生命周期加固(堵住重入卸载的三个缺口)、事务化的 Loader 配置变更(应用失败的候选配置自动回滚)等。这本身就是"一切皆插件"精神的延伸:连框架层也是一个可以整体替换的组件。

  • 用一个比喻结束,然后立刻落回精确语义:传统"改产品"是把电线焊进主板 ------fork 源码、改内核、从此与上游分道扬镳;dsh 的插件体系是墙上的插座 ------插上电器(插件挂载:注册服务、监听事件、贡献工具 schema),拔掉电器(插件卸载:副作用逆序回退,墙面上不留线头)。落回精确语义:插座对应 Cordis 的 Context;"插上"是 ctx.on() / ctx.effect() 把副作用登记到当前 fiber(纤维,Cordis 的执行与生命周期单位)上;"拔掉"是 fiber 的 dispose(资源释放)过程,按登记信息把每一条副作用撤销。论文证明的就是:只要大家遵守插座协议,无论多少电器插上拔下多少次,电路都不会出问题。

💡 深挖 :论文第 5 章实现的另一半是"声明式 loader 与 HMR"(Hot Module Replacement,热模块替换)。dsh 里它对应 cordis.yml / cordis.patch.yml 配置树、dsh plugin 安装、以及自定义 profile 的 patch 热重载------改一行 patch 文件,运行中的插件树即时重组。换句话说,dsh 的"可配置"不是产品特性,而是论文理论的直接产物。Cordis 概念的入门读物就在仓库里:docs/cordis-primer.zh.md

1.7 技术栈与工程面貌

  • 在动手之前,认识一下你要打交道的这具agent躯体的规格:

  • 语言与仓库形态 :TypeScript 全家桶,pnpm monorepo(单一仓库多包管理)。packages/ 下有 56 个一级分组、247 个包目录(packages/*/*/package.json 实数),另有 apps/(CLI 与 Web 应用)、vendor/(内嵌框架层)、native/(原生组件)、python/(Python SDK 与运行时 wheel)、website/(文档站)。

  • 运行环境 :根 package.json 的 engines 字段原文------"node": "^22.19.0 || >=24.0.0",包管理器钉死 pnpm@11.7.0

    • 注意有下限:Node 18、20 一律不保证,一些第三方文档声称"Node 18 可用"是错的。
  • 前端 :Web UI 是 React 应用(apps/web + client 模块)。

  • SDK :除 TypeScript SDK 外,还有 Python SDK(python/sdk,文档在 docs/user/guide/python-sdk.zh.md),通过打包 dsh --profile sdk 的运行时 wheel 驱动同一棵插件树。

  • 质量门禁docs/testing.zh.md 描述了六层测试------单元测试、覆盖率门禁、真实 API e2e、预期输出测试、快照测试、Web 浏览器快照。其中覆盖率门禁的原文值得一看:"对 packages/*/*/src 按文件 100% 覆盖"------全仓库 src 达到按文件 100% 行覆盖,是 CI 的硬性门禁,未覆盖的行会被当作应删除的死代码。仓库还带几十个 verify-* / gen-* 脚本,把"文档与代码一致"也做成了门禁。

这套工程配置想说明一件事:dsh 虽然是 0.1.x 的预览版,但它不是玩具------它的工程纪律(覆盖率、文档门禁、事故复盘 docs/postmortem/)达到甚至超过很多 1.0 产品。

⚠️ 常见误区:版本号小 ≠ 质量差,但 ≠ 稳定。工程门禁防的是"代码写错",防不了"预览期 API 设计变更"。破坏性变更(如 rc.8 的存储格式)在门禁全绿的情况下照发不误------这是有意为之的快速迭代,不是事故。

1.8 版本与生态现状(截至 2026-08)

dsh 于 2026-08-13 发布开发者预览,随后以罕见的节奏迭代(以下节点信息来自各版本 release notes):

时间 版本 要点
2026-08-13 开发者预览 首次公开发布
08-17 v0.1.0-rc.7 插件设置卡片;Claude Code / Codex 子代理接入 Job Panel
08-19 v0.1.0-rc.8 子代理改为以 Profile Bundle 安装(dsh plugin add @deepseek-ai/dsh-subagent-codex 等,命令见 apps/cli/reference/README.zh.md);SQLite 存储格式不兼容变更
08-21 v0.1.1-rc.1 / rc.2 视觉模型 DeepSeek-V4-Flash-Vision-Exp;修复 Bubblewrap /proc 逃逸;Files API 上传图像
08-27 v0.1.2-alpha.1(本系列基准) 会话流折叠;@Remote 网关统一;Web UI 一次性 token 认证;Code Mode 更名 PTC mode;SSRF 防护
  • 其中几个节点值得注意。

    • rc.8 的存储格式变更意味着升级后旧会话可能直接报错打不开(对应错误 SessionFormatUnsupportedError)------这是"预览期破坏性变更"的活例子。
    • Bubblewrap /proc 逃逸修复则是沙箱安全 bug 的修复,呼应 SAFETY.zh.md 的立场:沙箱降低风险,但不承诺绝对隔离。
    • PTC(Programmatic Tool Calling,程序化工具调用)mode 由更早的 Code Mode 更名而来------让模型写代码来编排工具调用,而非逐个 JSON 调用(仓库里的 pnpm run demo:ptc 即其演示脚本)。
    • v0.1.2 的另外两项对普通用户有感:Web UI 一次性 token 认证,让本机端口不再是谁都能碰的裸端口;会话流折叠,让长会话的界面不至于被工具输出刷成瀑布。
  • 社区热度 (写作时点数据,以实时页面为准):GitHub 约 20 万 star、1.4 万+ 提交;Hacker News 主帖 314 条评论;r/LocalLLaMA 有过热帖。生态侧:GitHub topic dsh-plugin 下已有 700+ 仓库;社区维护的 awesome 清单(libukai/awesome-deepseek-harness)聚合插件与教程;官方渠道包括 GitHub Discussions、Discord、企业微信群(README 里有入群二维码)与微信公众号。判断一个开源项目的"可持续性",提交节奏与第三方插件数量比 star 数更有说服力------这两项 dsh 目前都很健康。

1.9 本系列学习路线图与使用方法

本系列《DeepSeek Harness(dsh)从零到全栈》共 32 章,分四个阶段

  • 01-入门篇(Ch01--06):认识 dsh,环境搭建对话,核心概念地图,日常使用完全指南,模型配置深入,排错手册与FAQ.md
  • 02-核心原理篇:Cordis 框架层、事件系统、会话模型、agent loop,capability seam 三角色详解、steer 与循环的深入机制。
  • 03-插件开发篇:动手写插件,"开发一个 Tool"。
  • 04-高级篇:沙箱内核、批处理、自进化等主题。

使用方法有三条约定:第一,源码对照 。每章给出的仓库路径都真实存在。第二,版本基准 0.1.2-alpha.1 。dsh 迭代很快,凡涉及行为细节,以你检出的源码为准;教程会在易变处显式标注。第三,术语回查 。遇到陌生名词先翻 03-核心概念地图.md,那里按七层组织了全部术语。

FAQ

Q1:dsh 是一个大模型吗?和 DeepSeek API 什么关系?

  • 不是模型,一行神经网络代码都没有。dsh 是 harness:它调用模型 API(默认适配 DeepSeek 官方 API),把模型输出变成受约束的实际行动。没有配模型 key 的 dsh 能启动、能看帮助,但没法对话。

Q2:dsh 能接 Claude、OpenAI、本地模型吗?

  • 能。模型适配器本身是 ctx.llm seam 上的插件,任何 OpenAI 兼容端点(含 Ollama、vLLM)都可接入,配置层面的兼容性开关(compat 字段)也都有------完整步骤与坑位在 05-模型配置深入.md

Q3:dsh 和 LangChain 这类框架是什么区别?

  • LangChain 是编排库 ,你在自己的 Python/JS 程序里 import 它,自己搭链、自己管状态;dsh 是运行时 harness,它本身就是一个可运行的产品(Web UI / CLI / SDK 进程),自带持久化、审批、沙箱、插件热加载,你要做的是配置与扩展它,而不是从头搭建它。两者甚至可以互补:用 dsh 跑 agent,用 LangChain 写它的下游数据处理。

Q4:要付费吗?

  • dsh 本身 MIT 开源,免费。你付的是模型 API 的钱(用 DeepSeek 官方 API 就充platform.deepseek.com 的余额,用本地模型则零成本)。

Q5:能用于生产吗?

  • 现在不能,官方原话是"尚未接受安全审计,不得视为安全或可用于生产环境的软件"。预览期正确的用法是:个人开发环境、一次性虚拟机/容器、有备份的实验环境;绝不要把敏感凭据暴露给它,也不要把它当作不可信工作负载的唯一安全控制(SAFETY.zh.md 原话)。

Q6:Windows 支持吗?

  • 支持,而且是第一优先级:仓库 CI 有专门的 Windows 门禁(package.json 里的 check:ci:windows-* 系列),packages/shell 同时内置 bash 与 PowerShell(pwsh)双套本地/沙箱提供方,本系列教程的主环境就是 Windows。

Q7:为什么不直接用 npm 上的 Cordis,要自己 vendor 一份?

  • 两个官方理由:完全拥有框架层(可审计、可加固、版本钉死),以及避免上游名字被抢注。实际收益还有第三条:18 处本地加固(如事务化配置回滚)对 dsh 的稳定性是实质贡献,不依赖上游发版节奏。

Q8:dsh 和 MCP(Model Context Protocol)什么关系?

  • MCP 是一个跨 harness 的"外部工具怎么接进来"的协议,dsh 支持它(仓库含 packages/mcp,使用场景见 docs/user/guide/mcp-memory.zh.md)。但要注意方向:MCP 只解决外部工具接入这一件事;dsh 的 seam 体系覆盖面大得多,模型、文件系统、进程、沙箱、审批、持久化都是可替换的 seam。可以粗略地说:MCP 是 dsh 工具体系的一条"对外接口",而不是它的扩展机制本身。

动手实验

实验 ①:浏览仓库,找到"一切皆插件"的原文(约 5 分钟)

  • 如果你还没有在本地下载源码,先克隆:
bash 复制代码
# 来自 README.zh.md「从源码运行」一节(本实验只需 clone,无需 build)
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
  • 在仓库根目录执行 ls,对照确认顶层布局(节选):
text 复制代码
// 真实输出(节选):仓库根目录
apps/     docs/     native/   packages/  patches/  python/  scripts/
snapshots/ vendor/  website/  README.zh.md  SAFETY.zh.md  AGENTS.md  LICENSE  package.json

然后打开 docs/architecture.zh.md,通读第 1 节「Cordis」。

  • 完成检验:你能逐字找到"产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身"这句话,并能说出 packages/shell/ 下哪三个包分别扮演 seam 的三种角色。

实验 ②:无 key 跑通 dsh --help(约 3 分钟)

  • 不需要任何 API key:
sh 复制代码
npx @deepseek-ai/dsh --help
  • 预期行为 (依据 apps/cli/reference/README.zh.md,具体文案以你拉到的版本为准):dsh --help 没有可供交付参数的 profile,因此打印启动器自身 的帮助信息并以 0 退出;npx @deepseek-ai/dsh -V 打印启动器版本。再试 npx @deepseek-ai/dsh web --help------第一个参数 web 会选中 web 子命令,这次打印的是web 应用 的帮助(其参数表:--host--port、可重复的 --trusted-host--no-open),同样不启动服务器。
  • 完成检验:两个命令都正常退出、都不需要 key------这验证了"没有模型,harness 照样能跑;模型只是树上的一个插件"。

常见坑

症状 原因 解法
启动 dsh 后无法对话,以为是软件坏了 dsh 是 harness 不是模型,未配置任何模型提供方 属预期行为;按第 02 章配置 API key
Node 18/20 上安装或启动出现莫名报错(往往不直说版本问题) engines 要求 `^22.19.0
从 npm 搜索 "cordis" 并安装,得到的是别人的框架 dsh 内嵌的是改名后的 @deepseek-ai/cordis,上游 cordis 是独立项目 只通过 @deepseek-ai/* 作用域使用 dsh 生态
升级版本后旧会话打不开 预览期存储格式不兼容变更(如 rc.8 的 SQLite 格式) 升级前备份 $DSH_HOME;处置见第 06 章
在重要机器上放开权限长跑任务 忽视 SAFETY.zh.md 警告:沙箱/审批降低风险但不保证隔离 最小权限;一次性虚拟机/容器;备份可访问文件

小结

  • 模型只输出 token; a g e n t = m o d e l + h a r n e s s , h a r n e s s agent = model + harness,harness agent=model+harness,harness把"能干活"变成"被约束地干活"。
  • harness 的五类职责:工具安全执行、上下文管理、状态持久化、权限审批、多轮编排,每一类失效都有真实事故形态。
  • dsh 是 DeepSeek AI 官方开源的 agent harness(dsh / @deepseek-ai/dsh),MIT,五种 profile(web / headless / sdk / sdk-minimal / acp)对应四种使用形态。
  • "一切皆插件"是字面意思:模型适配器、工具注册表、会话日志、agent loop 都是插件,不存在需要打补丁的特权内核。
  • capability seam 三角色:Service Definition(占据 ctx.<key>)、Service Provider(可替换实现)、Consumer(通常是面向模型的工具);换提供方即换产品行为。
  • 论文《A Programming Paradigm for Spatiotemporal Composability》把"组件装卸不留垃圾"(temporal,静态对应 RAII/词法作用域)与"依赖声明式激活"(spatial,静态对应模块 import)统一进 context paradigm;Cordis 是其可运行实现,被 dsh vendored 内嵌为 @deepseek-ai/cordis
  • 工程面貌:TypeScript pnpm monorepo、56 组 247 包、Node ^22.19.0 || >=24、React Web UI、Python SDK、六层测试与按文件 100% 行覆盖门禁。
  • 预览期警告是实质约束:破坏性变更已发生(rc.8 存储格式)、安全审计未做、生产环境禁用。

下一章预告

  • 认知地图画好了,该点亮真机了。02-环境搭建与对话.md 将带你用 npx @deepseek-ai/dsh web 一步起服务,配好第一个模型 key,越过新手第一大卡点,"选择工作区",完成第一次带权限审批的对话,并顺便弄清 Web UI 每个面板是干什么的。

参考资料

  • 官方文档(仓库路径):
    • README.zh.md(运行方式、社区渠道、预览期警告)
    • SAFETY.zh.md(安全说明全文,本章多处引用)
    • docs/architecture.zh.md("一切皆插件"与微内核声明、profile/bundle、能力 seam)
    • docs/glossary.zh.md(seam 三角色规范定义)
    • docs/cordis-primer.zh.md(Cordis 五个核心概念)
    • docs/testing.zh.md(六层测试与 100% 行覆盖门禁)
    • vendor/README.md(vendored 清单、@deepseek-ai/cordis 更名缘由、18 处本地改动日志)
    • apps/cli/reference/README.zh.md(CLI 命令与 --help 行为参考)
  • 源码(本章引用的关键文件路径):
    • package.json(版本 0.1.2-alpha.1、engines、scripts)
    • packages/shell/(seam 规范范例:shell/bash-local/bash-sandbox/tool-bash/
    • vendor/cordis/(内嵌 Cordis 源码)
  • 外部资料:
相关推荐
张忠琳1 天前
【deepseek-harness】Cordis 开源项目深度介绍
ai·agent·deepseek·harness·cordis·dsh
程序员三明治1 天前
【体验毛坯房】Deep Harness 入门教程
java·人工智能·后端·大模型·llm·deepseek·dsh
张忠琳3 天前
【deepseek-harness】Cordis 时空可组合性编程范式 — 三段式精读笔记(四)
ai·agent·deepseek·harness·cordis·dsh
张忠琳3 天前
【deepseek-harness】Cordis 时空可组合性编程范式 — 三段式精读笔记(五)
ai·agent·deepseek·harness·cordis·dsh
张忠琳4 天前
【deepseek-harness】Cordis 时空可组合性编程范式 — 三段式精读笔记(二)
ai·agent·deepseek·harness·cordis·dsh
张忠琳5 天前
【deepseek-harness】Cordis 时空可组合性编程范式 — 三段式精读笔记(一)
ai·agent·deepseek·harness·cordis·dsh
其美杰布-富贵-李6 天前
02. 快速开始:安装、Web UI、Headless 与第一次运行诊断
harness·dsh
其美杰布-富贵-李7 天前
06. Session 与 Event Sourcing:日志、Surface、Replay、Fork 与恢复
harness·dsh
oe10198 天前
以谈DSH为醋,包个饺子——Harness与RSI与Scaling
dsh·rsi