GitHub · 项目涌现

unicity-astrid/astrid

二〇二六年六月六日·★ 6,675·⑂ 61·Rust·Apache-2.0 ·最新发布 v0.7.0 · 2026-05-25 · GitHub 原仓库

Astrid是一个面向AI agent的用户态微内核操作系统,当前版本v0.5.0,由Unicity Labs开发。它将AI agent视为进程,提供带写时复制覆盖层的虚拟文件系统、ed25519能力令牌、IPC事件总线、WASM进程隔离和加密审计追踪。内核固定,其他组件均为可替换的capsule(隔离WASM进程),通过Capsule.toml清单声明依赖,支持离线运行、自定义agent架构、透明缓存和混合provider。安全模型包含策略、令牌、预算、批准和审计五层门控。

Astrid

面向AI agent的操作系统。

CI License: MIT OR Apache-2.0 MSRV Rust 2024


Astrid是一个用户态微内核,它对待AI agent的方式就像Linux对待进程一样。它拥有一个带启动序列的内核、一个带写时复制(copy-on-write)覆盖层的虚拟文件系统、ed25519能力令牌、一个IPC事件总线、WASM进程隔离,以及一个每条记录都哈希前一条记录的加密审计追踪。

内核是固定的。其他一切都是可替换的capsule:provider、orchestrator、工具、前端、拦截器。你不需要fork Astrid来进行定制。你只需将capsule组合成一个适合你用例的配置。相同的核心操作系统,不同的capsule集合,无限的配置。

当前版本v0.5.0。运行在用户空间。目前唯一的前端是内置的CLI(astrid chat)。该架构专为unikernel部署而设计。

为什么capsule很重要

大多数agent框架将其假设硬编码在代码中。LLM provider是一个库导入。编排循环是一个硬编码的函数。工具集是一个静态列表。改变其中任何一个都意味着fork框架、理解其内部结构,并维护一个分叉的副本。

Astrid颠覆了这一点。内核提供沙箱、IPC、文件系统、能力令牌、预算执行和审计。超出这个边界的一切都是capsule:一个由Capsule.toml清单描述的隔离WASM进程。Capsule通过类型化的[imports]/[exports]表声明它们提供什么以及需要什么。内核通过拓扑排序解析依赖关系并按顺序启动它们。

这不是一个附加在应用程序上的插件系统。它就是应用程序的架构。

这使得什么成为可能

完全离线运行。 将provider capsule替换为与Ollama或vLLM通信的capsule。其他一切工作方式完全相同。Orchestrator不知道也不关心运行的是哪个模型后端。

构建新颖的agent架构。 编写一个自定义的orchestrator capsule:辩论系统、蒙特卡洛树搜索规划器、验证链循环。Agent架构是AI研究的前沿。Astrid为研究人员提供了一个生产级运行时,其中沙箱、预算执行和审计已经得到解决。

通过透明缓存降低LLM成本。 在orchestrator和provider之间安装一个缓存capsule作为中间件。之前见过这个prompt吗?返回缓存的响应。Orchestrator和provider都不需要修改。

可通宵工作的自主agent。 将默认的orchestrator替换为一个自主工作capsule。它生成代码、运行测试、读取错误、自我纠正,并循环直到通过。聊天机器人和自主agent之间的区别在于编排逻辑,而该逻辑是一个可替换的capsule。

混合搭配provider。 同时运行多个provider capsule。一个路由capsule检查每个请求,并根据复杂度、成本或延迟选择最佳的provider。每个provider都使用相同的IPC事件模式。

自我修改的agent。 Agent可以编写一个新的capsule——Rust源代码、Capsule.toml、测试——通过astrid-build构建它,使用capsule install安装它,并通过向其IPC主题发布消息来执行它。它可以在运行时扩展自己的操作系统:添加新工具、新拦截器、新能力。它还可以跨会话修改自己现有的配置、环境和持久状态。身份capsule已经以微型方式做到了这一点——LLM在引导过程中重写自己的spark.toml。完整的图景是一个能够编写、测试和部署自己capsule的agent——在能力沙箱内进化自己的框架。

发布自定义发行版。 打包一个Distro.toml加上capsule。企业A获得一个需要审批的orchestrator。初创公司B获得一个带有本地模型的自主工作器。安全补丁同时推送给所有人。

这些场景在架构上今天就可以实现。内核、IPC总线、capsule清单系统和依赖解析器都已存在并经过测试。不同之处在于目前在这个基础上构建了多少个capsule。

