DeepSeek Harness 是什么:一切皆插件的开源 Agent 框架,与 Claude Code 的真实差别
2026 年 8 月 13 日,DeepSeek 把自己内部用来跑模型评测的那套 agent 框架整个开源了:MIT 协议,TypeScript,名字叫 DeepSeek Harness,命令行是 dsh。仓库上线约一天拿到 9.3 万 star。它不是又一个 Claude Code 克隆,而是一个可以从配置层把任何部分换掉的底座。这篇按「它是什么、怎么组装的、怎么跑起来、和成品工具差在哪、有哪些坑」的顺序拆开讲,每个技术细节都来自官方仓库文档,第三方数据单独标注口径。
一句话事实:8 月 13 日发生了什么
2026 年 8 月 13 日,DeepSeek 发布 DeepSeek Harness v0.1 开发者预览版,仓库 deepseek-ai/deepseek-harness 以 MIT 协议开源,命令行工具名为 dsh,npm 包 @deepseek-ai/dsh(当前版本 0.1.0-rc.6)。
| 口径 | 数值 |
|---|---|
| 仓库创建时间 | 2026-08-13 11:56 UTC |
| star / fork(截至 2026-08-14 查询) | 93,137 / 8,525 |
| 语言 | TypeScript |
| 许可 | MIT |
| 状态 | 开发者预览,官方明确会有破坏兼容的变更 |
同一天,DeepSeek 还上线了 V4-Pro 正式版(版本号 DeepSeek-V4-Pro-0813),并宣布 8 月 17 日零点起 API 改用峰谷定价。这两件事发生在同一天不是巧合,后面第九节专门讲。
需要先说清楚的是:Harness 不是模型,也不是一个替你写好一切的编程助手。官方对它的定义是「agent harness」,也就是模型外面那层壳。DeepSeek 自己用它来跑模型评测,仓库里那份 BENCHMARK.md 就是这个用途的残留。换句话说,这是他们内部真在用的工具,不是为开源单独做的展示品。
先把 harness 这个词定义清楚:Agent = Model + Harness
官方站点上写着一个等式:Agent = Model + Harness。模型负责推理,harness 负责让推理能作用于真实环境。
拆开说,harness 提供三样模型自己没有的东西:
- 对环境的理解。 当前在哪个目录、这个仓库长什么样、有哪些工具可以调用、上一步的结果是什么。
- 执行能力。 读写文件、跑 shell、调 LSP、开沙箱、派子 agent。
- 持续性。 会话能中断、能恢复、能分叉、能重放。
这个分工在 2026 年已经变成共识:模型能力再强,没有 harness 就只能聊天。真正决定一个编程 agent 好不好用的,很大一部分在 harness 层,不在模型层。同一个模型换个 harness,实际表现和成本可以差出好几倍(第八节有具体数字)。
所以 DeepSeek 开源 harness 这件事的含义是:他们把「模型之外的那一半」也交出来了。之前这半边一直是 Claude Code、Codex 这类闭源产品的护城河。
「一切皆插件」不是口号:Cordis 与没有特权内核的设计
Harness 底层不是自研框架,而是 Cordis,一个 TypeScript 元框架,设计思路见论文《A Programming Paradigm for Spatiotemporal Composability》(时空可组合性)。
Cordis 的核心主张是:软件组件应该在空间上可组合(哪些插件是激活的)也在时间上可组合(什么时候挂载、什么时候卸载)。插件向一个共享上下文 ctx 贡献服务、类型化事件和可逆的副作用。
官方架构文档里有一句话是整件事的关键:
不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边,而各项注册都是副作用,会在其插件卸载时撤销。
对比一下就明白这句话的分量。大部分「可扩展」的工具是这样的:有一个内核,内核在若干预留的位置开了口子(钩子、插件 API、配置项),你只能在这些口子里做文章。想改内核行为,只能 fork 然后打补丁,然后每次上游更新都要重新合。
Harness 的做法是把内核本身也做成插件。模型适配器是插件,工具注册表是插件,会话日志是插件,连 agent loop 本身也是插件。所以「换掉 agent 循环」这种在别处需要 fork 的操作,在这里是改一行配置。
下面这张表是官方列出的部分核心包,可以看出边界划在哪:
| 包 | 职责 | ctx 键 |
|---|---|---|
core/session | 仅追加的 SessionEvent 日志与存储 | ctx.sessions |
core/system-prompt | 提示词片段与工具 schema 的组装 | ctx.systemPrompt |
core/tools | 作用域化的工具注册表与带把关的执行流水线 | ctx.tools |
core/agent | Agent 接口、活跃 agent 注册表、agent/* 事件 | ctx.agents |
core/agent-loop | 实现该接口的默认驱动器 | ctx.agentLoop |
llm/llm | 消息与流式词汇表,以及适配器 seam | ctx.llm |
仓库 packages/ 下有 50 多个包,除了上面这些,还包括 mcp、lsp、acp、sandbox、e2b、skill、subagent、compaction、spill、guard、workflow、plan、todo、hooks、credentials、jobs、schedule、terminal、shell、fs、storage、preset 等。每一个都可以被替换。
profile、组合包与 patch:它到底怎么被组装起来
跑起来的 dsh 是一棵插件树,由启动时按顺序叠加的若干层组成。理解这个叠加顺序,是理解怎么改它的前提。
组合包(bundle) 是 Cordis 配置项加上挂载代码的分发格式。发行版自带三个关键包:
| 组合包 | 提供什么 |
|---|---|
dsh-base | 每个 profile 的第一层:模型适配器、工具、持久化、沙箱与审批策略、设置、凭据、遥测 |
dsh-web-app | 在 base 之上加浏览器应用 |
dsh-headless | 加一次性运行器,完全不带服务器 |
profile 是存放在 Harness home 里的具名组装。它列出自己要叠哪些组合包,存放自己安装的树外插件,并保存用户自己的 cordis.patch.yml。发行版自带 web 和 headless 两个模板。
各层的应用顺序是固定的,从空条目列表开始:
- 按 profile 列出的顺序应用每个组合包
- profile 自己的
cordis.patch.yml - home 级的
cordis.patch.yml - 任意
--patchoverlay
一条 patch 按 id 定位某个条目,替换它整个 config,或者插入新条目。后面的层永远可以改前面的层,这是「一切皆插件」在配置层面的具体兑现方式。
想知道自己机器上实际启动了什么,跑这条:
dsh --profile web --dump-config
它打印出来的任何一个条目,你都可以用自己的 patch 替换掉。这是我认为最值得记住的一条命令,因为它把「这东西到底装了什么」这个通常需要读源码才能回答的问题,变成了一条命令。
会话日志与「模型可见即已记录」:最容易被低估的一条
Harness 里所有会话状态都来自一个仅追加(append-only)的事件日志。官方文档写得很直白:
模型可见即已记录。抵达模型请求的一切都必须能从日志重建,并由一项运行时不变量断言这一点。
这句话是个强约束,不是口号。它意味着:系统提示词、推理内容、工具调用与结果、子 agent 调度、每一次上下文注入,全部都是日志里的事件。想给模型加一项新的可见输入?你必须同时新增一个会话事件类型,扩展 SessionEventMap,并让它能从日志渲染出来。绕不过去。
它换来的是四件事全部免费:
- 恢复:从日志重放即可回到任意状态
- 分叉:
ctx.sessions.fork(source, boundary?, childSessionId?) - 重放与审计:Trajectory 视图可以按来源分类查看模型到底看到了什么
- 保真的 UI:原始
assistant/chunk事件保留了流式细节
对比一下别的工具就知道这有多难得。大部分 agent 产品你只能看到「模型说了什么、调了什么工具」,看不到系统提示词里塞了什么、上下文被压缩掉了哪一段、某条注入是谁发起的。当 agent 行为出乎意料时,这些恰恰是唯一有用的信息。
轮次流程也是公开的。一个步骤是一次模型请求加上它调用的工具;一个轮次包含零个或多个步骤:
turn/start
领取 next-step 输入与一条排队消息
组装提示词片段 + 工具 schema
-> agent/pre-step 可拒绝,或改写消息
step/start
agent/request -> llm/stream -> assistant/chunk* -> assistant/message
tool/call* -> tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result*
step/end
-> agent/turn-stopping
turn/end
其中 agent/pre-step、agent/request、llm/stream 和三个 tools/* 是 waterfall 事件,监听器必须调用 next() 才会往下委托,也就是说你可以在任意一层拦截并改写。agent/turn-stopping 是 serial 事件,没有 next()。
事件分三个域,选对域是大多数改动的第一个决定:会话事件(持久事实,重载后仍在)、Agent 事件(agent/*,携带活跃 agent,用于观察或拦截进行中的工作)、能力事件(fs/*、tools/*、telemetry/*,无需导入循环即可附加策略)。
能力 seam:换一个提供方,整个产品跟着变
Harness 把可替换能力叫做 seam(接缝)。一个 seam 有三个角色:声明接口的 Service Definition、实现它的 Service Provider、使用它的 Consumer(通常是面向模型的工具)。
官方文档给了一个很有说服力的例子:文件系统提供方和进程提供方共享同一个执行世界,所以把它们指向远程沙箱,Bash、PTY 和 LSP 就一起搬过去了,不需要为每个提供方单独 fork 一份实现。
这是「换一个部件改变整个产品」的具体形态。同理,subagent 提供方在同一个接口之后可以千差万别:新建一个子 agent 是它,把一个轮次委派给另一个产品也是它。
下面这张是官方给的「新行为该放哪」映射表,摘录几条常用的:
| 你想做的事 | 机制 |
|---|---|
| 添加模型提供方 | 在 ctx.llm 上注册适配器 |
| 添加面向模型的能力 | 在 ctx.tools 上注册,schema 自动进提示词组装 |
| 让某个会话有不同的能力集合 | 组装一个 agent preset,服务行需要 isolate realm |
| 添加持久化终端执行 | 注册 ctx.terminals 后端 + dsh-tool-terminal |
| 添加用户命令 | 在 ctx.commands 上注册,无需模型轮次即可分派 |
| 限制所启动的进程 | 使用 ctx.sandbox 后端,消费方在启动前包装 argv |
| 添加模型可见上下文 | 调用 agent.inject(),落到下一次获准的请求中 |
| 添加持久会话状态 | 扩展 SessionEventMap,从日志渲染和回放 |
这张表本身就说明了这个项目的成熟度:它不是把代码扔出来了事,而是把「你要改什么就去改哪里」写成了可查的映射。对比 V2EX 上有人吐槽「官方文档还是空的」,那说的是面向普通用户的使用文档,面向开发者的架构文档其实相当完整,而且有中英双语。
四种运行模式与实际怎么跑起来
官方列出四种运行模式:
| 模式 | 用途 |
|---|---|
| Standard | 完整 agent:文件编辑、shell、搜索、计划、子 agent |
| Code | 工具通过 TypeScript SDK 暴露,做多步编排 |
| Minimal | 只有 bash 和文件编辑器,用于跑基准测试 |
| Creator | 自定义 preset 开发,可检视插件、运行时测试 |
最快的路径是一条命令:
npx @deepseek-ai/dsh web
它启动 Web UI,默认地址 http://127.0.0.1:3080。从源码跑则是 clone 之后 pnpm install && pnpm run build && pnpm dsh web。
环境要求(读自仓库 package.json):Node ^22.19.0 || >=24.0.0,包管理器 pnpm 11.7.0。Node 版本低于 22.19 会直接失败,这是第一个坑。
第二个坑:包名必须带 @ scope。 写成 npx deepseek-ai/dsh 找不到包,必须是 @deepseek-ai/dsh。
第三个坑:必须先选工作区,否则输入框是禁用的。 启动后要点「选择工作区」,把项目目录加进去并选中,会话输入框才可用。不少人卡在这里以为是 bug。
配置模型在「设置 → 模型」里做,填 DeepSeek API 密钥即可,改动下一次请求生效,不用重启。密钥是只写的:保存后页面只拿得到脱敏描述符,明文存在 $DSH_HOME/.credentials.yaml,settings 里只留凭据引用。
除 DeepSeek 外,它开箱支持 Anthropic、OpenAI、Bedrock、Vertex、Azure、Codex,以及任意 OpenAI 兼容端点(自定义提供方,填 Provider ID、base URL、协议、凭据和至少一个模型)。注意 Bedrock、Vertex、Azure、Codex 用的是各自的原生认证(AWS 凭据与区域、ADC 项目、api-version、OAuth),只填 API key 那一栏配不完。
还有一个容易踩的细节:手动录入的模型默认按纯文本对待,给它发图片会在请求发出前就被本地拒绝。要在 $DSH_HOME/settings.yaml 里给该模型加 input: [text, image],或在路由上设 defaultInput。DeepSeek 自家的 chat-completions 路由是纯文本的,这一条改不了。
无头模式用 dsh --profile headless "你的指令",适合塞进 CI。另外还有官方 Python SDK(pip install deepseek-harness-sdk),自带同版本运行时,装完不需要系统有 Node.js,这对 Python 侧的自动化很实用。要注意仓库示例用的是 danger-full-access 策略,只能在可丢弃的 checkout 或容器里跑。
和 Claude Code、Codex 的真实差别
这是搜索量最大的问题,也是最容易被带节奏的问题。先说结论:它们不是同一类东西,拿来直接比谁强谁弱是错的问法。
| 维度 | DeepSeek Harness | Claude Code / Codex |
|---|---|---|
| 本质 | 可改装的底座 | 打磨好的成品 |
| 许可 | MIT 开源,全部代码 | 闭源商业产品 |
| 扩展方式 | 插件树 + 配置 patch,连 agent loop 都能换 | 在产品预留的扩展点内(hooks、MCP、skills、子 agent) |
| 模型 | 任意提供方,含任意 OpenAI 兼容端点 | 绑定各自厂商的模型家族 |
| 主界面 | Web UI 优先(3080 端口),另有 headless profile | 终端优先 |
| 可观测性 | append-only 日志,模型看到的一切都可回放 | 有限的会话记录 |
| 成熟度 | v0.1 预览,官方明确会破坏兼容 | 长期迭代,生态成熟 |
| 上手成本 | 需要读架构文档才能发挥价值 | 装完就能干活 |
成本这一层有第三方数据,但要看清口径。 有测评统计同一个 DeepSeek 模型在不同工具里跑,每个成功任务的成本最多差约 7 倍:Claude Code 约 0.195 美元,专门为 DeepSeek 做前缀缓存优化的 Pi 约 0.028 美元。差距的来源不是模型质量,而是通用工具没有围绕 DeepSeek 的前缀缓存特性设计提示词结构。这个数字来自单一第三方测评,没有独立复现,引用时要标明。
这也印证了第二节那个判断:harness 层对成本的影响是数量级的。关于模型层的成本账,可以对照DeepSeek V4-Flash 的七个点那篇,里面拆过缓存命中价 98% 折扣是怎么回事。
生态现状要泼一盆冷水。 有社区站点收录了 101 个 dsh 插件,但其中只有 11 个是 npm 包,81 个只有 GitHub 源码(要自己 clone 构建),3 个装不上,部分还有 build 或 ESM 错误。这是一个上线一天的生态该有的样子,但如果你期待「装个插件就能用」的体验,现在还不是时候。
所以怎么选? 如果你现在就要写代码交活,Claude Code 或 Codex 更省心。如果你的诉求是「我要把 agent 的某一层换成我自己的」,比如接自家网关、换沙箱后端、改上下文压缩策略、把执行搬到远程,那 Harness 是目前唯一一个把这些位置都留出来并写清楚的开源选项。
同一天的另一半新闻:V4-Pro 与 8 月 17 日的峰谷定价
Harness 开源的同一天,DeepSeek 上线了 V4-Pro 正式版(DeepSeek-V4-Pro-0813),并公布了 API 调价。这两件事要放在一起看。
V4-Pro 正式版规格:100 万 token 上下文,最大输出 384K token,支持 JSON Output、Tool Calls、Responses API、Anthropic API 和对话前缀续写。
8 月 17 日零点起改峰谷定价(北京时间):
| 项目 | 现价 | 8 月 17 日起 |
|---|---|---|
| v4-pro 高峰输出(每百万 token) | 6 元 | 27 元 |
| v4-pro 缓存未命中输入 | 3 元 | 按同机制调整 |
| 空闲时段 | 无区分 | 为高峰价的一半 |
高峰时段定义为北京时间 9:00-12:00 与 14:00-18:00,其余为空闲时段。高峰输出价涨幅约 350%。
把这两件事连起来读,逻辑就清楚了:DeepSeek 把 harness 免费送出去,同时把旗舰模型的高峰价往上抬。送的是工具,收的是推理。开源 harness 降低了所有人接入 DeepSeek 模型的门槛,涨价则改善单位经济。这套组合拳跟半个月前 V4-Flash 用低价抢 OpenRouter 调用量是同一个战略的两个阶段。
对使用方的直接含义有两条。第一,如果你的任务不赶时间,把它挪到空闲时段跑,成本直接砍半。批量处理、夜间构建、定时抓取这类活最适合。第二,峰谷价差把「什么时候跑」变成了一个成本变量,而调度恰好是 harness 该管的事,dsh 的 schedule 包正好在这个位置。
五个还没解决的问题
把反面一起摆出来,判断才完整。
一、开发者预览意味着会碎。 官方在 README 第一屏就写了「未来将出现破坏兼容性的变更」。现在基于它做的任何深度定制,都要做好几周内重写的准备。当前 npm 版本还是 0.1.0-rc.6,连 0.1.0 正式版都没发。
二、面向用户的文档确实不全。 架构文档写得很好,但 docs/user/guide/ 下只有三篇:Web UI、配置模型、Python SDK。默认端口能不能改、怎么接第三方模型的细节、插件怎么发布,这些问题在发布当天的社区讨论里都被问过,官方还没有系统回答。
三、插件生态是空的。 101 个收录里 11 个在 npm,装不上的有 3 个。「一切皆插件」的价值兑现依赖社区补齐插件,而这需要时间,也需要 API 先稳定下来,而 API 稳定又跟第一条矛盾。
四、star 数不等于使用量。 一天 9.3 万 star 是个惊人的数字,但 DeepSeek 这个名字本身就有巨大的号召力,star 更多反映的是关注度而不是装机量。判断真实采纳要看几周后的 npm 下载量和 issue 质量,现在下结论太早。
五、它绑定了自家生态的重心。 虽然支持所有主流提供方,但默认配置、示例、Python SDK 的默认模型都是 DeepSeek。用它跑别家模型可行,但要自己趟路。
一个人干活的话,怎么用这件事
如果你是一个人在做产品,下面四条比「要不要换掉 Claude Code」更值得先想清楚。
-
先装起来看,但别急着迁移。
npx @deepseek-ai/dsh web五分钟能跑通,值得花这个时间建立第一手认知。但把主力工作流迁过去要等它至少发出 0.1.0 正式版,理由是第一条风险:预览期的破坏性变更会吃掉你所有定制。 -
把
--dump-config当成学习材料。 就算你不用它干活,读一遍它启动时装了哪些插件,也是理解「一个成熟 agent 到底由哪些部件组成」的最快路径。这份认知在你评估任何其他 agent 工具时都能复用。 -
真正值得抄的是那条不变量。 「模型可见即已记录」这个约束,你自己做 agent 时就该照抄。绝大多数 agent 调试困难的根源都是不知道模型当时看到了什么,而这个问题是设计阶段就能一次性消灭的,事后补非常痛苦。
-
峰谷定价现在就能拿到收益,不用等。 8 月 17 日之后,把不赶时间的批量任务挪到空闲时段,成本直接减半。这件事跟用不用 Harness 无关,是纯粹的调度问题,今天就可以改。
至于要不要把 agent 能力做进自己的产品里,可以先用项目可行性评估那套红线加六维打分过一遍。开源 harness 改变的主要是「实现成本」这一维,它并不自动改变需求是否成立。
常见问题
DeepSeek Harness 是模型还是工具?
是工具,准确说是一个 agent harness(智能体框架)。官方给的定义是 Agent = Model + Harness:模型负责推理,harness 负责提供环境理解、工具执行和会话持续性。它本身不含模型,你需要配置一个模型提供方才能用,可以是 DeepSeek,也可以是 Anthropic、OpenAI、Bedrock、Vertex、Azure 或任意 OpenAI 兼容端点。
怎么最快跑起来?需要什么环境?
安装 Node.js 后执行 npx @deepseek-ai/dsh web,会启动 Web UI,默认地址 http://127.0.0.1:3080。仓库 package.json 里的环境要求是 Node ^22.19.0 || >=24.0.0,版本低了会直接失败。三个常见坑:包名必须带 @ scope,写成 deepseek-ai/dsh 找不到包;启动后必须先「选择工作区」,否则输入框是禁用的;模型密钥在「设置 → 模型」里填,改动下一次请求生效不用重启。
它和 Claude Code 到底差在哪,能替代吗?
定位不同。Claude Code 是打磨好的成品,装完就能干活;DeepSeek Harness 是 MIT 开源的可改装底座,连 agent loop 本身都是插件、可以从配置替换。现阶段如果你要马上写代码交活,Claude Code 或 Codex 更省心,因为 Harness 还是 v0.1 开发者预览、官方明确会破坏兼容、插件生态基本是空的(收录的 101 个插件里只有 11 个在 npm)。如果你的诉求是把 agent 的某一层换成自己的实现,比如接自家网关、换沙箱后端、改上下文压缩策略,那 Harness 目前是唯一把这些位置都留出来并写清楚的开源选项。
「一切皆插件」和别的框架的插件系统有什么不一样?
区别在于有没有特权内核。常见做法是内核加预留扩展点,想改内核行为只能 fork 打补丁。Harness 底层用 Cordis 元框架,插件向共享上下文贡献服务、类型化事件和可逆副作用,注册本身是副作用、随插件卸载而撤销,所以模型适配器、工具注册表、会话日志乃至 agent loop 全都是插件,全都能从配置替换。具体机制是分层组装:按顺序叠加组合包,再依次应用 profile 级、home 级和 --patch 级的 cordis.patch.yml,后面的层永远可以按 id 替换前面的层。用 dsh --profile web --dump-config 可以看到实际启动的完整配置树。
「模型可见即已记录」是什么意思,为什么重要?
这是 Harness 的一条运行时不变量:抵达模型请求的一切都必须能从仅追加的会话日志里重建。系统提示词、推理、工具调用与结果、子 agent 调度、每一次上下文注入,全部是日志事件。想给模型新增一项可见输入,就必须新增一个会话事件类型并让它能从日志渲染,绕不过去。代价是开发时多一道约束,收益是恢复、分叉、重放、审计和 UI 保真全部免费拿到。当 agent 行为出乎意料时,「模型当时到底看到了什么」通常是唯一有用的信息,而多数工具答不上这个问题。
8 月 17 日 DeepSeek API 涨价,对我的成本影响有多大?
以 deepseek-v4-pro 为例,高峰时段每百万 token 输出价从 6 元升至 27 元,涨幅约 350%;同时引入峰谷机制,空闲时段为高峰价的一半。高峰时段是北京时间 9:00-12:00 和 14:00-18:00,其余算空闲。实际影响取决于你的调用时间分布:如果任务不赶时间,把批量处理、夜间构建、定时抓取这类活挪到空闲时段跑,成本直接砍半。这件事跟用不用 Harness 无关,今天就可以改调度。
现在适合把生产环境的 agent 迁到 Harness 吗?
不建议。官方在 README 第一屏就写明处于开发者预览、未来会有破坏兼容的变更,当前 npm 版本还是 0.1.0-rc.6,连 0.1.0 正式版都没发。面向用户的文档只有 Web UI、配置模型、Python SDK 三篇,插件生态刚起步。合理的做法是现在花几分钟装起来建立第一手认知,读一遍 --dump-config 的输出理解它的组成,等至少发出 0.1.0 正式版之后再考虑迁移主力工作流。