主题
00 — 多租户架构 (Multi-Tenancy)
📤 内部架构基线
本文是内部三层架构与 margin 模型的基线。对外付费版本(含 ¥198/月等定价)将在独立站点 + 独立项目中推出;本文的 Tier 3 描述仅供内部规划讨论。
Status: 📐 Architecture baseline · 2026-05-07 Scope: 锁与权限、多 profile 单机调度、AIGC 变现层 — 贯穿 P1 / P2 的横切维度 Code surface: Hermes profile 已带本地锁;backend / provisioner / token gateway 仍待实现
价值链:Tier 1 数据 → Tier 2 聚合校验 → Tier 3 AIGC 产品 — margin 引擎是用户共享 Tier 1
目标 (Goal)
把"多用户、多 profile、多主机"作为 P1/P2 设计的横切维度显式落到文档:
- 哪些资源由 Hermes 自带的本地锁覆盖(已就位,不需要我们做)
- 哪些跨 profile 共享资源需要单写者收敛(避免分布式协调)
- 三种身份(end user / profile / admin)的权限边界
- 单机 N profile 的资源约束 + 超额降级路径
- AIGC 输出怎么把 Tier 1 成本摊薄成 margin
三层模型
┌──────────────────────────────────────────────────────────────────┐
│ Tier 3 — AIGC 产品层(收入) │
│ skill prompts → research report → WeChat 推送 → ¥198/月 │
│ 每用户一个 profile(Hermes native multi-profile) │
│ margin = price × N − Tier1_cost − Tier2_ops │
└──────────────────────────────────────────────────────────────────┘
▲ verified claims
┌──────────────────────────────────────────────────────────────────┐
│ Tier 2 — 聚合 & 校验层(护城河,跨用户共享) │
│ core/citation + verifier + competence registry (v0.1.0 ✅) │
│ DuckDB cache (P1.0) / 4 层仓库 (P2-A) / 跨源比对 │
│ Postgres:用户、计费、quota(P1.1) │
└──────────────────────────────────────────────────────────────────┘
▲ cached / batched calls
┌──────────────────────────────────────────────────────────────────┐
│ Tier 1 — 数据采集层(成本中心,跨用户共享) │
│ Tushare Pro(1 个 paid token)· akshare · pytdx3 · Yahoo │
│ LLM tokens(New-API key 池,P2-C)· SearXNG(自托管,P2-C) │
└──────────────────────────────────────────────────────────────────┘核心 insight:每个 Tier 1 资源(Tushare 配额、SiliconFlow key 配额)的成本是固定的;用户越多,单位成本越低。多租户不是"功能",是 margin 引擎。
锁与并发模型
| 资源 | 写者 | 读者 | 锁机制 | 状态 |
|---|---|---|---|---|
Profile 状态 (state.db) | profile gateway 进程 | 同 profile | SQLite WAL(多读 + 单写) | ✅ Hermes 自带 |
| Profile gateway 进程 | 自己 | — | gateway.lock + gateway.pid | ✅ Hermes 自带 |
| Profile auth | 自己 | — | auth.lock(0-byte sentinel) | ✅ Hermes 自带 |
| DuckDB cache (P1.0) | FastAPI backend (单写) | 多 profile 通过 HTTP | DuckDB 文件锁 + backend 序列化 | ⏳ P1.0 |
| DuckDB warehouse (P2-A) | Mac Mini 单 ingest | Vultr replica | 写者唯一;读者从 rsync replica | ⏳ P2-A |
| Postgres(用户/计费) | backend workers | backend workers | Postgres MVCC + 行级锁 | ⏳ P1.1 |
| Profile registry git | 多用户 push | 多用户 pull | git ref CAS + 3-way merge | ⏳ P2-B |
| Tushare token | backend 进程串行 | 通过 cache 给 N profile | token bucket(backend 内存) | ⏳ P1.0 |
| New-API LLM 池 | New-API daemon | N profile 通过 OpenAI-compatible | 内置 round-robin + 健康检查 | ⏳ P2-C |
| Hermes 容器 (P1.1) | provisioner (docker run) | — | Docker 容器隔离 + resource limits | ⏳ P1.1 |
关键决策:所有"多 profile 同时争用"的写资源收敛到单写者进程。profile 之间不需要互相协调,Hermes 自带的本地锁就够用。
权限模型
三种身份
| 身份 | 凭证 | 权限 |
|---|---|---|
| End user | Bearer token(DB 里 SHA256 存 hash) | /price /fundamentals /search;scope + rate_limit_per_min + paid_until 约束 |
| Profile(user 的代理) | profile 配置里植入的 user-bearer + Keychain 平台 secrets | 代用户调 backend;本地处理 LLM;推 WeChat |
| Admin / Provisioner | 短期 admin bearer + 独立 scope | 发/撤 user token;clone profile from template;启停 Docker 容器;轮换密钥 |
边界
- Profile ↔ Profile:filesystem
chmod 700+ 各自state.db— Hermes 自带 - Profile → Backend:
Authorization: Bearer ...;backend 校验 hash + scope + 配额 - Backend → Tier 1:admin secrets(Tushare token、SiliconFlow key)只在 backend 进程内存;永不下发到 profile
- Provisioner ↔ Profile:仅在创建/销毁/巡检时刻有访问权;运行中只读 metadata
当前漏洞(v0.1.1 现状)
- ⚠️ Direct 模式下 user profile 持有 Tushare token —— P1.0 backend 上线后收回到 backend 集中持有,profile 只拿 user bearer
- ⚠️ profile config.yaml 直接含 LLM provider key —— 等 P2-C 上线后改为指向 New-API endpoint,单一 proxy key
- ⚠️ AGENTS.md/SOUL.md 是 Hermes 默认模板("US equity"风格),跟 A 股产品定位不符 —— v0.1.1 收尾任务
多 profile 单机调度
Vultr 4GB host
├── twilight-backend.service # FastAPI + DuckDB cache (多 profile 共享, Docker)
├── twilight-cloudflared.service # Cloudflare tunnel (Docker)
├── twilight-provisioner.service # 付款 → 创建用户 → 启动 Hermes 容器 (Docker)
├── twilight-postgres.service # 用户/计费/配额 (Docker)
├── hermes-user-001 # 每个付费用户一个 Docker 容器
├── hermes-user-002
└── hermes-user-N资源约束:每 profile ~80–150 MB RAM(state.db + Python runtime + Hermes core)
4 GB host 极限:~25-30 active profile(与 P1 spec 估算一致)
超过怎么办:把 overflow 推回 Mac Mini(P2-B 多主机同步 + Cloudflare Tunnel)
provisioner 工作流(P1.1):
WeChat Pay webhook
│
▼
provisioner (Docker 容器, 挂载 Docker socket)
│ 1. verify webhook signature
│ 2. issue user bearer (secrets.token_urlsafe(32))
│ 3. clone template-stock-research-pro → profile/user-N/
│ 4. plant secrets (TWILIGHT_API_TOKEN, WEIXIN_HOME_CHANNEL)
│ 5. docker run hermes:latest --name hermes-user-N
│ -v profile/user-N:/hermes/profile
│ --memory 150m --cpus 0.5
│ 6. wait for gateway.pid + weixin connected
│ 7. generate iLink QR
▼
return QR url to landing page關鍵決策點 (Open Questions)
Q1. profile 的 secrets 由 backend 集中持还是 profile 各持?
- A) backend 集中持(Tushare token / SiliconFlow key 都在 backend EnvironmentFile)
- B) profile 各持(每个 user 自己管理)
- C) 混合(user-bearer 在 profile,Tier 1 secrets 在 backend)
→ 建議 C(混合):user 看不到任何 Tier 1 secret;profile 只有自己的 user-bearer 和 platform secrets(WeChat 等)。这与"API key 不可见"的产品定位一致。
Q2. DuckDB 写者部署在 Mac Mini 还是 Vultr?
- A) Mac Mini(写)+ Vultr replica(读,rsync 同步)
- B) Vultr 直接读写(单点)
- C) Postgres 替代 DuckDB
→ 建議 A(Mac Mini 写 + Vultr 读 replica):Mac Mini 跑 batch ingest(24/7 不眠),P2-A 仓库的全量更新在那里完成;Vultr 拿夜间 rsync 后的只读副本。Postgres 只用于热写表(users / api_keys / payments / usage_log),不替代仓库。
Q3. 多 profile RAM 上限触发后怎么扩?
- A) 升级 Vultr 套餐(4GB → 8GB → 16GB)
- B) 把 overflow profile 推回 Mac Mini(用 Cloudflare Tunnel 公网化)
- C) 分担到额外 VPS
→ 已决 B(Mac Mini overflow):Docker 容器天然可移植,overflow 时 provisioner 在 Mac Mini 上 docker run 即可。Cloudflare Tunnel 让 Mac Mini 暴露 HTTPS endpoint。前 30 个 user 在 Vultr,超出推 Mac Mini。
Q4. profile 模板里要不要 pre-bundle 一组默认 cron?
- A) 模板里有一组(每天早上推送昨日复盘)
- B) 模板纯净,user 自己加
- C) 模板里有但默认 disabled
→ 建議 C(disabled by default):让 user 看到产品边界,但不会因为没加白名单收到骚扰;上线后通过引导流程开启。
與其他層的關係
- L5 Hermes:profile 已是 native 多租户;本节增的是跨 profile 共享资源的协调,不重写 Hermes
- L4 Skills:skill 代码是只读的,被多个 profile 共享 install(修改通过
install-skill.sh推送,新版本同时影响所有 profile) - L4' Competences:domain knowledge 跨用户共享("A 股财年 12 月 31 日结束"对所有用户都成立)
- L3 Tools:通过 backend 的 cache + rate-limiter 收敛到 Tier 1
- L2/L1 数据:仓库是单写者;replica 模式让多 profile 不需要锁
下一步 (Next Steps)
短期(Week 1):
- 替换 stock-research_Agent profile 的 AGENTS.md/SOUL.md(A 股专用版)
- 同步进
profile/template-stock-research-pro/为 P1.1 provisioner 备料
中期(Week 2 起):
- P1.0 backend 上线时把 Tushare token 撤出 user profile,发 user bearer
- 写
scripts/issue-token.pyadmin CLI
长期(P2):
- A: 中央仓库(Q2 决策落地)
- B: profile registry + provisioner(Q4 模板决策落地)
- C: New-API token 池(关闭 §"当前漏洞" 第二条)
- D: Hermes Docker image 构建 + 多主机调度(Mac Mini overflow)
进一步阅读
- 01 — 数据层:Tier 1 / Tier 2 数据决策
- 03 — Agent 框架:cite + verifier 怎么把 Tier 2 的护城河落到代码
- Phase 1 spec:P1.0–P1.3 各阶段交付
- Phase 2 spec:A/B/C 三个 initiative 的详细设计
07-aigc-monetization:Tier 3 的产品 + 商业模型