如果 skill 像工作手冊,那 plugin 就比較像「系統的插槽和擴充卡」。
它不是單純給 agent 看的內容,而是會真的改變 OpenClaw 如何載入能力、如何記錄 install、如何啟用功能,甚至如何對待來源與信任。
第 28 天我想談的是:
plugin 在 ClawHub 裡到底扮演什麼角色?它跟 skill 為什麼都走 ClawHub,但又不是同一種東西?
這題很重要。
因為一旦你把 skill 和 plugin 混成同一種「安裝項目」,你就會很難理解為什麼有些東西裝進來只是讓 agent 多一本手冊,有些東西卻會讓整個系統多一個能力。
我會把 plugin 看成三層:
這三層組合起來,plugin 才算真的進到 OpenClaw。
skill 比較像「內容」;plugin 比較像「可執行的系統模組」。
所以 plugin 的關鍵問題不是「內容是不是對」,而是:
這個模組會不會影響 runtime 行為?它是不是能被正確啟用?它的來源可不可以被追蹤?
先看 onboarding plugin install 的主入口說明。
📄 原始碼:
src/commands/onboarding-plugin-install.ts(本機版本行號已變動,僅標到檔案)
/**
* Onboarding plugin installation flow.
*
* It selects local, ClawHub, npm, or override install sources; records durable
* install metadata; and enables plugins requested by setup workflows.
*/
這一小段註解其實已經把 plugin 角色講完一半了。
再看它怎麼決定來源。
📄 原始碼:
src/commands/onboarding-plugin-install.ts:1154-1184
type InstallChoice = "clawhub" | "npm" | "local" | "skip";
const clawhubSpec = resolveClawHubSpecForOnboarding(entry.install);
const npmSpec = resolveNpmSpecForOnboarding(entry.install);
const defaultChoice = resolveInstallDefaultChoice({
cfg: next,
entry,
localPath,
bundledLocalPath,
hasClawHubSpec: Boolean(clawhubSpec),
hasNpmSpec: Boolean(npmSpec),
});
這裡可以看到 plugin 的世界不是單一管道。
它可能來自:
這很合理,因為 plugin 有時候是官方發佈,有時候是開發中的本地版本,有時候甚至是操作員明確指定的 override。
再看 ClawHub 安裝時怎麼把結果轉成 install record。
📄 原始碼:
src/commands/onboarding-plugin-install.ts:951-977
if (result.ok) {
const enableResult = await applyPluginEnablement({
cfg: next,
pluginId: result.pluginId,
label: entry.label,
prompter,
runtime,
});
if (!enableResult.enabled) {
return {
cfg: enableResult.config,
installed: false,
pluginId: result.pluginId,
status: "failed",
};
}
next = enableResult.config;
next = recordPluginInstall(next, {
pluginId: result.pluginId,
...buildClawHubPluginInstallRecordFields(result.clawhub),
spec: clawhubSpecs?.recordSpec ?? clawhubInstallSpec,
installPath: result.targetDir,
});
}
這段很關鍵。
plugin 安裝不是只要 result.ok 就結束,還要:
這表示 plugin 在 OpenClaw 裡是「安裝後還要被治理」的東西。
再看 install record 本身存什麼。
📄 原始碼:
src/plugins/clawhub-install-records.ts:6-25
export type ClawHubPluginInstallRecordFields = {
source: "clawhub";
clawhubUrl: string;
clawhubPackage: string;
clawhubFamily: Exclude<ClawHubPackageFamily, "skill">;
clawhubChannel?: ClawHubPackageChannel;
clawhubTrustDisposition?: "clean" | "review-recommended" | "review-required" | "blocked";
clawhubTrustScanStatus?: string;
clawhubTrustModerationState?: string;
clawhubTrustReasons?: string[];
clawhubTrustPending?: boolean;
clawhubTrustStale?: boolean;
clawhubTrustCheckedAt?: string;
clawhubTrustAcknowledgedAt?: string;
version?: string;
integrity?: string;
resolvedAt?: string;
installedAt?: string;
artifactKind?: "legacy-zip" | "npm-pack";
artifactFormat?: "zip" | "tgz";
};
這裡已經不是一般「已安裝清單」的規模了。
它是一份 install provenance 的摘要。
OpenClaw 在意的不只是插件存在,而是:
再看 install record 的寫回。
📄 原始碼:
src/plugins/installs.ts:49-67
export function recordPluginInstall(
cfg: OpenClawConfig,
update: PluginInstallUpdate,
): OpenClawConfig {
const { pluginId, ...record } = update;
const previous = clearStaleInstallRecordFields(cfg.plugins?.installs?.[pluginId]);
const nextRecord = {
...previous,
...record,
installedAt: record.installedAt ?? new Date().toISOString(),
};
return {
...cfg,
plugins: {
...cfg.plugins,
installs: {
...cfg.plugins?.installs,
[pluginId]: nextRecord,
},
},
};
}
這代表 plugin install 是配置的一部分。
也就是說,plugin 不是臨時下載到某個資料夾就算結束,而是會進到 config 的世界,成為系統的一部分記錄。
最後再看 manifest 層怎麼定義 plugin 的身份。
📄 原始碼:
src/plugins/manifest.ts:160-183
export type PluginManifestActivation = {
onStartup?: boolean;
onProviders?: string[];
onAgentHarnesses?: string[];
onCommands?: string[];
onChannels?: string[];
onRoutes?: string[];
onConfigPaths?: string[];
onCapabilities?: PluginManifestActivationCapability[];
};
這個欄位很能說明 plugin 的角色。
plugin 不只是「能裝」,而是要告訴 core:
這就是 plugin 跟 skill 最本質的差異之一。
如果 skill 是一本工作手冊,那 plugin 是一塊真的插進主機板的模組。
因此 plugin 在 ClawHub 裡扮演的角色是:
你可以想像成:
這就是為什麼 plugin install 會比 skill install 更在意 config、record、activation、trust。
它不是一份內容包,而是一個會改變系統行為的組件。
但這樣才合理。
因為 plugin 真的就是系統層的能力,不可能像文章或手冊那樣單純。
這三天我一直在講 plugin 是「系統模組」、是 runtime 擴充。
但講到這裡,其實只回答了「它是什麼」,還沒回答一個更具體的問題:
所謂的 runtime 能力,到底是指什麼?plugin 拿得到、skill 拿不到的,是哪些東西?
明天我想挑其中最有份量的一項來看。那是一組 API,能讓 plugin 編排一連串跨越多個 agent 的工作,而且那些工作的進度可以活過整個系統重啟。
多 agent 協作不能只靠上下文,TaskFlow 補上調度這一層