Files
beige/Clover架构方案.md
yangqianqian 6a2632da70 baseline: Clover 独立仓库首次基线提交
将 Clover 从上层产品包旧仓库中独立出来,建立专属版本控制。
当前状态=纵切片端到端已打通(登录→选品→出文出图→审核→下载包),
M1文案质量去套路化已验收。此提交作为后续按核销清单逐条修复的基线。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:30:22 +08:00

287 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Clover 🍀 · 统一产品技术架构方案
> 项目代号:**Clover三叶草** —— 取"种草"之意,接小红书业务 + 倩倩姐设计稿的小草视觉。
> 对外正式品牌名待定,开发期用此代号。
> 版本:**v0.37洞对齐版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_idworker内部查库→解密→调模型明文只在函数局部变量
- 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+roleHS256签名防篡改、每请求验签)
权限读操作凭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_idSSE推送
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建表+矩阵号管理UIL2人设层激活
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-serverPlaywright跑小红书自家JS算签名但"系统替客户取数据"=违规+封号风险,只作**北哥内部自用插件、二期可选模块,不进对外标配**
- 官方蒲公英/聚光接口=二期看北哥企业资质再议
-**软件收费06-04洞4已拍板**MVP阶段软件**免费**不做计费墙token耗材费走自家token站、按账号key隔离不在产品层计费。收费逻辑(底层麻烦)产品成熟后单独讨论
### 待拍板
- **P1 短信服务商**:用阿里云短信还是腾讯云短信?(影响成本和接入,都需企业实名)(注:仅二期自助注册才需要,一期手动建北哥账号不阻塞)
- ~~P2 标杆链接读不到时的兜底~~ → **已由06-04洞1解决**:对外=截图手填(主通道),登录态采集作内部插件,不再是待拍板项
- **P2 北哥账号开通**:一期北哥账号由我们手动建(已定,不接短信);自助注册留二期