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.
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
# AgentOS 工程约定
|
||||
|
||||
本文件面向在本仓库内工作的代码代理。修改前先读本文件、根
|
||||
`Cargo.toml`,再读目标 crate 的源码。不要根据旧 Python 版本、Octos 或
|
||||
`npu_features/` 中的厂商样例臆测当前行为;`crates/` 才是实现事实来源。
|
||||
|
||||
## 项目目标
|
||||
|
||||
AgentOS 是运行在裸 Linux 上的 low-level OS agent,而不是 Linux 发行版、
|
||||
容器沙箱或内核 fork。核心原则是尽量复用 Linux 原生能力:进程 UID/GID、
|
||||
文件权限、Unix 凭据、pidfd、`no_new_privs`、Btrfs subvolume/snapshot 和设备
|
||||
ioctl。
|
||||
|
||||
当前安全模型是稳定的 `AgentId -> (owner UID, agent UID, agent GID)` 绑定:
|
||||
|
||||
- agent 进程不能以 UID 0 或 GID 0 运行;
|
||||
- 每次执行前必须核对进程的 effective UID/GID;
|
||||
- 一个状态数据库中,agent UID 只能绑定给一个 active `AgentId`;
|
||||
- 不额外构造 namespace、容器或通用 sandbox;
|
||||
- `no_new_privs` 是补充保护,不能替代 UID/GID 和工具策略;
|
||||
- 模型不能获得任意 shell,更不能直接获得 root shell。
|
||||
|
||||
不要把 `owner_uid` 与 `agent_uid` 混为一谈。前者表示拥有者,后者才是内核
|
||||
实际执行主体。新增 daemon 或 broker 时,Unix socket 对端必须用内核提供的
|
||||
peer credentials 鉴权,不能信任请求体里的 UID。
|
||||
|
||||
## 当前成熟度边界
|
||||
|
||||
已经可用:
|
||||
|
||||
- `agentos` one-shot CLI、doctor 和确定性 fake backend;
|
||||
- OpenAI-compatible Chat Completions / Responses 非流式后端;
|
||||
- `agentos.chat.v1` 内部协议、严格工具 schema、预算和循环检测;
|
||||
- 只读 Linux 工具、SQLite 审计/记忆、Btrfs worldline 与 copy fallback;
|
||||
- CALCULET PCIe ABI、Rust ioctl/DMA 包装、Calbin 解析、张量/命令结构;
|
||||
- Candle/Qwen3 host pipeline、tool-call 模板和 CALRT 张量适配;
|
||||
- 旧 llama-server UDS bridge;HTTP 消息格式直接承载在 AF_UNIX 上,不经过 TCP。
|
||||
|
||||
尚未完成:
|
||||
|
||||
- 纯 Rust CALRT 的 CCU relocation、job launch/completion 和设备 KV reset;
|
||||
- 可在真实 NPU 上完成推理的 `npu_candle` backend;
|
||||
- typed mutation broker 和任何变更型系统工具;
|
||||
- 长驻 AgentOS control daemon、control UDS RPC、服务安装和完整硬件端到端测试。
|
||||
|
||||
`ConfiguredRuntime::submit()` 当前必须 fail closed 并返回
|
||||
`HardwareExecutionUnavailable`。在没有真实板卡证据前,不得把
|
||||
`npu_candle` 标记为 ready,不得让 `auto` 选择它,也不得用 mock 测试宣称
|
||||
硬件推理已验证。
|
||||
|
||||
## Workspace 与模块所有权
|
||||
|
||||
除 `agentos-cli` 外,`crates/` 下均为 library crate。
|
||||
|
||||
| Crate | 职责 |
|
||||
| --- | --- |
|
||||
| `agentos-cli` | `agentos` 与 `agentos-npu-bridge` 两个 binary;只做参数解析和装配入口 |
|
||||
| `agentos-runtime` | composition root、环境配置、identity/backend/tool 装配、doctor |
|
||||
| `agentos-agent` | 有预算的 agent loop、工具调度、循环检测、审计事件 |
|
||||
| `agentos-protocol` | provider-neutral `agentos.chat.v1` 类型与 `ChatBackend` trait |
|
||||
| `agentos-inference` | ntex HTTP、OpenAI-compatible、subprocess、fake/scripted backend |
|
||||
| `agentos-tools` | fail-closed registry、schema 校验、审批契约和 Linux 只读工具 |
|
||||
| `agentos-core` | ID、principal、execution identity、审计和 worldline 公共类型 |
|
||||
| `agentos-kernel` | Linux/rustix 边界、凭据、pidfd、文件原子写、Btrfs ioctl |
|
||||
| `agentos-memory` | SQLite WAL、FTS5、principal 绑定、memory 和 audit event |
|
||||
| `agentos-worldline` | 类 Git 的 filesystem history、branch/commit/diff/rollback/recovery |
|
||||
| `agentos-npu` | NPU probe、旧 bridge、Rust Candle NPU backend 装配 |
|
||||
| `agentos-candle` | Qwen3 模板/tokenizer/sampling 与 Calbin prefill/decode host runner |
|
||||
| `calculet-pcie-abi` | 驱动 0.9.0 / ABI 1.0.0 的 64-bit Linux ioctl 布局 |
|
||||
| `calculet-pcie` | 安全的设备、BAR、DMA、MSI、reset 和 board/process API |
|
||||
| `calculet-calrt` | Calbin、allocator、tensor、command stream、DeviceIo 和 runtime 骨架 |
|
||||
|
||||
保持依赖方向从高层向低层:
|
||||
|
||||
```text
|
||||
agentos-cli -> agentos-runtime -> agentos-agent/tools/inference/npu/worldline/memory
|
||||
agentos-npu -> agentos-candle -> calculet-calrt -> calculet-pcie -> calculet-pcie-abi
|
||||
agentos-kernel/core/protocol 是底层公共边界
|
||||
```
|
||||
|
||||
不要让底层 crate 反向依赖 CLI 或 runtime。跨 provider 的消息类型放在
|
||||
`agentos-protocol`;Linux syscall/ABI 放在 `agentos-kernel` 或对应的
|
||||
`calculet-*` crate;composition 逻辑只放在 `agentos-runtime`。
|
||||
|
||||
## 不可破坏的设计约束
|
||||
|
||||
### Linux 与系统调用
|
||||
|
||||
- 项目只支持 Linux;当前 CALCULET ABI 只验证过 64-bit Linux。
|
||||
- 项目自有的低层 syscall/ioctl 优先走 `rustix`,不要直接新增 `libc` 调用。
|
||||
- 这不表示最终二进制完全不链接 libc;Rust `std`、OpenSSL 等依赖仍可使用
|
||||
系统 ABI。
|
||||
- `unsafe` 仅允许出现在无法避免的 ABI 边界,必须就结构布局、指针生命周期
|
||||
和 opcode 写英文 `SAFETY` 注释,并在调用前完成长度、对齐和范围校验。
|
||||
- 不要为了 worldline patch 内核。优先使用现有 Btrfs ioctl;非 Btrfs 环境保留
|
||||
copy fallback。
|
||||
|
||||
### 工具与权限
|
||||
|
||||
- registry 必须显式 allowlist;未知工具一律拒绝。
|
||||
- 所有 tool schema 默认 strict:object、列出全部 required、
|
||||
`additionalProperties: false`。
|
||||
- 参数和输出必须有字节上限,外部命令必须有 deadline、`kill_on_drop`,并移除
|
||||
API key 环境变量。
|
||||
- 只有标记为 `ConcurrencyClass::Safe` 的只读工具可以并行;变更工具必须
|
||||
exclusive。
|
||||
- 现有 `ApprovalLedger` 只是进程内、单次、精确参数绑定的契约。实现 mutation
|
||||
前还必须有 typed broker、内核凭据校验、持久审计和失败恢复,不能把审批 ID
|
||||
当作任意命令授权。
|
||||
- 不得增加通用 `shell`、`exec`、任意路径写入或任意 systemd unit 工具。
|
||||
|
||||
### 推理后端
|
||||
|
||||
- 内部统一使用 `agentos.chat.v1`,provider 差异留在 backend adapter。
|
||||
- 缺少 NPU 硬件时的 mock 是远程 OpenAI-compatible 模型,不是内置
|
||||
`FakeBackend`。远程传输可以使用 HTTP 或 HTTPS;使用 HTTPS 时必须验证 peer。
|
||||
- 本机常驻模型服务必须使用 filesystem Unix domain socket,禁止监听或连接
|
||||
localhost、loopback 或其他 TCP 地址。纯 Rust Candle in-process 路径不需要 IPC。
|
||||
- 本机 llama-server 可以保留 OpenAI-compatible HTTP 消息格式,但必须通过
|
||||
ntex 自定义 connector 承载在 AF_UNIX 上,用户配置只能暴露 socket path,不能
|
||||
接受本机 URL。
|
||||
- OpenAI-compatible HTTP 和 UDS HTTP client 使用 `ntex`,不要引入 `reqwest`。
|
||||
- 禁止自动 redirect;响应大小、超时和 retry 必须有界。
|
||||
- 支持 Chat Completions 与 Responses 两种方言,但不要假设所有兼容服务支持
|
||||
完全相同的字段。新增兼容逻辑必须有请求构造和响应解析测试。
|
||||
- subprocess backend 只通过 stdin/stdout 传 JSON,stderr 仅用于有界错误信息;
|
||||
不要把 secret 传给子进程。它只作为显式测试/bridge adapter,不能代表本机
|
||||
常驻模型传输,也不能进入 `auto`。
|
||||
- `auto` 当前顺序是 UDS legacy NPU、远程 OpenAI-compatible。Fake 和
|
||||
subprocess 必须显式选择,Rust Candle NPU 在硬件提交完成前不能进入 auto。
|
||||
|
||||
### NPU
|
||||
|
||||
- `npu_features/` 是忽略提交的厂商源码/部署抓取,仅作逆向参考,不能成为
|
||||
发布包运行时依赖。
|
||||
- 原始版本边界是 driver package 0.9.0、driver ABI 1.0.0、CALRT 0.7.6。
|
||||
- ioctl struct 使用 `repr(C, packed)`,任何改动都必须同步 size/opcode 测试。
|
||||
- DMA 单次上限 8 MiB,已知 H2C/C2H 各 8 个 channel;不要绕过现有验证。
|
||||
- Calbin 参数部署会真实写设备。没有用户明确要求和真实硬件测试计划时,不要
|
||||
默认开启 `deploy_parameters`。
|
||||
- captured Qwen3 fixture 的 logits 是 151936,tokenizer vocab 是 151669;额外
|
||||
267 个 padded logits 必须在采样前屏蔽。
|
||||
- host-side `MockDevice` 测试只能验证解析、地址、buffer 和命令编码,不能证明
|
||||
job submission、同步、KV cache 或输出数值正确。远程模型 mock 同样不能证明
|
||||
NPU 硬件正确。
|
||||
- legacy llama-server 的默认 socket 是 `/run/agentos/npu.sock`;doctor 必须检查
|
||||
它确实是可写的 Unix socket,不能仅检查路径存在。
|
||||
|
||||
### Worldline 与持久化
|
||||
|
||||
- Btrfs commit tree 使用 readonly snapshot;branch/current 使用 writable
|
||||
snapshot。
|
||||
- copy fallback 用于开发和无 Btrfs 环境,但当前不会提供内核强制的只读
|
||||
commit tree。不要在文档里把它描述成与 Btrfs 等价的不可变性。
|
||||
- commit 是内容/元数据哈希标识;rollback 必须创建新 commit,不能改写历史。
|
||||
- checkout 要保留 transaction journal、目录 fsync 和可恢复的 replaced tree。
|
||||
- 分支提交必须检查 base HEAD,禁止 stale branch 覆盖新 HEAD。
|
||||
- SQLite principal 绑定不可静默重绑;schema 变更要考虑已有数据库升级。
|
||||
|
||||
## Rust 与依赖规则
|
||||
|
||||
- 使用 workspace 的 Rust edition,不添加 MSRV 或 `rust-toolchain.toml`。
|
||||
- 第三方依赖集中写在根 `Cargo.toml` 的 `[workspace.dependencies]`。
|
||||
- 版本只写主版本号,例如 `serde = "1"`,不要固定 `1.2.3`。
|
||||
- 内部 crate 统一用 `*.workspace = true`。
|
||||
- 读取依赖源码时,从 `$CARGO_HOME/registry/src` 找实际锁定版本,不靠记忆猜 API。
|
||||
- 优先复用已有 crate 和抽象,不复制协议类型、HTTP client、schema validator、
|
||||
runtime probe 或设备 ABI。
|
||||
- 代码注释默认英文;用户可见文档分别维护英文与中文。
|
||||
- 不要加入 Python、`reqwest` 或直接 `libc` 依赖。
|
||||
- 保持开发/测试 profile 的快速编译取向,除非有基准数据,不要随意调高 dev
|
||||
优化或减少 codegen units。
|
||||
|
||||
## 修改流程
|
||||
|
||||
1. 用 `rg` 定位实现和调用方,先确认改动属于哪个 crate。
|
||||
2. 先写清安全边界和失败模式;系统层能力默认 fail closed。
|
||||
3. 修改公共协议时,同步所有 backend、tool adapter、CLI 和双语 README。
|
||||
4. 新增环境变量时,同步 `RuntimeConfig::from_env`、doctor 和配置表。
|
||||
5. 新增 NPU ABI 时,对照 `npu_features/cal-pcie-0.9.0` 或 CALRT 源码,并补布局、
|
||||
opcode、边界和 mock 测试。
|
||||
6. 不要改写或删除用户的 `npu_features/` 抓取、模型文件和未提交工作。
|
||||
|
||||
完成前至少执行:
|
||||
|
||||
```bash
|
||||
cargo fmt --all --check
|
||||
cargo test --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
```
|
||||
|
||||
涉及 CLI 时还要实际运行相关命令;涉及 OpenAI-compatible 时至少覆盖两种 API
|
||||
方言的 serialization/parsing;涉及硬件而本机无板卡时,明确报告未执行的验证。
|
||||
|
||||
部分 NPU 测试依赖本地、被 `.gitignore` 忽略的
|
||||
`npu_features/snapshot_20260801`。fixture 不存在时,应将硬件抓取测试与普通
|
||||
workspace 测试分层,而不是把模型数据提交进仓库或伪造通过结果。
|
||||
|
||||
## 完成标准
|
||||
|
||||
一次改动只有在以下条件都满足时才算完成:
|
||||
|
||||
- crate 边界和依赖方向没有被破坏;
|
||||
- 非法输入、权限不足、后端缺失和硬件缺失均 fail closed;
|
||||
- 无 secret 出现在日志、tool output、子进程或 doctor 报告中;
|
||||
- 单元/集成测试覆盖正常路径与关键拒绝路径;
|
||||
- fmt、workspace test、严格 clippy 通过;
|
||||
- README 与实际成熟度一致,未把 host-side `MockDevice` 或远程模型 mock 写成
|
||||
NPU 硬件验证。
|
||||
Reference in New Issue
Block a user