- Introduced a new Chinese version of the README (README_CN.md) to provide localized documentation for AgentOS. - Refactored the NPU bridge to utilize Unix domain sockets instead of HTTP loopback, enhancing security and performance. - Updated the NPU backend to include a server socket configuration, ensuring proper communication over Unix sockets. - Modified the Ntex client to support both network and Unix socket transports, improving flexibility in backend communication. - Adjusted validation logic to enforce the use of Unix sockets for local model endpoints, rejecting loopback HTTP addresses. - Enhanced error messages and documentation throughout the codebase to clarify the new socket-based architecture.
331 lines
14 KiB
Markdown
331 lines
14 KiB
Markdown
# 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 <worldline-id>
|
||
"${AGENTOS[@]}" commit <worldline-id> --message "描述变更"
|
||
"${AGENTOS[@]}" rollback <commit-id> --message "回退到已知状态"
|
||
"${AGENTOS[@]}" discard <worldline-id>
|
||
```
|
||
|
||
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。
|