Files
agentos/AGENTS.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

210 lines
11 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 工程约定
本文件面向在本仓库内工作的代码代理。修改前先读本文件、根
`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 bridgeHTTP 消息格式直接承载在 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-*` cratecomposition 逻辑只放在 `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 默认 strictobject、列出全部 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 传 JSONstderr 仅用于有界错误信息;
不要把 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 是 151936tokenizer 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 snapshotbranch/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 硬件验证。