🐳 第一章 Harness不只是另一个Coding Agent
📄 一句话概括

加 Tool 是往一个核心程序里塞功能;皆插件是把能力拆成可独立装卸的件。差别不在【有几个能力】,而在能不能拆开装。

📝 本节和前面几节的关系

1.2 讲了【什么都是插件】,这一节讲为什么非得是插件。关键的两个词是【改动粒度】和【接缝】——第 4 章讲的 Skill、Tool、Hook 三层扩展,就是从这里长出来的。

一、两条路的差别

最容易产生的误解是:Harness 不就是给模型多挂几个工具吗? 差别不在【挂几个】,在【怎么挂】。同样是加一个能力,两条路很不一样:

同样是 100 个能力,能不能拆开装,决定了这东西是产品还是平台。

二、同一项能力,可以有不同实现

最能说明问题的,是【同类能力可以有不同实现】。以【执行命令】这项能力为例, DSH 把它拆成三个角色:

这三个角色的关系是:换提供方的时候,定义和使用方一个字都不用改。 把本机执行换成沙箱执行,改一行配置就够了。

这就是 DSH 说的接缝(seam):在能力边界上留一道缝,缝的两边各走各的。 缝的位置选得好,改动就只影响一小块。

三、改动的粒度

接缝不只一处,它们分布在不同的深度上。从浅到深排一下:

越往里改,影响面越大。这张表的意思不是【只改浅的】, 而是改之前先想清楚:我要动的是哪一层? 很多返工不是能力不够,是一开始改错了层。

四、为什么官方要放弃特权

这里有一个反直觉的设计,值得单独说:DSH 的官方插件没有任何特权接口。

Cordis 内核本身不实现任何 Agent 能力——它不管模型、不管工具、不管会话, 只管插件之间的加载、卸载和依赖。这种【克制的内核】是故意做的:

这是开放生态能成立的结构前提。如果官方插件偷偷走了快捷通道,第三方就永远只能做次一等的东西。

五、动手 Demo:把两条路的差别并排列出来

同一个诉求【加一个能力】,两条路的做法逐条对比:

rows = [("要改哪", "改核心代码", "改配置的一行"),
        ("谁来做", "只有平台方", "任何会写插件的人"),
        ("会不会冲突", "同一个表里挤", "按作用域分层"),
        ("卸得掉吗", "难", "能,卸载自动撤销"),
        ("官方有特权吗", "有", "没有,官方与三方平级")]
for a, b, c in rows:
    print("%-14s 加 Tool:%-12s 皆插件:%s" % (a, b, c))

实跑输出:

--------------------------------------------------------------------
为什么这不只是【多加几个 Tool】
--------------------------------------------------------------------
  容易产生的误解是:Harness 不就是给模型多挂几个工具?
  差别在【改动的粒度】上。同样是加一个能力,两条路完全不同:

                   加 Tool 的思路       换插件的思路
  -----------------------------------------------------------
  要改哪           改核心代码           改配置的一行
  谁来做           只有平台方           任何会写插件的人
  会不会冲突       会,同一个表里挤     不会,按作用域分层
  卸得掉吗         难,代码里长住了     能,插件卸载自动撤销
  官方有特权吗     有                   没有,官方与三方平级
  -----------------------------------------------------------

  最能说明问题的是【同类能力可以有不同实现】。
  以【执行命令】为例,DSH 把它拆成三个角色:

  角色         职责                                 会不会变
  -------------------------------------------------------------
  能力定义     声明有这么个能力、类型是什么         几乎不变
  提供方       真正去执行(本机 / 沙箱 / 容器)     可整体替换
  使用方       调用它的人(模型、其它插件)         完全不知情
  -------------------------------------------------------------

  换提供方的时候,只动提供方那一处——
  把本机执行换成沙箱执行,改一行配置,定义和使用方都不用动。
  这就是【接缝】的意思:能力边界上留一道缝,缝两边各走各的。

  改动的粒度还能再往上抬一层:

  想改什么           改哪儿             影响面
  -------------------------------------------------------------
  换个模型           模型路由那一行     最小,界面和工具都不动
  换个工具实现       工具提供方         小,调用方无感
  整套能力换一组     换一个 Preset      中,只影响这一个会话
  换整个运行环境     换宿主组合         大,全部会话一起变
  -------------------------------------------------------------

  小算例:DSH 官方内置插件 100 个以上、仓库 49 个包。
  如果按【加 Tool】的思路,这 100 多个能力要被写进一个核心程序里;
  按【皆插件】的思路,它们是 100 多个可以各自装卸的独立件。
  同样是 100 个能力,能不能拆开装,决定了这是产品还是平台。

五行里最值钱的是最后一行。官方没有特权,第三方才敢往里投东西。 一个插件生态能不能活,不取决于官方写了多少插件,而取决于别人写的插件是不是跟官方的一样好用。 这一条,后面的第 4 章(三个扩展层次)和第 8 章(设计自己的 Preset)会反复用到。

30 秒实验

  1. 找一个你现在常用的软件,判断它的功能是【写死在核心里的】还是【可以插拔的】。
  2. 在配置树里找一处 disabled: 开头的行,看它是怎么做到【有条件地不加载某个插件】的。
  3. 想一个你想改掉的行为,先判断改的是【定义】【提供方】还是【使用方】,再动手。

常见误区

  1. 错误:皆插件就是把功能拆成很多小文件。——纠正:关键不是文件拆多小,而是每个件能不能独立装卸、装卸时会不会互相污染。
  2. 错误:插件多了会互相冲突。——纠正:DSH 的工具注册表按作用域分层,近者遮蔽远者,不会挤在同一张表里。
  3. 错误:官方插件肯定比第三方的好。——纠正:官方没有任何特权接口,和第三方插件挂在同一套接口上——这是开放生态的结构前提。
自测三问(点开对答案) 1. 加 Tool 和皆插件,根本差别在哪? —— 前者往一个核心程序里塞功能,后者把能力做成**可独立装卸的件**;差别在能不能拆。 2. 同一项能力的三个角色是什么? —— 能力定义(声明有什么,几乎不变)、提供方(真正执行,可整体替换)、使用方(调用的人,完全不知情)。 3. 为什么说【官方没有特权】这么重要? —— 因为内核不实现任何 Agent 能力、官方与第三方插件挂在同一套接口上,**第三方才有可能做出和官方同等级的东西**——这是生态能活的结构前提。

相关笔记