Architecture v2 · ← 返回文档首页

代码架构 v2:一套底座,三个产品

编写日期2026-09-27取代v1 的《05 写真代码架构》《06 音频代码架构》(已归档)

详细规格见各开发 spec:`00_共享底座_开发spec/`、`01_陪练_开发spec/`、`02_写真_开发spec/`、`03_音频_开发spec/`

1. 相对 v1 的架构变化

方面 v1 v2 原因
图像生成 自己部署 ComfyUI + GPU 运维 + LoRA 训练 调用编辑类模型的 API,经过模型网关;不训练 LoRA 一个人维护 GPU 太重;自部署的模型许可证有隐患;编辑模型用 1~3 张照片就能保持主体长相
质检 人脸特征模型(InsightFace,非商用许可) 视觉大模型打分 + 客户自己挑图 许可证干净;客户挑图取代了人工挑图
人工环节 挑图台、审听编辑器、服务工单、Fiverr 录入 全部取消;只保留一个异常队列 零人工交付
模型调用 各模块直接调用厂商 SDK 统一的模型网关:按区域路由、计量成本、容灾切换 国内必须用已备案的模型;模型会停用、会涨价
部署 国内服务器 + 零散的海外实例 同一代码,两套部署(global / cn),数据不互通 国内外都做
自部署部分 图像 + 音频 只保留音频(修音、分离、混音、剪辑都没有合适的 API)和视频渲染 只在必要时自部署
获客 手工运营 增长组件:水印分享、短视频自动发布、SEO 页面生成、弃单召回、邀请 获客要能规模化

2. 总体结构

monorepo/
├── core/                  # 共享底座(Python 包)
│   ├── auth/  billing/  storage/  jobs/  notify/  audit/
│   ├── labeling/          # AI 标识(显式 + 隐式)
│   ├── compliance/        # 年龄确认、内容安全、授权存证、数据删除、休息提醒
│   ├── gateway/           # ★ 模型网关
│   ├── growth/            # ★ 增长组件
│   └── analytics/
├── media/                 # 自部署的媒体引擎(worker 镜像)
│   ├── audio/             # 分离、降噪、修音、人声链、混音、母带、响度、剪辑、字幕
│   └── video/             # 竖屏视频渲染、字幕烧录、宣传短视频合成
├── products/
│   ├── pixorder/          # 02 照片礼物
│   ├── sonicflow/         # 03 修音
│   └── talktale/          # 01 剧情陪练(含内容生产流水线)
├── web/                   # Next.js:三个产品的前端 + 管理后台(按域名区分)
├── miniapp/               # 国内小程序(Taro,复用 web 的业务逻辑层)
└── deploy/
    ├── global/            # 海外:docker-compose / 云主机
    └── cn/                # 国内
层 选型
后端 Python 3.11 + FastAPI
数据库 PostgreSQL 16(每个产品一个 schema;海外和国内各一个实例)
队列 Redis 7 + RQ(队列按"产品.类型"命名)
前端 Next.js 14 + Tailwind;国内小程序用 Taro
媒体 worker Docker 镜像:CPU 版(音频 DSP、视频渲染)+ GPU 版(人声分离、语音识别)
对象存储 海外 Cloudflare R2;国内阿里云 OSS
分析 海外 PostHog;国内自部署

3. 模型网关(core/gateway)

所有 AI 调用都必须经过这里,业务代码里不允许直接使用厂商 SDK。

class Gateway:
    def llm(self, task: str, messages: list, *, schema: dict | None = None, region: str) -> LLMResult: ...
    def image_edit(self, task: str, images: list[bytes], prompt: str, *, n: int, region: str) -> list[ImageResult]: ...
    def image_generate(self, task: str, prompt: str, *, refs: list[bytes] = (), n: int, region: str) -> list[ImageResult]: ...
    def tts(self, task: str, text: str, voice: str, *, region: str) -> AudioResult: ...
    def stt(self, task: str, audio: bytes, lang: str, *, words: bool, region: str) -> Transcript: ...
    def vision_judge(self, task: str, images: list[bytes], rubric: str, *, region: str) -> JudgeResult: ...
机制 说明
按任务路由 task 名(例如 pet_portrait.renaissance、talktale.checkpoint_reply)对应配置里的"首选模型 + 备选模型"
按区域限制 region=cn 时只能路由到已备案模型白名单里的模型,配置之外的一律拒绝,写在代码里做硬校验
成本计量 每次调用记录:任务、模型、token 或张数或秒数、费用、所属订单/用户
容灾 首选模型超时或出错 → 自动切换到备选;5 分钟错误率 > 20% → 熔断并告警
缓存 相同输入的结果缓存(内容生产流水线大量受益)
预算 每个产品每天有费用上限;超过 80% 时告警,超过 100% 时降级为只处理付费订单

