DeepSeek Harness 插件开发简易指南(保姆级教程)

  发布时间:2026-08-26 09:57:48   作者:由数入道   我要评论
这篇文章给大家介绍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--patch overlay。后层按 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 —— 一个最小但完整的工具插件
import z from '@deepseek-ai/schemastery'
import { defineTool } from '@deepseek-ai/dsh-tools'
export const name = 'my-tool'            // 插件名(kebab-case,全局唯一)
export const inject = ['tools']          // 声明注入的服务键,Loader 据此排序
export const Config = z.object({         // schemastery 配置 schema(可留空对象)
  greeting: z.string().default('Hello from my plugin'),
})
export function apply(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 }],
    },
    async execute(args, exec) {
      // exec.signal 必填且只读——必须观测/转发取消信号
      const msg = `${config.greeting}, ${args.name}!`
      return args.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. 初始化工程

mkdir dsh-my-plugin && cd dsh-my-plugin
npm init -y
npm i -D typescript 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 --format esm --dts --out-dir lib

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

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

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

# 当前你的文件是 [],改成:
- insert:
    - id: my-plugin
      name: dsh-my-plugin
      config:
        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-*),插件 name kebab-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 兜底。

八、实践路径

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

  1. cordis_define/cordis_run 在会话里验证一个 30 行的工具原型(比如"读 Excel 并统计");
  2. 原型通过后,按第四节的六步把它工程化成一个 dsh-<name> npm 包,file: 依赖挂进 ~/.dsh/profiles/web
  3. cordis.patch.yml 插入一行即可被当前 Web 会话加载。

到此这篇关于DeepSeek Harness 插件开发简易指南(保姆级教程)的文章就介绍到这了,更多相关DeepSeek Harness 插件开发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

相关文章

最新评论