前言¶
DeepSeek Harness(dsh)的核心理念是「一切皆插件」:模型、工具、會話、沙箱、調度,乃至界面,都可以在 Cordis 內核上組合或替換,而不必去改 Harness 源碼。官方倉庫 deepseek-ai/deepseek-harness 把這件事寫得很清楚。
插件能「加能力」,並不等於插件能「改別人的能力」。一個社區插件如果想在不 fork、不改對方源碼的前提下,改寫另一個插件裏某個函數的參數或返回值,官方插件機制通常到不了這一層。Minecraft 生態裏,Fabric 用 Mixin 在加載期改寫遊戲代碼,原版 JAR 可以保持不動。社區插件 fabric 做的就是同一類事情,只不過目標從遊戲模組換成了 DSH / Cordis 插件。
本文介紹的是社區目錄裏的 fabric,不是 DeepSeek 官方應用。目錄站點 deepseek-harness-plugin.com 是獨立收錄站,與 DeepSeek / 幻方沒有官方從屬關係。
fabric 是什麼¶
fabric 是一款 工具與能力 類 DSH 插件,由 GitHub 組織 omdsh-dev 維護,倉庫地址是 omdsh-dev/fabric。目錄頁一句話定位是:「一種類似 MC Fabric 的 hook 處理器。」
倉庫自述更完整:它是一套面向 DSH 的 Fabric / Mixin 擴展層,結構對齊上游 fabric 的三包拆分,再加一個可安裝的 profile bundle 載體。根包名是 cordis-fabric-bundle,當前版本 0.0.3,主要語言是 TypeScript。GitHub 主題標了 dsh 和 dsh-plugin。目錄頁 2026-08-09 收錄,當時顯示 9 星;截至 2026-08-17,GitHub 倉庫星標爲 14。
它要解決的問題可以壓成一句:讓受信任的插件在加載期對目標模塊做代碼變換,從而在不修改對方源碼的情況下掛鉤子。它不是給模型用的工具,也不是給聊天窗口加按鈕;底層變換本身不產生任何模型可見內容。
核心功能¶
倉庫裏只有三個完整包,三包之外的改動(例如官方 @deepseek-ai/dsh-tool-cordis 的行爲修正)一律放在 patches/ 裏做 pnpm 依賴補丁,不會再拆第四個包。
1、cordis-fabric:純 Cordis 的加載期變換服務。 提供 FabricService、bootstrapFabric、Orchestrion 變換、Node loader hooks、bridge、瀏覽器 transform 和 testkit。這個包不導入任何 DSH 模塊。受信任插件通過 ctx.fabric.register() 註冊 patch,可以對目標函數做四種操作:
before:在原函數體執行前改寫參數after:觀察或替換成功結果(含異步 settlement 之後)around:決定原函數體是否執行,可通過invoke()委託replace:完全接管調用;只有 handler 調用invoke()時才跑原函數體
機制是加載期代碼變換:transform hook 把目標函數體重寫爲向進程內 bridge 發調用記錄,runtime 再分發給當前註冊的 handler。沒有活躍 handler 時,變換後的代碼原樣委託給原函數體。
2、cordis-fabric-api:協作式兼容門面。 只 peer 依賴 Cordis 和 cordis-fabric,提供 FabricCompatService 和 buildCompatInstrumentations。文檔把它比作 Minecraft Fabric API 那一層:在 loader 與 Mixin 之上,給 Mod 一個相對穩定的註冊入口。bundle 不會自動掛這一行,需要 Mod 自己 import FabricCompatService from 'cordis-fabric-api'。
3、cordis-fabric-dsh:DSH 集成包。 對外暴露 ctx.fabricAgent、ctx.fabricTools、ctx.fabricPrompt、ctx.fabricCommands,瀏覽器側是 ctx.fabricClient,另外還有包 invariant 和 profile bootstrap(installFabricBootstrap)。這些 facade 把 prompt、tools、commands、agent 事件和瀏覽器 command/slot 註冊委託給權威 DSH 服務,不另存一份領域狀態,也不能繞過權限、審批、超時、日誌或取消語義。
bundle 往 profile 裏插入的兩行默認都是禁用的 opt-in:
- id: cordis-fabric
name: 'cordis-fabric'
disabled: true
- id: cordis-fabric-dsh
name: 'cordis-fabric-dsh'
disabled: true
裝上 bundle 不等於 Fabric 層已經生效。需要在 profile 組合裏啓用這兩行,並且用倉庫提供的 fabric-dsh 啓動器注入 loader hooks。直接跑官方 dsh 只走官方代碼,不會激活 Fabric hooks。
信任模型也寫得很硬:patch handler 是通過 ctx.fabric.register() 綁上去的受信任代碼;可執行 handler 不會從 YAML 或模型輸入裏反序列化。cordis_mount 臨時插件和 repository 插件在獲得顯式授權前不得使用 Fabric 能力。
安裝與啓用¶
社區目錄頁給出的安裝命令如下,在 DeepSeek Harness 終端裏運行:
dsh plugin add github:omdsh-dev/fabric
目錄頁同時說明:如需可復現安裝,可以固定 commit 哈希:
dsh plugin add github:omdsh-dev/fabric#<commit>
把 <commit> 換成倉庫裏實際的提交哈希。不要憑空編一個。
倉庫英文 README 當前推薦的是官方 bundle 插件通道 + 預構建 Release 產物(GitHub Release v0.0.3 裏確有 pkg.tgz):
dsh plugin add https://github.com/omdsh-dev/fabric/releases/latest/download/pkg.tgz
裝完後重啓 web 應用,再在 profile 組合中啓用 cordis-fabric / cordis-fabric-dsh。
這裏有一處來源不一致,需要按一手資料處理,不要混用過期命令:
- 目錄頁寫的是
github:omdsh-dev/fabric - 英文 README 寫的是上面這條
pkg.tgz地址 - 中文 README 仍寫
dsh plugin --profile web add github:dsh-external/fabric - 根
package.json裏三個運行時依賴也指向github:dsh-external/fabric#main&path:/packages/...
安裝前以目錄頁命令和倉庫當前英文 README 交叉覈對;中文 README 與 dsh-external/fabric 這條路徑是否仍可用,以倉庫當時狀態爲準,不要默認它們已經合併成同一個安裝入口。
Fabric 層要真正掛鉤,load-time 變換必須趕在任何目標模塊 import 之前。bundle 自帶 fabric-dsh 啓動器做這件事,宿主源碼保持不動(patches/README.md 寫明宿主補丁目前是空的)。profile 裝好之後,可以直接跑 profile 裏的 bin:
# 針對純官方 deepseek-harness checkout
$DSH_HOME/profiles/web/node_modules/.bin/fabric-dsh \
--harness <deepseek-harness-checkout> web --port 8000
$DSH_HOME 和 profile 名從安裝路徑推導。開發形態仍可用:
node /scripts/fabric-dsh.mjs --harness <deepseek-harness-checkout> --profile web
如果是從本倉庫做首次準備,README 給出的入口是:
pnpm run install:host -- <deepseek-harness-checkout> --dsh-home "$HOME/.dsh_dev"
這條腳本會裝宿主依賴並構建、播種 profile、走官方插件通道裝 bundle,並啓用 cordis-fabric-dsh 行。patches/README.md 裏的示例把 --dsh-home 寫成 $HOME/.dsh_dev,這是文檔裏的路徑,不是必須用這個目錄。
啓動是否走了 Fabric,看 stderr:hooks 裝好時會打 fabric-dsh: 標記,隨後打印 hook 彙總,列出每條 patch 及其命中的目標文件。
典型用法¶
下面兩段都來自倉庫文檔,不是虛構場景。
1. 用受信任插件註冊一條 before patch
文檔示例:在目標包 @example/target-package 的 lib/index.js 裏,攔截同步函數 greet,把第一個參數改成大寫。插件需要聲明 inject = ['fabric']:
import type { Context } from 'cordis'
import type { FabricCall, FabricService } from 'cordis-fabric'
export const inject = ['fabric']
export function apply(ctx: Context & { fabric: FabricService }): void {
ctx.fabric.register({
id: 'my-vendor/rewrite-greeting',
target: {
module: '@example/target-package',
versionRange: '^1.0.0',
filePath: 'lib/index.js',
functionQuery: { functionName: 'greet', kind: 'Sync' },
},
operation: 'before',
handler(call: FabricCall) {
call.arguments[0] = String(call.arguments[0]).toUpperCase()
},
})
}
靜態描述符可以寫在用戶 overlay(例如 $DSH_HOME/config.yaml 或 --config 文件)的 config.fabric.patches 下,但那裏只放 id / target / operation。handler 不寫在 YAML 裏,必須由插件在運行時通過 ctx.fabric 綁定。
2. 走協作層,而不是直接碰 Mixin
文檔建議 Mod 只聲明自己消費的 service。下面這個例子監聽 agent 狀態,並往 system prompt 里加一節:
import type { Context } from 'cordis'
import type { FabricAgentService, FabricPromptService } from 'cordis-fabric-dsh'
export const name = 'my-mod'
export const inject = ['fabricAgent', 'fabricPrompt']
export function apply(
ctx: Context & {
fabricAgent: FabricAgentService
fabricPrompt: FabricPromptService
},
): void {
ctx.fabricAgent.onStatus((agent, status) => {
ctx.logger.info('agent %s is %s', agent.id, status)
})
ctx.fabricPrompt.section({
name: 'my-mod-identity',
order: -80,
text: 'my-mod is active',
})
}
掛載 Host bundle 本身也很直接:
import * as fabricDsh from 'cordis-fabric-dsh'
import type { Context } from 'cordis'
declare const ctx: Context
await ctx.plugin(fabricDsh)
對應的 profile overlay 是把 cordis-fabric-dsh 行打開:
- id: cordis-fabric-dsh
disabled: false
協作層公開表面不導出 AST selector、模塊文件路徑或原始 bridge handle。底層 ctx.fabric patch 仍是 Mixin 子系統的逃生艙,不是這一層契約的一部分。
適用場景與注意事項¶
適合誰:已經在用源碼形態 DeepSeek Harness、需要給其他插件做加載期掛鉤的插件作者。如果你只是想給智能體加一個計算器、搜索或通知,普通 DSH 插件就夠了,不必上 Fabric。
使用前先看這幾條邊界,都來自倉庫 README 和文檔,不是推測。
-
啓動器限制。 npm 安裝的官方
dsh跑不了fabric-dsh:CLI 是預構建產物,沒有可 preload 的源碼入口。源碼 checkout 通過fabric-dsh啓動。README 寫到,等官方倉庫合入接線後,這類宿主才能用(拆分提交65bcaf9902已包含接線,但是否已合入上游,以當時官方倉庫爲準)。 -
運行時要求。 根
package.json聲明node爲^22.19.0 || >=24.0.0,包管理器是pnpm@11.7.0。Node 加載期變換要求預編譯 JavaScript;把原始.ts交給 Node load hook 會失敗。瀏覽器路徑會在應用 handler 前剝離 TypeScript。 -
Git 依賴與 SSH。 英文 README 仍寫:pnpm 通過 SSH 解析 GitHub 依賴,安裝機器需要對
dsh-external/fabric有 GitHub SSH 訪問權。若你走的是pkg.tgz,也要覈對該 tarball 解包後的依賴是否還指向這個倉庫。 -
權限與安全。 目錄頁和技能要求寫明的那條同樣適用:插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前請檢查源代碼倉庫和許可證。變換後的代碼在目標模塊內擁有進程級權限。目標校驗失敗會在註冊時拋出;格式正確但匹配不到任何文件時,模塊保持未變換(靜默)。
required: true的 patch 在啓動完成後若從未改寫過任何東西,會 loud 失敗。 -
許可證。 根
package.json聲明BSD-3-Clause。GitHub 倉庫元數據裏license字段爲空,根目錄文件列表裏也沒有獨立的LICENSE文件。以倉庫當時聲明爲準,安裝前自行覈對。 -
不要把它當成模型可寫配置。 低層 transformer 不產生模型可見內容;handler 不能從模型輸入反序列化。協作層註冊的 tool / prompt / command 是否對模型可見,完全取決於它委託的權威 DSH 服務。
小結¶
fabric 把 Minecraft Fabric 那套「加載期掛鉤、不改原版」搬到了 DeepSeek Harness 上:三包拆分、默認禁用、handler 只走受信任代碼。它面向的是要改其他插件行爲的宿主開發者,不是日常聊天增強。裝目錄命令只是第一步,真正生效還要啓用 profile 行,並用 fabric-dsh 而不是普通 dsh 啓動。
目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/fabric/
GitHub:https://github.com/omdsh-dev/fabric