appso 16小时前
DeepSeek Harness 大起底:这一次,重新定义「插件」
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_keji1.html

 

「万物皆插件。」

这句话放在模型、工具、技能上,听起来还算容易理解;但如果我告诉你,会话、沙箱、文件系统也都被列进了插件的范围——等一下,这些东西怎么也能叫插件?

一直以来我们最熟悉的「插件」,大概还是 Chrome 扩展。浏览器已经是一款完整的软件,我们再往里面安装广告拦截、翻译、截图等插件,让它多出一些原来没有的功能。插件卸载了,Chrome 依然是 Chrome,也依然知道怎么打开网页。

现在,这个词已经被 DeepSeek Harness 重新定义了,是时候换个角度理解它。

让模型「上岗」,也需要「配套」

首先得从今年以来 AI 业界越来越常见的另一个词讲起:Harness。

假设一家公司招来了一个能力很强的新员工。

人招进来了,不代表就能立刻原地马上开始工作,还得给他安排工位和电脑,开通邮箱、内部系统和数据库账号,发门卡,告诉他共享的网盘、文件、工作流程怎么走、哪些操作需要审批,甚至还要留下过去的项目记录,让他知道同事之前已经做到哪一步。

如果把这个新员工看成一个大模型,那么围绕它准备的这一整套工作条件,就很接近 Harness。

模型决定了这个「员工」本身大概有多聪明、会不会推理、会不会写代码;Harness 则负责把这些能力接进真实环境。它可能包括模型能够调用哪些工具、能读写哪些文件、当前任务的上下文如何保存、不同权限怎样管理、程序在哪里运行、一次任务失败以后应该怎样继续,以及模型在「看资料—采取行动—观察结果—再决定下一步」之间如何循环。

这也是为什么同一个模型,放进不同 Agent 产品里,实际使用感受可能差很多。员工还是同一个员工,但一边给的是一台配置完整的电脑、清楚的权限和成熟的工作流程;另一边连账号都没开齐,最后做出来的事情当然不一样。

从这个角度看,Harness 可以有一个非常朴素的解释:它就是让模型从「有能力」变成「能上岗」所需要的一整套配套系统。

普通插件 = 添砖加瓦

理解了 Harness,再回头看我们熟悉的 Chrome 插件,会发现传统插件通常有一个很稳定的前提,软件主体已经存在,插件负责在主体之上增加能力。

Chrome 本来就能浏览网页,翻译插件只是让它多一个翻译功能;Photoshop 本来就能编辑图片,第三方插件可以增加一种滤镜或工作流。即使没有这些插件,软件最核心的运行方式并不会消失。

如果继续用「员工上岗」来打比方,这种插件有点像公司已经准备好了办公室,又因为增员,往里面添了一台打印机、一块白板或者一个新的显示器,这些是锦上添花、添砖加瓦。

其实很多 Agent 的扩展也符合这种直觉。给 Agent 接一个搜索工具、一个 GitHub 工具或者一个数据库接口,本质上都是在现有 Harness 上增加一种新的能力。因此我们看到 Tool、MCP、Skill 经常和「插件」一起出现,并不奇怪。

以 Claude Code、Codex 这类成熟产品为例,基于 Harnes 的扩展,基本集中在几处:

Tool / MCP:注册一个新的函数调用接口,让模型多一个可执行动作,工具 schema 会进入系统提示;

Skill 与指令文件:往上下文里加一段可按需加载的说明,例如项目根目录里的约定文件;

Hook:在工具执行前后插入校验、日志或审批;

Subagent:把一部分任务派给子智能体,主流程只接收结构化结果。

这些扩展有一个共同前提:很多东西都属于产品内部的实现。主循环怎么轮转、上下文如何组装、会话怎么存、沙箱如何隔离、模型适配层怎么写……这些你可以让模型「多会一件事」,但很难改变它「怎么决定下一步」。

就好像,你能添一台打印机、发一份操作手册,甚至安排一个实习生分担工作;但打卡制度、审批流程、档案怎么归档,都已经由公司定死。

在 DeepSeek Harness 里,插件不只是一个功能,它更接近一种技术理念:「万物皆插件」,把模型、会话、沙箱、文件系统这些通常更接近 Harness 基础设施的部分也放了进去。

这时「插件」这个词,就不能再简单理解成给软件增加功能的小东西了。

