- 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.
11 KiB
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。
当前成熟度边界
已经可用:
agentosone-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_candlebackend; - 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 骨架 |
保持依赖方向从高层向低层:
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。
修改流程
- 用
rg定位实现和调用方,先确认改动属于哪个 crate。 - 先写清安全边界和失败模式;系统层能力默认 fail closed。
- 修改公共协议时,同步所有 backend、tool adapter、CLI 和双语 README。
- 新增环境变量时,同步
RuntimeConfig::from_env、doctor 和配置表。 - 新增 NPU ABI 时,对照
npu_features/cal-pcie-0.9.0或 CALRT 源码,并补布局、 opcode、边界和 mock 测试。 - 不要改写或删除用户的
npu_features/抓取、模型文件和未提交工作。
完成前至少执行:
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 硬件验证。