习慈羊xiciyang
联系
订阅
正在读取订阅状态…

插件、Skill、MCP、CLI:先判断这份能力该不该进模型上下文

上个月我在同一个星期里做了两个相反的取舍:一个写作能力做成命令行,46 个测试、一个退出码;一个视觉记忆做成插件工具,因为调用时机只有模型自己知道。

判断标准只有一条:这份能力该不该进模型上下文。写给已经在用 DeepSeek Harness、准备给自己或团队扩能力的人;没用过它,下面的数字没有参照系。

工具声明每一步都在场,66 个插件把清单撑到 92 个工具

模型看不到文件系统。它每走一步,看到的是一份由 harness 拼出来的清单:工具的名字、描述、参数结构,技能目录,注入的规则文本。单个工具按 200 到 400 字符估,92 个就是两三万字符,占掉固定文本的三分之一。这份清单不只在第一次请求里付一次,它跟着每一步重发。

本机的量级:web profile 里叠了 66 个 bundle[4],工具总数被折进 27 个按需组,模型平时只看见组名和组内工具数量。即便如此,一个开过若干按需组的会话,工具声明仍有 92 个,固定文本 74,008 字符。官方基准是 60 个工具、160,000 字节、130,000 字符固定文本[4]。

启动过程本身是分层的[1]:66 个 bundle 各带一份补丁,按顺序叠在 profile 的空树上,再叠 profile 自己的补丁与用户覆盖层。覆盖按 id 整段替换配置,不做深合并,所以改一层的键必须把整段重述一遍。这个细节决定了一件事:能力装得越多,每一层的重述成本越高,而模型看不见这些,它只看见最终的清单。

有一种写法让人误以为声明可以消失。PTC 模式把 47 个工具的 TypeScript 声明搬进了系统消息,工具列表里只剩一个入口工具,看起来干净了。声明没有消失,它换了位置,仍然每一步都在,合计约 11.3k token[3]。只量工具列表的检查会在这里报假绿。

清单一旦变化,前缀缓存就失效,下一次请求要按未命中重算。中途打开一个工具组、改一次系统注入,都会让整段历史重新计费。这也是「能一次装好就别分两次」的实际原因。

所以第一个结论很朴素:加能力的默认代价是「每一步都付一次」。一周用一次的东西,如果让每一步的清单再长一行,就是用每步的预算买每周一次的便利。

常驻成本三档:每步都在场、按需加载、进程外

图 1:同一份能力的三档常驻成本。折叠改变的是付钱的时机,不是总量。

三个问题分完六种形态:只有工具和 Skill 该每步在场,其余都出门

工具、Skill、MCP、套件、领域包、脚本,名字像六种技术,实际是同一件事的六种摆放方式。三个问题就能定位。

谁决定调用时机。 模型自己在对话中途决定用,就必须进上下文。人、构建脚本、定时任务决定用,就不必进。别的客户端或别的 agent 也要用,走协议。

多久用一次。 每一步都可能用,是工具;一次会话用几次,是 Skill 或按需组;一周几次,是命令行;只跑一次,是脚本。

崩了会污染谁。 会卡住主进程、会吃掉上下文、依赖一堆外部库的,放进程外。只在返回值里出错的,放工具里也安全。

三个答案合起来,指向下表的一行。

形态谁调用常驻成本热重载失败隔离本机例子
工具(插件内)模型声明每一步都在改 bundle 要重启进程同进程,靠 fail-soft 兜视觉记忆的取图与画框
Skill模型按需加载目录一次注入改文件下一轮生效只读指令,无执行写作前过意图门这套方法
MCP模型(外部工具面)声明每一步都在,可改成按会话启用服务侧重启独立进程已有文档服务、跨客户端复用
套件 / CLI / 脚本模型显式调用,或构建脚本零改完即用独立进程,用退出码表达结论意图门校验、渲染检查
领域包套件与 agent 读取零改完即用是数据,不执行写作契约的五项输入

三个问题把能力分到六种形态

