news 2026/8/24 4:05:22

DeepSeek Harness 插件开发简易指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek Harness 插件开发简易指南

DeepSeek Harness 插件开发简易指南

一、先理解架构:DSH = Cordis 插件系统 + 补丁式组合

DSH 不是单体应用,而是构建在Cordis 插件框架@deepseek-ai/cordis,Koishi 系)之上的分层插件树。

概念说明
Profile$DSH_HOME/profiles/<name>/(我的是C:\Users\AIcncc\.dsh\profiles\web)。含package.json(声明dsh.profile.bundles有序组合包列表)+ 用户自己的cordis.patch.yml
组合包(bundle)声明了"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }的 npm 包。dsh-basedsh-web-app都是 bundle
补丁分层空条目根cordis.yml→ 各 bundle 的 patch(按序)→ profile 级cordis.patch.yml→ home 级~/.dsh/cordis.patch.yml--patchoverlay。后层按id覆盖前层整段configinsert添加新行,支持!!js表达式
插件行每个插件是一行{ id, name, config?, disabled? }name是模块说明符,config由插件自己的Config(schemastery)校验
安装dsh plugin --profile web add <pkg>把 pnpm 参数原样转发到 profile 目录,把包装进 profile 的依赖
激活Loader 并发挂载条目,服务可用性驱动激活inject声明依赖,先有提供方后激活消费方)

工具目录中几乎所有可见能力(run_codepwshtodo_writesubagentworkflow…)都是一个插件包,例如dsh-tool-tododsh-tool-pwsh——这就是你插件的参照物

二、插件的标准形态(源码确认的约定)

第一方插件使用命名空间导出(无默认导出,docs/postmortem/0001规定默认导出会丢失inject):

// lib/index.ts —— 一个最小但完整的工具插件importzfrom'@deepseek-ai/schemastery'import{defineTool}from'@deepseek-ai/dsh-tools'exportconstname='my-tool'// 插件名(kebab-case,全局唯一)exportconstinject=['tools']// 声明注入的服务键,Loader 据此排序exportconstConfig=z.object({// schemastery 配置 schema(可留空对象)greeting:z.string().default('Hello from my plugin'),})exportfunctionapply(ctx:Context,config:ConfigType){ctx.tools.register(defineTool({name:'my_hello',// 模型可见的工具名(snake_case)description:'Say hello. Returns a friendly greeting.',parameters:{name:{type:'string',required:true,description:'Who to greet'},loud:{type:'boolean',description:'Uppercase the greeting'},},output:{schema:{type:'string'},render:(_args,value)=>[{type:'text',text:value}],},asyncexecute(args,exec){// exec.signal 必填且只读——必须观测/转发取消信号constmsg=`${config.greeting},${args.name}!`returnargs.loud?msg.toUpperCase():msg},}))}

三条硬性规范(注册表强制校验):

  1. output: { schema, render }必填——没有输出声明注册直接失败;
  2. execute只能返回输出 schema 声明的无损 JSON,通过exec.signal协作停止;
  3. Confignameinjectapply四个导出缺一不可(Config可省,但专业插件应带配置)。

三、五类插件(按你的需求选型)

类型注入/API用途
工具插件(最常见)ctx.tools.register(),schema 自动流入系统提示词给模型新增能力(读文件、查库、调 API…)
服务插件ctx.provide('myService', impl)+ 消费方ctx.inject(['myService'])在工具/其他插件之间共享状态,如dsh-sessiondsh-jobs-local
Skill 插件ctx.skills.register(...)dsh-skill-filesystem目录给 agent 注入指令/方法论(比工具轻量,不进工具列表)
客户端 UI 插件dsh-client-*系列,ctx.slots.register(React)自定义 Web 界面(会话卡片、设置页、工具调用展示)
Host 插件ctx.get('webserver')/apiproxy/frontend-static起服务、挂路由、托管静态资源
组合包 bundle包内cordis.patch.yml把一组插件+配置打包成可复用发行单元

工具自带 UI 呈现用presentCall/presentResult返回 card 意图(generic/terminal/read/diff/search/web),UI 无需按工具名写特例。

四、标准开发流程(六步)

1. 初始化工程

mkdirdsh-my-plugin&&cddsh-my-pluginnpminit-ynpmi-Dtypescript tsup @deepseek-ai/cordis @deepseek-ai/dsh-tools @deepseek-ai/schemastery# package.json: "type": "module", "main": "lib/index.js", "types": "lib/index.d.ts"

2. 写插件(见上文模板)

3. 构建

tsup lib/index.ts--formatesm--dts--out-dir lib

4. 本地安装到 profile(两种方式)

# 方式 A:发布后安装dsh plugin--profilewebadddsh-my-plugin# 方式 B:本地开发(推荐,file: 引用即改即用)cd~/.dsh/profiles/webpnpmaddD:\path\to\dsh-my-plugin

5. 注册进加载树——编辑~/.dsh/profiles/web/cordis.patch.yml

# 当前你的文件是 [],改成:-insert:-id:my-pluginname:dsh-my-pluginconfig:greeting:你好

要点:id是 patch 寻址键(后续可用- id: my-plugin+config:覆盖);name必须是 profile 依赖里真实存在的模块说明符。文件热重载(watchUserPatches),改了立即生效,无需重启——但首次安装包后需要重启dsh web

6. 验证

dsh web --dump-config# 离线合成配置树,确认你的行已合入# 或进入会话后让模型执行 cordis_inspect(自省工具,列出全部已注册工具/服务/插件 fiber)

