项目: deepseek-ai/deepseek-harness(dsh)· MIT 协议 · 发布 2 天即获 4.1 万+ Star
核心设计: 一切皆插件(Everything is a Plugin),基于 vendored Cordis 构建

2026 年 8 月 13 日,DeepSeek 官方在 GitHub 开源了 DeepSeek Harness(简称 dsh)——一个插件化的 Agent Harness(智能体框架),口号只有一句话:Everything is a Plugin。仓库发布两天 Star 数突破 4.1 万、Fork 3283,热度直逼年初 DeepSeek 开源大模型时的盛况。

本文不部署、不跑 demo,直接对克隆下来的源码做一次架构级拆解:它到底"新"在哪、代码怎么组织、“一切皆插件"是怎么落到每一行代码上的。


一、仓库全景:这不是一个"小玩具”

先看几个硬数字(截至 2026-08-14 主分支):

指标数值
包目录(packages/54 个
TypeScript 源文件1247 个(不含测试)
TS 源码总行数约 20 万行
Git 提交数12293 次
主贡献者Tianyi Cui(5235 次提交)等
版本0.1.0-rc.5(明确标注 Developer Preview,破坏性变更随时可能发生)
许可证MIT

技术栈上:Node.js + TypeScript(全 ESM)+ pnpm workspaces,前端是自研 Web UI(Vue 系组件库),另带一个 Python SDKpython/sdk/,走 JSON-RPC)。仓库还有 native/(Landlock 沙箱的 Node 插件)、website/(VitePress 文档站)。

最值得注意的是代码质量工程化:每个 npm 包都是 @deepseek-ai/dsh-* 命名,单测要求每个源文件 100% 行覆盖率(CI 门禁),并且每个包都必须自带一个 invariant(运行时不变量断言模块)——这不是普通开源项目会做的自我要求。


二、核心架构:一切皆插件,连 Agent Loop 本身都是插件

dsh 底层是 Cordis——一个插件化框架(源码直接 vendor 进仓库的 vendor/cordis/)。Cordis 的核心抽象是:

  • 插件向共享上下文(Context)贡献服务(Service)、类型化事件(Event)和可逆副作用(Effect);
  • 插件之间通过 ctx.xxx 键互相引用,注册即副作用,卸载自动撤销。

dsh 的产品层——模型适配器、工具注册表、会话日志、甚至 agent loop 本身——全部是插件。文档里原话:“不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边。”

Profile 与组合包:配置即组装

运行中的 dsh 是一棵由多层配置叠加出来的插件树。核心概念:

  • Profile:存放在 Harness home 的具名组装,列出要叠放的组合包(webheadless 是随发行版交付的模板);
  • Bundle(组合包):Cordis 配置项 + 挂载代码的分发格式;
  • Patch:按 id 定位条目、替换整个 config 或插入新条目的覆盖机制。

叠放顺序:空条目列表 → profile 列出的各组合包 → profile 的 cordis.patch.yml → home 级 patch → --patch overlay。也就是越晚叠的层权力越大,任何一条启动配置都能被你的 patch 替换。

dsh-base 是每个 profile 的第一层(模型、工具、持久化、沙箱、审批、设置、凭据、遥测),dsh-web-app 加浏览器应用,dsh-headless 提供无服务器的"跑一次就退"模式。


三、事件驱动:三类事件,三种职责

事件是 dsh 的扩展点,选对事件域是改动的第一个决定:

