ARTICLE · 1338956
dsh 插件开发 01|认知:连 Agent 循环都是插件,该从哪层写起
摘要:模型只给下一步动作,其余都在插件树里。dsh 插件开发 01 把三层分开,看清「没有特权内核」意味着什么,前两章不装环境。
把一个编码 Agent 拆开,通常能分出三样东西:模型、驱动模型的那圈代码、以及这圈代码能调用的工具。多数产品把扩展边界画在后两者之间,你能写的插件基本都在第三层,工具是工具,循环是循环,循环不归你碰。
DeepSeek Harness 把这条线挪了位置。
本号 10 月初那篇讲四大 Agent 方向的稿子横向提过 dsh,说的是它是什么、和另外三家哪里不一样。从这一篇起是另一件事:dsh 插件开发 这套连载,讲怎么给它写插件。那篇里的产品卖点和数字这里都不沿用,本篇的架构表述全部换成官方一手文档。
三层
官方 README.zh.md 第一屏写着,DeepSeek Harness(dsh)是 DeepSeek AI 开发的开源 agent harness(智能体框架)。Harness 在这里就是模型外面那一圈基础设施:轮次怎么排、工具怎么注册、上下文怎么拼、发生过什么怎么记、谁能动哪些文件。
它构建于「一切皆插件」的架构之上,由 Cordis 驱动。Cordis 是一个只管插件加载、依赖解析和服务注册,完全不知道 Agent 是什么的元框架。官方 README 提到它的设计见论文《A Programming Paradigm for Spatiotemporal Composability》。
四层关系:
[模型] 一次 llm/stream 请求,产出下一步动作[Harness] 轮次 / 步骤 / 工具注册表 / 系统提示词 / 会话日志 / 审批[插件树] agent-loop / llm / tools / session / shell / fs / ...[Cordis] 服务容器 / inject / fiber / effect关系:Harness 由插件树构成,插件树由 Cordis 调度。这张图是本系列按官方架构文档做的教学拆分。真正要记住的是最后一行:dsh 里「服务和插件由谁管、什么时候激活、卸载时留下什么」这个问题,答案不在 dsh,在 Cordis。所以第 03 到 06 章会拿四章专门拆这套机制,第 01 章不展开。
模型只出现在其中一行。官方 docs/architecture.zh.md 给的轮次流程很长,按它简化后是这样(简化图同样由本系列归纳):
turn/start step/start agent/request llm/stream <- 模型只在这一行 tool/call -> tools/execute -> tool/result step/endturn/end同一个文档里还定义了两个词:步骤是一次模型请求加上它调用的工具,轮次包含零个或多个步骤。模型负责的是看一眼上下文、给出下一步;把这一步接住、把工具跑完、把结果写回日志、决定还要不要再来一步,全是 Harness 的活。
循环本身也是插件
Everything is a Plugin 在别的项目里多半形容插件生态丰富,dsh 的架构文档把它写成了一句可核对的陈述:产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身,因此每个都可以从配置替换。
连驱动模型反复提问的那段循环也是插件。
同一页紧接着写了后果:
不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边,而各项注册都是副作用,会在其插件卸载时撤销。
两段合起来,扩展的位置就落在同一棵插件树旁边:再挂一行配置,那一行和官方自带的行在加载机制眼里是同一类东西。在 dsh 里,插件是构成材料,不是外挂。
官方给了一条能直接验证的命令:
dsh --profile web --dump-config官方对这条命令的说明是「它打印出的任何条目,都可以由你自己的 patch 替换」。patch 在这里指一份只写要改的配置行的 YAML,按 id 定位条目、替换其整个 config,或者直接插入新条目。第 02 章会真的跑它,把本机挂了哪些行打印出来;这一章只需要知道,那张输出是一份可编辑的清单。
架构文档还给了一个更具体的例子:文件系统与进程提供方共享同一个执行世界,把它们指向远程沙箱,Bash、PTY 和 LSP 会一起搬过去,不用给每个工具单独做一套。换一个提供方,消费侧一行不改,是这套分层直接推得出的结果。
项目状态
CONTRIBUTING.md 里有两处值得原样看。一处是官方目前不接受外部 PR,原文 we cannot accept external pull requests at the moment。另一处紧接着解释这不等于关上门,原文 We do not believe that packages in the official repository are inherently more important than packages created by the community.。官方把这个仓库定位成一个想法、一次官方示范、一份灵感来源,明说它不构成规定。同一份文档建议的参与方式里,就有「写一个让你自己兴奋的插件,给 GitHub 仓库加上 dsh-plugin topic」。
给 dsh 做扩展的正路是自己建一个包,挂进自己的 profile(一份可启动的命名组合),需要分享就加 topic。这个差别直接决定了后面 20 章的写法,我们全程都在写「旁边的那个包」。
README.md 的 Developer preview 一节还有一句必须放在第一页:未来将出现破坏兼容性的变更,英文原文是全大写的 THERE WILL BE COMPATIBILITY-BREAKING CHANGES.。许可是 MIT。
本系列因此定了三条口径:不写死版本号,不写 Star 数和插件总数,不承诺某个 API 永远有效。学 Cordis 的 inject(服务依赖)、fiber(插件状态机)、effect(可逆注册)和 seam(能力接缝)三角色,比记某个 rc 版本里哪个包叫什么耐用得多。真要查当前版本,去 npm 和仓库现场看。
跑之前
README 在开发者预览那段下面留了一行:运行本项目前,请阅读安全说明。这份说明是仓库根的 SAFETY.zh.md,内容比常见的免责声明具体得多,第一章就该读完。
它说 DeepSeek Harness 是实验性的开发者预览软件,尚未接受安全审计,不得视为安全或可用于生产环境的软件。原因是这个项目可以执行模型生成的代码与命令、加载第三方插件,并访问向它开放的网络、进程、凭据和文件;错误的模型输出、缺陷、配置错误、恶意输入或不可信插件都可能改删文件、泄露数据。
关于沙箱,官方的措辞同样不留余地:沙箱、审批提示与权限控制可以降低风险,但不保证隔离,也不能保证防止损害;即使限制被正确执行,也无法保护项目本身获准访问的那些资源。结论写得很直白,不要把 dsh 当作不可信工作负载唯一的安全控制措施。
SAFETY.zh.md 给的五条使用建议,照抄一遍比转述有用:
仅授予所需的最小权限和访问范围 优先在一次性虚拟机、容器或专用环境中运行 备份项目可以访问的文件 除非接受风险,否则不要暴露敏感凭据或数据 允许运行前检查插件、配置和拟执行命令
这套边界也解释了系列的节奏:前两章不急着装环境,先看清你要往哪台机器上放一个能跑代码、能读文件的东西。
二十章
这个系列叫 dsh 插件开发,按六段走;每篇标题里的两字徽标,标出这一章讲哪个方面。前面十章不写一行业务代码:
把底座放在全景前面,是因为按官方架构文档,运行中的 dsh 是一棵插件树,由启动时按序叠加的各层组合而成。插件能不能加载、什么时候激活、服务消失后谁跟着停,全由 Cordis 决定。跳过这套机制直接抄 apply(ctx),后面遇到「插件没有任何输出」,多半只能靠猜。
贯穿案例是一个只读自有小程序项目 app.json 的巡检插件,从第 15 章认识工具能力开始,到第 20 章做成可安装、可发布的包。这个案例由本系列自定,官方示例里没有;场景换成安卓工程或前端构建产物,章节骨架不用动。
这一章不用装 Node,也不用配 API Key。
真要动手,先做两件不费事的事:把官方 README 的开发者预览一节和 SAFETY.zh.md 五条读完,再决定这台机器要不要用来跑它;决定跑,就优先给一次性容器或虚拟机,别放在装着公司代码和凭据的工作机上。下一篇 dsh 插件开发 02|认知:两条路径跑起来,先看第一棵插件树。起服务后用 --dump-config 打印这台机器实际挂了哪些行,再回头对照这一章的四层图。
本篇一手出处:github.com/deepseek-ai/deepseek-harness 的 README.md / README.zh.md、docs/architecture.zh.md、CONTRIBUTING.md、SAFETY.md / SAFETY.zh.md、docs/glossary.zh.md(核实日期 2026-11-10,分支 master)。逐条硬事实与存疑项见同目录 2026-11-10-dsh-01-what-is-dsh-facts.md。















































































