Skip to content

Plugin internals

這是 OpenClaw 外掛系統的深度架構參考。如需實用指南,請從下方的專屬頁面開始。

Install and use plugins

新增、啟用及疑難排解外掛的終端使用者指南。

Building plugins

使用最小可運作清單的第一個外掛教學。

Channel plugins

建立訊息頻道外掛。

Provider plugins

建立模型提供者外掛。

SDK overview

匯入映射與註冊 API 參考。

功能是 OpenClaw 內部的公開原生外掛模型。每個原生 OpenClaw 外掛都會向一或多種功能類型註冊:

功能註冊方法範例外掛
文字推理api.registerProvider(...)openai, anthropic
CLI 推理後端api.registerCliBackend(...)openai, anthropic
嵌入api.registerEmbeddingProvider(...)供應商擁有的向量外掛程式
語音api.registerSpeechProvider(...)elevenlabsmicrosoft
即時轉錄api.registerRealtimeTranscriptionProvider(...)openai
即時語音api.registerRealtimeVoiceProvider(...)openai
媒體理解api.registerMediaUnderstandingProvider(...)openaigoogle
Transcripts 來源api.registerTranscriptSourceProvider(...)discord
圖像生成api.registerImageGenerationProvider(...)openaigooglefalminimax
音樂生成api.registerMusicGenerationProvider(...)googleminimax
影片生成api.registerVideoGenerationProvider(...)qwen
網頁擷取api.registerWebFetchProvider(...)firecrawl
網頁搜尋api.registerWebSearchProvider(...)google
頻道 / 訊息傳遞api.registerChannel(...)msteamsmatrix
閘道探索api.registerGatewayDiscoveryService(...)bonjour

功能模型已落地於核心,並由內建/原生外掛程式使用,但外部外掛程式相容性仍需比「只要已匯出,即已凍結」更嚴格的標準。

外掛程式情況指導原則
現有外部外掛程式讓基於 Hook 的整合繼續運作;這是相容性基準。
新的內建/原生外掛程式優先使用明確的功能註冊,而非供應商特定的深入存取或新的僅限 Hook 設計。
採用功能註冊的外部外掛程式允許使用,但除非文件標記為穩定,否則請將特定功能的輔助介面視為持續演進中。

功能註冊是預期的方向。在過渡期間,舊版掛鉤仍是外部外掛最安全的不中斷路徑。匯出的輔助子路徑並非完全同等——比起附帶的輔助匯出,優先選擇狹義且記載於文件的合約。

OpenClaw 根據每個已載入外掛的實際註冊行為(而不僅是靜態中繼資料)將其歸類為一種形態:

plain-capability

註冊單一能力類型(例如僅提供者外掛程式,如 mistral)。

hybrid-capability

註冊多種能力類型(例如 openai 擁有文字推論、語音、媒體理解和影像生成)。

hook-only

僅註冊掛鉤(型別或自訂),不包含功能、工具、指令或服務。

non-capability

註冊工具、指令、服務或路由,但不包含功能。

使用 openclaw plugins inspect <id> 查看外掛程式的形狀和能力細分。詳情請參閱 CLI 參考資料

before_agent_start hook 仍受支援,作為僅 hook 外掛程式的相容性路徑。舊版的實際外掛程式仍依賴它。

方向:

  • 維持其運作
  • 將其記載為舊版
  • 進行模型/提供者覆寫工作時,建議優先使用 before_model_resolve
  • 進行提示詞變異工作時,建議優先使用 before_prompt_build
  • 僅在實際使用率下降且測試覆蓋率證明移轉安全後才移除

當您執行 openclaw doctoropenclaw plugins inspect <id> 時,可能會看到下列其中一個標籤:

