當 ClawHub 推出時,它看起來像是擴充 AI 代理執行環境的顯而易見方式。一個技能市集——安裝你需要的,跳過你不需要的,貢獻你自己的。這個模型對瀏覽器擴充功能、VS Code 外掛、npm 套件都有效。為什麼不用在 AI 代理上?
到 2026 年初,答案很清楚了。安全研究員發現 41.7% 的已發布 ClawHub 技能包含漏洞。數百個是徹頭徹尾的惡意——專門上傳來危害安裝它們的使用者的套件。事實證明,外掛模型在應用於以提升的權限在你的機器上執行的軟體時有一個根本性的問題。
ZeroClaw 在設計時就考慮到了這個失敗模式。它使用 Rust trait 而不是外掛系統。
執行時外掛系統有什麼問題
傳統外掛系統的核心問題不是實作品質——而是模型本身。當你安裝外掛時,你從網路下載程式碼並在你的應用程式程序中執行它,具有你的應用程式的權限。外掛可以讀取你的檔案、存取你的網路、讀取你的環境變數,以及做你的應用程式可以做的任何其他事情。
對於新增語法高亮的文字編輯器外掛來說,這沒問題。對於可以存取你的憑證、你的檔案系統和你的聊天頻道的 AI 代理執行環境來說,這不行。
具體的失敗模式是可預測的。執行時程式碼載入意味著外掛在宿主程序中執行任意程式碼——沒有沙箱、沒有隔離、沒有能力模型。預設信任意味著一旦外掛被安裝,它就有與宿主應用程式相同的權限。供應鏈攻擊非常容易:發布一個名稱與熱門套件相似的套件,等待使用者安裝它。外掛之間的版本衝突創造了難以除錯且在平台層級不可能防止的相依性地獄。
OpenClaw 的 ClawHub 在 2026 年展示了每一個這些失敗模式。惡意技能並不複雜——它們只是恰好被信任市集的使用者安裝的套件。
Trait:一種不同的模型
Rust trait 是由編譯器強制執行的介面契約。它定義了實作必須提供哪些方法、這些方法接受和返回什麼型別,以及它們必須維護什麼執行緒安全保證。以下是 ZeroClaw 的頻道 trait,簡化版:
```rust
pub trait Channel: Send + Sync + 'static {
fn name(&self) -> &str;
async fn connect(&mut self) -> Result<()>;
async fn receive(&self) -> Result
每個頻道——Telegram、Discord、WhatsApp、Signal、Matrix、IRC——都實作這個 trait。編譯器保證型別安全(你不能將 Discord 回應發送到 Telegram 頻道)、執行緒安全(`Send + Sync` 約束確保安全的並發存取)和完整性(每個必需的方法都必須被實作——沒有執行時的「找不到方法」錯誤)。
關鍵是:新頻道被編譯進二進位檔,而不是在執行時載入。沒有程式碼注入,沒有動態載入,沒有在安裝時需要做的信任決策。擴充功能在執行之前就由編譯器驗證。
新增一個新頻道
擴充 ZeroClaw 的實際體驗是實作 trait。以下是 Matrix 頻道適配器的樣子:
```rust pub struct MatrixChannel { homeserver: String, client: MatrixClient, }
impl Channel for MatrixChannel { fn name(&self) -> &str { "matrix" }
async fn connect(&mut self) -> Result<()> { self.client = MatrixClient::new(&self.homeserver).await?; self.client.login().await?; Ok(()) }
async fn receive(&self) -> Result
async fn send(&self, msg: Response) -> Result<()> { self.client.send_text(&msg.channel_id, &msg.text).await?; Ok(()) }
async fn disconnect(&self) -> Result<()> { self.client.logout().await } } ```
一個完整的頻道適配器大約 50 行。編譯器在程式碼發布之前驗證實作是否正確。如果你忘記實作一個方法,或返回錯誤的型別,或違反執行緒安全約束,你會得到編譯錯誤——而不是生產環境中的執行時崩潰。
每個擴充點都使用相同的模式
ZeroClaw 在系統需要可擴充的每個地方都使用 trait。AI 供應商實作 `Provider` trait:
```rust
pub trait Provider: Send + Sync {
async fn complete(&self, messages: &[ChatMessage]) -> Result
從 OpenAI 切換到 Anthropic 再到 Ollama 就是用不同的 HTTP 呼叫實作相同的 trait。ZeroClaw 的其餘部分不知道也不關心哪個供應商是活躍的——它只是呼叫 trait 方法。
工具實作 `Tool` trait,要求預先聲明權限:
```rust
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
async fn execute(&self, args: Value) -> Result
每個工具聲明它需要什麼——檔案存取、網路存取、特定路徑——在它執行之前。執行環境根據這些聲明強制執行允許清單。聲稱需要讀取 `~/documents` 的工具不能悄悄存取 `~/.ssh`。
記憶體後端實作 `MemoryBackend` trait,這就是為什麼 SQLite 是預設值但替代後端是可能的,而不需要更改任何其他程式碼。
安全比較
| 方面 | 外掛系統 | Trait 系統 | |--------|--------------|-------------| | 程式碼來源 | 執行時下載 | 建置時編譯 | | 驗證 | 基於信任 | 編譯器驗證 | | 權限 | 執行時,通常未檢查 | 在型別中聲明,強制執行 | | 供應鏈 | 易受攻擊 | 沒有外部程式碼載入 | | 型別安全 | 執行時錯誤 | 編譯時錯誤 | | 並發 | 可能有競爭條件 | 資料競爭不可能 |
關鍵洞察很簡單:如果你沒有供應鏈,就不可能有供應鏈攻擊。ZeroClaw 的擴充功能是編譯進去的,不是下載的。沒有可以被攻擊的市集,沒有可以被拼字搶注的套件,沒有在安裝時需要做的信任決策。
真正的取捨
Trait 方式意味著你不能通過下載檔案來安裝新頻道。新增自訂擴充功能需要編寫 Rust、將其新增到 ZeroClaw 原始碼,並編譯一個新的二進位檔。對於大多數使用者來說,30 多個內建頻道和工具涵蓋了他們需要的一切。對於需要自訂擴充功能的開發者,trait 系統提供了一個清晰的、型別安全的契約來實作。
這個取捨是刻意的。較小的、經過驗證的擴充面比大的、未經驗證的更好。OpenClaw 的 ClawHub 證明了當你為生態系統規模而不是安全性優化時會發生什麼。ZeroClaw 優化相反的方向,CVE 數量反映了這個選擇。