engineering architecture

Trait 驱动架构:ZeroClaw 如何在没有插件的情况下实现可扩展 AI 智能体

ZeroClaws.io

ZeroClaws.io

@zeroclaws

2026年2月25日

8 分钟

Trait 驱动架构:ZeroClaw 如何在没有插件的情况下实现可扩展 AI 智能体

当 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; async fn send(&self, msg: Response) -> Result<()>; async fn disconnect(&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 { let event = self.client.next_message().await?; Ok(Message::from(event)) }

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; async fn embed(&self, text: &str) -> Result>; fn model_name(&self) -> &str; } ```

从 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; fn permissions(&self) -> Permissions; } ```

每个工具在运行之前声明它需要什么——文件访问、网络访问、特定路径。运行时根据这些声明强制执行白名单。声称需要读取 `~/documents` 的工具不能悄悄访问 `~/.ssh`。

记忆后端实现 `MemoryBackend` trait,这就是为什么 SQLite 是默认的但替代后端是可能的,而不需要更改任何其他代码。

安全比较

| 方面 | 插件系统 | Trait 系统 | |--------|--------------|-------------| | 代码来源 | 运行时下载 | 构建时编译 | | 验证 | 基于信任 | 编译器验证 | | 权限 | 运行时,通常未检查 | 在类型中声明,强制执行 | | 供应链 | 易受攻击 | 无外部代码加载 | | 类型安全 | 运行时错误 | 编译时错误 | | 并发 | 可能有竞争条件 | 数据竞争不可能 |

核心洞察很简单:如果你没有供应链,就不可能有供应链攻击。ZeroClaw 的扩展是编译进去的,不是下载的。没有可以被攻击的市场,没有可以被仿冒的包,没有在安装时需要做的信任决策。

真实的权衡

Trait 方法意味着你不能通过下载文件来安装新频道。添加自定义扩展需要编写 Rust,将其添加到 ZeroClaw 源代码,并编译新的二进制文件。对于大多数用户,30+ 个内置频道和工具涵盖了他们需要的一切。对于需要自定义扩展的开发者,trait 系统提供了一个清晰的、类型安全的契约来实现。

这个权衡是有意为之的。较小的、经过验证的扩展面比大的、未经验证的更好。OpenClaw 的 ClawHub 证明了当你为生态系统规模而不是安全性优化时会发生什么。ZeroClaw 优化相反的方向,CVE 数量反映了这个选择。

保持关注

获取新版本、集成和 Rust 驱动的 Agent 基础设施更新。不发垃圾邮件,随时退订。