2026-02-22 · AI
32
AI · 2026-02-22

Claw 生态03: ZeroClaw vs IronClaw - Rust 重写的两种哲学

OpenClaw 生态里有两个 Rust 重写版本:ZeroClaw 和 IronClaw。

一个追求极致性能(ZeroClaw:<5MB 内存,<10ms 启动),一个追求极致安全(IronClaw:WASM 沙箱,加密存储,prompt injection 防御)。

同样是 Rust,为什么会有两种完全不同的设计哲学?这篇文章深入对比两者的架构、权衡、适用场景。

为什么选 Rust

在讨论两者的差异之前,先说说为什么都选 Rust。

Rust 有三个特性,特别适合写 AI Agent:

1. 零成本抽象
- 高层抽象(trait、泛型)不会带来运行时开销
- 编译后的性能接近 C/C++

2. 内存安全
- 编译期检查,没有 null pointer、use after free、data race
- 不需要 GC,内存占用可控

3. 并发安全
- 所有权系统保证线程安全
- 不会出现 race condition

这三点对 AI Agent 来说很重要:
- 性能:LLM 调用、工具执行、并发处理都需要快
- 内存:嵌入式场景需要低内存占用
- 安全:Agent 会执行代码、访问文件,必须安全

ZeroClaw:性能优先

GitHub: zeroclaw-labs/zeroclaw
团队: Harvard/MIT/Sundai 学生
星标: ~16.8k

ZeroClaw 的目标是:把 OpenClaw 做到极致快、极致轻

结果:
- 内存占用: <5MB
- 启动时间: <10ms(0.8GHz 核心)
- 二进制大小: 3.4MB
- 支持硬件: $10 开发板、树莓派、老手机

架构设计

ZeroClaw 用 Rust 的 trait 系统实现模块化:

// 核心 trait 定义
pub trait Provider {
    fn generate(&self, prompt: &str) -> Result<String>;
    fn generate_stream(&self, prompt: &str) -> Result<Stream<String>>;
}

pub trait Channel {
    fn listen(&self, callback: Box<dyn Fn(Message) -> String>);
    fn send(&self, chat_id: &str, message: &str) -> Result<()>;
}

pub trait Tool {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn execute(&self, args: &str) -> Result<String>;
}

pub trait Memory {
    fn save(&self, content: &str) -> Result<()>;
    fn search(&self, query: &str) -> Result<Vec<String>>;
}

所有组件都是可替换的:

// 组装 agent
let agent = Agent::builder()
    .provider(Box::new(OpenAIProvider::new(api_key)))
    .channel(Box::new(TelegramChannel::new(token)))
    .tool(Box::new(WebSearchTool::new()))
    .memory(Box::new(HybridMemory::new(db_path)))
    .build();

// 运行
agent.run();

性能优化技巧

ZeroClaw 的性能优化做到了极致:

1. 零拷贝

// 错误:多次拷贝字符串
fn process(data: String) -> String {
    let upper = data.to_uppercase();  // 拷贝
    let trimmed = upper.trim();       // 拷贝
    trimmed.to_string()               // 拷贝
}

// 正确:用引用,避免拷贝
fn process(data: &str) -> String {
    data.trim().to_uppercase()  // 只在最后拷贝一次
}

2. 内存池

// 复用 buffer,避免频繁分配
struct BufferPool {
    pool: Vec<Vec<u8>>,
}

impl BufferPool {
    fn get(&mut self) -> Vec<u8> {
        self.pool.pop().unwrap_or_else(|| Vec::with_capacity(4096))
    }

    fn put(&mut self, mut buf: Vec<u8>) {
        buf.clear();
        if self.pool.len() < 10 {
            self.pool.push(buf);
        }
    }
}

3. 异步 I/O

