# AgentOS P0 这是 AgentOS 的第一个可运行单机纵向闭环: ```text 模拟语音文本输入 -> 主 Runtime 检索长期记忆 -> 本地 NPU 模型提出多个可执行选项 -> 用户选择 -> Runtime 判断操作是否会重大影响未来时间线 -> Btrfs 从同一基点分叉需要执行的世界线 -> 本地 NPU 模型生成各世界线的执行计划 -> Docker 启动独立 AgentInstance -> 查看结果和文件差异 -> 提交, 丢弃或保留分叉 ``` ## 安全边界 每个 active AgentInstance 使用独立临时数值 UID/GID. 子 Agent 容器具有以下约束: - `--network none`; - 只读容器根文件系统; - `--cap-drop ALL`; - `no-new-privileges`; - CPU, RAM, PID 和文件描述符限制; - 不挂载 Docker socket, 模型目录, 记忆数据库或宿主仓库; - 只读挂载执行计划, 读写挂载专属世界线工作区; - 执行前把专属分叉的所有权移交给临时 UID/GID, 执行结束后完整恢复原所有者; Docker 复用物理机内核. Docker 不是业务授权源, 主 Runtime 仍负责选项、记忆和世界线状态. ## 工作区与回滚 默认状态目录为 `~/.local/share/agentos`. 当前工作区位于: ```text ~/.local/share/agentos/workspace/current ``` 在 Btrfs 上, 每次执行通过可写 subvolume snapshot 创建分叉. 子 Agent 不会直接修改 `current`. 提交时旧 `current` 被移动到 `history`, 新分叉切换为 `current`. 丢弃时分叉 被原子移动为 `history/.discarded`, 当前工作区不变, 后续由受控 GC 物理清理. `:rollback ` 可以恢复该次提交前的完整 Btrfs 状态. 非 Btrfs 文件系统使用完整目录复制作为功能降级. 重大操作会为模型给出的 N 个选项建立 N 条世界线. 用户选择的世界线在前台执行并显示 完整结果, 其余 N-1 条交给后台 multi 子 Agent 执行. 后台世界线完成后自动保留为 `kept` 并只向终端发送完成或失败通知, 不会自动覆盖 `current`. 所有分支都在前台执行前从同一个文件系统基点创建, 其 diff 也固定使用该基点, 不受主世界线后续提交影响. 默认后台 worker 数为 4, 可通过 `AGENTOS_BACKGROUND_WORKERS` 调整. ## 本地模型 默认复用现有模型命令: ```text /home/emmett/Repos/npu_models/run.sh ``` 可通过环境变量覆盖: ```bash export AGENTOS_MODEL_COMMAND='/path/to/model-command' ``` 主 Runtime 在宿主机调用 NPU 模型, token 会实时输出并同时缓存供 JSON 解析. 子 Agent 容器不直接访问 NPU. 单块 NPU 的推理调用会串行化, 已生成计划的多个 Docker 子 Agent 仍可并行执行. 模型命令必须支持 `--request-json-stdin`, 并从 stdin 接收: ```json {"system_prompt":"...","prompt":"...","max_new_tokens":512} ``` 因此用户输入和召回记忆不会出现在进程命令行参数中. ## 长期记忆 长期记忆保存在 `~/.local/share/agentos/agentos.sqlite3`. 每次模型推理都会重新执行以下链路: ```text 当前用户输入 + 已选方案 + 世界线状态 -> SQLite FTS/中文子串候选召回 -> 相关性 65% + 重要性 20% + 时间新鲜度 15% 排序 -> 按条数和 token 预算裁剪 -> 生成带 current_time/memory_id/kind/timestamp 的动态 system context -> 生成逐级减少低相关记忆的 system context 候选 -> 由 Qwen tokenizer 精确选择不超过 NPU 1024 token 限制的最大候选 -> 通过独立 system role 调用 NPU 模型 ``` 默认最多召回 6 条、占用约 320 token, 可通过 `AGENTOS_MEMORY_RECALL_LIMIT` 和 `AGENTOS_MEMORY_TOKEN_BUDGET` 调整. 只有已提交世界线的执行经验会进入 active 长期记忆; 丢弃、失败和回滚的记录仍保留审计数据, 但不会再被召回. 若去掉全部记忆后任务提示仍然超限, NPU 适配器会保留提示开头和末尾并仅截断中间部分. 因此 JSON 输出约束仍会保留, 超限也不会再产生 Python traceback. ## 开发 ```bash PYTHONPATH=src uv run python -m unittest discover -s tests -v uvx ruff check . uvx ruff format --check . ``` 离线冒烟模式不调用 NPU: ```bash PYTHONPATH=src uv run python -m agentos.cli \ --fake-model \ --once '记录第一条输入' \ --choice 1 \ --decision commit ``` ## 部署 ```bash ./deploy/install.sh ``` 安装脚本会安装并启动 Docker, 将当前用户加入 `docker` 组, 构建 `agentos-worker:0.1.0`, 然后使用 `uv tool` 安装 `agentos` 命令. 首次加入 Docker 组后 需要重新登录. 当前会话可用 `sg docker -c 'agentos --fake-model ...'` 验证. 交互启动: ```bash agentos ``` 命令: ```text :history :jobs :memory [query] :forget :rollback :workspace :quit ``` ## 当前 P0 边界 - 输入源是终端文本, 语义上视为未来 ASR 的 transcript. 交互行编辑支持中文宽字符. - 子 Agent 执行模型生成的非交互 Bash 脚本. - Runtime 与模型之间目前使用单次进程调用, 后续可替换为常驻模型服务. - 外部网络和现实副作用尚未开放. - 长期记忆包含已提交执行经验和模型生成的低权重备注, 支持动态 system context 和 forget.