图 2:三个问题的组合指向六种形态;只有第一列要每一步付费。

结论:形态是代价表,不是身份

六个形态没有能力高低,它们是四种代价的不同组合:每步上下文、热重载、失败隔离、复用范围。选错的代价不是功能不够,而是长期为看不见的东西付费,或者在需要它出现的时候它根本不在场。

判断顺序可以固定成两句:先问「它必须让模型看见吗」,再问「它需要确定性执行吗」。前一个答案是肯定的,就在工具、Skill、MCP 里挑;是否定的,就在套件、领域包、脚本里挑。

还有一条更实用的:形态可以升级,不必一步到位。 一个能力先做成命令行,等它被每周调用三次以上,再考虑放进按需组;等模型必须在对话中途自主决定调用,才升级成常驻工具。升级的触发条件是调用频率与决策归属变了,不是「插件看起来更正式」。

进上下文的三种:工具要输出可控,Skill 删掉执行后得有用

工具。 门槛有三条:调用时机只有模型知道;执行是确定性的;输出可控。第三条最容易被忽略。工具返回值会整段进入上下文,一个把全量日志原样吐回来的工具,能把半篇预算吃掉。本机的做法是让读取类工具只回摘要、路径和行号,细节等真正需要时再读一次;把十万字符的构建日志直接返回,一次调用就能把上下文顶到窗口边缘。工具的输出是接口,得按接口设计。

Skill。 它是一份指令,不是执行器。写「必须先跑测试」,不会让测试真的跑起来,只会让模型知道该跑。判据很好用:把执行部分删掉,只留知识,还剩价值吗?剩,才适合 Skill。一份方法、一组判据、一套流程,都剩;一条命令、一个校验,都不剩。

Skill 的失效方式很隐蔽:模型读过,但没照做。一次长会话里,它可能记住前半段的规则,后半段又回到旧习惯。所以 Skill 适合可被提醒的方法,不适合一旦漏掉就出错的约束;后者要落到闸门。

MCP。 门槛是两条里至少一条:这个能力已经有一个对外服务;或者它要被多个客户端、多个 agent 共用。两条都不满足时,MCP 只是给一个命令行套了协议壳,还多出一层声明和进程管理。本机的处理办法是把重型 MCP 改成按会话启用,需要时才把工具面挂进来。

出上下文的三种:套件拿退出码当闸门,领域包只生产约束

套件。 一个独立 npm 包,一条命令,一个退出码[2]。输入输出能用文件和退出码表达,且不需要模型在每一步决定,就该做成套件。意图门的实现就是这样:校验命令用退出码 0 与 1 表示「意图完整」与「打回」,构建脚本可以拿它当闸门,模型也可以调用它,但它从不占用每一步的清单。

这里有一条容易被低估的差别:闸门是硬约束,模型调用是软约束。 模型可以跳过一个「建议先检查」的工具;构建脚本里的一行校验命令跳不过去,不过就不出产物。凡是「必须发生」的事,最终都要落到命令或闸门上。

意图门本身就是这样演化的:第一版是纯命令行,在构建发布链里跑,不过校验就不出产物;第二版加上 Skill,让模型知道写文章前有这道门。它始终没有升级成常驻工具,因为调用时机由流程决定,不由模型决定。视觉记忆走了相反的路:它必须先有工具,模型才会在写作中途想起来「这张截图值得存」,做成命令行等于让它不存在。

领域包。 一组冻结的契约文件,加一个校验器。它不生产行为,只生产约束。写作契约把撰写模式的输入冻成五项:读者、目的、风格契约、素材、断言证据;校验器在产物出来之前跑一遍,契约文件改错了当场报错。把同样的规则写进提示词,它会漂移,还会每一步付费;写成 yaml 加校验器,它可复现,且只在被读取时存在。

领域包的价值在复用:同一份写作契约同时约束 agent、构建脚本和评审器,三处读到的是同一份文件,改一处三处生效。如果只有一个消费者,写成文档里的一张表更省。

