详情

首页手游攻略 认识 DeepSeek Harness(DSH):Agent、Harness 与“一切皆插件“实用指南

认识 DeepSeek Harness(DSH):Agent、Harness 与“一切皆插件“实用指南

佚名 2026-10-13 09:10:01

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“认识 DeepSeek Harness(DSH):Agent、Harne……”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

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

摘要:本章从"模型只会输出 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-ch@t,它不会打开文件、不会执行命令、不会记住上一次的对话(除非你把历史又发一遍)。它是一个纯函数式的文本进、文本出的机器。
  • 落到代码里,那你在 ChatGPT、Claude Code 或者别的"AI 助手"里看到的"它帮我改了文件、跑了测试"是怎么回事?因为模型外面套了一层软件:这层软件把用户的话塞进提示词,把模型输出的文本解析成"调用某个工具"的指令,替模型真正去执行那条命令,把结果再拼回上下文发回去,如此往复,直到任务完成。Agent = Model + Harness在这个场景下,,这个等式里的 Harness(马具、挽具)就是这层软件:模型是那匹马力强劲但不知方向马,harness 负责套缰绳、递缰绳、防止它冲下悬崖。
  • 一个最小的 harness 循环长这样:
// 示例代码:最小 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.json 的 version 字段)。

  • 运行形态。一条命令即可起 Web UI:
# 来自 README.zh.md「运行」一节
npx @deepseek-ai/dsh web
  • 它默认在 (链接已移除) 启动 Web UI,本机启动时会用默认浏览器打开页面;借助 SSH 启动时只打印宿主机 URL(本地转发由 SSH 客户端持有),--no-open 可仅运行服务器不开浏览器。深一层看,"形态"在 dsh 里不是硬编码的产品分支,而是五个随发行版交付的 profile 模板:
profile形态面向
webWeb UI + HTTP 服务器(dsh web)日常交互采用
headless不挂服务器的一次性运行器脚本与流水线,如 dsh --profile headless "跑一遍测试"
sdk / sdk-minimalstdio 上的 JSON-RPC 服务器TypeScript / Python SDK 程序化驱动
acpAgent 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.(如 ctx.shell),注意它是一个 Cordis Service 类,而不是 TypeScript interface;
  • Service Provider(服务提供方):实现该接口的具体行为,能够有一个或多个;
  • Consumer(消费方):采用这项能力的插件,通常是面向模型的工具。
  • packages/shell 是官方术语表点名的规范范例,目录结构如下所示:
// 真实目录结构: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",包管理器钉死 [email protected]。
  • 注意有下限: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-17v0.1.0-rc.7实际处理时,插件设置卡片;Claude Code / Codex 子代理接入 Job Panel
08-19v0.1.0-rc.8实际处理时,子代理改为以 Profile Bundle 安装(dsh plugin add @deepseek-ai/dsh-subagent-codex 等,命令见 apps/cli/reference/README.zh.md);SQLite 存储格式不兼容变更
08-21v0.1.1-rc.1 / rc.2结合项目来看,视觉模型 DeepSeek-V4-Flash-Vision-Exp;修复 Bubblewrap /proc 逃逸;Files API 上传图像
08-27v0.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 分钟)

  • 若你还没有在本地下载源码,先克隆:
# 来自 README.zh.md「从源码运行」一节(本实验只需 clone,无需 build)
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
  • 在仓库根目录执行 ls,对照确认顶层布局(节选):
// 真实输出(节选):仓库根目录
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:
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 || >=24.0.0升级 Node 或用 nvm 切换;细节见第 02、06 章
从 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.)、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 源码)
  • 外部资料:
    • 论文:A Programming Paradigm for Spatiotemporal Composability (链接已移除)
    • Cordis 上游:(链接已移除)
    • 官方文档站:(链接已移除)
    • 仓库:(链接已移除)

从实现思路看,总的来说,DSH适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。

点击查看更多
推荐专题
热门阅读