Agent拥有自主权。人类拥有权威。

传统计算将人类置于中心。AI agent颠覆了这种关系。Agent操作、推理和行动。人类监督、批准和引导。Astrid从一开始就是为这种颠倒的模型构建的。

内核强制执行边界,以便agent可以在边界内自由行动。审批门控确保人类在关键时刻参与,而不是每一步都参与。审计追踪为每个行动提供加密问责。能力系统允许随着agent证明其可靠性而逐步扩展信任。

你保留多少权威取决于你。mode = "safe"在工作区之外的每个行动前询问。mode = "guided"自动允许读取,询问写入。mode = "autonomous"移除护栏。对于大胆的Astrinauts:mode = "yolo"

安全模型

每个敏感操作在执行前都要经过五个层:

Agent提出行动
       |
  [1. 策略]    硬性阻止。"sudo"始终被拒绝。路径遍历始终被拒绝。
       |        管理员控制的拒绝列表、允许的路径、拒绝的主机。
       |        不能被令牌或批准覆盖。
       |
  [2. 令牌]    是否存在有效的ed25519能力令牌覆盖此操作?
       |        通过globset匹配限定到资源模式。
       |        有时间限制。链接到创建它的审计条目。
       |
  [3. 预算]    会话是否在其支出限额内?
       |        每个操作和每个会话的限制,原子执行。
       |        双重预算:会话预算和工作区预算必须同时允许。
       |        基于预留:批准时保留成本,拒绝时退还。
       |
  [4. 批准]    没有令牌?询问人类。
       |        允许一次 / 允许会话 / 允许工作区 / 始终允许 / 拒绝。
       |        "始终允许"会为下次铸造一个签名的能力令牌。
       |        "允许会话"创建一个范围化的许可,自动匹配未来的调用。
       |        人类不可用?操作排队,而不是静默跳过。
       |
  [5. 审计]    每个决策——允许、拒绝、延迟——都被记录。
                 每个条目由运行时的ed25519密钥签名。
                 每个条目包含前一个条目的内容哈希。
                 篡改历史记录会导致链断裂。

这是真实的代码。SecurityInterceptor实现了这个确切的流程。测试涵盖了策略阻止、预算耗尽、拒绝时预算预留退还、异步取消时预算退还、能力令牌授权、"允许会话"许可铸造路径以及"始终允许"令牌铸造路径。

两个沙箱

WASM沙箱。 Capsule通过Extism/Wasmtime在WebAssembly中运行。没有系统调用,没有文件描述符,没有主机内存访问。每个外部资源(文件系统、网络、IPC、KV存储)都通过一个经过能力检查的主机函数进行门控。主机ABI暴露了49个函数,涵盖文件系统、IPC、存储、网络、身份、生命周期、进程管理、批准、钩子和时钟子系统。硬限制:64 MB内存上限,5分钟挂钟超时,capsule二进制文件上的BLAKE3哈希验证(没有哈希或哈希错误意味着不加载)。

VFS覆盖层。 Agent操作一个写时复制文件系统。工作区是只读的下层。写入进入一个由临时目录支持的临时上层。会话结束:将差异提交到工作区,或删除临时目录以丢弃。路径遍历(../../etc/passwd)在到达主机文件系统之前在VFS层被拒绝。文件句柄使用基于能力的DirHandle/FileHandle类型。

主机ABI

WASM到主机的边界是一个扁平的syscall表。WASM guest不能导入任意的主机函数。

子系统 Syscalls
文件系统 astrid_fs_exists, astrid_read_file, astrid_write_file, astrid_fs_mkdir, astrid_fs_readdir, astrid_fs_stat, astrid_fs_unlink
IPC astrid_ipc_publish, astrid_ipc_subscribe, astrid_ipc_recv (阻塞), astrid_ipc_poll (非阻塞), astrid_ipc_unsubscribe
上行链路 astrid_uplink_register, astrid_uplink_send
存储 astrid_kv_get, astrid_kv_set, astrid_kv_delete, astrid_kv_list_keys, astrid_kv_clear_prefix
HTTP astrid_http_request, astrid_http_stream_start, astrid_http_stream_read, astrid_http_stream_close
网络 astrid_net_bind_unix, astrid_net_accept, astrid_net_poll_accept, astrid_net_read, astrid_net_write, astrid_net_close_stream
身份 astrid_identity_resolve, astrid_identity_link, astrid_identity_unlink, astrid_identity_create_user, astrid_identity_list_links
生命周期 astrid_elicit (安装期间的用户输入), astrid_has_secret, astrid_signal_ready, astrid_get_caller, astrid_get_config
进程 astrid_spawn_host, astrid_spawn_background_host, astrid_read_process_logs_host, astrid_kill_process_host
批准 astrid_request_approval (阻塞guest直到人类响应或超时)
安全 astrid_check_capsule_capability
钩子 astrid_trigger_hook, astrid_get_interceptor_handles
时钟 astrid_clock_ms
日志 astrid_log