DSH 的「插件」,更像可以随时替换的办公室模块

给 Chrome 上装插件好理解,一整个办公室怎么可能变成插件?

举个例子:打卡。打卡在以前,是签到表,是打卡机;到后来,有了指纹打卡、人脸识别;到现在用 app 就能打卡。无论技术怎么变化,打卡的核心是不变的:识别人员、记录时间、地理定位。

这时候,打卡就从一套写死的基础设施,变成了一个可以替换的模块。只要能实现这些功能,究竟是打卡机还是企微钉钉,都没关系,也随时可以替换。文件系统也是一样。对于上层 Agent 来说,它真正需要关心的未必是文件究竟存放在本地磁盘、远程空间还是某个隔离沙箱里,而是「我能不能读」「能不能写」「路径怎么表示」「出了错误会返回什么」。如果不同实现,都遵守同样的接口,Harness 就可以用相似的方式去调用它们。

因此,DSH 所谓的「一切皆插件」,从原来在一个已经固定下来的 Agent 外面继续安装新功能的思路中跳脱出来,试图把 Harness 里的不少能力都进一步拆解、细分成可以替换和组合的模块。

在这条路线上,之前有 Pi 这个先行者,Pi 的核心负责人之一,也在第一时间发文表示 DSH 带来的启发。

Pi 的确和 DSH 的出发点很像,但最后停在了不同的位置。Pi 的做法是把核心缩到极小:模型只拿到四个工具——读文件、写文件、改文件、跑命令(`read`、`write`、`edit`、`bash`)。子智能体、计划模式、待办清单、MCP,这些别的产品通常会内置的功能,Pi 干脆一个都不做,全部交给扩展。而它的扩展就是一段 TypeScript,可以注册工具、命令、快捷键和事件监听,也可以接管终端界面;官方示例里就包括子智能体、计划模式、权限闸门、路径保护、SSH 远程执行和沙箱。

回到上面办公室的说法,这像是公司提供了一间空房间和几件基本工具,剩下的桌椅、流程和制度,都可以自己制作。

但即便如此,Pi 和 DSH 仍然不是同一件事。Pi 缩小的是核心的体积,扩展依然挂在这个核心留出的口子上。会话怎么存(Pi 存成一棵可以分叉的树)、主循环怎么跑,仍然由 Pi 自己决定。DSH 想做的则是让核心的构成可替换:会话日志、主循环、提示词组装本身也只是插件,理论上可以整个换掉。

一个是把地基砌得尽量薄,一个是把地基也拆成砖。前者更克制,也更容易稳定;后者自由度更大,代价是每一块砖都有不稳定性。

「可插拔」、「可组合」是怎么做到的

DSH 的底座是一个叫 Cordis 的插件元框架,基于这个框架,一个正在运行的 dsh,本质上是启动时立时组合出来的一棵服务树:所有能力都挂在共享上下文 `ctx` 上,用稳定的 key 对外暴露。

插件通过 `inject` 声明自己依赖哪些服务,依赖满足才会激活;更关键的是,注册行为被设计成可撤销的——插件卸载时,它注册过的工具、事件监听、提示词片段和服务实现会一并回收。官方架构文档有这样的表述,「没有一个需要打补丁的特权内核」,扩展 dsh 的方式,是在其他插件旁边再挂一个插件。

真正承担「替换」的结构,官方叫 seam,由三个角色组成:声明接口的 Service Definition、实现接口的 Service Provider,以及使用它的 Consumer ——后者通常就是模型可见的那个工具。三者齐全才算一个 seam,只写一个实现不算。

这也解释了为什么换掉一个 provider 会改变整个产品的行为:文件系统和子进程共享同一个执行世界,把它们指向远程沙箱,Bash、PTY、LSP 会跟着一起搬过去,不需要为每个工具各 fork 一份实现。

在实现「可组合」上,DSH 把执行过程分成两级,step 是一次模型请求加上它触发的工具调用;turn 从领取输入开始,到不再欠任何后续工作为止,可能包含零个或多个 step。

一次 step 的事件顺序大致是:

agent/pre-step → step/start → agent/request → llm/stream → assistant/chunk → tool/call → tools/pre-execute → tools/execute → tools/post-execute → step/end

