13 KiB
13 KiB
v2.6 部署方案设计
版本: v2.6.2-deploy 基于: technical-design-v2.6.md v2.6.2 作者: 庞统(副军师)🐦 日期: 2026-05-16
1. 部署环境
| 项目 | 规格 |
|---|---|
| 主机 | 楚锋的 Mac mini (Apple M4, ARM64, 16GB RAM, macOS) |
| Python | 3.11(moziplus venv) |
| Node.js | v22.22.1 |
| PM2 | 6.0.14 |
| OpenClaw Gateway | 127.0.0.1:18789 |
| NAS | 192.168.2.154(SMB /Volumes/stock/) |
| Windows-Test-Node | 192.168.2.33 |
目录规划
| 用途 | 路径 | 说明 |
|---|---|---|
| 开发目录 | ~/.openclaw/sanguo_projects/sanguo_moziplus_v2/ |
Git 管理 |
| 安装目录 | ~/.sanguo_projects/sanguo_moziplus_v2/ |
PM2 运行 |
| Git 远程 | gitee (origin) + gitea (NAS 192.168.2.154) | 双远程 |
2. 部署架构
PM2 (进程管理器)
├── sanguo-moziplus-v2 (port 8083) ← 🆕 v2 主进程(API + Daemon ticker + 前端)
├── sanguo-moziplus (port 8082) ← v1 保留(v2 验证后下线)
├── sanguo-git-sync ← 不变
├── sanguo-mail-* (8个) ← v2 验证后逐步下线
└── sanguo-mozi ← 不变
进程内部结构:
sanguo-moziplus-v2
├── uvicorn (FastAPI) — asyncio event loop
│ ├── API 路由(黑板/Daemon/SSE/项目)
│ ├── 静态文件服务(frontend/dist/)
│ └── SSE 推送端点(/api/events)
├── asyncio background task: Daemon ticker(30s)
├── asyncio background task: Inbox watcher(1s 轮询)
├── Agent spawn: asyncio.create_subprocess_exec(异步非阻塞)
└── ActiveAgentCounter(asyncio.Semaphore)
纯 asyncio 单线程。 Daemon ticker、API、SSE、Agent spawn 全部在同一个 asyncio event loop 中,无同步阻塞调用。Full Agent spawn 用 asyncio.create_subprocess_exec(不 await 完成),Subagent 用 Gateway 内部 API。不新增 PM2 进程。
3. 多项目数据布局
~/.sanguo_projects/sanguo_moziplus_v2/
├── projects/
│ ├── _registry.yaml ← 全局注册表(YAML,人可读,Git 版本管理)
│ ├── sanguo_quant_live/
│ │ ├── blackboard.db ← per-project 黑板
│ │ ├── config/
│ │ │ └── project.yaml ← per-project 配置覆盖
│ │ ├── artifacts/ ← per-project 产出物
│ │ │ └── {task-id}/
│ │ │ ├── outputs/
│ │ │ ├── reviews/
│ │ │ ├── archive/
│ │ │ └── data/
│ │ └── experiences/ ← per-project 经验库
│ │ └── skills/ ← per-project Skill 覆盖/扩展
│ ├── sanguo_vnpy/
│ │ └── ...
│ └── _archived/ ← 归档项目(只读)
│ └── old_project/
│
├── inbox/
│ └── daemon.jsonl ← Inbox 事件推送
│
├── skills/ ← 全局 Skill 库
│ ├── builtins/ ← 系统内置 Skill
│ │ ├── blackboard_operations/
│ │ ├── code_review/
│ │ └── data_validation/
│ └── custom/ ← 蒸馏产出/用户创建 Skill
│ └── {skill_id}/
│ ├── SKILL.md ← 四要素
│ ├── template.md ← 可选详细模板
│ └── meta.yaml ← 版本/来源/tag
│
├── config/
│ ├── default.yaml ← 全局默认配置
│ ├── guardrails.yaml
│ ├── template_components.yaml
│ └── review_protocols/
│ ├── plan_review.yaml
│ ├── output_review.yaml
│ ├── analysis_review.yaml
│ └── final_review.yaml
│
├── prompt_templates/ ← L2 模板(全局共享)
├── schemas/ ← Schema 校验(全局共享)
└── src/ ← 代码
物理隔离:每个项目的 blackboard.db 完全独立。一个项目数据库损坏不影响其他项目。
4. PM2 配置
// ecosystem.config.cjs
module.exports = {
apps: [{
name: 'sanguo-moziplus-v2',
script: '~/.sanguo_projects/sanguo_moziplus_v2/.venv/bin/uvicorn',
args: 'src.main:app --host 0.0.0.0 --port 8083',
cwd: '~/.sanguo_projects/sanguo_moziplus_v2',
interpreter: 'none',
autorestart: true,
max_restarts: 10,
restart_delay: 3000,
watch: false,
env: {
PYTHONPATH: '~/.sanguo_projects/sanguo_moziplus_v2',
BLACKBOARD_ROOT: '~/.sanguo_projects/sanguo_moziplus_v2/projects',
INBOX_PATH: '~/.sanguo_projects/sanguo_moziplus_v2/inbox/daemon.jsonl',
LOG_LEVEL: 'INFO',
},
out_file: '~/.sanguo_projects/sanguo_moziplus_v2/logs/daemon.out.log',
error_file: '~/.sanguo_projects/sanguo_moziplus_v2/logs/daemon.err.log',
}]
}
5. 配置体系
5.1 全局配置(default.yaml)
daemon:
tick_interval: 30 # Tick 间隔(秒)
task_timeout: 600 # 单任务超时(秒,10分钟)
max_global_agents: 5 # 全局最大并发 Agent
max_per_agent: 1 # 每 Agent 最大并发(默认 sequential)
zombie_threshold: 20 # 连续 N tick 无变更 → 告警
inbox:
path: "inbox/daemon.jsonl"
watch_interval: 1 # Inbox 轮询间隔(秒)
max_size_bytes: 1048576 # 1MB 触发 truncate
review:
default_max_rounds: 3
debate_max_rounds: 5
confidence_threshold: 0.7 # 低于此值升级庞统
experience:
distill_threshold: 5 # 同 tag 积累 N 条触发二级蒸馏
expire_days: 30 # 30天无引用 → deprecated
logging:
level: INFO
max_file_size: 10MB
5.2 Per-project 配置覆盖
# projects/{project_id}/config/project.yaml
project:
name: "量化实战项目"
description: "sanguo_quant_live"
agents:
- pangtong-fujunshi
- simayi-challenger
- zhangfei-dev
- guanyu-dev
- zhaoyun-data
- jiangwei-infra
max_global_agents: 3 # 覆盖全局默认
context:
nas_path: "/Volumes/stock/"
backtest_service: "http://192.168.2.154:8088"
frameworks:
- "vnpy"
- "sanguo_vnpy"
6. 部署流程
6.1 首次部署
# 1. 创建安装目录
mkdir -p ~/.sanguo_projects/sanguo_moziplus_v2/{projects,inbox,logs,config}
# 2. 同步代码(从开发目录)
rsync -av --exclude='.venv' --exclude='node_modules' --exclude='.git' \
~/.openclaw/sanguo_projects/sanguo_moziplus_v2/ \
~/.sanguo_projects/sanguo_moziplus_v2/
# 3. 安装 Python 依赖
cd ~/.sanguo_projects/sanguo_moziplus_v2
python3 -m venv .venv
.venv/bin/pip install fastapi uvicorn pyyaml
# 4. 构建前端
cd src/frontend && npm install && npm run build && cd ../..
# 5. 启动 PM2
pm2 start ecosystem.config.cjs
# 6. 验证
curl http://127.0.0.1:8083/api/daemon/status
curl http://127.0.0.1:8083/ # 前端页面
6.2 日常更新
# 1. 同步代码
rsync -av --exclude='.venv' --exclude='node_modules' --exclude='.git' \
~/.openclaw/sanguo_projects/sanguo_moziplus_v2/ \
~/.sanguo_projects/sanguo_moziplus_v2/
# 2. 如果前端有变更
cd ~/.sanguo_projects/sanguo_moziplus_v2/src/frontend && npm run build && cd ../..
# 3. 重启
pm2 restart sanguo-moziplus-v2
# 4. 验证
curl http://127.0.0.1:8083/api/daemon/status
6.3 创建项目
# 通过 CLI 创建
python3 src/cli/admin.py project create \
--name "量化实战" \
--id "sanguo_quant_live" \
--agents "pangtong-fujunshi,simayi-challenger,zhangfei-dev,guanyu-dev,zhaoyun-data,jiangwei-infra"
# 自动创建 projects/sanguo_quant_live/ 目录和 blackboard.db
7. 回滚方案
| 场景 | 回滚方式 |
|---|---|
| v2 启动失败 | pm2 stop sanguo-moziplus-v2,v1 (8082) 不受影响 |
| Daemon tick 异常 | API POST /api/daemon/stop 停 ticker 不停服务 |
| 单项目数据库损坏 | 删除该项目的 blackboard.db,重启自动重建 |
| 全局不可用 | v1 仍在 8082 运行,切换回 v1 |
| 前端构建失败 | 回退 dist/ 目录到上一版 Git commit |
v1 和 v2 完全独立。v2 出问题直接停掉,v1 继续服务。
8. 监控
8.1 健康端点
GET /api/daemon/status
{
"ticker_running": true,
"last_tick": "2026-05-16T23:00:00",
"tick_interval_seconds": 30,
"projects": {
"sanguo_quant_live": {
"active_agents": 2,
"tasks_summary": {"pending": 3, "working": 1, "review": 1, "done": 15},
"db_size_bytes": 45056
}
},
"inbox_pending": 0,
"active_sessions": 2
}
8.2 逻辑健康自检
Daemon 每 tick 检查:连续 N tick(默认 20,即 10 分钟)无任何任务状态变更 → 写 observation 告警 + 通知用户。
PM2 只能检测进程崩溃,逻辑死循环/卡死需要应用层检测。
8.3 日志
# Tick 日志
pm2 logs sanguo-moziplus-v2 --lines 100 | grep "Tick"
# Agent spawn 日志
pm2 logs sanguo-moziplus-v2 --lines 100 | grep "Spawning"
# 审查日志
pm2 logs sanguo-moziplus-v2 --lines 100 | grep "review\|rebuttal"
8.4 SSE 推送监控
前端通过 /api/events SSE 接收实时事件。推送 4 级:
| 级别 | 图标 | 场景 |
|---|---|---|
| 🔴 紧急 | 任务失败/系统异常 | 立即推 |
| 🟡 需关注 | 任务超时/审查不通过 | 实时推 |
| 🟢 日常 | 任务完成/日报 | 批量推 |
| 🔵 可选 | Agent 活动日志 | 用户订阅 |
9. 安全
| 项目 | 措施 |
|---|---|
| SQLite 文件权限 | blackboard.db owner-only 读写(0600) |
| API 认证 | 内网环境,暂不认证;后续可加 API Key |
| CLI 限制 | blackboard.py 只能本地 exec,不暴露网络 |
| Agent 权限 | SOUL.md 约束 + claim assignee 检查 |
| 项目隔离 | per-project SQLite 物理隔离,一个 WHERE 漏掉也不会跨项目 |
| Session 清理 | fcntl 文件锁保护 sessions.json 编辑 |
| 归档安全 | 项目归档前必须无 working 状态任务 |
10. 性能预估
| 指标 | 预估值 | 理由 |
|---|---|---|
| Tick 耗时 | <50ms | 单项目 <10 张表几十条记录 |
| Agent spawn 延迟 | 2-5s | openclaw agent 冷启动 |
| 并发 Agent 数 | ≤5(全局) | ActiveAgentCounter 控制 |
| 项目数上限 | ~20 | SQLite 单文件无压力,PM2 不新增进程 |
| Inbox 文件大小 | <200KB | 每秒 truncate,崩溃积压 ~200KB/1000条 |
| blackboard.db 大小 | <5MB/项目 | 每任务几 KB,含 experiences |
| 前端首屏加载 | <2s | Vite 构建优化 + 本地网络 |
11. v1 → v2 迁移计划
Phase 1: v2 后端验证(v1 不动)
├── v2 部署到 8083
├── CLI 验证全流程
└── E2E 测试通过
Phase 2: v2 前端验证
├── 前端构建部署
├── Dashboard 功能验证
└── SSE 推送验证
Phase 3: 并行运行
├── v1 继续服务(8082)
├── v2 接受新任务(8083)
└── 对比 v1/v2 行为一致性
Phase 4: v1 下线
├── pm2 stop sanguo-moziplus
├── pm2 delete sanguo-moziplus
├── v2 可选接管 8082
└── v1 代码和数据库保留只读(历史归档)
Phase 5: Mail 逐步下线(远期目标,与黑板评论长期共存)
├── v2 上线后 Mail 和黑板评论并行
├── 所有 Agent 的 Skill 更新支持黑板评论后逐步关闭 Mail poller
└── 最终只保留 Mail 作为外部通知通道
12. 交付检查清单
P1 部署前逐项验证:
- 项目创建、git init、远程配置完成
- PM2 配置正确,
pm2 start成功 - 全局注册表
_registry.yaml可读写,项目列表正确 - CLI
admin.py project create创建项目成功 - per-project
blackboard.db自动创建且 schema 正确(含 reviews/experiences/comments.comment_type) - CLI
blackboard.py read/claim/output/comment/decide/observe/create/review全部可用 - Daemon tick 30s 循环正常运行
- Inbox JSONL watcher 正常消费 + truncate
- Agent spawn 成功(Popen 非阻塞 + sessions_spawn)
- Session 完成后自动存档
- ActiveAgentCounter 并发控制生效
- API 端点全部可用(/api/projects/ /api/daemon/ /api/events)
- SSE 推送正常工作
- 前端构建产物可访问(8083 端口)
- 健康端点返回正确状态
- 逻辑健康自检(连续 20 tick 无变更→告警)
- v1 (8082) 不受 v2 (8083) 影响