脚本。 只跑一次的东西,别给它设计形态。写完就删也可以。

三种装错的代价,以及判据失效的边界

把批处理装成插件。 一个每周跑一次的索引器做成工具,声明却常驻每一步。它几乎不被模型调用,因为模型不需要在对话中途索引文件;它每次都收费,因为它躺在清单里。正确形态是套件加定时任务。

把需要模型判断的做成命令行。 模型看不见它,就不会主动调用,能力等于不存在。判据是:如果「什么时候用」这个决定需要模型来做,它必须进上下文,至少进一个按需组。

用 Skill 承载确定性执行。 Skill 说「跑一下校验」,模型可能跳过,尤其是在长对话的后半段。需要保证的事,落到命令与闸门,Skill 只负责让模型知道有这么一道闸门。

还有两种更隐蔽的。把领域契约整段抄进提示词:规则会漂移,还每一步付费。

最后一种是全都装:本机 66 个 bundle 靠折叠机制救回来,按需组让约 700 个工具不至于全摆在桌上,但组目录一次注入 13,090 字符,开组要多走一步,还会打断前缀缓存。折叠不是免费的,它把「每步一点点」换成了「开组时一次性一大笔」。本机的 27 个组按用途分,浏览器、Office、数据库各占一组;组越大,开一次越贵,所以把 200 个推理服务工具塞进同一组并不是最优解,拆成三组反而更省。

边界也要说清。这套判据假设能力会被反复使用,且至少有一个人在维护它。一次性脚本、还没稳定的需求、只有自己用的本地小工具,都不值得走这套流程:先写成一个 .mjs,等它一周被调用三次以上再谈形态。团队规模同理,两个以上的人要复用同一套判据,领域包才划算;一个人维护的契约,写在文档里就够。

动手前先量三件事:现在 92 个工具,装完多的每一个都要解释

一、量上下文占用。 装之前跑一次预算检查,记录工具数、固定文本字符数。本机当前是 92 个工具、74,008 字符固定文本,基准是 60 个工具、160,000 字节、130,000 字符。装完再跑一次,差值是这次扩展的每步成本。数字变大不是错,讲不出为什么变大才是错。

二、验热重载。 改一行客户端代码,刷新页面看是否生效。bundle 插件的客户端部分要重启进程才会重新扫进启动清单,重载命令对 bundle 无效;运行时注入的插件才能热重载与自重载。这条验收决定以后改一个字的返工成本。

三、验可卸载。 删之前先确认目标目录不是符号链接,依赖目录里的链接不会出现在依赖声明里;再用 tar 做快照,本地链接型插件不能用会重建的备份工具。删完 grep 一遍残留的工具名与配置键。一个卸不掉的能力,比一个装不上的能力更贵。

失败隔离算第 2.5 条:装在主进程里的插件崩了,靠 fail-soft 把故障插件隔离、必要时修复;放在进程外的东西崩了,只会让它自己不可用。哪种更安全,取决于这个能力坏了之后,主进程还敢不敢继续跑。

下一步:同一套判据,三种角色的代价落在不同地方

「什么该进 harness」只是一半。另一半是角色问题:个人开发者要判断装、写还是接;团队负责人要判断准入、退出与升级;想贡献生态的人要判断打包与收录。同一套判据,三种用法,接下来按角色各写一篇。

参考文献

[1] DeepSeek Harness. 插件与生命周期[EB/OL]. 开发文档, 2026. https://deepseek-harness.github.io/deepseek-harness/develop/framework/

[2] DeepSeek Harness. 打包与安装插件[EB/OL]. 开发文档, 2026. https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish

[3] Anthropic. Code execution with MCP[EB/OL]. 2025. https://www.anthropic.com/engineering/code-execution-with-mcp

[4] 本站. 从字节数账:上下文预算到底花在哪[EB/OL]. 2026-10-17. https://xiciyang.com/blog/token-audit-from-bytes/(本机工具快照与固定文本口径的原记录)

评论

填个昵称就能发,不需要注册或登录