将 Clover 从上层产品包旧仓库中独立出来,建立专属版本控制。 当前状态=纵切片端到端已打通(登录→选品→出文出图→审核→下载包), M1文案质量去套路化已验收。此提交作为后续按核销清单逐条修复的基线。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
287 lines
20 KiB
Markdown
287 lines
20 KiB
Markdown
# Clover 🍀 · 统一产品技术架构方案
|
||
|
||
> 项目代号:**Clover(三叶草)** —— 取"种草"之意,接小红书业务 + 倩倩姐设计稿的小草视觉。
|
||
> 对外正式品牌名待定,开发期用此代号。
|
||
> 版本:**v0.3(7洞对齐版,2026-06-04)** —— 经9-agent团队5轮审核(R1多维独立+R2挑刺+R3交叉验证+R4一致性+R5汇总),对齐06-04的7洞决策,修复13处脱节/漏洞
|
||
> 受众:产品负责人(可读)+ 开发团队(可落地)
|
||
> 关联:[../banana复用评估.md] [../产品架构蓝图.md] [../前端交互设计.md] [../采集框架.md] [test/各洞验证落盘.md]
|
||
>
|
||
> **v0.3修订摘要**:M1标杆采集定性(对外截图手填) / M2 Celery不传key(修安全矛盾) / M3去水印+达人素材交付包 / M4文案双轨+可调prompt / M5 delivery_packages表 / M6 token-url收口自家站 / M7软件MVP免费 / M8违禁词三级处理+banned_words表 / M9飞轮权重填定 / M10偏好表data_ownership字段 / M11 JWT表述工程化 / M12-13可选优化
|
||
|
||
---
|
||
|
||
## 〇、一句话定性
|
||
|
||
一座"小红书内容工厂":北哥是第一个车间,将来郑州客户来了直接开新车间,互不干扰。
|
||
核心差异化 = **偏好飞轮**(越用越懂你的"老师傅")。技术底座复用 banana 半成品,但新建干净仓库抽离。
|
||
|
||
---
|
||
|
||
## 〇.5、基石约束(不可动摇,违反即返工)
|
||
|
||
> 经两轮外部AI审核 + 两轮自校验,沉淀出以下铁律。任何代码/设计违反这些 = 必须返工。
|
||
|
||
### A. "凡业务参数,一律不写死"(最高原则)
|
||
- **品类**不写死:预置素颜霜/精华/面膜 + 客户自助上传新品类(source区分),代码和prompt禁止出现品类枚举
|
||
- **生成数量**不写死:文案出几条、图出几张,由用户自己设定。飞轮信号强弱随用户设定走(设10选3=强信号,设3选1=弱信号),系统不锁死
|
||
- **文案角度**不写死:痛点/成分/场景等角度跟着产品走,或引导客户自己输入,落进产品档案当可配置项
|
||
- 判断标准:任何"看起来像枚举/常量"的业务概念,先问"客户会不会想改?"会→做成数据不做成代码
|
||
|
||
### B. 安全铁律(API Key)
|
||
- 明文key**绝不进Celery参数**(Redis broker会存)。Celery只传task_id,worker内部查库→解密→调模型,明文只在函数局部变量
|
||
- key用Fernet加密存MySQL;**解密用的FERNET_KEY走环境变量/密钥管理,绝不进代码库**(锁和钥匙不放一起)
|
||
- key解密不落盘、不打日志
|
||
- 每账号自录自用,按key各算各的,禁止合并站级key混算
|
||
|
||
### C. 多租户隔离
|
||
- workspace_id **逻辑隔离**(同一MySQL用workspace_id强制过滤),**不是物理隔离**(暂不做每客户独立DB)
|
||
- JWT放user_id/current_workspace_id/role当加速字段,但**所有写操作+切换workspace必须查 workspace_members 校验当前权限**(读操作可信JWT加速)
|
||
|
||
### D. 采集↔生产接缝不能断(漏洞C)
|
||
- 采集框架里北哥团队填的"好图标准/好坏样本/质检标准"等**人工判断标准,必须在Clover里有落点**:进系统→帮组长审核→最终蒸馏成AI审核员
|
||
- 这是采集层和生产层的接缝,设计时必须打通,不能让采集成果悬空
|
||
|
||
### E. 飞轮验收必须可测(不靠"感觉更准")
|
||
- events正确写入 ✓ / aggregator返回明确prompt片段 ✓ / 下次Gemini prompt trace含该片段 ✓ / UI显示"本次已注入:最近偏好/打回原因" ✓
|
||
- 四点全过才算飞轮MVP达标
|
||
|
||
### F. 文档诚实
|
||
- 不放"N个agent生成"这类AI背书;用工程化表述(JWT签名防篡改/短期有效/关键接口查membership),不用"写死不可伪造"这种话
|
||
|
||
---
|
||
|
||
## 一、整体架构总览
|
||
|
||
### 分层(从上到下)
|
||
```
|
||
浏览器(Next.js)
|
||
熟手:选题→看生成→8选3文案→挑图→提审
|
||
组长:看审核队列→通过/打回(写原因)
|
||
管理员:维护品牌库/标杆/成员
|
||
│ HTTPS/SSE(流式推进度)
|
||
FastAPI(API层)
|
||
认证:JWT(含workspace_id+role,HS256签名防篡改、每请求验签)
|
||
权限:读操作凭JWT加速;写操作+切换workspace必须查workspace_members校验权限(逻辑隔离)
|
||
Key解密:Fernet解密,只在worker内存活,不落盘
|
||
│ 同步↓ 异步↓(推Celery队列)
|
||
业务应用层 Celery Worker(后台)
|
||
品牌库管理 ①分析标杆笔记
|
||
飞轮信号采集 ②批量生成文案(一次出5角度)
|
||
审核流转 ③并发生成图片(asyncio.gather)
|
||
偏好上下文组装 ④偏好重算(第二期激活)
|
||
│ │
|
||
数据层(双引擎)
|
||
MySQL(主存储,一期14表) MongoDB(只写AI debug trace)
|
||
业务全量数据/账号/权限 AI调用过程快照,出错排查用
|
||
品牌库/候选/飞轮信号 业务逻辑不依赖它
|
||
API Key(Fernet加密) Redis(Celery队列+SSE推送通道)
|
||
```
|
||
|
||
### 一次任务的数据流转
|
||
```
|
||
1.管理员预置品牌库(产品档案+标杆笔记)
|
||
2.熟手发起任务:选产品+选标杆 → 后端检查有没有配key(没有→引导去配)
|
||
→ **只把task_id推入Celery队列(绝不推key,遵基石B)**
|
||
3.Worker异步:①分析标杆提8特征 ②生成5角度文案(动态注入卖点+违禁词+风格+偏好)
|
||
③并发生图A/B/C → 每步推SSE,前端实时看进度
|
||
4.熟手8选3文案 → 飞轮信号入口1;挑图 → 入口2
|
||
5.提交审核 → 组长看队列
|
||
6.组长通过(+5分,最重)/打回(写原因,下次自动注入prompt提醒AI别再犯)
|
||
7.归档(永久保留)
|
||
```
|
||
|
||
### 偏好飞轮怎么转(产品的魂)
|
||
```
|
||
【采信号】选文案+3 / 选图+3 / 审核通过+5(最重) / 打回写原因-3 / 重新生成-1 → 全进 preference_events 表
|
||
(此为开发起步默认权重,北哥调教后可配置校准)
|
||
【聚合】 下次生成查最近50条 → 哪个角度被选最多(L3个人) + 打回原因最近3条原文拼进prompt
|
||
不足5条信号 → 用产品档案冷启动
|
||
【三层继承】L1公司品牌基线 > L2矩阵号人设 > L3个人手感(运行时叠加,有L3用L3,没有往上兜底)
|
||
⚠️ 按产品维度分开学:素颜霜偏好不串到精华/面膜
|
||
【越用越准】1次=全靠静态基线均匀分布;10次=知道你爱"痛点切入";30次=措辞从"供参考"升为明确指令
|
||
【诚实克制】banana的假评分(88分)MVP彻底不接,eval_score留NULL,等真评分(组长标准蒸馏)再装
|
||
```
|
||
|
||
---
|
||
|
||
## 二、核心设计决策(已拍板)
|
||
|
||
开发期不得推翻,变更需产品负责人重新确认。
|
||
|
||
| 决策项 | 结论 |
|
||
|---|---|
|
||
| 主存储 | MySQL存所有业务数据(飞轮聚合要JOIN),MongoDB只存AI debug trace |
|
||
| API Key | 每账号自录自用、Fernet加密、不同workspace各自独立,禁止混算;**token站url统一收口=自家站endpoint,账号表只存encrypted_key不存url字段**(06-04洞4,旧"兼容任意中转站url"已废止) |
|
||
| 软件费 | **MVP阶段免费,不做计费墙**(06-04洞4);token耗材费走自家站按key隔离,不在产品层计费;收费逻辑产品成熟后单独议 |
|
||
| Key解密位置 | 只在Celery worker内存局部变量,不落盘不打日志 |
|
||
| 多租户隔离 | workspace_id写进JWT,所有查询强制带此条件(安全红线) |
|
||
| 任务主键 | MySQL自增BIGINT + mongo_trace_id VARCHAR(24),飞轮JOIN性能好 |
|
||
| 文案生成 | **双轨**(06-04洞2):轨A=自带强模型一次返5角度JSON(不串行不并发5次);轨B=客户导入外部文案(豆包等)直接进候选池跳过AI;**客户可在产品档案配自调prompt** |
|
||
| 图片生成 | asyncio.gather并发,一次A/B/C三策略各一张(复用banana) |
|
||
| 加密算法 | cryptography.fernet.Fernet,环境变量FERNET_KEY,全仓统一 |
|
||
| 策略命名 | 对外API用A/B/C,内部method用minimal_edit系,建中心常量文件消除三套打架 |
|
||
| 审核记录 | 不建独立notes表,审核字段平铺generation_tasks,打回原因存preference_events |
|
||
| 偏好快照 | preference_profile表预建结构,MVP不写入,实时查events,第二期开物化缓存 |
|
||
| 品类动态 | products.category是纯数据字段,代码和prompt禁止出现任何品类枚举 |
|
||
| **审核演进** | **先组长人工审为主→积累"过/不过+理由"蒸馏人工标准→生图够好+标准清晰后,AI当审核员接班(第三期)** |
|
||
|
||
---
|
||
|
||
## 三、数据模型全览(16张表 = 一期14张 + 二期预留2张)
|
||
|
||
> 14张=banana搬3 + 多租户基础3(不含matrix_accounts) + 业务主体7 + 飞轮1。matrix_accounts、preference_profile 二期预留,一期不建。
|
||
> 06-04增补:业务主体从5张增至7张(加 delivery_packages 素材交付包 + banned_words 违禁词库)。
|
||
|
||
```
|
||
Alembic 001 — 从banana搬3张(改造)
|
||
users 用户账号(删credits字段)
|
||
login_records 登录记录(无改)
|
||
user_preferences UI设置偏好(无改,API Key另建表)
|
||
|
||
Alembic 002 — 多租户基础(全新)
|
||
workspaces 租户/公司(北哥=1个)
|
||
workspace_members 用户↔workspace+角色
|
||
user_api_keys 个人API Key(Fernet加密)
|
||
[matrix_accounts] 矩阵号 —— 二期预留,一期不建(矩阵号一期不做)
|
||
|
||
Alembic 003 — 业务主体7张(全新)
|
||
products 产品档案(卖点/违禁词/风格/调性/标签/文案角度/可调prompt/source/workspace_id)
|
||
benchmark_notes 标杆笔记(爆款链接/图/亮点说明,一对多挂product)
|
||
generation_tasks 生产任务(状态机+审核字段平铺)
|
||
text_candidates 文案候选(角度数量用户设定,MySQL主存储;source=ai/import区分双轨)
|
||
image_candidates 图片候选(数量用户设定)
|
||
delivery_packages 达人素材交付包(洞6):id/workspace_id/product_id/theme/status(pending/ready/downloaded)/package_path/created_at
|
||
banned_words 违禁词库(洞5):word/level(auto_fix自动改/soft_warn软提示/hard_block硬拦截)/replacement/updatable/workspace_id(可覆盖)
|
||
|
||
Alembic 004 — 飞轮信号(全新)
|
||
preference_events 飞轮信号日志(所有信号全在此;含data_ownership字段=client_data/platform_asset,洞7分层归属)
|
||
[preference_profile] 偏好快照 —— 二期预留,一期不建(一期实时查events;二期同步加data_ownership标记)
|
||
```
|
||
|
||
### 关键字段
|
||
**任务状态机**:pending→generating→pending_selection→pending_review→approved/rejected→archived
|
||
(打回后回到pending_selection;修订轮次靠查events统计)
|
||
|
||
**generation_tasks 审核字段(平铺,需明确定义)**:
|
||
review_status / reviewer_id / reviewed_at / reject_reason / approved_at / archived_at
|
||
|
||
**preference_events**:
|
||
- signal_type: text_select | image_select | approve | reject_with_reason | regenerate
|
||
- signal_weight(已定初始默认值,北哥调教后可校准):选文案+3 / 选图+3 / 审核通过+5(最重) / 打回-3 / 重新生成-1
|
||
- angle_label: 跟着产品的"文案角度"配置走,不写死
|
||
- reason: 打回原因原文(不做AI归纳)
|
||
- **data_ownership: client_data(原始输入产出,客户可导出) | platform_asset(飞轮蒸馏成果,归平台)** —— 洞7分层归属技术口子
|
||
- workspace_id + product_id: 都必须有(跨公司隔离 + 按产品分开学)
|
||
|
||
**user_api_keys**:UNIQUE(user_id, workspace_id, provider)
|
||
|
||
**usage记录(一期必做,否则计费/排障断档)**:每次AI调用记 usage(谁/用了多少token),存 ai_call_logs 或 mongo debug trace 的 usage 字段;token站查询失败要有兜底;调用失败归因到个人key
|
||
|
||
---
|
||
|
||
## 四、复用 / 复活 / 新造清单
|
||
|
||
开发第一步先看这张表:哪些直接搬、哪些改造、哪些新写。
|
||
|
||
### 🟢 直接复用(复制基本不改)
|
||
| banana模块 | 改动量 |
|
||
|---|---|
|
||
| gemini_service.py 核心AI方法 | 只改__init__ 4行,AI调用方法一行不动 |
|
||
| json_stream_extractor.py 流式解析 | 加variants到watched_keys |
|
||
| constants SCHEMA_METHODS | 扩展补全 |
|
||
| orchestrator analyze流程 | 数据源从Mongo改读MySQL products/benchmark_notes |
|
||
| celery_tasks 任务框架 | task_id改BIGINT,**只传task_id(绝不传key,遵基石B)**,worker内部查库取encrypted_key→FERNET_KEY解密,加第4任务壳 |
|
||
| api/stream.py SSE框架 | 补发历史事件(修漏洞),结构不变 |
|
||
| prompt_composer.py | 新增compose_variants方法,原方法保留 |
|
||
| docker-compose | 直接复用,调环境变量名 |
|
||
|
||
### 🟡 复活(banana写好但没接线的死代码)
|
||
| 死代码 | 怎么复活 |
|
||
|---|---|
|
||
| task_skills.py Invariants 8特征 | analyze后把8特征写入events.signal_meta,飞轮统计维度从单一angle扩到8维(第三期) |
|
||
| loader.py PromptLoader版本alias | 新建variants模板走版本机制,未来改prompt只改模板不改代码 |
|
||
| gemini_service evaluate_schema | MVP彻底不搬,eval_score留NULL,第二/三期接真评分(避免假信号污染飞轮) |
|
||
|
||
### 🔴 完全新造(banana没有,灵魂部件)
|
||
| 新造模块 | 作用 |
|
||
|---|---|
|
||
| gemini_factory.py + Fernet解密 | 解决全局单例,每任务用自己的key构建实例 |
|
||
| preference_collector.py | 飞轮3信号入口(选文案/选图/审核)写入events |
|
||
| preference_aggregator.py | 实时聚合events→prompt片段,三层继承叠加 |
|
||
| api/products + benchmark_notes | 品牌库CRUD,含source=preset预置品类 |
|
||
| api/matrix_accounts | 矩阵号CRUD(MVP前端可后做,库和接口先建) |
|
||
| api/api_keys | 录入/删除/查询(只显后4位),首登强制引导 |
|
||
| middleware/workspace_guard | 所有接口强制注入workspace_id,防串数据 |
|
||
| api/review | 组长待审列表/通过/打回 |
|
||
| generate_text_variants | 一次调用5角度JSON,替代banana单条循环 |
|
||
| text_import_handler | 轨B:导入外部文案(豆包等)直接进候选池,跳过AI生成(洞2文案双轨) |
|
||
| banned_word_checker | 违禁词三级扫描:🟢自动改写/🟡软提示给建议词/🔴硬拦截,词库可配置(洞5) |
|
||
| image_postprocessor | 出图后处理:重编码去C2PA元数据+转JPG/轻重采样削像素水印+压缩(洞3去水印) |
|
||
| package_exporter | 生成达人素材交付包:按笔记分文件夹+图(01/02命名)+文案.txt+发布清单+合规说明(洞6) |
|
||
| _combine_benchmarks | 1-5篇标杆合并成综合reference |
|
||
| base_workspace_repo | 所有workspace相关Repo继承,强制过滤 |
|
||
| Alembic 001-004 | 按序建14张表(一期) |
|
||
| constants/strategies.py | 统一命名中心文件,消除三套打架 |
|
||
|
||
---
|
||
|
||
## 五、构建顺序(三期,一期拆1A/1B)
|
||
|
||
> 修正:原"一期3-4周"塞太满。拆成 1A生产链闭环 + 1B飞轮闭环,先证明能产出,再证明会学习。
|
||
|
||
### 一期·1A:生产链闭环(先让北哥能产出内容)
|
||
手动建北哥账号(不接短信)、手动/截图录标杆、产品库、按用户设定数量出文案(双轨)、出图去水印、选择、审核、打包交付。
|
||
1. **基础设施**:建仓库+6容器;Alembic 001-002(不含matrix_accounts);手动初始化北哥workspace+管理员
|
||
2. **品牌库**:Alembic 003;产品档案CRUD(含文案角度+可调prompt可配置);标杆笔记CRUD;预置素颜霜1条;初始化banned_words(MVP起步5词:美白/祛斑/速效/医用/药妆,updatable,北哥合规标准来了批量导入)
|
||
- ⚠️ 标杆录入主通道=**截图+手填亮点**(洞1实测确定可行);登录态采集=北哥内部插件,二期可选
|
||
3. **API Key录入**:user_api_keys+Fernet+录入界面;FERNET_KEY走环境变量;token站url固定自家站;没配key时按钮置灰引导
|
||
4. **核心生产链**:中心常量文件;GeminiService改造+gemini_factory(key只在worker内解密);analyze搬入;**文案双轨(轨A生成5角度/轨B导入外部文案)**;**违禁词三级扫描**;并发生图(数量用户设定);Celery只传task_id;SSE推送
|
||
5. **选择+审核+交付包**:选文案/选图/提审/审核队列/通过打回(审核字段明确定义);**出图后处理(去水印)**→**生成达人素材交付包**
|
||
- 出图后处理(洞3):图像库重编码去C2PA元数据 + 转JPG/轻重采样削像素水印 + 压缩瘦身,对客户透明
|
||
- 交付包结构(洞6):按笔记分文件夹,每夹含图(01/02/03命名防传错序)+文案.txt(标题+正文+标签),附📋发布清单.txt + ✅合规说明.txt(违禁词已过/已去水印)
|
||
- 验收:北哥1名熟手不靠开发,从选产品→生成→选择→组长审→**下载达人能直接发的素材包**,全程跑通
|
||
|
||
### 一期·1B:飞轮闭环(让产出会学习)
|
||
1. Alembic 004(只建preference_events,不建preference_profile)
|
||
2. 三信号入口接线(选文案/选图/审核)
|
||
3. compose_preference_context 实时聚合(最近50条,workspace_id硬过滤)
|
||
4. 偏好+打回原因注入prompt
|
||
- 验收(四点全过):events正确写入 / aggregator返回明确片段 / 下次prompt trace含该片段 / UI显示"本次已注入"
|
||
|
||
**一期整体验收**:北哥熟手独立跑完生产链;飞轮选过3次后下次生成能看到偏好摘要并验证注入。
|
||
|
||
### 二期:多团队+对外销售(再2-3周)
|
||
> 留口子已在地基,二期只"打开注册开关",不回头改表。
|
||
1. 手机号+验证码自助注册(选短信服务商) + workspace创建 + 邀请成员
|
||
2. matrix_accounts建表+矩阵号管理UI;L2人设层激活
|
||
3. preference_profile物化(events满10条触发重算,加载<50ms)
|
||
4. 管理后台:各workspace用量统计+飞轮健康度
|
||
|
||
### 三期:效果回流+AI审核员(看业务)
|
||
1. 发布效果回填(赞/收藏/评论→outcome_score加权)
|
||
2. L3 vs L1偏差检测(个人偏好偏离品牌基线>60%提示,防学坏)
|
||
3. Invariants 8维特征接线(飞轮统计从单一angle扩到8维)
|
||
4. **AI审核员**:用积累的"组长过不过+理由"蒸馏人工标准,训练AI审核员逐步接班(补banana假评分窟窿,呼应基石D)
|
||
|
||
---
|
||
|
||
## 六、待拍板判断点
|
||
|
||
### 已拍板(2026-06-03)
|
||
- ✅ 项目代号:**Clover**,文件夹建在 北哥小红书产品/Clover/
|
||
- ✅ 先做北哥单车间,但地基留口子,其他车间可快速打通
|
||
- ✅ 审核:先组长人工审为主 → 蒸馏人工标准 → 后期AI审核员接班
|
||
- ✅ 注册方式:**手机号+验证码**(对标小红书,已查证小红书就是手机号注册)。需接短信验证码服务商(阿里云/腾讯云SMS)
|
||
- ✅ 矩阵号:**一期不做**。L2人设层一期不激活,飞轮一期只跑"L1品牌基线+L3个人手感"两层;matrix_accounts表仍建好留口子,二期补L2
|
||
- ✅ 排版:**不做独立排版环**,第7环并入第6环——AI生图时直接把文字/版式排在图上(出成品图)
|
||
- ✅ **标杆采集通道(06-04洞1已拍板,实测3条真链接裸抓全返回风控假页)**:
|
||
- 对外SaaS一期主通道=**截图+手填亮点**(客户自己截图,零平台风险)
|
||
- 链接自动读取=**登录态采集方案**(本地已有跑通代码:n8n-nodes-xiaohongshu + xhs-sign-server,Playwright跑小红书自家JS算签名),但"系统替客户取数据"=违规+封号风险,只作**北哥内部自用插件、二期可选模块,不进对外标配**
|
||
- 官方蒲公英/聚光接口=二期看北哥企业资质再议
|
||
- ✅ **软件收费(06-04洞4已拍板)**:MVP阶段软件**免费**,不做计费墙;token耗材费走自家token站、按账号key隔离,不在产品层计费。收费逻辑(底层麻烦)产品成熟后单独讨论
|
||
|
||
### 待拍板
|
||
- **P1 短信服务商**:用阿里云短信还是腾讯云短信?(影响成本和接入,都需企业实名)(注:仅二期自助注册才需要,一期手动建北哥账号不阻塞)
|
||
- ~~P2 标杆链接读不到时的兜底~~ → **已由06-04洞1解决**:对外=截图手填(主通道),登录态采集作内部插件,不再是待拍板项
|
||
- **P2 北哥账号开通**:一期北哥账号由我们手动建(已定,不接短信);自助注册留二期
|