// 用 tokio 实现高并发
#[tokio::main]
async fn main() {
    let mut tasks = vec![];

    // 同时处理多个聊天平台
    tasks.push(tokio::spawn(telegram_gateway.listen()));
    tasks.push(tokio::spawn(discord_gateway.listen()));
    tasks.push(tokio::spawn(whatsapp_gateway.listen()));

    // 等待所有任务
    futures::future::join_all(tasks).await;
}

4. 编译优化

# Cargo.toml
[profile.release]
opt-level = 3           # 最高优化级别
lto = true              # Link Time Optimization
codegen-units = 1       # 单个编译单元(更好的优化)
strip = true            # 去掉调试符号
panic = 'abort'         # panic 时直接 abort(更小的二进制)

Hybrid Memory

ZeroClaw 的 memory 系统很有意思:SQLite vector + keyword 混合搜索

pub struct HybridMemory {
    db: Connection,
}

impl HybridMemory {
    pub fn save(&self, content: &str) -> Result<()> {
        // 生成 embedding
        let embedding = self.generate_embedding(content)?;

        // 存储到 SQLite
        self.db.execute(
            "INSERT INTO memory (content, embedding, timestamp) VALUES (?1, ?2, ?3)",
            params![content, embedding, Utc::now()],
        )?;
        Ok(())
    }

    pub fn search(&self, query: &str) -> Result<Vec<String>> {
        let query_embedding = self.generate_embedding(query)?;

        // 向量搜索(余弦相似度)
        let vector_results = self.db.query_row(
            "SELECT content FROM memory ORDER BY cosine_similarity(embedding, ?1) DESC LIMIT 5",
            params![query_embedding],
        )?;

        // 关键词搜索(FTS5)
        let keyword_results = self.db.query_row(
            "SELECT content FROM memory WHERE content MATCH ?1 LIMIT 5",
            params![query],
        )?;

        // 合并结果
        Ok(merge_and_deduplicate(vector_results, keyword_results))
    }
}

为什么混合搜索?
- 向量搜索:语义相似,但可能漏掉精确匹配
- 关键词搜索:精确匹配,但可能漏掉语义相似

两者结合,召回率更高。

启动时间优化

ZeroClaw 的启动时间 <10ms,靠的是:

1. 延迟加载

// 不在启动时加载所有工具
lazy_static! {
    static ref TOOLS: Mutex<HashMap<String, Box<dyn Tool>>> = Mutex::new(HashMap::new());
}

// 第一次使用时才加载
fn get_tool(name: &str) -> Box<dyn Tool> {
    let mut tools = TOOLS.lock().unwrap();
    tools.entry(name.to_string()).or_insert_with(|| {
        load_tool(name)  // 动态加载
    }).clone()
}

2. 预编译配置

// 编译时嵌入配置(避免运行时解析 JSON)
const CONFIG: &str = include_str!("config.json");

lazy_static! {
    static ref PARSED_CONFIG: Config = serde_json::from_str(CONFIG).unwrap();
}

3. 静态链接

# 静态链接所有依赖(避免动态库加载)
[profile.release]
target-feature = "+crt-static"

IronClaw:安全优先

GitHub: nearai/ironclaw
团队: Near AI / Illia Polosukhin
星标: ~2.9k

IronClaw 的目标是:做最安全的 AI Agent

核心特性:
- WASM 沙箱:工具在隔离环境执行
- Prompt injection 防御:检测和过滤恶意 prompt
- Credential 保护:加密存储 API key
- 本地加密 PostgreSQL:数据全加密
- 无遥测:不发送任何数据到外部

架构设计

IronClaw 的架构围绕安全层设计:

User Input
    ↓
[Input Sanitizer]      # 过滤恶意输入
    ↓
[Agent Loop]
    ↓
[Tool Router]
    ↓
[Safety Check]         # 检查工具调用是否安全
    ↓
[WASM Sandbox]         # 隔离执行
    ↓
[Output Filter]        # 过滤敏感信息
    ↓
User Output

