DeepSeek Harness 开源了什么:连 Agent Loop 都能拔的插件系统,和给它撑腰的一篇论文

DeepSeek 于 2026-08-13 以 MIT 协议开源 agent harness「dsh」。深读其架构(turn/step 事件模型、会话日志唯一事实源、能力接缝、profile 配置分层)与理论底座 Cordis 论文《A Programming Paradigm for Spatiotemporal Composability》:可撤销效应 + 反应式余效应 + 合流定理,把「热替换插件不炸」从工程纪律升格为数学性质。附与 SWE-agent、Claude Code、Prime Agent 的谱系对照。

2026 年 8 月 13 日晚,DeepSeek 把自己的 agent harness 开源了:MIT 协议,TypeScript 写的,命令行叫 dsh。据搜狐报道,发布数小时 GitHub star 破 2.7 万;The New Stack 稍晚的报道称已超 3.3 万(均为媒体数字,我没有逐时核对)。但热度不是重点。重点是:这个框架里没有特权核心——模型适配器、工具、沙箱、连驱动一切的 agent loop 本身,全是可替换的插件;而「随时拔掉一块不炸」这件事,不是靠工程纪律保证的,是靠一篇 88 页的论文证出来的。

我在《什么才是好的 Harness》里写过:好 harness 把规则从提示词搬进代码,从恳求变成物理法则。DeepSeek Harness(下称 DSH)回答的是下一个问题——当物理法则本身需要频繁更换时(换模型、换沙箱、换整套循环逻辑),怎么保证换法则的过程不出事故? 它的答案是把「可组合性」从架构口味升格为数学对象。这是本文的一句话主线。

名词速查