其中 `agent/pre-step`、`agent/request`、`llm/stream` 和三个 `tools/*` 是瀑布式事件,监听者必须调用 `next ( ) ` 才会继续往下传递。也就是说,插件可以在这里改写模型即将看到的消息,甚至直接拒绝这一次输入——被拒绝的输入仍然会关闭一个没有消耗 step 的 turn,日志里留下这次尝试。审批策略、上下文注入、工具改写都发生在这一层,而不是产品源码里。

会话日志是另一条硬约束。它是仅追加的事件流,模型看到的历史由 `deriveMessages ( ) ` 从日志投影出来,文档把规则压成一句话:model-visible means logged ——任何进入模型请求的内容都必须能从日志重建,运行时会对此做断言。恢复、分叉、回放、遥测和持久化因此消费同一份事件流;想新增一种模型可见的输入,就得扩展 `SessionEventMap`,而不是私下往提示词里塞一段字符串。

最后,组合发生在配置层,而不是代码层。bundle 是一批 Cordis 配置行加上它们挂载的代码,profile 是按顺序叠起来的 bundle 再加用户自己的 `cordis.patch.yml`;加载顺序为 bundle、profile 补丁、home 级补丁,最后是命令行 `--patch`,后面的层可以按 id 覆盖前面任意一行配置。想知道自己机器上究竟启动了什么,可以把这棵树直接打出来:

bashdsh --profile web --dump-config

「可组合」之所以是一个可验证的说法而不只是宣传,很大程度上就是因为最终组合可以被看见。

真正被「插件化」的,也不是电脑、门禁或文件系统这些东西本身,而是 Harness 与这些东西连接的方式。只要连接方式足够标准化,背后的具体实现就有机会更换。

DSH 如何重写定义

在「插件」的维度和在「harness」的维度,DSH 都有很大的思路创新,把两种 harness 的可替换范围摊开来看,差别会更清楚。

需要补充的是,这种彻底的可替换性并不自动等于更好用。v0.1 的仓库已经明确提示后续会有破坏兼容性的改动,而把接口拆得越细,也越容易遇到版本错配、依赖冲突和更难定位的调试问题。

当然,这并不意味着两种「插件」之间存在一道绝对的技术分界。不同 Agent 框架会把 Extension、Plugin、Skill、Tool、MCP 划在不同位置,有些插件也可以深入修改软件内部行为。真正值得注意的,不是某个模块最后被叫作 plugin 还是 extension,而是它到底可以介入系统的哪一层。

DSH 的反常识之处就在这里,它把「插件」这个过去经常位于软件外围的概念,推到了 Agent Harness 更靠近内部的位置。

为什么 Agent 时代会出现这样的设计,也并不难理解。模型越来越像一个通用但可替换的「员工」,真实工作环境却千差万别。有人需要本地文件,有人需要远程沙箱;有人想接 DeepSeek,有人也可能测试其他模型;不同团队对工具、权限、记忆和工作流程的要求都不一样。如果这些配套被牢牢写死在同一个 Harness 里,每改变一项,都可能意味着重新改造整个系统。把它们变成可插拔组件,则给开发者留下了重新组合的空间。

所以,DeepSeek Harness 的范式创新,并不只是「DeepSeek 也开始做插件生态了」,更准确地说,它在尝试回答一个更基础的问题:当模型越来越容易被替换以后,围绕模型搭起来的那套工作配套,能不能也变得更灵活、更模块化?

这不是没有代价,对于普通用户来说,开箱即用仍然是一个合理到不能再合理的需求——就像去公司上班,谁愿意总是背自己的电脑?但对于极客程序员、工程师来说,从键盘到显示器到人体工学椅,都有自己的讲究,那花时间甚至是自费上班,是一件有乐趣的事。

DSH 想做的,是一种技术思路的创新,也让人看到,哪怕是办公室里,许多东西从一开始就不必被钉死。

我们正在招募伙伴

简历投递邮箱hr@ifanr.com

✉️ 邮件标题「姓名 + 岗位名称」(请随简历附上项目 / 作品或相关链接

更多岗位信息请点击这里

宙世代

宙世代

ZAKER旗下Web3.0元宇宙平台

一起剪

一起剪

ZAKER旗下免费视频剪辑工具

相关标签

chrome ai 翻译
相关文章
评论
没有更多评论了
取消

登录后才可以发布评论哦

打开小程序可以发布评论哦

12 我来说两句…
打开 ZAKER 参与讨论