我知道代理公司真正需要什么,所以我在第 2 天就做了多租户
在代理公司行业 20 年后,我知道多租户架构不能等,所以在只有一个可用 AI agent 的第 2 天,我把开发复杂度提升了 3 倍,以避免未来重写。
2025 年 8 月 21 日。构建 STRAŦUM 的第 2 天。
我坐在桌前,手里只有一个可用的 AI agent(Business Strategy)、基础认证和一个非常简单的数据模型。咖啡已经快凉了。我非常清楚自己想服务谁:需要 AI 营销帮助的 SMEs,以及希望在多个客户上复用能力的代理公司。
两个受众。从 Day 1 就都要覆盖。
我在代理公司侧工作了 20 年,我很清楚代理公司真正需要什么,不是宣传材料里的漂亮版本,而是同时管理 10-15 个客户时那种混乱现实:不同策略、不同品牌规范、几乎所有东西都不同。我也知道 SMEs 极度需要可负担的战略支持。
但在第 2 天,当我盯着这份简单模型时,我意识到一件不太舒服的事:如果要同时服务这两类受众,就必须现在就做多租户架构。不是以后。
到当天结束时,我做了一个决定:它会把开发复杂度拉到 3 倍,并把时间线拉长数周。
我在第 2 天就做了多租户架构。
这是野心还是疯狂?坦白说,当时我不确定。现在也还没 100% 确定。但这个几乎在“产品还没成型”时做出的决定,后来成了我最关键的技术选择之一。
为什么同时做两类受众?因为 20 年代理公司经验
我的愿景从来不是只做 SME。从一开始,我就想服务两类不同受众:
SMEs(小企业,1-30 人) — 你负担得起的战略联合创始人:
- 付不起营销代理公司或顾问
- 缺少战略营销能力
- 需要不必经历长学习曲线的快速成果
代理公司(管理 5-15+ 客户) — 扩的是战略产能,不是人头:
- 在多个客户的策略工作里被淹没
- 需要可规模化的统一方法论
- 需要客户之间的绝对数据隔离
为什么做代理公司?因为我在这一侧干了 20 年,痛点我亲身经历。
我见过策略师同时处理 12 个客户、12 套品牌规范,在不同工具间复制粘贴上下文,还要祈祷不要把错误策略发给错误客户。我也见过代理公司因为无法在不增加人头的情况下扩大战略能力,最终把优秀人才耗走。
说实话?我也想挑战自己。只做 SME 会简单得多——一个用户、一个组织、路由直接。但做代理公司意味着多客户看板、数据隔离、基于角色的权限、所有内容都要 client-scoped。
我想做复杂一点的东西。真正解决我看了二十年的难问题。
第 2 天的认知:多租户无法后补
在第 2 天盯着那份简单模型时,我明白了:
SME 架构(我当时已有):
```
users → campaigns → agent_outputs
```
多租户架构(代理公司需要):
```
organizations (SME or AGENCY)
↓
clients (agencies only)
↓
campaigns
↓
agent_outputs (with org_id AND client_id)
```
这不是“多加几列”那么简单,而是完全不同的数据模型。
如果先做 SME,再补代理公司,我将面临:
- 给所有现有表迁移增加 org_id
- 整库补齐 RLS 策略
- 前端路由重写以支持 client 上下文
- 所有功能在多租户场景下重测
这不是加功能,这是重写。
拖得越久,补起来越贵。Day 2 成本低。Day 60 会很痛。Day 200 可能会变成“要不干脆给代理公司做个独立产品”。
所以我做了决定:第 2 天就做多租户,或者接受代理公司永远不会是一等公民。
取舍:多租户真实代价是什么
这部分我本该停下来问自己:“你确定吗?你现在只有一个可用 agent。一个。”
但我没停。我直接开始像疯子一样写 SQL schema。第 2 天做多租户,意味着接受这些让理性人会再三犹豫的成本:
成本 1:开发复杂度(3 倍)
每张表都要 org_id。代理公司相关表还要 client_id。RLS 策略要双重过滤。每个查询、每个 API、每条前端路由都必须具备多租户意识。
预估复杂度提升:同样功能,开发时间 3 倍。
(剧透:实际更接近 4 倍。我低估了。典型我自己。 :P)
成本 2:开发周期延长
从 Day 1 就兼顾双受众,意味着更长的上线路径:
时间线:
- 8 月 20 日:开工(从 Day 1 就是多租户)
- 9 月 15 日:第 4 周,3 个 agents 可用,目标 10 月上线
- 10 月:我病了 10 天,无法写代码
- 11 月 5 日:Private Alpha 上线(总计 75 天)
多租户增加的工作:
- public 与 agency 表之间的 schema 路由
- 每张表的 RLS 策略(最终 26 张表共 83 条)
- client 上下文在每个 agent 流程里传递
- 双路由模式(SME 与 agency URL)
如果当时走 SME-only,会不会快 3-4 周上线?大概率会。但那之后代理公司一来,我就要面对重写。
成本 3:安全要求(风险更高)
SME 的数据隔离是基本盘。代理公司的数据隔离是生死线。
新增要求:
- 26 张表 83 条 RLS 策略
- schema 级隔离(public vs agency)
- 每个 CRUD 操作都要数据库路由函数
- 全面审计日志
- 多因素认证选项
安全复杂度:比 SME-only 高 5 倍。
有些周里,我花在 Row-Level Security 上的时间比 AI agent 开发还多。你可以感受下这个权重。
成本 4:测试复杂度(用例翻倍)
每个功能都要测:
- ✅ SME 流程(更简单)
- ✅ Agency 流程(带 client 范围)
- ✅ 数据隔离(Nike ≠ Adidas)
- ✅ 权限边界(agency 能看到 SME 数据吗?不能)
测试维护成本:翻倍。
最“有趣”的事情是什么?同一套测试在不同上下文里写两遍。没人会真的喜欢这个。
---
我为什么仍然接受这个取舍
我再复述一遍:3 倍复杂度、延长周期、5 倍安全开销、测试翻倍……我还是做了?
是的。我的思路如下:
原因 1:后补是噩梦
Day 2:代码几乎没写,模型还很灵活,没有用户要迁移。
Day 60:45 张表、20 万行代码、15 个 alpha 用户。此时加多租户等于重写半个代码库。
结论:架构决策越晚改,成本呈指数级上升。
Day 2 成本:约 5 小时重画数据模型。
Day 60 成本:约 200 小时重构全链路。
我见过公司后补多租户,真的很 brutal。等于在飞行中重造飞机,而且机上乘客还在付费。
原因 2:我真的懂代理公司
这不是纸面市场调研。我花了 20 年看代理公司在这个问题上挣扎。
我知道他们需要:
- 绝对数据隔离(客户 1 不能看到客户 2 策略)
- 所有核心对象都 client-scoped(品牌规范、persona、campaign)
- 基于角色的访问控制(AM 与策略师权限不同)
- 支持白标展示给客户的潜力
我能把这个做对,因为我经历过。不想把这个优势浪费在“先做 SME,代理公司以后再说”。
原因 3:挑战本身就是目的
这点我不常说:我就是想做点难的。
我是有家庭的中年创始人,不是 22 岁可以靠能量饮料和少睡硬扛的人。如果我要花一年做一件事,它必须足够有挑战,也让我技术上有成就感。
多租户 + 数据隔离 + RLS + schema 路由,这很难,也很有意思。这类工程问题会让我凌晨两点还保持投入。
做 SME-only 会更快,但我是否还能保持同样动力穿过所有难关?大概率不会。
原因 4:两类受众会互相增强
SME 和代理公司不是竞争关系,而是互补关系:
- 代理公司验证产品:如果代理公司敢把客户数据放进来,SME 也更敢用
- SME 提供规模反馈:用户更多,反馈更快,迭代更快
- 同一架构服务两边:团队账号、角色权限、白标能力两边都能用
双受众意味着从一开始做的是完整解法,而不是迟早会过时的简化版。
原因 5:面向未来的选择权
即便不谈代理公司,多租户架构也解锁了:
- 团队账号(SME 多成员)
- 分销/代理伙伴模式
- 白标机会
- 企业销售通道(如果未来要走)
选择权价值:多租户在 Day 2 就解锁了我当时甚至还没完全想到的商业可能性。
落地实现:Day 2 的架构决策到底长什么样
这是 8 月 21 日我实际做的内容:
数据库 Schema(核心决策)
```sql
-- Organizations table (SME or AGENCY)
CREATE TABLE organizations (
id UUID PRIMARY KEY,
name TEXT,
type TEXT CHECK (type IN ('SME', 'AGENCY')), -- Critical distinction
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Clients table (agencies only)
CREATE TABLE clients (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id), -- Which agency owns this
company_name TEXT,
slug TEXT UNIQUE, -- For URL routing
created_at TIMESTAMPTZ DEFAULT NOW(),
-- Constraint: Only agencies can have clients
CONSTRAINT clients_agency_only CHECK (
(SELECT type FROM organizations WHERE id = org_id) = 'AGENCY'
)
);
-- Campaigns table (multi-tenant aware)
CREATE TABLE campaigns (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id), -- Always required
client_id UUID REFERENCES clients(id), -- Required for agencies, null for SMEs
name TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Agent outputs (multi-tenant + client-scoped)
CREATE TABLE agent_outputs (
id UUID PRIMARY KEY,
org_id UUID REFERENCES organizations(id),
client_id UUID REFERENCES clients(id),
campaign_id UUID REFERENCES campaigns(id),
agent_type TEXT,
content JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
```
Day 2 的关键决策:
- 每张表都带 org_id(便于 RLS)
- client_id 可空(SME 没有 clients)
- organizations 用 type 区分(SME vs AGENCY)
- 约束:只有 agency 能创建 clients
Row-Level Security(Day 2 规划)
```sql
-- RLS policy for campaigns (multi-tenant isolation)
CREATE POLICY campaigns_org_isolation ON campaigns
FOR ALL TO authenticated
USING (
org_id = get_user_org_id() AND
(client_id IS NULL OR client_id IN (SELECT id FROM clients WHERE org_id = get_user_org_id()))
);
```
这条策略保证:
- ✅ 用户只能看到自己组织下的 campaigns
- ✅ Agency 用户看不到 SME 的 campaigns
- ✅ 代理公司之间互相看不到客户数据
代价: Day 2 先写了 5 条 RLS,发布时增长到 83 条。
URL 路由(从 Day 1 就按多租户设计)
```typescript
// Frontend routing structure (planned Day 2)
// SME routes (simple)
/campaigns/:campaignId
/agents/strategy/:campaignId
// Agency routes (client-scoped)
/clients/:clientSlug/campaigns/:campaignId
/clients/:clientSlug/agents/strategy/:campaignId
```
这套 URL 结构带来的能力:
- ✅ agency 场景里每个 URL 都带 client 上下文
- ✅ SME 与 agency 流程清晰分离
- ✅ URL 可收藏、可分享
- ✅ 可按 client 做分析追踪
结果:这笔账划算吗?
上线时间:2025 年 11 月 5 日(开工后第 75 天)
多租户额外开发负担:
- schema 设计与迁移
- 26 张表 83 条 RLS 策略
- 数据库路由函数
- 双路由模式(SME vs agency)
- client 上下文全链路传递
在 Claude Code 和 Gemini 2.5 Pro 帮助下,纯编码速度比我单打独斗快了不少。但那些“看起来应该能跑却就是不跑”的 RLS 调试,凌晨两点照样痛苦,AI 也不能替你完全省掉。
我现在拥有的:
- 组织之间完整数据隔离
- 支持 client scope 的 agency-ready 架构
- 26 张表 83 条 RLS 策略
- schema 级路由(public vs agency)
- Day 1 内建白标潜力
- 一个真的能同时服务 SME 与 agency 的产品底座
值不值?
6 个月后再问我,那时如果有真实客户付费,答案会更硬。现在我还在 private alpha(15+ 用户),继续摸索哪些有效、哪些无效。
但有一件事我确定:我已经有了同时服务两类受众的架构。如果当初先做 SME 再补 agency,此刻我大概率正在面对 3 个月重写。现在我可以把精力放在 PMF,而不是架构债。
这个取舍,对我来说是对的。
一个判断框架:什么时候该早做多租户
不是每个产品都要在 Day 2 做多租户。可以用这个框架:
这些情况建议尽早做:
✅ 目标市场包含代理/分销商(单客户价值更高)
✅ 数据隔离要求高(法律/合规驱动)
✅ B2B 且高概率有团队账号(Slack、Figma 这种模式)
✅ 存在白标机会(分销 GTM 策略)
✅ 可能走企业销售(Day 1 就需要多客户能力)
这些情况建议先不做:
❌ B2C 产品(个人用户、无组织层级)
❌ MVP 首要目标是速度(先验证 PMF)
❌ 没有团队/代理场景(单人工具)
❌ 数据模型很简单(后续加 org_id 成本可控)
❌ 独立开发者仍在学习期(复杂度可能过高)
经验总结:按你的真实专长建架构
1. 受众认知应驱动架构
不要为假想用户设计,要为你真正懂的用户设计。
我的优势:20 年代理公司经验,让我非常清楚他们需要数据隔离、client scope、角色权限。
错误做法:“先做 SME,以后懂了再加代理公司。”
正确做法:“我已经懂代理公司了,趁便宜现在就做。”
如果你在某个细分市场有深度认知,就用它,不要机械服从“先做简单版”。
2. 早期复杂度,胜过后期重构
Day 2 架构成本:5 小时重画模型。
Day 60 架构成本:200 小时重构全局。
40 倍差距。
如果你有 80% 把握未来会需要多租户,就早点做。越晚越贵。
3. 技术挑战本身可以成为驱动力
这点比较个人化:我就是想做难题。
多租户 + RLS + schema 路由 + 真正数据隔离,这是足够有挑战的工程问题。它让我在难关里保持投入。
如果你是 solo founder,不要低估“动力”这个变量。做一个能持续挑战你的东西,价值可能比“先快点上线”更大。
4. 架构会直接决定商业模式
多租户不只是技术决策,它直接开启了:
- 代理公司定价层级(等我把定价摸透)
- 白标机会
- 企业销售潜力
- SME 团队账号
架构 = 写在代码里的商业选择权。
5. Solo Founder 也能做多租户
“多租户太复杂,一个人做不了” → 错。
有了现代工具(Supabase RLS、数据库函数、AI 辅助开发),solo founder 完全可以做出企业级多租户。
时间成本:70 天(兼职节奏)。
得到的东西:真正数据隔离,而不是将来会后悔的临时 hack。
如果你认真想同时服务两类受众,这笔投入是值得的。
最后想法
Day 2 时其实太早了,根本无法知道 STRAŦUM 会不会成功。我只有一个 agent,没有用户,没有验证,只有 20 年代理公司经验告诉我代理公司到底需要什么。
延长时间线在一些时刻非常痛苦。别人都在发新版本时,我还在调 RLS、写数据库路由函数。那种挫败感不是一句“有点烦”能概括的。确实有些天我会怀疑:这一切复杂度真的值吗?
但现在我知道:从 Day 1 同时为两类受众设计,是正确决定。不是因为我算出了多漂亮的单元经济模型——我现在还没完全确认定价。是因为我已经拥有了真正服务两边的架构。
第 2 天做多租户,不只是技术选择。它是一个下注:为我真正理解的用户而建,而不是为“以后再研究”的假想用户而建。
这个下注回本了吗?
我还在 Private Alpha(15+ 用户),还没有最终答案。
但我可以确定一件事:当代理公司来问“你们能不能在多客户场景下做严格数据隔离?”时,我能直接说“可以”。不需要说“我们正在做”。
这就是一个正确的基础。
时间会证明我是有远见还是只是顽固。(很可能两者都有。) :)
你有没有做过一个当时看起来“太激进”的早期架构下注?最后回本了吗?很想听听你的故事。
致敬,
Chandler
STRAŦUM 架构系列: Day 2 的这个决定只是开头。到 Day 67,我不得不重建整套多租户层,因为一次安全审计暴露了架构缺陷。接着出现了 31 个由导航上下文丢失引发的空白屏,随后我又发现数据库 技术上正确但慢了 296 倍。
---
正在构建多租户 SaaS? STRAŦUM 的架构从 Day 1 就支持 SME 与 Agency 两类客户。申请 alpha: https://stratum.chandlernguyen.com/request-invitation
---
Still learning that architecture decisions are business decisions in disguise. Still debugging RLS policies. Still questioning my Day 2 choices (but less so now). More building adventures at https://www.chandlernguyen.com/.
---