五、"专业标准完整"插件清单(对标dsh-tool-todo/dsh-tool-pwsh

源码里第一方工具普遍具备以下工程素养,照做即是"专业标准":

  1. 名称纪律:包名dsh-*(第三方常dsh-*dsh-plugin-*),插件namekebab-case 唯一,工具名 snake_case 且描述首句就是完整指令(模型看到的第一句决定它会不会用)。
  2. Config 带默认值 + 部署语义z.object({ allowParallel: z.boolean().default(true) })——配置是部署者政策,不是插件内部细节;配置变更记录进描述(如 todo 的并行策略会改写工具描述)。
  3. 类型化参数与严格 schemadefineTool参数用ParameterSchemaSpecadditionalProperties: false封闭对象,让模型写错即失败(INVALID_ARGS),而不是静默吞掉。
  4. 规范化输出契约:输出{ schema, render, presentationMeta? };值(机器消费)与呈现(模型消费)分离;render是纯函数,UI 流式回放时会反复调用。
  5. 错误即结果:可预期的失败返回{ isError: true, error: { message, info } }而不是抛异常;基础设施失败才抛HarnessError(带name/code)。
  6. 协作取消execute(args, exec)必读exec.signal,把signal透传给底层(readFile(path, { signal })fetch(url, { signal })),绝不在已启动的 Promise 未结算时提前返回。
  7. 并发安全声明:可并发的工具实现isConcurrencySafe(args)返回 true;共享状态竞态必须可交换,否则拒绝。
  8. 状态写入会话日志而非内存:持久状态用exec.agent.session.append('my/write', data)(事件溯源),重放/UI 都从事件渲染(todo 的todos投影就是这么做的)。
  9. 文档与双语文案README.md+README.zh.md(含配置表、公开 API、扩展点、模型体验、KV Cache 影响、已知限制)。
  10. 测试与门禁:schema 验证、执行器单测、verify门禁(如verify-cordis-catalog防止契约漂移)。

六、调试与快速原型三板斧

  • 动态插件(零安装验证):会话里让模型执行cordis_define(提交 host 半 + 可选浏览器半)→cordis_run沙箱求值 →cordis_stop/cordis_undefine原型验证用这个,正式落地再走上面六步。注意:动态包不跨重启、不写文件、不会自动变成正式插件。
  • 配置排障dsh web --dump-config看最终组合树;--dump-default-config看 bundle 层(不含你的 patch)。
  • HMR:改cordis.patch.yml秒级生效;改插件源码需重新 build + 依赖引用为file:时自动跟随。

七、安全边界(必须知道,否则插件不合格)

  • 沙箱:文件操作经dsh-fs-sandbox(当前workspace-write);命令经dsh-bash-sandbox/dsh-pwsh-sandbox。插件不能绕过,只能走sandbox_permissions升级通道(需用户批准)。
  • 审批 seamctx.get('approval')ask/deny/allow);未部署时ask退化为拒绝——插件必须把拒绝当正常路径处理。
  • 作用域:普通上下文注册 = 全局;agent.ctx注册 = 仅该 agent 并遮蔽同名全局。ctx.tools.restrict()是可见性组合,不是权限边界
  • 内容替换不是保密边界:编程消费方不能收到的值,要阻止或替换(post-execute),不能指望 finalizeContent 兜底。

八、实践路径

如果你的环境已就绪(dshCLI、web profile、cordis_inspect自省工具都在)。最省事的上手路线:

  1. cordis_define/cordis_run在会话里验证一个 30 行的工具原型(比如"读 Excel 并统计");
  2. 原型通过后,按第四节的六步把它工程化成一个dsh-<name>npm 包,file:依赖挂进~/.dsh/profiles/web
  3. cordis.patch.yml插入一行即可被当前 Web 会话加载。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 4:05:08

PT助手Plus上手指南:把PT站点的种子下载变成一次点击

PT助手Plus上手指南&#xff1a;把PT站点的种子下载变成一次点击 【免费下载链接】PT-Plugin-Plus PT 助手 Plus&#xff0c;为 Microsoft Edge、Google Chrome、Firefox 浏览器插件&#xff08;Web Extensions&#xff09;&#xff0c;主要用于辅助下载 PT 站的种子。 项目地…

作者头像 李华
网站建设 2026/8/24 4:03:31

一条命令装好第一个 Codex 技能:Agent Skills 实战入门

一条命令装好第一个 Codex 技能&#xff1a;Agent Skills 实战入门 【免费下载链接】skills Skills Catalog for Codex 项目地址: https://gitcode.com/GitHub_Trending/skills4/skills 上周一个 PR 里堆了 20 条 review 评论&#xff0c;逐条翻找处理很耗时间&#xff…

作者头像 李华
网站建设 2026/8/24 3:58:03

从一道CSP-J真题出发:聊聊贪心排序与计数排序

题源&#xff1a;洛谷 P14357 [CSP-J 2025] 拼数 / number&#xff08;民间数据&#xff09; 背景 在算法竞赛和日常刷题中&#xff0c;有一类问题看似是"字符串处理"&#xff0c;本质上却是排序思想的灵活运用。这类问题里&#xff0c;最常被低估、也最容易让人&qu…

作者头像 李华
网站建设 2026/8/24 3:57:01

小户型可折叠跑步机怎么选?十款机型收纳与实用性盘点

开篇引言小户型买跑步机&#xff0c;最纠结的两件事是&#xff1a;放不放得下&#xff0c;以及搬不搬得动。很多人在"占地小"和"跑得稳"之间摇摆——机器太轻巧&#xff0c;跑起来可能晃动&#xff1b;机器太重&#xff0c;收纳挪位又费劲。其实这两件事并…

作者头像 李华
网站建设 2026/8/24 3:56:47

curl 邮件协议实战:SMTP、POP3、IMAP 几分钟完整上手

curl 邮件协议实战&#xff1a;SMTP、POP3、IMAP 几分钟完整上手 【免费下载链接】curl A command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, …

作者头像 李华