引言
AI 代理正在从“能说”走向“能做”。OpenClaw 等项目的爆火,让开发者看到 AI 直接操作系统的可能性。然而,执行层的可靠性、性能和安全性成了新的瓶颈——任务重复执行、代理失控、恶意插件等问题层出不穷。
agent-core 应运而生。它是一个用 Rust 编写的 AI 代理执行引擎,核心目标是:为 AI 代理提供 Exactly‑Once 执行保障、安全沙箱和分布式调度能力。本文将从技术架构、核心实现、性能数据等方面,深入剖析 agent-core 的设计与优化。
技术栈概览
agent-core 构建于 Rust 生态之上,依赖以下关键库:
- Tokio:异步运行时,支撑高并发任务调度。
- wasmtime:WASM 沙箱,提供安全隔离。
- redis-rs:Redis 客户端,实现分布式任务队列。
- sled:嵌入式持久化存储,用于幂等性记录。
- axum:Web 框架,提供 HTTP API 和 Prometheus 指标端点。
幂等性核心:Exactly‑Once 保障
问题
在分布式系统中,任务可能因网络重传、节点崩溃等原因被重复执行,导致数据不一致。
解决方案
agent-core 基于 CRDT(冲突-free 数据类型) 和 Fencing Tokens 设计幂等性存储。每个任务有唯一 ID 和版本号,存储后端提供原子 compare-and-swap 操作,确保状态变更只生效一次。
关键 Trait 定义
#[async_trait]
pub trait IdempotencyBackend: Send + Sync + 'static {
async fn create(&self, key: &str, owner: Option<&str>, ttl: Option<Duration>) -> Result<Record>;
async fn complete(&self, key: &str, result: Vec<u8>, expected_version: u64) -> Result<()>;
async fn fail(&self, key: &str, error_msg: &str, expected_version: u64) -> Result<()>;
async fn get(&self, key: &str) -> Result<Option<Record>>;
// ...
}
性能数据
| 操作 | 内存后端 | Sled 持久化 |
|---|---|---|
| create | 1.28 µs | 17.0 µs |
| complete | 321 ns | 1.91 µs |
内存操作接近硬件极限,持久化性能与 RocksDB 相当,但无 C++ 依赖。
分布式调度器:基于 Redis Streams
架构设计
- 任务提交时
XADD到 Stream,消费者通过XREADGROUP获取任务,支持多 worker 并发。 - 使用 PEL(Pending Entries List)实现可靠确认,任务失败后自动重试,达到最大重试次数后进入死信队列。
- 通过 pipeline 合并
XACK和XADD,将网络往返从 2 次减为 1 次,大幅降低延迟。
关键代码片段(nack 方法优化)
async fn nack(&self, task_id: &str, error_msg: &str) -> Result<()> {
if let Some((_, (message_id, mut task))) = self.pending_tasks.remove(task_id) {
let mut conn = self.conn.clone();
task.retry_count += 1;
task.last_error = Some(error_msg.to_string());
if task.retry_count >= self.max_retries {
// 移入死信
let serialized = Self::serialize_task(&task)?;
let _: String = conn.xadd(&self.dead_letter_key, "*", &[("task", serialized)]).await?;
} else {
// pipeline 合并 XACK 和 XADD
let serialized = Self::serialize_task(&task)?;
let mut pipe = pipe();
pipe.xack(&self.stream_key, &self.consumer_group, &[message_id.as_str()])
.xadd(&self.stream_key, "*", &[("task", serialized.as_str())]);
let (acked, new_message_id): (usize, String) = pipe.query_async(&mut conn).await?;
debug!("Re-submitted task {} with new ID {}", task_id, new_message_id);
}
}
Ok(())
}
性能数据
| 操作 | 延迟 |
|---|---|
| submit | 1.15 ms |
| pop + ack | 3.94 ms |
经过 pipeline 优化后,Redis 操作延迟降低约 40%,优于大多数 Python 队列。
WASM 沙箱:安全隔离
安全机制
- 内存限制、燃料(CPU)计量、宿主函数白名单。
- 5 项安全测试通过,确保插件无法逃逸。
关键代码片段(加载与调用)
// 加载 WASM 模块
let plugin = load_wasm_plugin("./plugin.wasm", "my_plugin", "1.0", 64 * 1024 * 1024, 10_000_000, logger)?;
// 调用导出函数
let result = plugin.call("add", json!([3, 5])).await?;
assert_eq!(result, 8);
性能数据
- 简单加法调用:828 ns,接近原生性能。
可观测性
agent-core 内置 Prometheus 指标,通过 /metrics 端点暴露:
agent_tasks_total:总任务数agent_tasks_completed:成功任务数agent_tasks_failed:失败任务数agent_wasm_exec_duration_ms:WASM 执行耗时
快速上手
-
添加依赖:
[dependencies] agent-core-temp = "0.1" tokio = { version = "1.40", features = ["full"] } -
启动服务(使用 Redis 调度器和 sled 持久化):
$env:SCHEDULER_TYPE="redis" $env:REDIS_URL="redis://127.0.0.1:6379" $env:IDEMPOTENCY_STORAGE="sled" $env:SLED_PATH="./data/sled" cargo run --features redis-scheduler,sled-storage -
提交任务:
curl -X POST http://127.0.0.1:3000/run \ -H "Content-Type: application/json" \ -d '{"intent":{"type":"transfer","to":"alice","amount":100,"asset":"USDC"}}' -
查看指标:
curl http://127.0.0.1:3000/metrics
性能对比与行业水平
| 系统 | 操作 | 延迟 | 相对倍数 |
|---|---|---|---|
| agent-core(内存) | submit | 1.06 µs | 基准 |
| BullMQ Python | submit | ~160 µs | 慢 150 倍 |
| RQ | submit | ~350 µs | 慢 330 倍 |
| agent-core(Redis) | submit | 1.15 ms | 基准 |
| BullMQ Python Redis | submit | ~1.5-2 ms | 相近 |
| agent-core WASM | add | 828 ns | 基准 |
| Node.js | 加法 | 12-50 µs | 慢 15-60 倍 |
数据可视化提示:您可以从 Criterion 生成的 HTML 报告(target/criterion/report/)中截取性能对比图,插入文章中。
未来展望
- 对接 OpenClaw 等 AI 代理框架。
- 支持 WASI 0.3,使 WASM 插件能使用系统调用。
- 企业级特性:TEE 证明、多链支付。
结论
agent-core 用 Rust 实现了微秒级响应、Exactly‑Once 保障和安全的 WASM 执行。它不仅是 AI 代理的可靠后端,也可作为通用任务队列。欢迎试用、反馈和贡献!