訊號含義
組態有效組態解析正常且外掛已解析
相容性建議外掛程式使用受支援但屬舊版模式(例如 hook-only
舊版警告外掛程式使用 before_agent_start,該功能已棄用
嚴重錯誤配置無效或外掛程式載入失敗

目前 hook-onlybefore_agent_start 都不會導致您的外掛程式中斷:hook-only 僅供參考,而 before_agent_start 只會觸發警告。這些訊號也會出現在 openclaw status --allopenclaw plugins doctor 中。

OpenClaw 的外掛程式系統包含四個層級:

  1. Manifest + discovery

    OpenClaw 會從設定路徑、工作區根目錄、全域外掛程式根目錄以及捆綁的外掛程式中尋找候選外掛程式。探索會先讀取原生 openclaw.plugin.json 資訊清單以及支援的捆綁資訊清單。

  2. 啟用 + 驗證

    核心會決定已探索到的外掛程式是已啟用、已停用、已封鎖,還是被選取用於記憶體等獨佔插槽。

  3. Runtime loading

    原生 OpenClaw 外掛程式會在程序內載入,並將功能註冊到中央註冊表中。封裝的 JavaScript 透過原生 require 載入;第三方本機原始碼 TypeScript 是緊急備用的 Jiti 回退機制。相容的捆綁包會被正規化為註冊表記錄,而不需匯入執行時期程式碼。

  4. 介面消耗

    OpenClaw 的其餘部分會讀取註冊表,以公開工具、通道、提供者設定、Hook、HTTP 路由、CLI 指令和服務。

具體來說,對於外掛程式 CLI,根指令探索分為兩個階段:

  • 解析時期的元資料來自 registerCli(..., { descriptors: [...] })
  • 實際的外掛程式 CLI 模組可以保持延遲載入,並在第一次叫用時註冊

這樣能讓外掛程式擁有的 CLI 程式碼保留在外掛程式內,同時仍讓 OpenClaw 在解析前保留根指令名稱。

重要的設計邊界:

  • 資訊清單/配置驗證應該能透過 資訊清單/結構描述元資料 運作,而無需執行外掛程式程式碼
  • 原生功能發現可能會載入受信任的外掛程式進入點程式碼,以建立非啟用的註冊表快照
  • 原生執行時期行為來自外掛程式模組的 register(api) 路徑以及 api.registrationMode === "full"

這種分離讓 OpenClaw 能在完整執行時期啟動之前驗證組態、解釋遺失/已停用的外掛程式,並建立 UI/綱要提示。

Gateway 啟動時會為目前的設定快照建立一個 PluginMetadataSnapshot。該快照僅包含元資料:它會儲存已安裝的外掛程式索引、資訊清單註冊表、資訊清單診斷、擁有者對應、外掛程式 ID 正規化器以及資訊清單記錄。它不會保留已載入的外掛程式模組、提供者 SDK、套件內容或執行時期匯出項。

外掛程式感知的設定驗證、啟動時自動啟用以及 Gateway 外掛程式啟動程序會使用該快照,而不是獨立重建資訊清單/索引元資料。PluginLookUpTable 衍生自同一個快照,並為目前的執行時期設定新增啟動外掛程式計畫。

啟動後,Gateway 會將當前的元資料快照保持為可替換的執行時產品。重複的執行時提供者探索可以借用該快照,而不必為每次提供者目錄傳遞重建安裝索引和清單註冊表。快照會在 Gateway 關機、配置/外掛程式清單變更以及安裝索引寫入時被清除或替換;當不存在相容的當前快照時,呼叫者會回退到冷清單/索引路徑。相容性檢查必須包含外掛程式探索根目錄(例如 plugins.load.paths)和預設代理程式工作區,因為工作區外掛程式是元資料範圍的一部分。

該快照和查找表讓重複的啟動決策保持在快速路徑上:

  • 通道擁有權
  • 延遲通道啟動
  • 啟動外掛程式 ID
  • 提供者和 CLI 後端擁有權
  • 設定提供者、命令別名、模型目錄提供者和資訊清單合約擁有權
  • 外掛程式組態綱要和通道組態綱要驗證
  • 啟動自動啟用決策

安全邊界是快照替換,而非變更。當配置、外掛清單、安裝記錄或持久化索引策略變更時,請重建快照。切勿將其視為廣泛的可變全域註冊表,也請勿保留無限的歷史快照。執行時期外掛載入與中繼資料快照保持分離,以免過時的執行時期狀態被隱藏在快取中。

快取規則記錄在 外掛程式架構內部細節 中:除非呼叫者持有當前流程的明確快照、查找表或清單註冊表,否則清單和探索元資料都是最新的。隱藏的元資料快取和牆時 TTL 不是外掛程式載入的一部分。只有在程式碼或安裝成品實際載入後,執行時載入器、模組和依賴成品快照才可能會持續存在。

某些冷路徑呼叫者仍然直接從持久的已安裝外掛程式索引重建清單註冊表,而不是接收 Gateway PluginLookUpTable。該路徑現在會按需重建註冊表;當呼叫者已經有查找表或明確的清單註冊表時,建議透過執行時流程傳遞當前查找表或明確的清單註冊表。

啟用規劃是控制平面的一部分。在載入更廣泛的執行時期註冊表之前,呼叫者可以詢問哪些外掛與具體指令、提供者、通道、路由、代理程式工具或功能相關。

規劃器保持與當前清單行為相容:

  • activation.* 欄位是明確的規劃器提示
  • providerschannelscommandAliasessetup.providerscontracts.tools 和 hooks 仍是清單所有權的後備方案
  • 僅限 ID 的規劃器 API 仍向現有呼叫者開放
  • 規劃 API 會回報原因標籤,以便診斷工具能區分明確提示與擁有權後備

通道插件無需為一般聊天動作註冊單獨的傳送/編輯/反應工具。OpenClaw 在核心中保留一個共用的 message 工具,而通道插件則擁有其後的特定通道探索與執行邏輯。

目前的邊界為:

  • 核心擁有共用的 message 工具主機、提示連接、會話/執行緒記帳以及執行分發
  • 頻道外掛程式擁有範圍動作的發現、功能發現,以及任何特定於頻道的結構描述片段
  • 頻道外掛程式擁有特定於提供者的會話對話語法,例如對話 ID 如何編碼執行緒 ID 或繼承自父對話
  • 頻道外掛程式透過其動作介面卡執行最終動作

對於通道插件,SDK 介面為 ChannelMessageActionAdapter.describeMessageTool(...)。這個統一的探索呼叫允許插件同時回傳其可見動作、能力和 Schema 貢獻,以便這些部分不會分離。

當特定通道的訊息工具參數攜帶媒體來源(例如本機路徑或遠端媒體 URL)時,插件也應從 describeMessageTool(...) 回傳 mediaSourceParams。核心使用該明確清單來套用沙箱路徑正規化和輸出媒體存取提示,而無需將插件擁有的參數名稱硬編碼。在該處偏好使用動作範圍的映射,而非一個通道範圍的扁平清單,這樣僅限檔案的媒體參數就不會在像 send 這類無關動作上被正規化。

核心將執行時範圍傳遞到該發現步驟。重要欄位包括:

  • accountId
  • currentChannelId
  • currentThreadTs
  • currentMessageId
  • sessionKey
  • sessionId
  • agentId
  • 信任的輸入 requesterSenderId

這對於上下文敏感的插件很重要。通道可以根據活動帳戶、目前房間/執行緒/訊息或信任的請求者身份來隱藏或公開訊息動作,而無需在核心 message 工具中硬編碼特定通道的分支。

這就是為什麼內嵌執行器路由變更仍是插件工作的原因:執行器負責將目前的聊天/會話身份轉發到插件探索邊界,以便共用的 message 工具為目前回合公開正確的通道擁有介面。

對於通道擁有的執行輔助程式,內掛插件應將執行運行時保留在其自己的擴充模組內。核心不再擁有 src/agents/tools 下的 Discord、Slack、Telegram 或 WhatsApp 訊息動作運行時。我們不發布單獨的 plugin-sdk/*-action-runtime 子路徑,內掛插件應直接從其擴充擁有的模組匯入自己的本機運行時代碼。

同樣的邊界通常也適用於提供者命名的 SDK 縫隙:核心不應匯入針對 Slack、Discord、Signal、WhatsApp 或類似擴充功能的通道特定便利匯入檔案桶。如果核心需要某種行為,請使用內掛插件自己的 api.ts / runtime-api.ts 匯入檔案桶,或者將需求提升為共享 SDK 中的狹窄通用能力。

內掛插件遵循相同的規則。內掛插件的 runtime-api.ts 不應重新匯出其自己的品牌 openclaw/plugin-sdk/<plugin-id> 外觀。這些品牌外觀仍然是外部插件和舊版使用者的相容性填充層,但內掛插件應使用本機匯出以及狹窄的通用 SDK 子路徑,例如 openclaw/plugin-sdk/channel-policyopenclaw/plugin-sdk/runtime-storeopenclaw/plugin-sdk/webhook-ingress。除非現有外部生態系統的相容性邊界有要求,否則新程式碼不應新增特定於插件 ID 的 SDK 外觀。

具體針對投票,有兩條執行路徑:

  • outbound.sendPoll 是適合常見輪詢模型的通道的共享基準
  • actions.handleAction("poll") 是通道特定輪詢語義或額外輪詢參數的首選路徑

核心現在會延遲共享投票解析,直到插件投票調度拒絕該動作之後,這樣插件擁有的投票處理程式就可以接受通道特定的投票欄位,而不會先被通用投票解析器阻擋。

請參閱 Plugin architecture internals 以了解完整的啟動順序。

OpenClaw 將原生外掛視為公司功能的擁有權邊界,而非雜亂無章的整合集合。

這意味著:

  • 公司外掛通常應擁有該公司所有面向 OpenClaw 的介面
  • 功能外掛通常應擁有其引入的完整功能介面
  • 通道應使用共享的核心功能,而非臨時重新實現提供者行為
Vendor multi-capability

openai 擁有文字推論、語音、即時語音、媒體理解和圖像生成。google 擁有文字推論以及媒體理解、圖像生成和網路搜尋。qwen 擁有文字推論以及媒體理解和影片生成。

Vendor single-capability

elevenlabsmicrosoft 擁有語音功能;firecrawl 擁有網路擷取功能;minimax / mistral / moonshot / zai 擁有媒體理解後端。

Feature plugin

voice-call 擁有呼叫傳輸、工具、CLI、路由和 Twilio 媒體串流橋接功能,但會使用共享的語音、即時轉錄和即時語音功能,而不是直接匯入廠商外掛程式。

預期的最終狀態是:

  • OpenAI 駐留在一個外掛中,即使它涵蓋了文字模型、語音、圖像和未來的影片
  • 其他供應商可以對其自己的功能範圍執行相同的操作
  • 通道不在乎哪個供應商外掛擁有該提供者;它們使用核心公開的共享功能合約

這是關鍵區別:

  • 外掛 = 擁有權邊界
  • 功能 = 多個外掛可以實現或使用的核心合約

因此,如果 OpenClaw 新增一個領域(例如影片),第一個問題不是「哪個供應商應該將影片處理邏輯硬編碼?」。第一個問題是「核心影片能力合約是什麼?」。一旦該合約存在,供應商插件便可以註冊該合約,而通道/功能插件則可以使用它。

如果該能力尚未存在,通常正確的做法是:

  1. 定義能力

    在核心中定義缺失的能力。

  2. 透過 SDK 公開

    透過插件 API/執行時以型別化的方式公開它。

  3. 連接消費者

    將通道/功能針對該能力進行連接。

  4. 供應商實作

    讓供應商插件註冊實作。

這使所有權保持明確,同時避免依賴單一供應商或特定於插件的一次性程式碼路徑的核心行為。

在決定程式碼歸屬時,請使用此心智模型:

共享的協調、策略、後備、配置合併規則、交付語意以及型別化合約。

例如,TTS 遵循此形狀:

  • core 擁有回覆時刻 TTS 策略、後備順序、偏好設定以及通道交付
  • openaielevenlabsmicrosoft 擁有合成實作
  • voice-call 使用電話 TTS 執行時期輔助程式

未來的能力應優先採用相同的模式。

企業外掛程式從外部來看應該感覺是渾然一體的。如果 OpenClaw 對於模型、語音、即時轉錄、即時語音、媒體理解、圖像生成、影片生成、網頁擷取和網頁搜尋都有共享合約,供應商就可以在一個地方擁有所有的介面:

import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry";
import { describeImageWithModel, transcribeOpenAiCompatibleAudio } from "openclaw/plugin-sdk/media-understanding";
const plugin: OpenClawPluginDefinition = {
id: "exampleai",
name: "ExampleAI",
register(api) {
api.registerProvider({
id: "exampleai",
// auth/model catalog/runtime hooks
});
api.registerSpeechProvider({
id: "exampleai",
// vendor speech config — implement the SpeechProviderPlugin interface directly
});
api.registerMediaUnderstandingProvider({
id: "exampleai",
capabilities: ["image", "audio", "video"],
async describeImage(req) {
return describeImageWithModel({
provider: "exampleai",
model: req.model,
input: req.input,
});
},
async transcribeAudio(req) {
return transcribeOpenAiCompatibleAudio({
provider: "exampleai",
model: req.model,
input: req.input,
});
},
});
api.registerWebSearchProvider(
createPluginBackedWebSearchProvider({
id: "exampleai-search",
// credential + fetch logic
}),
);
},
};
export default plugin;

重要的不是確切的輔助函式名稱。重要的是結構:

  • 一個外掛程式擁有供應商介面
  • 核心仍然擁有功能合約
  • 通道和功能外掛程式使用 api.runtime.* 輔助程式,而非廠商程式碼
  • 合約測試可以斷言外掛程式註冊了其聲稱擁有的功能

OpenClaw 已經將影像/音訊/影片理解視為一個共享功能。同樣的所有權模型也適用於此:

  1. 核心定義合約

    核心定義媒體理解合約。

  2. Vendor plugins register

    廠商外掛程式會視情況註冊 describeImagetranscribeAudiodescribeVideo

  3. 消費者使用共享行為

    通道和功能外掛程式使用共享的核心行為,而不是直接連線到供應商程式碼。

這樣可以避免將某個供應商的影片假設硬編碼到核心中。外掛程式擁有供應商介面;核心擁有功能合約和後備行為。

影片生成已經使用了相同的流程:核心擁有類型化功能合約和執行時期輔助程式,而廠商外掛程式會針對其註冊 api.registerVideoGenerationProvider(...) 實作。

需要具體的推出檢查清單?請參閱 Capability Cookbook

外掛程式 API 表面是有意設計為類型化並集中在 OpenClawPluginApi 中的。該合約定義了支援的註冊點以及外掛程式可能依賴的執行時期輔助程式。

為何這很重要:

  • 外掛程式作者獲得一個穩定的內部標準
  • 核心可以拒絕重複的所有權,例如兩個外掛程式註冊相同的供應商 ID
  • 啟動時可以針對格式錯誤的註冊提供可操作的診斷資訊
  • 合約測試可以強制執行套件外掛程式的擁有權,並防止無聲偏移

有兩層強制執行機制:

Runtime registration enforcement

外掛程式註冊表會在外掛程式載入時驗證註冊。例如:重複的提供者 ID、重複的語音提供者 ID,以及格式錯誤的註冊會產生外掛程式診斷資訊,而不是未定義的行為。

Contract tests

套件外掛程式會在測試執行期間被擷取到合約註冊表中,以便 OpenClaw 能明確宣告擁有權。目前這用於模型提供者、語音提供者、網路搜尋提供者,以及套件註冊擁有權。

實際效果是 OpenClaw 能預先知道哪個外掛程式擁有哪個介面。這讓核心和通道能無縫組合,因為擁有權是被宣告、具類型且可測試的,而不是隱含的。

  • 具類型
  • 小型
  • 特定於功能
  • 由核心擁有
  • 可由多個外掛程式重複使用
  • 可由通道/功能在無廠商知識的情況下使用

如果有疑問,請提高抽象層級:先定義功能,然後讓外掛程式插入其中。

原生 OpenClaw 外掛程式與閘道 在行程內 (in-process) 執行。它們未被沙箱化。已載入的原生外掛程式具有與核心程式碼相同的行程層級信任邊界。

相容的套件預設較為安全,因為 OpenClaw 目前將其視為中繼資料/內容套件。在目前的版本中,這主要指套件的技能。

對於非套件的外掛,使用允許清單及明確的安裝/載入路徑。將工作區外掛視為開發時期的程式碼,而非生產環境預設值。

對於打包的工作區套件名稱,請預設將外掛 ID 錨定在 npm 名稱中:@openclaw/<id>,或在該套件故意公開較狹隘的外掛角色時,使用經核准的類型後綴,例如 -provider-plugin-speech-sandbox-media-understanding

OpenClaw 匯出的是能力,而非實作便利性。

保持能力註冊為公開。修剪非合約的輔助匯出:

  • 套件外掛專屬的輔助子路徑
  • 非意圖作為公開 API 的執行期管道子路徑
  • 供應商特定的便利輔助程式
  • 屬於實作細節的設置/入門輔助程式

保留的打包外掛輔助子路徑已從產生的 SDK 匯出對應表中移除。請將擁有者專用的輔助工具保留在擁有外掛套件內;僅將可重複使用的主機行為提升為通用 SDK 合約,例如 plugin-sdk/gateway-runtimeplugin-sdk/security-runtimeplugin-sdk/plugin-config-runtime

如需關於載入管線、登錄模型、提供者執行階段掛鉤、Gateway HTTP 路由、訊息工具架構、通道目標解析、提供者目錄、內容引擎外掛以及新增功能指南的資訊,請參閱 外掛架構內部