每个参数都以原始字节形式跨越边界。SDK在此基础上添加了类型化的易用性,镜像了std模块布局(fsnetprocessenvtimelog)以及Astrid特定的模块(ipckvhttphooksuplinkidentityapprovalruntime)。

Capsule

Capsule是操作系统模型中的进程:由Capsule.toml清单描述的隔离执行单元。一个capsule可以组合多个引擎:

一个清单声明了capsule的[imports](它需要从其他capsule获取什么)和[exports](它向系统提供什么),使用带semver版本要求的命名空间接口名称。Capsule之间的依赖关系在启动时通过拓扑排序解析。内核在任何capsule启动之前验证所有必需的导入是否已满足。

一个清单还可以声明命令、技能、拦截器、IPC主题、MCP服务器和上行链路。

use astrid_sdk::prelude::*;

#[derive(Default)]
pub struct MyTools;

#[capsule]
impl MyTools {
    #[astrid::tool]
    fn search_issues(&self, args: SearchArgs) -> Result<SearchResult, SysError> {
        let token = env::var("GITHUB_TOKEN")?;
        let resp = http::get(&format!(
            "https://api.github.com/search/issues?q={}", args.query
        ))?;
        // ...
    }
}

#[capsule] proc宏生成所有WASM ABI样板代码:extern "C"导出、跨边界的JSON序列化,以及工具、命令、钩子、安装和升级入口点的分发路由。Capsule作者依赖astrid-sdkserde

来自OpenClaw生态系统的TypeScript和JavaScript插件通过全Rust管道(OXC transpiler、QuickJS/Wizer、导出缝合器)编译为WASM。Tier 1插件不需要Node.js。

拦截器

Capsule可以在IPC主题上注册拦截器——类似eBPF的中间件,在核心处理程序之前(或代替它)触发。拦截器返回ContinueFinalDeny来控制链。优先级为10的守卫可以在优先级为100的核心处理程序看到事件之前否决它。工具是一种IPC约定:工具capsule拦截tool.v1.execute.<name>tool.v1.request.describe主题。路由器capsule处理发现和分发。内核不知道工具模式。

快速开始

先决条件: Rust 1.94+。默认发行版需要LLM provider(例如Anthropic API密钥),但内核本身不需要。

# 从crates.io安装(同时安装astrid和astrid-daemon二进制文件)
cargo install astrid

# 初始化——获取默认发行版,安装capsule,设置PATH
astrid init

# 启动一个会话(守护进程在首次使用时自动启动)
ANTHROPIC_API_KEY=sk-... astrid chat

# 或者从源码构建
git clone https://github.com/unicity-astrid/astrid.git
cd astrid
cargo build --release
./target/release/astrid init

三个二进制文件协同工作:astrid(CLI前端)、astrid-daemon(内核进程)和astrid-build(capsule编译器)。当你运行astrid chat时,CLI会自动以后台进程启动守护进程,通过Unix域套接字连接,并渲染流式事件。守护进程管理VFS、capsule、IPC、审计和安全。CLI管理输入和显示。

无头/脚本模式

# 单prompt,非交互式——打印响应并退出
astrid -p "summarize the git log"

# 管道stdin
git diff HEAD~1 | astrid -p "write a commit message for this diff"

# 多轮脚本化对话
SESSION=$(astrid -p "start a task" --print-session 2>&1 | tail -1)
astrid -p "continue the task" --session "$SESSION"

# 自主模式(自动批准所有工具请求)
astrid -p "fix all failing tests" --yes

守护进程生命周期

astrid start     # 启动一个持久守护进程(终端关闭后仍存活)
astrid status    # 显示PID、运行时间、连接的客户端、加载的capsule
astrid stop      # 优雅关闭
astrid self-update  # 下载最新的发布二进制文件到~/.astrid/bin/

