AgentOS P0
这是 AgentOS 的第一个可运行单机纵向闭环:
模拟语音文本输入
-> 主 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. 当前工作区位于:
~/.local/share/agentos/workspace/current
在 Btrfs 上, 每次执行通过可写 subvolume snapshot 创建分叉. 子 Agent 不会直接修改
current. 提交时旧 current 被移动到 history, 新分叉切换为 current. 丢弃时分叉
被原子移动为 history/<worldline>.discarded, 当前工作区不变, 后续由受控 GC 物理清理.
:rollback <worldline-id> 可以恢复该次提交前的完整 Btrfs 状态.
非 Btrfs 文件系统使用完整目录复制作为功能降级.
重大操作会为模型给出的 N 个选项建立 N 条世界线. 用户选择的世界线在前台执行并显示
完整结果, 其余 N-1 条交给后台 multi 子 Agent 执行. 后台世界线完成后自动保留为 kept
并只向终端发送完成或失败通知, 不会自动覆盖 current. 所有分支都在前台执行前从同一个文件系统基点创建,
其 diff 也固定使用该基点, 不受主世界线后续提交影响. 默认后台 worker 数为 4, 可通过
AGENTOS_BACKGROUND_WORKERS 调整.
本地模型
默认复用现有模型命令:
/home/emmett/Repos/npu_models/run.sh
可通过环境变量覆盖:
export AGENTOS_MODEL_COMMAND='/path/to/model-command'
主 Runtime 在宿主机调用 NPU 模型, token 会实时输出并同时缓存供 JSON 解析. 子 Agent 容器不直接访问 NPU. 单块 NPU 的推理调用会串行化, 已生成计划的多个 Docker 子 Agent 仍可并行执行.
模型命令必须支持 --request-json-stdin, 并从 stdin 接收:
{"system_prompt":"...","prompt":"...","max_new_tokens":512}
因此用户输入和召回记忆不会出现在进程命令行参数中.
长期记忆
长期记忆保存在 ~/.local/share/agentos/agentos.sqlite3. 每次模型推理都会重新执行以下链路:
当前用户输入 + 已选方案 + 世界线状态
-> 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.
开发
PYTHONPATH=src uv run python -m unittest discover -s tests -v
uvx ruff check .
uvx ruff format --check .
离线冒烟模式不调用 NPU:
PYTHONPATH=src uv run python -m agentos.cli \
--fake-model \
--once '记录第一条输入' \
--choice 1 \
--decision commit
部署
./deploy/install.sh
安装脚本会安装并启动 Docker, 将当前用户加入 docker 组, 构建
agentos-worker:0.1.0, 然后使用 uv tool 安装 agentos 命令. 首次加入 Docker 组后
需要重新登录. 当前会话可用 sg docker -c 'agentos --fake-model ...' 验证.
交互启动:
agentos
命令:
:history
:jobs
:memory [query]
:forget <memory-id>
:rollback <worldline-id>
:workspace
:quit
当前 P0 边界
- 输入源是终端文本, 语义上视为未来 ASR 的 transcript. 交互行编辑支持中文宽字符.
- 子 Agent 执行模型生成的非交互 Bash 脚本.
- Runtime 与模型之间目前使用单次进程调用, 后续可替换为常驻模型服务.
- 外部网络和现实副作用尚未开放.
- 长期记忆包含已提交执行经验和模型生成的低权重备注, 支持动态 system context 和 forget.