diff --git a/docs/design/technical-design-v2.6.md b/docs/design/technical-design-v2.6.md index 7335a1f..3f0f5d4 100644 --- a/docs/design/technical-design-v2.6.md +++ b/docs/design/technical-design-v2.6.md @@ -864,13 +864,128 @@ per-project 测试用 `:memory:` SQLite。全局注册表测试用临时文件 --- -## 14. 风险 +## 14. 容量估算 -| 风险 | 缓解 | -|------|------| -| per-project SQLite 并发 tick | WAL + busy_timeout + per-project asyncio.Lock | -| Agent spawn 子进程回收 | health.py 僵尸检测 + reclaim | -| Inbox JSONL 并发写入 | truncate(不删除),实测 200 并发 0 丢失 | -| 前端 v1→v2 迁移 | v1 Tab 全保留,渐进替换 | -| Daemon 逻辑死循环 | 连续 N tick(默认 20)无变更 → observation 告警 + 通知用户 | -| 反驳权无限协商 | max_rounds 兜底 + 超轮次升级庞统 | +### 14.1 存储容量 + +| 组件 | 单项目估算 | 说明 | +|------|-----------|------| +| blackboard.db | 1-5 MB / 100 任务 | tasks + comments + outputs + reviews + events + experiences,平均每任务 ~50 行数据 | +| artifacts/ | 10-50 MB / 100 任务 | 代码文件、分析报告、数据文件 | +| experiences/ | < 1 MB | 经验条目轻量,文本为主 | +| Inbox JSONL | < 100 KB | 持续 truncate,不累积 | +| _registry.yaml | < 10 KB | 项目元信息,轻量 | + +**总磁盘预估(10 项目,1000 任务)**:~500 MB - 1 GB,完全在 Mac mini 容量范围内。 + +### 14.2 内存占用 + +| 组件 | 占用估算 | 说明 | +|------|---------|------| +| Daemon + FastAPI | 50-100 MB | Python 进程基础 + asyncio event loop | +| 每个 Agent spawn | 100-300 MB | openclaw agent CLI 进程,执行期间临时占用 | +| SQLite 连接池 | < 10 MB | per-project 连接,用完释放 | +| 前端 dist 静态服务 | < 5 MB | 内存映射 | + +**峰值内存(max_global=5,5 个 Agent 同时执行)**:~1-1.5 GB,16GB Mac mini 无压力。 + +### 14.3 并发能力 + +| 维度 | 设计上限 | 瓶颈分析 | +|------|---------|----------| +| 同时活跃项目 | 无硬限(10+) | tick 30s 扫全部项目,每项目 tick 耗时 < 100ms,10 项目 < 1s | +| 并发 Agent | 5 (max_global) | ActiveAgentCounter 控制,超出排队 | +| SSE 连接 | 10-20 | 单机场景足够,FastAPI SSE 无硬限 | +| Inbox 吞吐 | 200+ 写/秒 | truncate 模式,实测无丢失 | +| API QPS | 100+ | FastAPI 单进程足够,无 LB 瓶颈 | + +### 14.4 性能约束 + +| 场景 | 延迟 | 说明 | +|------|------|------| +| 用户提需求 → 任务写入黑板 | < 5s | Agent 对话 + CLI 写入 | +| 任务 pending → Agent 开始执行 | 30s 内 | 最坏等一轮 tick;Inbox 触发可秒级 | +| Agent 完成 → 下游任务 pending | 30s 内 | tick 扫描依赖推进 | +| SSE 事件推送延迟 | < 1s | event loop 内直接推送 | +| 审查 → 反驳权启动 | 30s 内 | tick 扫描 review 状态 | + +--- + +## 15. 失败模式与可靠性 + +### 15.1 进程级故障 + +| 故障 | 检测 | 恢复 | +|------|------|------| +| Daemon 进程崩溃 | PM2 auto restart | PM2 5s 内自动拉起,tick 恢复扫描 | +| Agent spawn 子进程僵死 | health.py 僵尸检测 | 连续 20 tick 无变更 → observation 告警 + reclaim 释放 semaphore | +| Agent spawn 失败(CLI 错误) | spawner 异常捕获 | 标记任务 failed,写入 events 表,不阻塞其他任务 | +| FastAPI 进程异常 | PM2 restart | 与 Daemon 同进程,PM2 统一管理 | + +### 15.2 数据级故障 + +| 故障 | 检测 | 恢复 | +|------|------|------| +| SQLite 写入冲突 | busy_timeout=5s 等待 + WAL 模式 | WAL 允许并发读写;超时后 raise,tick 下次重试 | +| SQLite DB 损坏 | 连接时 PRAGMA integrity_check | per-project 隔离,单 DB 损坏不影响其他项目;从最新 Git 备份恢复 | +| Inbox JSONL 损坏 | JSON 解析异常 | truncate 清空重置,Agent 重发事件 | +| _registry.yaml 损坏 | YAML 解析异常 | Git 版本管理,`git checkout` 恢复 | + +### 15.3 逻辑级故障 + +| 故障 | 检测 | 恢复 | +|------|------|------| +| Agent 无限循环 | 连续 20 tick 无状态变更 | observation 告警 + 通知用户 + reclaim | +| 反驳权无限协商 | max_rounds 兜底 | 超轮次自动升级庞统裁决 | +| 任务卡在 blocked | tick 依赖推进检查 | 每轮 tick 重算依赖,不依赖缓存 | +| Guardrail 误杀 | L1 assert 可能误判 | L2 subagent 二次确认;用户可在 Dashboard 手动 override | + +### 15.4 恢复优先级 + +``` +P0: Daemon 进程 → PM2 auto restart +P1: 数据完整性 → SQLite WAL + Git 备份 +P2: 任务进度 → tick 全量扫描自动恢复 +P3: 经验数据 → experiences 表 + skills/ 目录 Git 版本管理 +``` + +--- + +## 16. 演进路径 + +### 16.1 已知限制与扩展点 + +| 当前限制 | 触发条件 | 演进方向 | +|---------|---------|--------| +| SQLite 单机 | 项目 > 20 或 DB > 100MB | 迁移 PostgreSQL(per-project schema),代码层只改 db.py | +| max_global=5 | Agent 并发不够 | 调整 ActiveAgentCounter 参数;引入优先级队列 | +| 单机部署 | 需要多节点 | Agent spawn 改为远程调度(Windows-Test-Node 已可远程执行) | +| SSE 单进程 | SSE 连接 > 50 | 引入 Redis pub/sub + 多 worker | +| 无用户认证 | 多用户协作需求 | 引入 API token + per-project 权限(project.yaml 扩展) | + +### 16.2 接口抽象层(为演进预留) + +关键接口已做抽象,替换底层不影响上层逻辑: + +| 接口 | 当前实现 | 替换时影响范围 | +|------|---------|--------------| +| `blackboard.db.py` | SQLite | 只改 db.py,operations/queries 不变 | +| `daemon.spawner.py` | asyncio.create_subprocess_exec | 只改 spawner.py,dispatcher 不变 | +| `daemon.counter.py` | asyncio.Semaphore | 只改 counter.py,dispatcher 不变 | +| `api.sse_routes.py` | FastAPI SSE | 只改 sse_routes.py,前端不变 | + +--- + +## 17. 风险 + +| 风险 | 概率 | 影响 | 缓解 | +|------|------|------|------| +| per-project SQLite 并发 tick | 中 | 中 | WAL + busy_timeout + per-project asyncio.Lock | +| Agent spawn 子进程回收 | 中 | 中 | health.py 僵尸检测 + reclaim | +| Inbox JSONL 并发写入 | 低 | 低 | truncate(不删除),实测 200 并发 0 丢失 | +| 前端 v1→v2 迁移 | 低 | 低 | v1(8082) 和 v2(8083) 独立运行,渐进替换 | +| Daemon 逻辑死循环 | 低 | 中 | 连续 20 tick 无变更 → observation 告警 + 通知用户 | +| 反驳权无限协商 | 低 | 低 | max_rounds 兜底 + 超轮次升级庞统 | +| 上下文窗口膨胀 | 中 | 中 | L0-L3 四层分级 + 产出写入黑板不累积 | +| 经验注入噪声 | 低 | 低 | 只注入 matching tag 的经验;N 条阈值可控 | +| Guardrail 误杀 | 低 | 中 | L1+L2 双层验证;用户可 Dashboard override |