Das erste Plugin für DeepSeek Harness

In Harness ist ein Plugin ein TypeScript-Modul, das eine apply-Funktion exportiert.

Das Framework ruft apply beim Laden des Plugins auf und übergibt ein ctx (Kontextobjekt).

Wir registrieren Fähigkeiten über ctx, wie Ereignis-Listener, Tools und LLM-Adapter.

ctxKontext ist das Kontextobjekt, das das Framework an jedes Plugin übergibt.

ctxEs dient sowohl als Einstiegspunkt zum Registrieren von Fähigkeiten als auch zum Aufzeichnen aller vom Plugin registrierten Ressourcen.


Erstellen Sie ein lokales Projekt

Zuerst müssen wir aus dem Quellcode installieren:

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

Erstellen Sie als Nächstes ein scratch-plugin-Projekt, das unser Plugin aufnimmt.

Im Stammverzeichnis des Repositorys ausführen:

mkdir -p scratch-plugin/src

Minimales Plugin: hello-plugin

Erstellen Sie my-plugin.ts unter scratch-plugin/src.

cd scratch-plugin/src

Nachfolgend finden Sie eine vollständige, nutzbare Plugin-Konfiguration – nichts fehlt.

Beispiel

// Dateipfad: scratch-plugin/src/my-plugin.ts
import type { Context } from '@deepseek-ai/cordis'

// name ist der Plugin-Name, der verwendet wird, um dieses Plugin in Protokollen und in der Konfiguration zu identifizieren.
export const name = 'hello-plugin'

// apply ist der Einstiegspunkt des Plugins: Das Framework ruft es beim Laden des Plugins auf.
export function apply(ctx: Context) {
  // Die erforderlichen Abhängigkeiten sind bereit, bevor apply ausgeführt wird (siehe Teil 9)
  console.log('[hello-plugin] Plugin geladen!')
}

Dieser Code macht nur eine Sache: Er gibt beim Laden eine Logzeile aus. Er registriert keine Fähigkeiten, ist aber bereits ein qualifiziertes Plugin.


Drei Formen des Plugins

Zusätzlich zur oben gezeigten Funktionsform unterstützen Plugins auch die Objektform und die Klassenform.

FormSyntaxAnwendbare Szenarien
FunktionsformEine unabhängige apply-Funktion exportierenFür die meisten Plugins ist dies der einfachste und direkteste Ansatz.
Objektformexport default ein Objekt mit name / inject / applyWenn Sie gleichzeitig Metadaten deklarieren müssen
Klassenformexport default eine Service-UnterklasseWenn ein Plugin anderen Plugins Dienste bereitstellen muss

Funktionsform

Das getrennte Exportieren von name und apply ist der Standardstil in den offiziellen Beispielen.

Beispiel

// Dateipfad: scratch-plugin/src/my-plugin.ts (Funktionsform)
import type { Context } from '@deepseek-ai/cordis'

export const name = 'my-plugin'

export function apply(ctx: Context) {
  // Fähigkeiten hier registrieren
}

Objektform

name, inject und apply in ein default-exportiertes Objekt setzen.

Beispiel

// Objektform: ein Default-Export-Objekt
import type { Context } from '@deepseek-ai/cordis'

export default {
  name: 'my-plugin',
  inject: ['tools'],
  apply(ctx: Context) {
    // ...
  },
}

Klassenform

Die Klassenform erbt von der Basisklasse Service und eignet sich für Plugins, die Dienste nach außen bereitstellen.

Beispiel

// Klassenform: Service-Unterklasse, kann Dienste nach außen bereitstellen
import { Service, type Context } from '@deepseek-ai/cordis'

export default class MyService extends Service {
  static inject = ['tools']

  constructor(ctx: Context) {
    // Der erste Parameter ist ctx, der zweite ist der Dienstname
    super(ctx, 'myService')
    // Synchrone Initialisierung in den Konstruktor legen
  }
}

Wie man wählt

In den meisten Fällen reicht die Funktionsform aus.

Wenn ein Plugin Dienste für andere Plugins bereitstellen muss, verwenden Sie die Klassenform.

Tipp: Der Kern der Klassenform ist super(ctx, 'service name').

Der vollständige Mechanismus von Diensten und Abhängigkeiten wird in Teil 14 behandelt.

插件结构与加载示意

Weitere Erweiterungen