发行版系统

一个发行版是一个Distro.toml清单,描述了一组针对特定用例精选的capsule。astrid init获取清单,呈现一个多选provider组选择器,通过交互式提示解析{{ var }}模板变量,并使用进度条安装所有选定的capsule。Distro.lock以原子方式写入,包含每个已安装capsule的BLAKE3哈希,以实现可重现的部署。

# 安装默认发行版(astralis)
astrid init

# 安装自定义发行版
astrid init --distro @myorg/my-distro

# 从本地Distro.toml安装
astrid init --distro ./path/to/Distro.toml

Capsule管理

# 从GitHub安装(下载预构建的.wasm发布资产,回退到从源码构建)
astrid capsule install @org/capsule-name

# 从本地路径安装
astrid capsule install ./path/to/capsule

# 列出已安装的capsule及其能力元数据
astrid capsule list
astrid capsule list --verbose

# 显示导入/导出依赖关系图
astrid capsule tree

# 更新特定capsule(或所有capsule)
astrid capsule update my-capsule
astrid capsule update

# 移除一个capsule(移除前检查依赖项)
astrid capsule remove my-capsule
astrid capsule remove my-capsule --force  # 绕过依赖检查

内容寻址的WASM二进制文件使用BLAKE3哈希存储在~/.astrid/bin/中。当没有其他capsule引用相同的哈希时,capsule移除会清理bin/中的二进制文件。二进制存储本身(bin/wit/)是仅追加的;计划中的astrid gc用于显式清理。

目录布局

Astrid在~/.astrid/下使用Linux FHS对齐的布局(可通过$ASTRID_HOME覆盖):

~/.astrid/
├── etc/
│   ├── config.toml         部署配置
│   ├── servers.toml        MCP服务器配置
│   ├── gateway.toml        守护进程配置
│   └── hooks/              系统钩子
├── var/
│   └── state.db/           系统KV(SurrealKV,持久化)
├── run/                    临时运行时状态
│   ├── system.sock         Unix域套接字
│   ├── system.token        会话认证令牌
│   └── system.ready        守护进程就绪哨兵
├── log/                    系统日志
├── keys/
│   └── runtime.key         ed25519签名密钥
├── bin/                    内容寻址的WASM二进制文件(BLAKE3命名)
├── wit/                    内容寻址的WIT接口定义
└── home/
    └── {principal}/        每个principal的隔离
        ├── .local/
        │   ├── capsules/   用户安装的capsule
        │   ├── kv/         capsule KV数据
        │   ├── log/        capsule日志(每日轮转,保留7天)
        │   ├── audit/      每个principal的审计链
        │   ├── tokens/     能力令牌
        │   └── tmp/        VFS /tmp挂载点
        └── .config/
            └── env/        capsule环境配置覆盖

<project>/.astrid/          工作区级配置(可提交)
├── workspace-id            将项目链接到全局状态的UUID
└── ASTRID.md               项目级agent指令

配置遵循优先级链:工作区 > 用户 > 系统 > 环境变量 > 编译默认值。工作区配置只能收紧安全设置,不能放宽。

多principal支持

每个principal(用户身份)在home/{principal}/下获得完全隔离的capsule、KV数据、审计链、能力令牌和日志。操作中的principal透明地通过每个IPC消息链传递——capsule永远不会看到或处理principal路由。KV命名空间格式:{principal}:capsule:{name}。每次调用的principal解析意味着跨用户调用会写入正确principal的审计日志和KV。

架构

Astrid遵循严格的内核/用户空间划分。内核(原生Rust守护进程)拥有所有特权资源。Capsule(WASM guest)没有环境权限,必须通过主机ABI请求一切。

内核crate

