Files
agentos/README_CN.md
T
emmettlu f863f83960 chore: Add Chinese README and refactor NPU backend to use Unix domain sockets
- 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.
2026-08-02 15:48:09 +08:00

331 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 ToolRegistryLinux 只读工具)
-> 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 本身仅支持 LinuxCALCULET 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 snapshotcommit 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。