AllDSH

进阶 · 1 分钟读完 · 更新于 2026-09-06

构建 DSH 插件:从空目录到成功加载

一份实用的 DeepSeek Harness 插件构建指南,从包结构搭建到 apply(ctx) 入口点,再到本地测试。

作者 AllDSH 编辑部 · 编辑团队

负责维护本站目录中的验证等级、分类与安装命令。 ·

构建一个 DSH 插件,更接近于写一个小型库,而不是给一个封闭应用写扩展。你需要一个包、一个入口点,以及一份 dshTarget 声明。本指南会依次走完这三件事,然后演示如何在真实会话中测试结果。

插件到底是什么

插件就是一个导出 apply(ctx) 函数的包。harness 在启动时用一个上下文对象调用它,你注册的一切都经由这个对象完成:工具、命令、界面区域、事件处理器。当插件被卸载时,运行时会销毁你注册过的东西。

这种设计意味着你永远不需要伸手去动全局状态。如果你的插件只有靠修改它并不拥有的东西才能工作,那么它在下一个版本上就会坏掉。

第 1 步:创建包

mkdir my-dsh-plugin && cd my-dsh-plugin
npm init -y
npm pkg set type=module
npm pkg set name=dsh-my-plugin

加上生态话题标签,方便日后被目录站点发现,同时在 README 和包元数据里声明你所针对的 harness 版本:

{
  "name": "dsh-my-plugin",
  "type": "module",
  "keywords": ["dsh-plugin", "deepseek-harness"],
  "dsh": { "target": "rc.6" }
}

第 2 步:编写 apply(ctx)

从一个最小可用的插件开始:一个模型可以调用的工具。

import type { Context } from '@deepseek-ai/dsh';

export function apply(ctx: Context) {
  ctx.tool({
    name: 'word_count',
    description: 'Count words in a piece of text.',
    parameters: {
      type: 'object',
      properties: { text: { type: 'string', description: 'Text to count' } },
      required: ['text'],
    },
    async execute({ text }: { text: string }) {
      const words = text.trim().split(/\s+/).filter(Boolean).length;
      return { words };
    },
  });
}

这段代码里有三点值得注意。description 是写给模型看的,不是写给人看的,因为模型正是靠它来决定要不要调用这个工具。参数 schema 必须写明确,含糊的 schema 会带来糟糕的调用。返回值是结构化数据,而不是格式化好的字符串,因为调用方通常要基于它做推理。

第 3 步:不只注册工具

工具是最常见的接入面,但不是唯一的一个。想清楚你需要哪种接入面,然后通过 ctx 注册:

  • 命令,用于你自己从输入框触发的操作。
  • 事件,用于响应会话生命周期的变化。
  • 界面区域,如果你做的是 UI 而不是能力。
  • 能力接缝,当你为别的插件所消费的东西提供实现时,比如一个记忆提供方。

第 4 步:在真实会话里测试

在包含插件源码的目录下,把它装进 web profile:

dsh plugin --profile web add /absolute/path/to/my-dsh-plugin

然后启动 harness,检查两件事:插件是否无报错地加载,以及模型在合适的场合是否真的会调用你的工具。一个存在但从未被选中的工具,通常问题出在描述上,而不是代码上。

第 5 步:诚实地处理失败

插件的失败应该是可读的。如果一次工具调用无法完成,请返回一个明确指出缺了什么的错误,而不是返回空结果。如果你的插件需要配置,就在加载时失败并说明缺少哪个字段,而不是等到三个会话之后第一次使用时才失败。

第 6 步:把契约写下来

发布之前,写清楚你依赖什么:你注册的能力、你需要的权限、你所针对的 harness 版本。这份文档正是一个目录站点准确收录你所需要的信息,也是审阅者信任这个插件所需要的信息。

FAQ

必须用 TypeScript 吗?

不是必须,但上下文对象的类型定义能挡掉人们写第一个插件时的大多数错误。

一个插件可以依赖另一个插件吗?

可以间接依赖,通过能力接缝。插件之间直接私有导入会在升级时坏掉,还会带来加载顺序问题。

不发布到 npm 该怎么测试?

从本地路径安装,如第 4 步所示。harness 会像对待任何其他包一样对待本地目录。

什么时候该抬高 dshTarget?

每当你采用一项新的运行时能力时。声明一个比你实际需要更新的目标版本,只会把使用旧版本的用户挡在门外,而没有任何好处。

下一步

阅读 Cordis 插件生命周期来理解销毁与加载顺序,然后把你的插件发布并提交到目录站点。

来源与参考

本页的技术判断建立在以下第一手资料之上,链接可直接追溯核对。

  1. [1]deepseek-ai/deepseek-harness — GitHubDeepSeek Harness、Cordis 运行时与插件加载模型的上游仓库。
  2. [2]@deepseek-ai/dsh on npm — npm已发布的 harness 包,也是本站 dshTarget 字段跟踪的版本来源。
  3. [3]About semantic versioning — npm Docs兼容性与 dshTarget 建议所依据的版本号约定。
  4. [4]Keep a Changelog 1.1.0 — Keep a Changelog建议插件采用的可维护变更日志约定。

全部链接最后核验于 2026-09-11

ESC

Type to search the index. Built at deploy time by Pagefind.