术语一句话解释
harness包裹模型的有状态程序:决定模型每步看见什么、输出能对世界做什么(专文
agent loop「调模型 → 执行工具 → 把结果喂回去」的核心循环(Claude SDK 篇有拆解)
CordisDSH 底层的插件元框架:只管插件的装载/卸载和依赖管理,自己不带任何业务功能
effect(效应)插件对共享运行环境做的修改(注册服务、加监听器);DSH 里每个效应都带一个「怎么撤销」的逆操作
coeffect(余效应)效应的反方向:插件对环境的依赖声明——「我需要环境里有 X 才能工作」
HMRHot Module Replacement,热替换:不重启进程直接换掉一个模块
seam(接缝)接口定义、实现方、使用方三分离的扩展点;换一个实现方,所有使用方跟着迁移
profile / bundleDSH 的配置组合单位:profile 是分层叠加的命名配置,bundle 是配置的分发格式
confluence(合流性)数学性质:不管以什么顺序装卸组件,最终稳定状态都一样

一、先回答标题的问题:开了什么,没开什么

开了的:完整的 harness 运行时,仓库 deepseek-ai/deepseek-harness,MIT 协议,pnpm workspace 组织的 TypeScript monorepo(含 packages/apps/python/native/ 等目录)。装好 Node.js 后一条命令能跑起来:npx @deepseek-ai/dsh web,本机 3080 端口出一个 Web UI。

没开的:这不是新模型,也不是 API 客户端。DeepSeek 官方的表述是 Model + Harness = Agent——除模型权重之外的一切(工具、记忆、循环、沙箱、桌面集成、反馈系统)都归 harness。据小众软件和搜狐的报道(未独立核实),项目由曾在 Jane Street 工作、2026 年 3 月加入 DeepSeek 的 Cui Tianyi 领导,harness 团队 2026 年 5 月才组建,目标是让 V4 系列模型作为自主编程智能体运行。

边界:当前是 v0.1 开发者预览版,官方明说后续会有破坏兼容的改动。README 直接把设计出处指向一篇论文——《A Programming Paradigm for Spatiotemporal Composability》(cordiverse/paper,2026-08-13 日期的 preprint,托管在 GitHub 而非 arXiv,仍在修订中)。一个工程框架的 README 把理论论文放在第一屏,这个姿态本身就值得注意。

二、Everything is a plugin:连 agent loop 都是

大多数 agent 框架的「支持插件」是指:核心循环写死,四周留几个钩子。DSH 反过来——框架核心(Cordis)只做一件事:装卸插件、管理依赖。以下全部是插件,按官方架构文档(docs/architecture.md)的模块划分:

模块职责
core/session只追加(append-only)的 SessionEvent 日志与存储
core/tools工具注册表 + 执行流水线
core/agentagent 接口与运行中注册表
core/agent-loop默认的 agent 驱动逻辑——注意「默认」二字,它可以被整个换掉
core/system-prompt提示词与工具 schema 的组装
llm/llm消息词汇表与模型适配器接口

部署差异用 profile 分层解决而不是代码分支:dsh-base(模型适配、工具、持久化、沙箱、凭据)之上叠 dsh-web-app(浏览器界面)或 dsh-headless(一次性无服务运行器),补丁按序应用,后层覆盖前层。

运行时的骨架是 turn/step 双层事件模型:一个 turn(完整任务)包含零到多个 step(一次模型请求 + 其工具调用)。事件流如下(依据官方架构文档整理):

flowchart LR
    A[turn/start] --> B[agent/pre-step<br>插件可改写或拒绝]
    B --> C[step/start<br>一次模型请求]
    C --> D[assistant/message]
    D --> E{有工具调用?}
    E -- 有 --> F[tool/call 执行]
    F --> G[step/end]
    E -- 无 --> G
    G --> H{任务完成?}
    H -- 否 --> B
    H -- 是 --> I[turn/end]

事件分三个域,各管一件事:session 事件(持久事实,写日志、重载后仍在)、agent 事件agent/*,观察和干预进行中的工作,比如 agent/turn-stopping 可以叫停一个 turn)、能力事件fs/*tools/*telemetry/*,往具体能力上挂策略和适配器)。插件不 patch 核心,只往这些接缝上挂东西。

我在《Loop 还是 Graph》里说过,agent 架构之争的真正变量是「控制流的真相放在哪里」。DSH 给了一个此前少见的答案:放在一个可以被整体换掉的插件里Hello-Agents 那篇讲循环的三次搬家(提示词 → 框架代码 → 模型权重);DSH 在「框架代码」这一站内部又拆了一层——循环固化成代码,但不固化成核心

三、会话日志是唯一事实源:“Model-visible means logged”

DSH 架构文档里最硬的一条纪律:模型看见的任何内容,必须能从会话日志确定性地重建deriveMessages() 从 append-only 日志推导出模型消息;流式输出的原始 assistant/chunk 事件也入日志以保证回放保真)。想给模型塞任何新的可见输入?必须先扩展 SessionEventMap、从日志渲染,没有旁路。

这条纪律买到三样东西:长任务的断点恢复、失败重试、会话分叉(fork 出平行探索)。我在《Agent 的断点续传》里从论文侧论证过「事件日志 + 副作用账本」是长任务可恢复的正解——DSH 是我见过的第一个把「Model-visible means logged」写成架构铁律的官方 harness 实现。用上一篇的语言说:上下文的可重建性在这里不是恳求,是物理。

四、能力接缝:换一个 provider,搬走整个产品

DSH 把扩展点定义为 seam(接缝):接口定义(Service Definition)、实现方(Service Provider)、使用方(Consumer)三分离。架构文档给的例子很有画面感:把文件系统和子进程两个 provider 指向远程沙箱,Bash、PTY、LSP 三个工具就整体迁移到了远程执行——工具代码一行不改

这解决的是 harness 工程里一个真实的痛点:本地开发、容器沙箱、远程集群三套环境,传统做法是三个代码分支越长越歪。DSH 的做法是把部署差异全部压进 profile 配置层。这一手对任何在做 agent 平台的团队都可以直接抄。

五、那篇论文:把「拔插件不炸」证成定理

现在到真正的深水区。「一切皆插件」喊口号容易,难的是回答两个问题:

  1. 时间维:卸载一个插件时,它对共享环境做过的所有修改怎么保证被干净撤销?(残留一个监听器就是内存泄漏或幽灵行为)
  2. 空间维:插件之间的依赖怎么声明、发现、校验?依赖拓扑变化时(它依赖的插件被卸了)怎么反应?

论文把这两个问题分别形式化为 temporal composabilityspatial composability,给出的机制是一对对偶概念:

Revertible effects(可撤销效应):插件对共享上下文的每一次变换都必须携带一个逆操作,运行时替插件记账。卸载时按 LIFO 顺序回放逆操作链。用伪代码表达这个核心机制(根据论文摘要与实现描述简化,非真实源码):

# 伪代码:可撤销效应的记账与回收
class Context:
    def effect(self, transform):
        inverse = transform.apply(self.shared_state)  # 每个变换返回自己的逆
        self.inverse_chain.push(inverse)              # 运行时记账,插件作者不用写卸载逻辑

    def dispose(self):
        while self.inverse_chain:
            undo = self.inverse_chain.pop()           # LIFO:后做的先撤
            undo()

Reactive coeffects(反应式余效应):依赖被建模为带键的部分函数表。插件声明「我需要环境里有 X」,运行时在依赖满足状态翻转时通知插件激活/停用。effect 是「我对环境做了什么」,coeffect 是「我需要环境是什么样」——论文把两者统一进同一个 context 类型,这就是「一切皆插件」在类型层面的含义。

论文再往上走一层,给出动态组合的演算(insert、mark retired、remove、load、unload 五个操作),并证明了关键定理——合流性(confluence):不管编排器以什么顺序装卸组件,系统最终静止状态与「按依赖序一次性静态组装」的规范形式同构。翻译成工程语言:热替换的结果和重启等价。这就是 HMR(论文里描述为三阶段事务式重载,失败则恢复缓存)敢在生产语义下做的底气。

论文里还有一个我认为最漂亮的洞察:时间维的效应独立性可以从空间维的余效应交换性推导出来——两个看似正交的问题在数学上是一个问题的两面。

两点诚实的补充:

  • Cordis 不是为 DSH 新造的。 论文的实证案例是聊天机器人框架 Koishi 的生态——4000 多个社区插件在这套模型上运行多年,插件作者不需要手写卸载路径(此信息来自论文解读文章,我未逐一核实 Koishi 插件数量)。DeepSeek 是把一个在别的领域被打磨过的组合性内核,搬来当 agent harness 的地基。
  • 定理的边界要看清(我的理解,标注为个人解读):可撤销的是插件对共享运行时上下文的修改——注册的服务、挂的监听器。Agent 对外部世界的副作用(写过的文件、发过的请求)不在此列,那是会话层和副作用账本的课题。合流定理保证的是组合秩序,不保证任何一个插件本身语义正确。

社区里有一种解读(如开发者 cedric chee 在 X 上的评论):这套形式基础指向 self-evolving harness——agent 安全地修改自己运行时的可能性。我部分同意:Prime Agent 那篇里 Continual Harness 只敢开放「对 playbook 的 CRUD」作为自我改进面,正是因为运行时自改没有撤销保证。如果每个效应都带逆、装卸有合流定理,「让 agent 换自己的插件」至少从危险动作降级为受控实验。但这是展望,DSH v0.1 并没有宣称做到这一步——此处是我的猜想。

六、放进谱系里读:到底学什么

用 harness 谱系对照,DSH 的位置就清楚了:

系统核心押注循环可换吗
SWE-agent(ACI 开山作,旧文详拆接口形状塑造 agent 行为否,研究脚手架
Claude Code产品体验 + 官方留的扩展点(hooks/MCP/skills)否,循环是产品的一部分
Prime Agent极简:唯一工具是 Python 解释器,harness 缩进语言运行时循环极简到几乎没有可换的东西
DSH可组合性本身:循环、工具、沙箱全是插件,装卸有形式保证是,core/agent-loop 只是默认实现

12 条 AI 顶级原理望远镜看:DSH 的主原理是组合与复用——它赌的不是某一种循环设计更聪明,而是「让所有设计都可插拔」这个元能力更值钱;辅以表示决定成败(append-only 日志是全部状态的唯一表示,可恢复性从表示层免费获得)。这和 DeepSeek 一贯的「Model + Harness = Agent、两者协同进化」策略一致:模型迭代快,harness 若不能同速换血,就会变成模型的枷锁。

给自己搭 agent 系统的人,五个可直接偷走的设计动作:

  1. 日志纪律:凡是模型可见的,必须能从事件日志重建——先立这条铁律,恢复/重试/分叉/审计全是它的推论。
  2. turn/step 分层:把「一次任务」和「一次模型请求」拆成两级事件,钩子挂在层间而不是散在代码里。
  3. 接缝三分离:接口、实现、使用方分开,部署迁移变成换 provider 而不是改工具。
  4. 配置分层替代代码分支:环境差异进 profile,不进 if-else。
  5. 撤销性当一等公民:每个对共享状态的修改都问一句「它的逆是什么、谁记账」——哪怕不用 Cordis,这个设问本身就能消灭一类幽灵 bug。

七、灰度:什么时候不该学它

这套设计不是普适最优,代价至少三条:

  • 概念税重。effect/coeffect/realm/seam 是实打实的学习曲线。如果你的场景是单一环境、单一模型、循环逻辑一年不变,Prime Agent 式的极简路线(一个解释器 + 一个日志)性价比高得多。插件化的收益随「需要替换的频率 × 替换的部件数」增长,低于某个阈值就是纯开销。
  • 预览期风险。v0.1 官方明说会破坏兼容,现在把生产系统押上去等于替 DeepSeek 做免费回归测试。
  • 形式保证的诱惑。定理容易让人高估安全边界——合流性不检查插件的业务语义,一个逻辑写错的插件被「安全地」装载后照样把任务带沟里。数学解决的是组合事故,不是质量问题。

诚实的提醒

  • 没有亲手运行 dsh,也没有读完论文全文(约 88 页,「88 页」这个数字来自论文解读文章);本文基于官方 README、docs/architecture.md、论文摘要,以及 The New Stack、小众软件、StableLearn、Medium 的多篇报道与解读交叉核对。
  • star 数、团队背景(Cui Tianyi、Jane Street、组队时间)、V4 模型型号均为媒体二手信息,正文已逐处标注。
  • 成本最低的验证实验:装好 Node.js 后跑 npx @deepseek-ai/dsh web(约十分钟),然后 clone 仓库确认两件事——core/agent-loop 是否确实是一个独立包、profile 配置里能否声明替换它。这两件事验证了本文的核心主张:agent loop 是插件而非特权核心。

参考来源

工程实践

论文

站内回链什么才是好的 Harness ·Agent 的断点续传 · Prime Agent 内幕 · Hello-Agents:同一个循环三次搬家 · Loop 还是 Graph · Claude Agent SDK 架构哲学