配置示例:

tasks:
  pet_portrait.default:
    global: [gemini-image-latest, seedream-global, flux-kontext-fal]
    cn:     [volc-seedream]
  quality_judge:
    global: [gemini-flash-vision]
    cn:     [doubao-vision]
  talktale.checkpoint_reply:
    global: [small-llm-a, small-llm-b]
    cn:     [doubao-lite]
cn_allowlist:            # 已备案模型白名单:名称 + 备案号,同时用于页面公示
  - {id: volc-seedream, name: "...", filing_no: "..."}

配置里的模型标识是示例。实际模型名称和版本以接入时厂商的当前文档为准,停用通知要订阅并及时处理。


4. 三个产品的核心流水线

4.1 02 照片礼物

上传 → 检查(清晰度 / 主体 / 内容安全)
  → 网关.image_edit × 4(按风格配置的模型)
  → 网关.vision_judge 逐张打分 → 不合格的补生成(最多 2 轮)
  → 加水印预览给客户 → 客户挑选 / 重新生成
  → 付款 → 放大到印刷分辨率 → 按商品规格出印刷文件
  → 代发平台接口下单 → 接收发货回调 → 通知客户

4.2 03 修音

上传人声 [+ 伴奏 | 原曲]
  → [分离原曲:伴奏 + 原唱人声](GPU)
  → 降噪 → 音高提取 → 与原唱对齐 → 参考旋律修音(WORLD 声码器重合成)
  → 按曲风的人声处理链 → 自动混音(响度比例 + 频段避让)→ 母带
  → 歌词识别与对齐(网关.stt)→ 竖屏歌词视频渲染(带或不带水印)
  → 交付

4.3 01 剧情陪练

【内容生产,离线,每集一次】
季设定 → 分集大纲 → 剧本(网关.llm,结构化输出)
  → 自动质检(词汇难度 / 一致性 / 安全)
  → 配音(网关.tts,按角色固定声音)→ 插画(网关.image_edit,角色参考图保持一致)
  → 打包上线 → 自动生成宣传短视频(media/video)

【用户运行时,每个口语关卡一次】
录音 → 网关.stt(词级)→ 发音评分
  → [自由回答] 网关.llm(小模型,带记忆和剧情状态)→ 短回复 网关.tts
  → 写入剧情变量和记忆

5. 增长组件(core/growth)

组件 02 03 01
程序化 SEO 页面 风格 × 犬种/猫种 × 场合 工具 × 场景("remove vocals from song" 等) 场景词汇页("Japanese phrases at a konbini")
水印分享 电子版免费预览带水印 免费档视频的水印角标 分享卡片
短视频自动生成 前后对比(客户授权) 前后对比(用户授权) 每集剪出 3 条
自动发布 通过平台官方接口发布到自有账号(TikTok、YouTube、Pinterest、抖音),发布前自动检查 AI 标注 同左 同左
弃单 / 流失召回 未付款的预览 免费额度用完 连续 3 天未打卡
邀请 送电子版 送 1 首无水印 送 7 天 Pro

6. 部署

            global(海外云主机)                         cn(国内云主机)
  ┌──────────────────────────────────┐      ┌──────────────────────────────────┐
  │ nginx → web(三个域名)→ api        │      │ nginx → web / 小程序后端 → api     │
  │ PostgreSQL / Redis                │      │ PostgreSQL / Redis                │
  │ CPU worker(音频 DSP、视频)        │      │ CPU worker                        │
  │ R2                                │      │ OSS                               │
  └──────────────┬───────────────────┘      └──────────────┬───────────────────┘
                 │                                          │
      GPU worker(按需:RunPod 等)                  GPU worker(按需:AutoDL 等)
      人声分离 / 语音识别                             人声分离 / 语音识别
  • 两套部署不共享数据库和存储;代码和镜像相同,靠 REGION 配置区分
  • GPU worker 主动从 Redis 拉取任务,不需要开放入站端口;队列空闲 15 分钟后自动关机
  • 现有的 yunyoufk.xtnet.vip 服务器可以作为 cn 的第一台机器(需要完成 ICP 备案并配置 HTTPS)

7. 成本结构(估算,按实际调用量核对)

项 02 03 01
主要可变成本 每单 AI ≤ $0.5;代发成本另计 每首 ≤ $0.05 每集内容 ≤ $1(一次性);每个用户每集 ≤ $0.02
固定成本(两个区域合计) 服务器、数据库、存储、监控,约 $100~200/月,三个产品共用