Crate 角色
astrid-kernel 启动运行时。拥有VFS、IPC总线、capsule注册表、MCP客户端、审计日志、KV存储。监听Unix套接字以接受CLI连接。
astrid-approval SecurityInterceptor:五层门控。策略引擎、预算跟踪器、许可存储、批准管理器。
astrid-capabilities 带glob资源模式和时间限制的ed25519签名能力令牌。
astrid-audit 链式链接的加密审计日志。每个条目都签名并哈希前一个条目。基于SurrealKV,带链验证。每个principal的链拆分。
astrid-vfs 写时复制覆盖文件系统。Vfs trait,带有HostVfsOverlayVfs实现。基于能力的DirHandle/FileHandle
astrid-events IPC事件总线。基于广播,带有异步接收器和同步订阅者回调。类型从astrid-types重新导出。
astrid-types 共享数据类型:IPC负载、LLM模式、内核API。最小依赖,WASM兼容。内核和SDK都使用。
astrid-capsule Capsule运行时:清单解析、WASM/MCP/静态引擎、通过拓扑排序的依赖解析、capsule注册表、热重载监视器。
astrid-mcp MCP客户端/服务器生命周期。封装rmcp,带有二进制哈希验证、能力门控和elicitation支持。
astrid-crypto Ed25519密钥对(通过ed25519-dalek)、BLAKE3内容哈希、签名。密钥在drop时清零。
astrid-storage 两层持久化。第1层:通过嵌入式SurrealKV的原始KV。第2层:带SurrealQL的完整SurrealDB查询引擎。
astrid-config 分层TOML配置:工作区 > 用户 > 系统 > 环境 > 默认值。工作区配置只能收紧安全设置,不能放宽。
astrid-workspace 工作区边界检测和进程沙箱配置。
astrid-hooks 用于会话生命周期、工具调用和批准流程的钩子系统。处理程序:命令、HTTP、WASM。
astrid-core 基础类型:SessionIdPrincipalIdPermission、身份原语、elicitation类型、会话令牌。

用户空间crate

Crate 角色
astrid-sdk 面向capsule作者的安全Rust SDK。镜像std布局。包括astrid-sys(syscall表)和astrid-sdk-macros#[capsule] proc宏)。独立仓库。
astrid-openclaw 用于OpenClaw插件兼容性的TypeScript到WASM编译器。全Rust管道:OXC + QuickJS/Wizer。

二进制文件

二进制文件 Crate 角色
astrid astrid-cli 终端前端。通过Unix套接字连接到守护进程。TUI渲染、无头/脚本模式、capsule管理、发行版初始化、守护进程生命周期命令。
astrid-daemon astrid-daemon 后台内核进程。启动内核、加载capsule、服务IPC请求。--ephemeral标志用于CLI生成的实例。
astrid-build astrid-build Capsule编译器和打包器。处理Rust、OpenClaw(JS/TS)和遗留MCP项目。由CLI作为伴随二进制文件调用。

基础设施crate

Crate 角色
astrid-telemetry 使用tracing的结构化日志。JSON和人类可读输出。基于文件的输出,每日轮转。
astrid-prelude 内部crate的通用重新导出。

存储

两层,一个API表面:

部署 KV后端 数据库后端
开发/单agent SurrealKV(嵌入式) SurrealDB(嵌入式,SurrealKV)
生产/多节点 SurrealKV(嵌入式) SurrealDB(基于TiKV,Raft)

Capsule KV存储按principal和capsule进行命名空间限定。内核、审计日志、能力存储和身份系统使用数据库层。从嵌入式扩展到分布式只是一个配置更改。

v0.5.0亮点

此版本的主要更改:

请参阅CHANGELOG.md获取完整的更改、修复和破坏性更改列表。

当前状态

v0.5.0。 核心运行时端到端工作:

尚未完成: 多节点SurrealDB(TiKV/Raft)。WASM组件模型迁移(Extism到WIT绑定)。除CLI外的其他前端。用于分发的capsule注册表。

开发

# 构建
cargo build --workspace

# 测试
cargo test --workspace -- --quiet

# 代码检查
cargo clippy --workspace --all-features -- -D warnings
cargo fmt --all -- --check

所有crate都强制执行#![deny(unsafe_code)],除了astrid-sysastrid-sdk(WASM FFI需要它)。Clippy在pedantic级别运行。整数算术溢出是一个lint错误(clippy::arithmetic_side_effects = "deny")。

macOS(x86_64、aarch64)和Linux(x86_64、aarch64)的发布二进制文件在标签推送时通过发布工作流自动构建。

操作员文档

贡献

欢迎贡献。Astrid使用分层贡献者系统来保护安全关键代码,同时为新贡献者敞开大门。每个PR必须链接到一个GitHub issue。请参阅CONTRIBUTING.md了解完整流程,包括issue优先工作流、层级描述和安全关键crate限制。

许可证

根据MIT和Apache 2.0双许可。

版权所有 (c) 2025-2026 Joshua J. Bouw 和 Unicity Labs。

译自 GitHub · 项目涌现 · 录于 二〇二六年六月六日