DeepSeek Harness 初探:1、一切皆插件的 Agent 框架
2026/9/6 23:58:09 网站建设 项目流程

系列第 1 篇 · 入门 | 项目定位、架构全景与源码速览
本文基于 dsh v0.1.0-rc.5,API 可能随版本变化,一切以官方仓库与本地源码为准。

摘要

DeepSeek 官方开源的 agent harness(智能体运行框架)DeepSeek Harness(dsh)以"一切皆插件"为架构宣言,基于内嵌(vendored)的 Cordis 框架构建。本文作为系列开篇,回答三个问题:dsh 是什么、为什么"一切皆插件"、二次开发能改什么。你将获得一张完整的架构全景图、一份仓库速览地图,以及一套避免踩坑的认知框架。后续 15 篇将带你从"会用"到"能改"再到"能发布自己的发行版"。

标签:DeepSeek Harness、AI Agent、插件开发、Cordis、开源项目


文章目录

    • 摘要
    • 1. 引言:为什么值得关注 dsh
    • 2. dsh 是什么:一个 agent harness
    • 3. 一切皆插件:理解插件树
      • 3.1 插件是什么
      • 3.2 插件树:Profile → Bundle → Patch
      • 3.3 核心服务一览
    • 4. 架构全景图
      • 一次对话的节奏:turn 与 step
    • 5. 仓库速览:一张二开地图
    • 6. 能力缝(Capability Seam):三件套思维
    • 7. 二次开发能改什么:官方扩展点地图
      • 本系列的路线图
    • 8. 风险与预期:先管理好"漂移"
    • 9. 术语速查(开篇用)
    • 10. 踩坑与经验(认知篇)
    • 11. 总结
    • 12. 延伸阅读

1. 引言:为什么值得关注 dsh

DeepSeek 最近的开源动作不断。这一次不是模型权重,而是一个 agent harness——一个用来构建、运行、调试智能体的"运行时框架"。它叫DeepSeek Harness(简称dsh),官方仓库在github.com/deepseek-ai/deepseek-harness

最吸引我的是它的架构宣言:Everything is a Plugin(一切皆插件)。这个说法在很多项目里是营销话术,但在 dsh 里是字面事实——连模型适配器、工具注册表、会话日志、甚至 agent 主循环本身,都是插件,都可以从配置里换掉。

这意味着什么?意味着二次开发的门槛被设计得很低:你想改 dsh 的任何一个行为,都不需要 fork 后硬改核心代码,而是写一个插件挂进去。这正好是本系列要带你做的事。

在开始之前,先把丑话说在前面:dsh 目前处于 **developer preview(开发者预览)**阶段,版本是v0.1.0-rc.5,官方在 README 里白纸黑字写着“THERE WILL BE COMPATIBILITY-BREAKING CHANGES”(必然存在破坏性变更)。所以本系列所有内容都会标注版本号,你在阅读时也要有这个心理预期——后面第 12 篇会专门讲"fork 之后如何管理这种漂移"。

2. dsh 是什么:一个 agent harness

先厘清概念。Agent Harness和"Agent 应用""Agent 框架"不是一回事:

  • Agent 框架(如 LangChain)给你一套组装 LLM 调用的积木;
  • Agent 应用(如某个聊天机器人)是组装好的成品;
  • Agent Harness介于两者之间:它提供运行 agent 的完整运行时——会话管理、工具执行、权限审批、持久化、Web UI、多进程,但把"你的 agent 长什么样"完全留给你通过插件/配置决定。