每一层都有安全检查。

WASM 沙箱

IronClaw 用 WASM 执行工具,比 Docker 更轻、更安全:

use wasmer::{Store, Module, Instance, imports};

pub struct WasmSandbox {
    store: Store,
}

impl WasmSandbox {
    pub fn execute(&self, tool_wasm: &[u8], args: &str) -> Result<String> {
        // 加载 WASM 模块
        let module = Module::new(&self.store, tool_wasm)?;

        // 限制导入(只允许安全的系统调用)
        let import_object = imports! {
            "env" => {
                "log" => Function::new_native(&self.store, log_fn),
                // 不允许 file I/O、network、exec 等危险操作
            }
        };

        // 实例化
        let instance = Instance::new(&module, &import_object)?;

        // 调用 execute 函数
        let execute = instance.exports.get_function("execute")?;
        let result = execute.call(&[args.into()])?;

        Ok(result.to_string())
    }
}

WASM 的优势:
- 隔离性强:无法访问宿主文件系统、网络
- 性能好:接近原生速度
- 体积小:比 Docker 容器小几百倍

Prompt Injection 防御

IronClaw 有专门的 prompt injection 检测:

pub struct PromptGuard {
    patterns: Vec<Regex>,
}

impl PromptGuard {
    pub fn check(&self, input: &str) -> Result<()> {
        // 检测常见的 injection 模式
        let dangerous_patterns = vec![
            r"ignore previous instructions",
            r"system:\s*you are now",
            r"<\|im_start\|>",
            r"```.*exec.*```",
        ];

        for pattern in dangerous_patterns {
            if Regex::new(pattern)?.is_match(input) {
                return Err(Error::PromptInjection(pattern.to_string()));
            }
        }

        // 检测异常长的输入(可能是攻击)
        if input.len() > 10000 {
            return Err(Error::InputTooLong);
        }

        Ok(())
    }
}

Credential 保护

IronClaw 用加密存储 API key:

use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, AES_256_GCM};

pub struct CredentialStore {
    key: LessSafeKey,
}

impl CredentialStore {
    pub fn save(&self, name: &str, value: &str) -> Result<()> {
        // 生成随机 nonce
        let nonce = Nonce::assume_unique_for_key([0u8; 12]);

        // 加密
        let mut encrypted = value.as_bytes().to_vec();
        self.key.seal_in_place_append_tag(nonce, Aad::empty(), &mut encrypted)?;

        // 存储到文件
        fs::write(format!(".ironclaw/credentials/{}", name), encrypted)?;
        Ok(())
    }

    pub fn load(&self, name: &str) -> Result<String> {
        // 读取文件
        let mut encrypted = fs::read(format!(".ironclaw/credentials/{}", name))?;

        // 解密
        let nonce = Nonce::assume_unique_for_key([0u8; 12]);
        let decrypted = self.key.open_in_place(nonce, Aad::empty(), &mut encrypted)?;

        Ok(String::from_utf8(decrypted.to_vec())?)
    }
}

输出过滤

IronClaw 会过滤输出中的敏感信息:

