Cordis 入門
Cordis は、DeepSeek Harness の基盤となるベンダー提供のプラグインフレームワークです。この入門では、ハーネスプラグインの作成者がサブシステムページにある生成済みのサービス/イベントリファレンスを読む前に必要となる Cordis の概念を説明します。Cordis チュートリアルでは、同じ概念を実践的に解説しています。ベンダー提供のソースと同期手順は、vendor/README.mdにあります。
Cordis の 5 つの考え方
- プラグインは Service を実装するオブジェクトです。 オプションの
injectフィールドとapply(ctx)フィールドを持つ関数、またはライフサイクルを Cordis が現在のコンテキストにマウントするServiceのサブクラスにできます。 - コンテキストはサービスのリポジトリです。 サービスは、コンテキスト内で
ctx.<key>、ctx.tools、ctx.llmなどの安定したctx.sessionsを確保します。ほかのプラグインは具体的な実装をインポートする代わりに、キーでサービスを見つけます。 - サービス依存関係は
injectで宣言します。 必要なサービスを指定するプラグインは、それらのサービスが存在するまで待機します。そのため、手動の起動シーケンスではなくサービス要件によってロード順序を表現できます。 - 通信には型付きイベントを使用します。 サービスは TypeScript の宣言マージによってイベント名を宣言し、リスナーが監視、ラップ、ファンアウト、または順番に実行するかに応じて、
emit、waterfall、parallel、serialとしてディスパッチします。 - 登録は元に戻せる副作用です。 プロンプトセクション、ツールスキーマ、アダプター、プロバイダー、リスナーは
ctx.effect()またはctx.on()を通じてインストールされるため、リロードと破棄で予測どおりに解除されます。
ディスパッチモード
各イベントには以下のいずれかのディスパッチモードを設定でき、それに応じてこれらのメソッドでのみディスパッチできます。
| モード | Await されるか | ディスパッチ順序 | 戻り値があるか |
|---|---|---|---|
emit | いいえ | リスナーは登録順に監視します | いいえ |
waterfall | いいえ | リスナーは登録順に監視します | はい |
parallel | はい | すべてのリスナーがイベントを並列に監視します | いいえ |
serial | はい | リスナーは登録順に監視します | はい |
ディスパッチモードはイベントの公開契約の一部です。新しいハーネスイベントでは@modeタグでこれを記録し、生成済みカタログが宣言とディスパッチ箇所を照合できるようにします。
Cordis の Waterfall セマンティクス
ctx.waterfallは around ミドルウェアです。リスナーは(...args, next)を受け取ります。next()を呼び出すと、必要に応じてラップされた結果を次のサービスに委譲できます。next()を呼び出さずに return すると、ショートサーキットします。値はnext()の戻り値を通じて伝播します。
協調するリスナーは通常、共有リクエストまたは決定オブジェクトを変更してから委譲します。リスナーは結果全体を置き換えることもでき、下流のリスナーには置き換え後の結果だけが見えます。リスナーを通常の登録より先に実行する必要がある場合にのみ、prepend: trueを使用してください。
単一決定イベントでは、ショートサーキットが設計意図です。ポリシーリスナーは決定を担う場合、next()を呼び出さずに return できます。一方、注釈付けまたは監視のみを行うリスナーは委譲する必要があります。
ローダー設定
@deepseek-ai/cordis-plugin-includeは!!jsを式ノードに解析します。ローダーは、エントリのconfig(宣言された注入が有効化された後、そのプラグインコンテキストを対象にします。ctx.serviceName)と、disabledフィールド(すべてのマウント判断時にローダーコンテキストを対象にします)を補間します。Include はターゲットの有効化までネストした行式を保持します。その他のエントリメタデータはリテラルのままです。環境によってプラグインを選択する場合はオーバーレイを使用してください。
実践ルール
振る舞いをプラグインにカプセル化します。ツールパイプラインイベントはctx.toolsに属し、モデルストリーミングはctx.llmに属し、ライブエージェントの協調はctx.agentsに属します。インターセプトとポリシーにはイベントを優先し、直接的な機能呼び出しにはサービスメソッドを優先してください。
すべての登録には disposer を用意します。ctx.effect()から disposer を返すか、それを代行する Cordis ヘルパーを使用してください。破棄順序が重要な場合は、関連する処理を 1 つの effect にまとめ、意図した順序で解除されるようにします。