# AgentOS [English](README.md) AgentOS 是一个使用 Rust 编写、仅面向 Linux 的 low-level 操作系统 agent。它把 有界 tool-calling 循环与 Linux 原生身份、只读系统检查、持久审计、Btrfs 文件 系统历史和多种推理后端组合在一起,其中包括一条仍在开发中的 CALCULET NPU 纯 Rust 路径。 > **开发状态:**远程 OpenAI-compatible mock 路径和显式 subprocess/fake 测试 > adapter 已经实现。本机部署的模型服务只使用 Unix domain socket,绝不使用 > localhost 或 TCP。Rust Candle/CALRT host pipeline 可以解析并校验抓取到的 > Qwen3 部署,但 CALRT 硬件 job submission 尚未实现。因此 `npu_candle` 会 > fail closed,目前不能用于生产。 ## 设计 AgentOS 不是容器 sandbox,也不是内核 fork。它以 Linux 进程身份作为隔离边界: - 每个 active `AgentId` 稳定绑定 owner UID 和非 root agent UID/GID; - runtime 在每次运行前核对进程的 effective UID/GID; - 拒绝 UID 0 或 GID 0 的 agent; - 在模型和工具执行前启用 `no_new_privs`; - 模型只能看到显式工具 allowlist,永远拿不到原始 root shell; - 在 typed、可鉴权的 broker 完成前,系统变更能力保持不可用。 当前执行路径如下: ```text agentos CLI -> runtime + Linux principal -> 有预算的 agent loop -> ChatBackend(远程 OpenAI-compatible / UDS NPU / in-process Candle) -> strict ToolRegistry(Linux 只读工具) -> SQLite 审计日志 文件系统状态 -> WorldlineStore -> Btrfs snapshot 或 copy fallback NPU host 路径 -> Candle/Qwen3 -> CALRT -> PCIe driver ABI 本机模型 IPC -> Unix domain socket -> OpenAI-compatible HTTP payload ``` ## 当前已经实现 - Provider-neutral 的 `agentos.chat.v1` 消息、工具、响应、usage 和 backend 接口。 - 基于 `ntex` 的远程 OpenAI-compatible 非流式 Chat Completions 和 Responses API,包含响应上限、超时、retry,以及选择 HTTPS 时的 TLS peer 校验。 - 通过 AF_UNIX 向本机 legacy llama-server 发送 OpenAI-compatible HTTP payload,不经过 localhost/TCP。 - 保留 JSON stdin/stdout subprocess adapter,用于显式测试和自定义 bridge; 它不是常驻本机模型服务的传输方式。 - Agent iteration、tool call、耗时、总 token 预算,并行只读调用,重复 call ID 检查,以及无进展/周期检测。 - Strict JSON tool schema、allowlist、参数/输出上限、deadline 和哈希审计记录。 - Linux、包管理器、systemd、journal 和 CALCULET NPU 的只读检查。 - SQLite WAL 状态、FTS5 memory 基础能力、不可重绑的 principal 和追加式 agent/tool 审计事件。 - 基于 Btrfs subvolume/snapshot 的 worldline,包括 branch、diff、commit、log、 非破坏 rollback、陈旧分支保护和 checkout 恢复。 - CALCULET driver 0.9.0 / ABI 1.0.0 的 Rust 数据布局、BAR/DMA 访问、Calbin 0.7.6 解析、内存分配、tensor 和 command 编码。 - 基于 Candle 的 Qwen3 host runner,包括 chat template、tool-call 解析、采样、 prefill/decode 契约、BF16/F32 logits 和厂商 tiled-logit 解码。 ## Workspace `agentos-cli` 是唯一的 binary crate,并生成两个二进制。其他 workspace member 全部是 library。 | Crate | 类型 | 职责 | | --- | --- | --- | | `agentos-cli` | binary | `agentos` CLI 和 `agentos-npu-bridge` | | `agentos-runtime` | library | 配置与 composition root | | `agentos-agent` | library | 有界 agent loop 与审计事件 | | `agentos-protocol` | library | provider-neutral chat/tool 协议 | | `agentos-inference` | library | ntex、远程、subprocess 和测试 backend | | `agentos-tools` | library | 工具策略、schema 校验、审批和 Linux 工具 | | `agentos-core` | library | 身份、ID、事件和公共状态类型 | | `agentos-kernel` | library | 基于 rustix 的 Linux/Btrfs 边界 | | `agentos-memory` | library | SQLite memory、审计和 principal 状态 | | `agentos-worldline` | library | 文件系统 branch/commit/rollback 历史 | | `agentos-npu` | library | NPU 发现、legacy bridge 和 Candle 装配 | | `agentos-candle` | library | Qwen3 host 推理与 CALRT tensor adapter | | `calculet-pcie-abi` | library | 抓取到的 64-bit Linux ioctl ABI | | `calculet-pcie` | library | 安全的 PCIe 设备操作 | | `calculet-calrt` | library | Calbin/runtime/command/tensor 实现 | ## 环境要求 - 64-bit Linux。AgentOS 本身仅支持 Linux,CALCULET ABI 目前也只在 64-bit Linux 上核对过。 - 支持 Rust 2024 edition 的当前 Rust toolchain。 - C toolchain、`pkg-config` 和 OpenSSL 开发文件。SQLite 使用 bundled 源码构建。 - 推荐使用 Btrfs,以获得内核强制只读的 commit snapshot;普通开发并不强制。 Debian/Ubuntu 通常需要: ```bash sudo apt install build-essential pkg-config libssl-dev ``` 构建两个 binary 和所有 library: ```bash cargo build --workspace ``` ## 无 NPU 硬件快速开始 先检查主机和 backend 配置: ```bash cargo run -p agentos-cli --bin agentos -- \ --state-dir target/agentos-state --json doctor ``` 运行一次确定性的模型/工具 plumbing 冒烟测试。内置 fake 会请求真实的只读 `system_inspect` 工具,但它不是在 NPU 硬件缺失时使用的远程 mock: ```bash cargo run -p agentos-cli --bin agentos -- \ --state-dir target/agentos-state --fake-model --json \ agent once "检查当前 Linux 系统" ``` 不要以 root 运行 agent。默认 principal 使用当前 real UID 作为 owner,使用当前 effective UID/GID 作为 agent 身份。 ## 远程 OpenAI-compatible Mock 推理 没有 NPU 硬件时,mock 测试使用远程 OpenAI-compatible 模型。AgentOS 支持 配置 API base URL 下的 `/chat/completions` 或 `/responses`。远程 URL 可以 使用 HTTP 或 HTTPS;涉及 credential 或不可信网络时应使用 HTTPS。模型 URL 不能是 localhost 或 loopback,因为本机模型服务必须使用 UDS。 ```bash export AGENTOS_MODEL_BACKEND=openai_compatible export AGENTOS_OPENAI_COMPATIBLE_API_KEY='...' export AGENTOS_OPENAI_COMPATIBLE_BASE_URL='https://api.openai.com/v1' export AGENTOS_OPENAI_COMPATIBLE_MODEL='your-model' export AGENTOS_OPENAI_COMPATIBLE_API='responses' # 或 chat_completions cargo run -p agentos-cli --bin agentos -- \ --state-dir target/agentos-state \ agent once "总结当前系统状态" ``` 也可以用 `OPENAI_API_KEY` 作为 fallback。远程 adapter 当前要求非空 credential。暂不支持 streaming。 ## 本机模型传输 同一台 Linux 主机上的常驻模型必须暴露 filesystem Unix domain socket。不要 监听 localhost、loopback 或其他 TCP 地址。Socket path 及其 owner/group/mode 属于 OS 安全边界的一部分。 Legacy llama-server 的 `--host` 参数以 `.sock` 结尾时已经支持这种模式。 AgentOS 通过 AF_UNIX 承载熟悉的 OpenAI-compatible HTTP 请求格式,所以这是 UDS 上的 HTTP 消息 framing,而不是 localhost 上的 HTTP。纯 Rust Candle backend 在进程内运行,不需要 IPC socket。 ## 只读工具 | 工具 | 可用条件 | 操作 | | --- | --- | --- | | `system_inspect` | 始终 | kernel、uptime、load、内存、根文件系统、OS release | | `npu_inspect` | 始终 | CALCULET 设备节点、module/sysfs/proc monitor、CALRT library | | `package_query` | 始终 | 通过 dpkg、rpm 或 pacman 精确查询一个包 | | `service_inspect` | 配置后 | 对 allowlist 内的 service 执行有界 `systemctl show` | | `journal_read` | 配置后 | 对 allowlist 内的 service 执行有界 journal 读取 | 使用精确、逗号分隔的 allowlist 启用 service 工具: ```bash export AGENTOS_SERVICE_INSPECT_ALLOWLIST='agentos.service,agentos-npud.service' ``` 当前没有任何 mutation 工具。`agentos-tools` 中的 approval ledger 只是契约 基础设施,不是完整的权限 broker。 ## 文件系统 Worldline Worldline 在不 patch 内核的前提下提供类似 Git 的文件系统历史。在 Btrfs 上, current/branch tree 是 writable snapshot,commit tree 是 readonly snapshot。 其他文件系统使用 copy fallback,但 fallback 不具备内核强制不可变性。 ```bash AGENTOS=(cargo run -q -p agentos-cli --bin agentos -- \ --state-dir target/agentos-state --json worldline) "${AGENTOS[@]}" init "${AGENTOS[@]}" branch "${AGENTOS[@]}" status "${AGENTOS[@]}" log --limit 20 ``` `branch` 会返回 worldline ID 和路径。修改 branch tree 后执行: ```bash "${AGENTOS[@]}" diff "${AGENTOS[@]}" commit --message "描述变更" "${AGENTOS[@]}" rollback --message "回退到已知状态" "${AGENTOS[@]}" discard ``` Rollback 会创建新 commit,不会改写历史。Worldline 当前仍由 CLI 显式管理; agent run 不会自动创建或提交 branch。 ## NPU 路径 ### Legacy llama-server bridge Legacy `npu` backend 会执行 `agentos-npu-bridge`,bridge 只连接 filesystem Unix domain socket,并通过该 socket 发送 `/v1/chat/completions`。此外还要求 CALCULET 设备、driver sysfs 状态和厂商 CALRT shared library 全部 ready。 ```bash export AGENTOS_MODEL_BACKEND=npu export AGENTOS_NPU_BRIDGE_COMMAND='agentos-npu-bridge' export AGENTOS_NPU_SERVER_SOCKET='/run/agentos/npu.sock' export AGENTOS_NPU_SERVER_MODEL='agentos-npu' # CALRT 不在自动检查路径时可覆盖: export AGENTOS_CALRT_LIBRARY='/opt/calculet/lib/libcalrt-linux-x86_64.so' ``` 抓取到的 llama-server 可使用 `--host /run/agentos/npu.sock` 启动,并通过 socket 目录及 socket 的 owner/group/mode 限制访问。不需要 TCP listener。 ### 纯 Rust Candle/CALRT 路径 `npu_candle` 用 Rust 替代魔改 llama.cpp 的 host 代码: ```bash export AGENTOS_MODEL_BACKEND=npu_candle export AGENTOS_NPU_CALBIN='/path/to/calbin-directory' export AGENTOS_NPU_TOKENIZER='/path/to/tokenizer.json' export AGENTOS_NPU_DEVICE_INDEX=0 ``` `doctor` 可以在不打开设备的情况下解析这些文件并报告 model plan。对抓取到的 Qwen3 部署,host 已校验 40,960 token context、151,936 logits 和 151,669 token vocabulary,并会屏蔽额外的 267 个 padded logit ID。 这个 backend 目前会刻意保持 not ready:`calculet-calrt` 已能部署参数和传输 tensor,但 `ConfiguredRuntime::submit()` 仍缺少 CCU relocation、job launch/completion 和设备 KV-cache reset。当前开发机没有验证过任何真实 NPU 推理结果。 ## 配置 | 环境变量 | 默认值 | 含义 | | --- | --- | --- | | `AGENTOS_STATE_DIR` | `$XDG_DATA_HOME/agentos` 或 `~/.local/share/agentos` | SQLite 与 worldline 根目录 | | `AGENTOS_MODEL_BACKEND` | `auto` | `auto`、`openai_compatible`、`npu`、`npu_candle`、`subprocess`、`fake` | | `AGENTOS_AGENT_ID` | `default-agent` | 稳定的逻辑 agent ID | | `AGENTOS_OWNER_UID` | real UID | owner Linux UID | | `AGENTOS_AGENT_UID` | effective UID | 要求的执行 UID | | `AGENTOS_AGENT_GID` | effective GID | 要求的执行 GID | | `AGENTOS_OPENAI_COMPATIBLE_API_KEY` | `OPENAI_API_KEY` | 远程 bearer credential | | `AGENTOS_OPENAI_COMPATIBLE_BASE_URL` | `https://api.openai.com/v1` | 远程 compatible API root;禁止 localhost/loopback | | `AGENTOS_OPENAI_COMPATIBLE_MODEL` | 空 | provider model 名称 | | `AGENTOS_OPENAI_COMPATIBLE_API` | `chat_completions` | `chat_completions` 或 `responses` | | `AGENTOS_OPENAI_COMPATIBLE_MAX_RETRIES` | `2` | 有界 HTTP retry 次数 | | `AGENTOS_MODEL_COMMAND` | 空 | 显式 subprocess 测试/bridge 命令 | | `AGENTOS_MODEL_TIMEOUT_S` | `240` | model/bridge 超时 | | `AGENTOS_NPU_BRIDGE_COMMAND` | 空 | legacy NPU bridge 命令 | | `AGENTOS_NPU_SERVER_SOCKET` | `/run/agentos/npu.sock` | legacy llama-server Unix socket | | `AGENTOS_NPU_SERVER_MODEL` | `agentos-npu` | legacy llama-server model 名称 | | `AGENTOS_NPU_SERVER_TIMEOUT_S` | `240` | legacy llama-server UDS HTTP 超时 | | `AGENTOS_NPU_CALBIN` | 空 | 纯 Rust Calbin 目录 | | `AGENTOS_NPU_TOKENIZER` | 空 | 纯 Rust tokenizer JSON | | `AGENTOS_NPU_DEVICE_INDEX` | `0` | `/dev/calculetN` 序号 | | `AGENTOS_CALRT_LIBRARY` | 自动检查 | 厂商 CALRT shared library 覆盖路径 | | `AGENTOS_SERVICE_INSPECT_ALLOWLIST` | 空 | 启用的 systemd service 名称 | | `AGENTOS_TOOL_OUTPUT_LIMIT_BYTES` | `65536` | 单个工具序列化输出上限 | | `AGENTOS_TOOL_ARGUMENT_LIMIT_BYTES` | `65536` | 单次调用参数上限 | | `AGENTOS_AGENT_MAX_ITERATIONS` | `8` | 模型/工具循环轮数 | | `AGENTOS_AGENT_MAX_TOOL_CALLS` | `16` | 单次 run 的 tool call 总数 | | `AGENTOS_AGENT_MAX_ELAPSED_S` | `120` | 单次 run 总 deadline | | `AGENTOS_AGENT_MAX_OUTPUT_TOKENS` | `2048` | 每轮模型输出预算 | | `AGENTOS_AGENT_MAX_TOTAL_TOKENS` | `65536` | 累计 token 预算 | | `AGENTOS_AGENT_MAX_SAFE_WORKERS` | `4` | 并行 safe-tool worker 数量 | `auto` 模式依次选择 UDS legacy NPU 和远程 OpenAI-compatible。Subprocess 与 fake 都是显式测试 adapter,未完成的 Candle backend 不会被自动选中。 ## 状态目录 ```text AGENTOS_STATE_DIR/ agentos.sqlite3 # principal、审计事件、memory、FTS index worldline/ current/ # 当前文件系统 tree branches/ # writable candidate tree commits/ # commit tree metadata/ # commit 和 branch 记录 refs/ # HEAD reference replaced/ # 可恢复的旧 checkout ``` ## 开发 ```bash cargo fmt --all --check cargo test --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings ``` 部分 NPU parser 测试使用本地、被 git 忽略的 `npu_features/snapshot_20260801` 抓取。这些测试只能验证 host 解析,不是硬件 测试;干净 clone 也可能不包含该 fixture。 项目自有的 low-level Linux 调用使用 `rustix`,AgentOS 不直接添加 `libc` syscall wrapper。这不代表使用 `std`/OpenSSL 的最终 binary 完全没有 libc ABI 依赖。 ## 已知缺口 - 尚无常驻 AgentOS 控制 daemon 或权限 broker;本机 llama-server 模型传输已经 使用 UDS。 - 尚无 mutation 工具或完整的权限审批路径。 - 远程推理尚不支持 streaming。 - 纯 Rust NPU job submission 和真实板卡验证尚未完成。 - Copy worldline backend 不具备 Btrfs 的内核强制只读 commit。 - Memory/recall 基础能力已存在于 library,但尚未暴露为 agent 工具或 CLI。 ## License 说明 AgentOS crates 声明为 Apache-2.0。抓取的 CALCULET PCIe ABI 与设备 wrapper crates 声明为 GPL-2.0-only,`calculet-calrt` 保留厂商 license 文件。重新分发前 请分别检查各 crate manifest。