pub struct OutputFilter {
    patterns: Vec<(Regex, &'static str)>,
}

impl OutputFilter {
    pub fn filter(&self, output: &str) -> String {
        let mut filtered = output.to_string();

        // 替换敏感信息
        let patterns = vec![
            (r"sk-[a-zA-Z0-9]{48}", "[API_KEY_REDACTED]"),
            (r"\b\d{16}\b", "[CARD_NUMBER_REDACTED]"),
            (r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", "[EMAIL_REDACTED]"),
        ];

        for (pattern, replacement) in patterns {
            let re = Regex::new(pattern).unwrap();
            filtered = re.replace_all(&filtered, replacement).to_string();
        }

        filtered
    }
}

对比:性能 vs 安全

维度
ZeroClaw
IronClaw

目标
极致性能
极致安全

内存占用
<5MB
~50MB(WASM runtime)

启动时间
<10ms
~100ms(加载安全模块)

工具执行
原生(快)
WASM 沙箱(慢 10-20%)

安全性
基础(allowlist)
多层防御

适用场景
生产环境、嵌入式
企业、高安全需求

性能对比

实测(树莓派 4,4GB RAM):

# ZeroClaw
$ time zeroclaw --version
real    0m0.008s

$ zeroclaw benchmark
Startup: 8ms
Tool execution (web_search): 234ms
Memory search: 12ms
Total memory: 4.2MB

# IronClaw
$ time ironclaw --version
real    0m0.095s

$ ironclaw benchmark
Startup: 92ms
Tool execution (web_search): 287ms (WASM overhead)
Memory search: 18ms
Total memory: 48MB

ZeroClaw 更快,但 IronClaw 的安全性值得这点性能损失。

安全对比

ZeroClaw 的安全措施
- Allowlist(白名单工具)
- Filesystem scoping(限制文件访问)
- Encrypted secrets(加密存储)

IronClaw 的额外安全措施
- WASM 沙箱(完全隔离)
- Prompt injection 防御
- Output filtering(敏感信息过滤)
- Audit logging(审计日志)
- No telemetry(无遥测)

如何选择

选 ZeroClaw 如果你需要
- 极致性能(生产环境、高并发)
- 低资源占用(嵌入式、边缘计算)
- 快速启动(serverless、短生命周期)

选 IronClaw 如果你需要
- 企业级安全(金融、医疗、政府)
- 隐私保护(本地部署、无遥测)
- 合规要求(GDPR、HIPAA)

实战:从 ZeroClaw 迁移到 IronClaw

假设你在用 ZeroClaw,但需要更高的安全性,迁移步骤:

1. 安装 IronClaw

# 下载二进制
wget https://github.com/nearai/ironclaw/releases/download/v1.0/ironclaw-linux-x64
chmod +x ironclaw-linux-x64
mv ironclaw-linux-x64 /usr/local/bin/ironclaw

2. 迁移配置

# ZeroClaw 配置
cat zeroclaw-config.json
{
  "provider": "openai",
  "api_key": "sk-xxx",
  "channels": ["telegram"]
}

# 转换为 IronClaw 配置
ironclaw migrate --from zeroclaw-config.json --to ironclaw-config.json

3. 迁移工具

# ZeroClaw 工具是原生 Rust
# IronClaw 需要编译为 WASM

# 安装 WASM 工具链
rustup target add wasm32-wasi

# 编译工具为 WASM
cd tools/web_search
cargo build --target wasm32-wasi --release

# 复制到 IronClaw
cp target/wasm32-wasi/release/web_search.wasm ~/.ironclaw/tools/

4. 迁移数据

# 导出 ZeroClaw memory
zeroclaw export --output memory.json

# 导入到 IronClaw
ironclaw import --input memory.json

5. 测试

# 运行 IronClaw
ironclaw --config ironclaw-config.json

# 测试工具调用
ironclaw test --tool web_search --args "rust wasm"

总结

ZeroClaw 和 IronClaw 代表了 Rust 重写 OpenClaw 的两种哲学:

两者都用 Rust 的零成本抽象、内存安全、并发安全特性,但在性能和安全之间做了不同的权衡。

选哪个?看你的场景:
- 需要快?选 ZeroClaw
- 需要安全?选 IronClaw
- 两者都要?用 ZeroClaw + 自己加安全层


相关链接
- ZeroClaw GitHub
- IronClaw GitHub
- ← 上一篇:PicoClaw - 在 $10 开发板上跑 AI Agent
- ← 返回系列总览
- 下一篇:TinyClaw - 用 400 行 Shell 实现多代理协作 →

目录 最新
← 左侧翻上一屏 · 右侧翻下一屏 · 中间唤出菜单