Skip to content

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 设计的横切维度显式落到文档:

  1. 哪些资源由 Hermes 自带的本地锁覆盖(已就位,不需要我们做)
  2. 哪些跨 profile 共享资源需要单写者收敛(避免分布式协调)
  3. 三种身份(end user / profile / admin)的权限边界
  4. 单机 N profile 的资源约束 + 超额降级路径
  5. 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 进程同 profileSQLite WAL(多读 + 单写)✅ Hermes 自带
Profile gateway 进程自己gateway.lock + gateway.pid✅ Hermes 自带
Profile auth自己auth.lock(0-byte sentinel)✅ Hermes 自带
DuckDB cache (P1.0)FastAPI backend (单写)多 profile 通过 HTTPDuckDB 文件锁 + backend 序列化⏳ P1.0
DuckDB warehouse (P2-A)Mac Mini 单 ingestVultr replica写者唯一;读者从 rsync replica⏳ P2-A
Postgres(用户/计费)backend workersbackend workersPostgres MVCC + 行级锁⏳ P1.1
Profile registry git多用户 push多用户 pullgit ref CAS + 3-way merge⏳ P2-B
Tushare tokenbackend 进程串行通过 cache 给 N profiletoken bucket(backend 内存)⏳ P1.0
New-API LLM 池New-API daemonN profile 通过 OpenAI-compatible内置 round-robin + 健康检查⏳ P2-C
Hermes 容器 (P1.1)provisioner (docker run)Docker 容器隔离 + resource limits⏳ P1.1

关键决策:所有"多 profile 同时争用"的写资源收敛到单写者进程。profile 之间不需要互相协调,Hermes 自带的本地锁就够用

权限模型

三种身份

身份凭证权限
End userBearer token(DB 里 SHA256 存 hash)/price /fundamentals /searchscope + 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 → BackendAuthorization: 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.py admin CLI

长期(P2):

  • A: 中央仓库(Q2 决策落地)
  • B: profile registry + provisioner(Q4 模板决策落地)
  • C: New-API token 池(关闭 §"当前漏洞" 第二条)
  • D: Hermes Docker image 构建 + 多主机调度(Mac Mini overflow)

进一步阅读

团队内部文档