事件域性质用途
会话事件session/event持久、追加式必须跨重启保留的事实:turn/*step/*user/messageassistant/*tool/*
Agent 事件agent/*实时携带活跃 Agent:inbox、步骤、状态、请求、验证、续跑
能力事件fs/*tools/*telemetry/*实时给 seam 附加策略和适配器,避免导入循环

设计铁律:“模型可见即已记录。” 抵达模型请求的一切都必须能从会话日志重建,运行时不变量断言这一点。所以新增一项模型可见输入,就必须新增一个会话事件。这保证了 fork、恢复、transcript、遥测都能从同一份事件流派生——日志是唯一的真相源。


四、轮次与步骤:Agent Loop 的心脏

packages/core/agent-loop/ 里是默认驱动器 ReactLoopAgent(约 500 行,agent.ts)。术语先厘清:

  • 步骤(Step) = 一次模型请求 + 它调用的工具;
  • 轮次(Turn) = 零到多个步骤,领取首条输入时打开,不再欠任何工作时关闭。

轮次流程(简化):

1
turn/start → 领取下一条输入 + 一条排队消息 → agent/pre-step(waterfall:监听器可改写消息或直接拒绝) → step/start → 从日志派生模型历史 → agent/request → llm/stream → assistant/chunk* → assistant/message → tool/call* → tools/pre-execute → tools/execute → tools/post-execute → tool/result* → step/end → 工具还欠请求?或有新输入?→ 再领取 → 下一个 step → agent/turn-stopping(serial,唯一没有 next() 的检查点) turn/end

几个值得注意的工程细节:

  1. waterfall vs serial 事件agent/pre-stepagent/requestllm/streamtools/* 是 waterfall 事件,监听器必须调用 next() 才能委托给下游——这是实现"拦截/改写"的机制;agent/turn-stopping 是 serial 事件,专门用于"是否该停"的终检。
  2. 空内容也记账assistant/message 会记录每次成功的提供方调用,包括返回空内容或以 max-tokens 结束的调用——空内容不进派生历史,但用量保留,sourceEventSeqs 精确对应 chunk 事件。
  3. 错误恢复有专门路径agent/request-error 处理规范上下文溢出,先做可选的工具结果剪枝,再选摘要;只有恢复真正推进了版本才会开新重试轮次。
  4. 输入走统一 inbox:注入的上下文留在 inbox 里等待唤醒,steering(中途引导)与注入消息经过同一个 agent/pre-step waterfall。

五、能力 Seam:可替换能力的标准姿势

一个 seam 是 dsh 里"可替换能力"的完整形态,包含三个角色:

  1. Service Definition:声明接口;
  2. Service Provider:实现它;
  3. Consumer:使用它(通常是面向模型的工具)。

换一个 Provider 就换掉整个产品能力——这是 dsh 最优雅的设计。文档举的例子:文件系统与进程 Provider 共享同一个执行世界,把 ctx.fs 指向远程沙箱(E2B),Bash、PTY、LSP 就全部一起搬过去了,不需要为每个能力写专门的 fork。

代码里对应的真实结构:

  • packages/fs/:fs 能力家族(fs + fs-e2b + fs-observation-policy 等)
  • packages/shell/:bash 能力(bash-local / bash-sandbox)
  • packages/subagent/subagent 能力家族,支持 6 种 Provider
  • packages/web/:web 搜索/抓取(deepseek / exa / perplexity 三个 Provider + http fetch)
  • packages/sandbox/:进程沙箱(local Landlock / windows-acl / policy)
  • packages/llm/:模型适配器(deepseek / pi-ai / retry)

六、模型能看到什么:内置工具生态盘点

docs/tool-catalog.md生成式目录——不是手写文档,而是"启动每个工具插件、读取真实 ctx.tools.schemas()“生成。这本身就说明工具注册是运行时行为。内置工具全家桶(24 个工具族):

文件与代码

  • read / write / edit / read_image(fs,配合"先读后写"策略插件)
  • glob / grep(打包了 ripgrep 二进制,不依赖宿主安装)
  • run_code(代码模式保留传输通道,支持并发子调用)
  • str_replace_editor(独立文本编辑工具)
  • lsp(语言服务器,provider 可换)

执行与终端

  • bash / pwsh(一次性命令)
  • terminal_open/read/send/... 六个工具(持久 PTY 终端)
  • job_list / job_kill / job_output(后台任务,bash/PTY/subagent 通用)

协作与智能体

  • subagent / subagent_fork(委派子 agent,支持后台可续跑)
  • send_message / interrupt_agent / list_agents(子 agent 控制)
  • report(子级向父级汇报)
  • create_goal / get_goal / update_goal(目标管理,带轮次上限)
  • ask_user_question(暂停工具调用,等 UI 返回人类回答)

信息与记忆

  • web_fetch / web_search(provider 可换)
  • skill(技能加载)
  • session_search / session_event_read 等 5 个(会话查询,只读)
  • todo_write(待办清单)
  • schedule_create/list/delete(会话内提醒)

自指(最激进的一组)

  • cordis_define / cordis_run / cordis_stop / cordis_inspect_*:让 Agent 在运行时定义、启动、停止自己的插件。默认不进任何发行树(刻意 opt-in),但仓库的 web-cordis 示例演示了一个能检查并修改内存中 Cordis 插件树的"自指 agent”。这是 dsh 区别于其他框架的标志性能力。

七、Subagent 家族:能真的拉起 Claude Code / Codex

packages/subagent/ 把"委派"做成了一个完整的可插拔能力:

Provider说明
subagent-spawn-in-process全新进程内子 agent
subagent-fork-in-process从父 agent 历史 fork 出子 agent
subagent-acp通过 ACP 协议启动进程外子 agent
subagent-codex启动真实 Codex app-server 子 agent
subagent-claude-code通过官方 Claude Agent SDK 启动真实 Claude Code
subagent-dsh-sdk通过 TypeScript SDK 启动进程外 Harness 子 agent

也就是说,dsh 里的 Agent 可以把活儿委派给另一个产品(Claude Code、Codex)当子 agent——多智能体编排在 seam 抽象下变成"选 Provider"的问题。


八、安全与沙箱:Landlock + Windows ACL + 远程沙箱

  • sandbox-local:Linux 上用 Landlock(通过 native Node 插件)限制子进程,支持逐会话策略(sandbox-policy 解析持久策略);
  • sandbox-windows-acl:Windows 的 ACL 方案;
  • e2b / fs-e2b / subprocess-e2b:把文件系统与子进程 Provider 指向 E2B 远程沙箱——一个替换,所有能力一起隔离,正是 seam 设计的红利;
  • hooks 家族(hooks-claude-code / hooks-codex):兼容 Claude Code / Codex 的 hook 协议,让 dsh 能接入既有工具链的钩子事件。

九、三种接入姿势:Web / CLI / 协议

1
npx @deepseek-ai/dsh web # Web UI,默认 http://127.0.0.1:3080 npx @deepseek-ai/dsh headless "task" # 一次性跑任务,无服务器

examples/ 里 6 个可运行 demo:

  • headless-agent:非交互式,接受任务 → 输出结果;
  • acp-agent:ACP(Agent Client Protocol)自动化服务器,面向程序化客户端;
  • jsonrpc-agent:Python SDK + JSON-RPC 驱动的无人值守编码 agent;
  • mcp-memory:通用 MCP 客户端连第三方记忆服务器;
  • web-cordis:自指 agent;
  • web-schedule:会话内提醒。

Python SDK(python/sdk/hatch/uv 管理)提供了 deepseek_harness.api / client / models 等封装,让 Python 侧可以直接驱动 Harness。


十、评价与展望

亮点

  1. 架构纯度罕见:把 “一切皆插件” 贯彻到连 agent loop、模型适配器、会话日志都是插件,配置(patch 叠层)与代码(插件注册)统一成一套组合模型。这是很多号称"可扩展"的框架做不到的——它们通常只是给核心留几个回调钩子。
  2. 事件即契约:“模型可见即已记录"的运行时不变式,让整个系统可以从日志重建、fork、回放,这是一套认真思考过可观测性的设计。
  3. seam 三件套:Definition / Provider / Consumer 的严格分工,让"替换 E2B 沙箱 = 整体迁移能力"这种全局替换成为可能。
  4. 工程纪律:100% 覆盖率门禁、每包 invariant、生成式目录文档、双语文档配对——工程化水平在开源 AI 项目里属于第一梯队。

风险与不足

  1. Developer Preview:0.1.0-rc.5,官方明说"破坏性变更随时发生”,SQLite schema 用单调版本号、会话格式版本无兼容承诺——现在不适合作为生产依赖。
  2. 重度绑定 Cordis:vendor 了 Cordis 源码(rescope 成私有包),框架选型一旦深入,迁移成本很高。
  3. 门槛:约 20 万行 TS、54 个包,插件开发需要吃透事件域和 seam 体系,文档虽全但学习曲线陡。
  4. 生态未起dsh-plugin topic 刚开放,第三方插件还很少;对模型提供方目前默认 DeepSeek 系(deepseek / pi-ai)。

一句话总结:DeepSeek Harness 不是又一个"Agent 框架",而是把"框架本身"也变成了可插拔组合的Agent 操作系统。它现在最大的价值是给 Agent 工程社区提供了一个极其干净的架构范本——而 0.1.0 的版本号意味着,真正的生态故事才刚刚开始。


参考: 分析基于 deepseek-ai/deepseek-harness @ 47f943859b(2026-08-14 克隆),README.zh.md / docs/architecture.zh.md / docs/agent-lifecycle.zh.md / docs/tool-catalog.md / packages/core/agent-loop 源码等。

作者: 喵本喵叁肆 · 技术博客 | 欢迎关注、收藏、评论区交流