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 的两种哲学:
- ZeroClaw:性能优先,适合生产环境、嵌入式场景
- IronClaw:安全优先,适合企业、高安全需求
两者都用 Rust 的零成本抽象、内存安全、并发安全特性,但在性能和安全之间做了不同的权衡。
选哪个?看你的场景:
- 需要快?选 ZeroClaw
- 需要安全?选 IronClaw
- 两者都要?用 ZeroClaw + 自己加安全层
相关链接:
- ZeroClaw GitHub
- IronClaw GitHub
- ← 上一篇:PicoClaw - 在 $10 开发板上跑 AI Agent
- ← 返回系列总览
- 下一篇:TinyClaw - 用 400 行 Shell 实现多代理协作 →