DeepSeek Harness 第一个插件

2026-09-08 00:00    #AI   #工具   #DeepSeek  

在 Harness 中,插件是一个导出 apply 函数的 TypeScript 模块。框架加载插件时调用 apply,并传入 ctx(上下文对象)。

ctx(Context) 是框架传给每个插件的上下文对象,既是注册能力的入口(事件监听、工具、LLM 适配器),也记录了插件注册的一切资源。

最小插件:hello-plugin

 1// 文件路径:scratch-plugin/src/my-plugin.ts
 2import type { Context } from '@deepseek-ai/cordis'
 3
 4// name 是插件名,用于在日志与配置中标识这个插件
 5export const name = 'hello-plugin'
 6
 7// apply 是插件的入口:框架加载插件时调用它
 8export function apply(ctx: Context) {
 9  // 需要的依赖在 apply 执行前就已就绪
10  console.log('[hello-plugin] plugin loaded!')
11}

这段代码只做一件事:加载时打印一行日志,没有注册任何能力,但已经是一个合格的插件。

插件的三种形态

形态写法适用场景
函数形式导出独立的 apply 函数大多数插件,最简单直接
对象形式export default 一个带 name / inject / apply 的对象需要同时声明元信息时
类形式export default 一个 Service 子类插件需要向其他插件提供服务时

函数形式

1import type { Context } from '@deepseek-ai/cordis'
2
3export const name = 'my-plugin'
4
5export function apply(ctx: Context) {
6  // 在这里注册能力
7}

对象形式

1import type { Context } from '@deepseek-ai/cordis'
2
3export default {
4  name: 'my-plugin',
5  inject: ['tools'],
6  apply(ctx: Context) {
7    // ...
8  },
9}

类形式

 1import { Service, type Context } from '@deepseek-ai/cordis'
 2
 3export default class MyService extends Service {
 4  static inject = ['tools']
 5
 6  constructor(ctx: Context) {
 7    // 第一个参数是 ctx,第二个参数是服务名
 8    super(ctx, 'myService')
 9    // 同步初始化放在构造函数里
10  }
11}

怎么选

大多数情况下,函数形式就足够了。当插件需要向其他插件提供服务时,用类形式。类形式的核心是 super(ctx, '服务名')

服务与依赖的完整机制见 Service 基类与类型声明inject 声明依赖