dsh 的官方定位是"open-source agent harness developed by DeepSeek AI"。它开箱即带:

  • 一个Web GUI(默认http://127.0.0.1:3080),直接npx @deepseek-ai/dsh web就能跑;
  • 一套headless运行方式(一次性任务,无服务器);
  • 一个ACP 自动化服务(Agent Client Protocol,给外部程序调用 agent 用)。

它依赖一个叫Cordis的框架。Cordis 是开源社区 cordiverse 维护的插件化框架(著名的 Koishi 机器人框架就基于它)。dsh 没有走 npm 依赖,而是把 Cordis 及其基础库以源码形式 vendor(内嵌)进了自己的仓库,重新命名到@deepseek-aiscope 下(如@deepseek-ai/cordis,当前版本4.0.0-rc.7),目的在vendor/README.md里写得很清楚:让 harness 完全拥有自己的框架层——可审计、可打补丁、可钉版本。这一点对二次开发者很重要:你改的"框架"和"产品"在同一个仓库里,没有黑盒。

3. 一切皆插件:理解插件树

3.1 插件是什么

在 Cordis 的世界里,插件(plugin)是一个最小的注册单元:它向一个共享的Context(上下文)贡献服务事件效果(effect)。一个典型的 dsh 插件长这样(改编自官方文档docs/cookbook/adding-a-tool.md的最小工具示例,简化了参数):

import{readFile}from'node:fs/promises'importtype{Context}from'@deepseek-ai/cordis'import{defineTool}from'@deepseek-ai/dsh-tools'exportconstname='my-tool'exportconstinject=['tools']exportfunctionapply(ctx:Context){ctx.tools.register(defineTool({name:'read_file',description:'Read a file from disk.',// 模型看到的就是这段描述parameters:{path:{type:'string',required:true,description:'Absolute path'},},output:{schema:{type:'string'},render:(_args,value)=>[{type:'text',text:value}],},asyncexecute(args,exec){returnreadFile(args.path,{encoding:'utf8',signal:exec.signal})},}))}

注意两个关键点:

  1. 注册是副作用:插件通过ctx.tools.register(...)这样的调用产生效果,插件卸载时效果自动逆注册(dispose),不留残留。整个 dsh 都遵循"注册即副作用、卸载即回收"这一纪律。
  2. 没有特权核心:上面这段代码注册的工具,和 dsh 内置的 bash、fs、web 工具处于完全相同的地位。dsh 官方文档(docs/architecture.md)原话是"There is no privileged core to patch"——你要扩展 dsh,不是去改一个特权核心,而是在一堆插件旁边挂一个自己的插件。

3.2 插件树:Profile → Bundle → Patch

一个正在运行的 dsh,是一个插件树(plugin tree)——由启动时按顺序叠加的多个"层"组合而成。理解这三层,是理解 dsh 配置体系(第 5 篇会展开)的钥匙:

是什么例子
Profile(档案)一个命名的组合,列出它要叠哪些 bundlewebheadless是官方自带模板
Bundle(包)可分发/可安装的 Cordis 配置行 + 代码的打包格式dsh-base(基础层)、dsh-web-app(Web 应用层)、dsh-headless
Patch(补丁)按"行 id"覆盖已有配置或插入新行用户的cordis.patch.yml--patch覆盖

层级叠加顺序大致是:profile 列出的 bundle 依次应用 → profile 的cordis.patch.yml→ 用户主目录的 patch → 命令行--patch覆盖。每一层都能改掉下面层的任何一行配置。

想亲眼看到你的机器真正 boot 出什么样的树,跑这一条命令(本机实测可用):

dsh--profileweb --dump-config

它会打印出完整的配置树——上面每一行都可以被你自己的 patch 覆盖。这是"配置即二次开发"的最轻入口。

3.3 核心服务一览

插件向Context贡献的服务通过ctx.<key>访问。以下是 dsh 的核心服务(摘自docs/architecture.md):

服务拥有什么ctx 键
Session追加式会话事件日志与内存存储ctx.sessions
System Prompt提示词分段与工具 schema 组装ctx.systemPrompt
Tools作用域工具注册表与受守卫的执行管线ctx.tools
AgentAgent接口、活动注册表、agent/*事件ctx.agents
Agent Loop实现Agent接口的默认驱动器(主循环)ctx.agentLoop
LLM消息与流式词汇表 + 适配器缝ctx.llm

注意ctx.agentLoop主循环本身也是一个可替换的服务。这也是"一切皆插件"最极致的体现——你甚至可以换掉 agent 怎么思考的主循环,只要实现同一个Agent接口。

4. 架构全景图

把上面的概念拼起来,dsh 的一次典型对话流程大致是:

能力层

运行时

用户层

Web GUI / CLI / ACP

Agent Loop(turn/step 驱动)

Session 日志(append-only 事件流)

System Prompt 组装

Tools 注册表 + 执行管线

LLM 适配器缝

shell / fs / web / subprocess / terminal ...

sandbox / approval(策略与审批)

(图 1:dsh 运行时全景。自绘,建议用 drawio 重新绘制后导出 PNG 上传)

几个值得记住的机制:

  • 模型可见 ⟺ 已记录:模型每次请求看到的上下文,都从 Session 日志投影(deriveMessages())而来。这条不变式意味着:任何想让模型看到的新输入,都必须对应一个新的事件类型——第 9 篇专门讲怎么扩展。
  • 事件是扩展点:会话事件(持久)、agent 事件(agent/*,拦截进行中的工作)、能力事件(fs/*tools/*telemetry/*,给能力缝挂策略和适配器)。
  • 瀑布事件要 next()agent/pre-stepagent/requestllm/streamtools/*的监听器是瀑布(waterfall),必须调用next()放行,否则会短路整条链——这是新手最容易写错的点(第 6 篇展开)。

一次对话的节奏:turn 与 step

dsh 里有两个节奏单位:**step(步)**是"一次模型请求 + 它调用的工具";**turn(回合)**是零个或多个 step,从第一个输入被认领开始,到没有欠账为止。典型流程是:

turn/start 认领下一步输入 + 一条排队消息 组装提示词分段 + 工具 schema -> agent/pre-step(可改写或拒绝) step/start 模型请求(llm/stream)-> assistant/chunk* -> assistant/message 工具调用(tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result*) step/end 工具还欠一次请求,或新输入到达 -> 下一步 turn/end

其中turn/*step/*user/messageassistant/*tool/*持久会话事件(写进日志、可回放),其余是运行期扩展点,分属三个事件域。第 6 篇会带着断点逐事件走一遍这条流程。

(图 3:turn 序列图。自绘,参考docs/agent-lifecycle.md的 sequence diagram 重绘后导出)

5. 仓库速览:一张二开地图

拿到源码后(本系列基于本地克隆,实测环境:Nodev24.15.0、pnpm11.7.0、HEAD47f943859b,版本0.1.0-rc.5),顶层结构如下(本机实测目录):

D:\ai\deepseek\deepseek-harness ├─ .agents/ # Agent Notes(决策记录)与工作流技能 ├─ apps/ # cli(命令行入口)、web(前端构建) ├─ docs/ # 架构/开发/子系统/手册,中英双语 ├─ examples/ # 可运行示例:acp-agent、headless-agent、mcp-memory ... ├─ native/ # Landlock 沙箱原生模块 ├─ packages/ # 219 个 @deepseek-ai/dsh-* 包(49 个组) ├─ patches/ # pnpm 补丁 ├─ python/ # Python SDK ├─ scripts/ # 门禁与生成器 ├─ vendor/ # vendored 的 Cordis 框架源码(9 个包) └─ website/ # 文档网站(VitePress)

(图 2:仓库顶层结构。作者实测Get-ChildItem输出整理)

二次开发者最需要熟悉的是packages/,它按"组"组织,每个组有明确职责(完整清单见packages/README.md),挑几个重要的:

  • core/:产品 API 骨架——sessionsystem-prompttoolsagentagent-loopscope
  • llm/:LLM 能力族——抽象服务 + 各 provider 适配器(llm-deepseekllm-pi-ai);
  • shell/ fs/ subprocess/ terminal/ web/:模型面向的执行能力(bash、文件、进程、PTY、网页搜索);
  • session/:会话持久化(JSONL/SQLite)、投影、标题、遥测;
  • client/ host/:Web GUI 的浏览器端与 HTTP 服务端;
  • bundle/:可安装的 profile 补丁层(base/web-app/headless);
  • interaction/:审批、权限、命令、ask-user;
  • sandbox/:进程沙箱(bwrap/Landlock/Seatbelt/Windows ACL)。

每个包都是标准形态:package.json@deepseek-ai/dsh-<name>private: true)、src/(TypeScript)、tests/README.md。所有包统一走 pnpm workspaces + 双聚合 tsconfig(Host/Client)构建,这带来一个现实:改动任何一个包的源码,都要通过仓库的构建和门禁——第 2 篇会带你把整套构建跑通。

docs/是双语文档体系,按层级组织:architecture.md(架构总览)→subsystems/(每个子系统的类型与 API 参考,50+ 页)→cookbook/(步骤式指南)→user/(产品手册)。中文版与英文版成对维护(如architecture.zh.md),仓库用自动配对与字数门禁保证它们不漂移——你在官方仓库里看到的任何.zh.md都不是机器直译的凑数内容。

6. 能力缝(Capability Seam):三件套思维

这是 dsh 架构里最重要的一个概念,值得在开篇就种下(第 7 篇会完整实战)。

一个**能力缝(Capability Seam)**是一个可替换的能力,由三个角色构成:

角色职责例子(shell 能力)
Service Definition(服务定义)声明接口、注入键、事件dsh-shell定义ctx.shell与请求/规格类型
Service Provider(服务提供者)实现该接口dsh-bash-local/dsh-pwsh-local(本机执行)、dsh-bash-sandbox/dsh-pwsh-sandbox(沙箱执行)
Consumer(消费者)使用该接口,通常是模型面向的工具dsh-tool-bash(bash 工具)

关键在依赖方向:Consumer 只依赖 Service Definition,绝不依赖具体 Provider。所以换一个 Provider,整个产品跟着换——比如把 fs/subprocess 的 Provider 指向远程沙箱,Bash、PTY、LSP 全部随之迁移,不需要改任何 Consumer 代码。

对二次开发者来说,这个思维的价值是:先找缝,再写插件。你想加的能力,大概率有一个现成的缝可以挂(工具缝、LLM 缝、shell 缝、fs 缝……),而不是去改核心循环。

7. 二次开发能改什么:官方扩展点地图

docs/architecture.md里有一张"Where new behavior goes"表,是二开最权威的起点,我摘录几个高频目标(完整版见官方文档):

你的目标机制
接一个新模型ctx.llm上注册适配器
加一个模型面向的能力注册到ctx.tools,schema 自动进入提示词组装
加 shell / 持久终端执行注册ctx.shell/ctx.terminals后端
拦截一次请求、工具或回合agent/*tools/*事件
给模型加上下文agent.inject(),落进下一次请求
加持久会话状态扩展SessionEventMap,从日志渲染和回放
加 UI / 编辑器集成驱动ctx.agents,从session/event渲染
给一个会话不同的能力集组合 agent preset(preset 插件)

配套的官方 cookbook 也值得收藏(都是步骤式指南,本系列会逐个展开):
docs/cookbook/adding-a-package.mdadding-a-tool.mdadding-an-llm-adapter.mdadding-a-conversation-node.mdextension-cookbook.md

本系列的路线图

把官方地图收进口袋后,说清楚本系列 16 篇怎么带你走完"从入门到精通":

  • 入门篇(01–05)· 会用:环境搭建(02)、第一个插件(03)、第一个工具(04)、配置体系(05)。目标:你能让 dsh 跑起来、能挂上自己的插件和工具。
  • 进阶篇(06–11)· 能改:核心包与事件流(06)、能力缝三件套(07)、接入新 LLM(08)、会话事件扩展(09)、Web GUI(10)、策略与安全(11)。目标:你能读懂核心源码、按官方范式改 dsh。
  • 精通篇(12–16)· 会造:fork 后私有构建与发布(12)、vendor 内核与自修改(13)、会话持久化与检索(14)、测试与门禁(15)、踩坑实录(16)。目标:你能维护自己的发行版。

每一篇都遵循同一条流水线:先用真实源码/文档核实每一个命令、路径与 API(禁止编造),再给出可运行的示例,最后标注哪些输出需要你实跑回填——确保文章里的每一行都经得起你在本地验证。

8. 风险与预期:先管理好"漂移"

先看生态现状,再谈风险。dsh 已经通过 npm 公开发布(官方 README 提供npx @deepseek-ai/dsh web一键启动,本仓库最近的提交也正好是feat/npm-publicpublish the dsh family publicly),官方有 Discord 社区,也鼓励插件仓库打上dsh-plugintopic 便于被发现。生态在起势,但远未稳定。

作为开篇,我想把最容易翻车的认知问题讲在前面。dsh 目前的状态决定了二开策略:

  1. rc 阶段无兼容承诺:官方明确"backends reject old on-disk formats"——旧格式的磁盘数据会被拒收。SQLite 用单调递增的SCHEMA_VERSIONdsh-sessionSESSION_FORMAT_VERSION保持在 0 且无兼容承诺。你的二开代码要跟着版本走,不要假设 API 稳定。
  2. 版本漂移管理:建议在 fork 上建立一个自己的基线(tag 或 release 分支),官方上游有更新时再评估合并。这是"能改"和"会造"的分水岭,第 12 篇完整讲。
  3. vendor 纪律vendor/里的 Cordis 是钉版本的源码副本,改动需要登记到vendor/README.md的 Local modifications 清单,并有 manifest 守卫。能通过插件解决的问题,不要动 vendor。
  4. 双语文档门禁:仓库对文档有严格的字数预算、中英配对、死链检查(doc-sync)。改代码时顺手改文档是仓库纪律,但发博客时注意区分"仓库纪律"和"读者需要"。

9. 术语速查(开篇用)

本文出现的术语都给了英文原名,这里汇总成一张速查表,后面 15 篇会反复用到:

术语含义
Plugin(插件)贡献服务/事件/效果的注册单元,卸载时效果自动回收
Context插件共享的上下文,服务通过ctx.<key>访问
Effect(效果)注册产生的副作用,随插件卸载逆注册(disposer)
Seam(能力缝)Service Definition / Provider / Consumer 三件套
Profile(档案)命名组合,列出要叠加的 bundle
Bundle(包)可分发的 Cordis 配置行 + 代码
Patch(补丁)按行 id 覆盖或插入配置
Waterfall(瀑布事件)监听器必须调用next()放行的链式事件
Turn / Step回合 / 步:一次对话的节奏单位
Harness homedsh 的用户主目录(profile、补丁、数据;本机实测DSH_HOME指向用户目录下的.dsh

10. 踩坑与经验(认知篇)

本篇是认知篇,没有代码坑,但有三个"认知坑",提前排掉:

  • 坑 1:把 rc 当稳定版用。有人照着旧文章配置cordis.yml,升级后字段失效。解法:写作/阅读一律标注版本;升级前看git log与 release notes;二开代码把版本号写进 README。
  • 坑 2:想改行为就改核心。dsh 的设计就是让你别这么干——先查扩展点表(第 7 节),90% 的需求能落到某个缝或事件上。改agent-loop意味着你要同步更新架构文档,代价很大。
  • 坑 3:忽略"注册即副作用"纪律。写插件时手动注册却忘了随卸载回收,会导致 HMR(热更新)后重复注册、行为叠加。记住:一切贡献走ctx.effect()/ctx.on(),注册函数的返回值就是 disposer。

11. 总结

本文你能带走的结论:

  1. dsh 是 DeepSeek 开源的 agent harness,基于 vendored Cordis,一切皆插件,没有特权核心——扩展 dsh 的方式是挂插件,不是改核心。
  2. 一个运行中的 dsh 是插件树:Profile(档案)→ Bundle(包)→ Patch(补丁)三层组合,dsh --profile web --dump-config能看你的树。
  3. 核心服务(sessions/tools/agents/agentLoop/llm)都可替换;模型可见 ⟺ 已记录是头号不变式。
  4. 仓库有 219 个包、双语文档、严格的构建门禁;二开入口在docs/cookbook/与扩展点表。
  5. 当前是 rc 阶段、无兼容承诺——先建自己的版本基线,再动手改

下篇预告:第 2 篇《DeepSeek Harness 二次开发:源码搭建与首次运行》——带你把环境搭好、构建跑通、Web GUI 亮起来,并亲手用--dump-config看清你的插件树。

12. 延伸阅读

  • 官方架构文档:docs/architecture.md(仓库内,改动 packages/ 前必读)
  • Cordis 入门:docs/cordis-primer.md
  • 术语表:docs/glossary.md
  • 包清单:packages/README.md
  • 扩展 cookbook:docs/cookbook/extension-cookbook.md
  • 官方仓库:https://github.com/deepseek-ai/deepseek-harness

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询