docs: 移交报告再补 —— 产品视角/产品架构 + 功能模块间关系 + 脚本 Agent 运行机制

- 产品视角(§1.5):一句话定位(商品→可投放竖屏 AI 带货短视频的多租户 SaaS)+ 产品形态 +
  用户主路径 + 产品功能模块↔后端 app 对照 + 模块间数据/依赖关系图(Team 为根,实体→资产→引用主数据线)
- 脚本 Agent(§2.6):SSE 流式对话、skill 系统提示词、3 模式收敛结构化 ScriptDraft、工具卡+思考流事件、
  后端可靠抽 JSON、落库回填 script_entities 给下游、预扣额度+断连兜底、多模型

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209
2026-06-24 11:06:51 +08:00
co-authored by Claude Opus 4.8
parent 1d688269da
commit 191cd1c3e5
+73
View File
@@ -73,6 +73,56 @@
--- ---
## 1.5 产品视角:这到底是个什么产品 + 产品架构
### 一句话定位
**AirShelf 是一个「把一个商品,一键变成可直接投放的竖屏 AI 带货短视频」的多租户 SaaS 工具**。卖家上传商品图 + 填基本信息,平台用 AI 跑完「脚本 → 角色/场景/商品素材 → 分镜 → 视频」整条产线,产出带口播/音效的成片。按**团队**开户、按**额度(credit)**计费。
### 产品形态
- **多租户 SaaS**:邀请码注册 → 开团队(owner) → 拉成员(分角色/给额度) → 团队内共享商品/项目/素材/余额。
- **两层界面**:① 团队「工作台」(商品库 / 视频项目 / 图片创作 / 模特库 / 成品库);② 平台超管「治理后台」(`/admin`:邀请码/团队/用户/提示词/审核/任务/供应商/计费/额度/治理)。
### 用户主路径(产品流)
```
注册(邀请码) → 开/进团队 → 商品库传商品图 → 新建视频项目(选成片时长)
→ ① 脚本(脚本 Agent 对话出稿/改稿)
→ ② 提取角色·场景 → ③ 基础资产(立绘/三视图/场景图/商品三视图,过人像审核)
→ ④ 故事板(分镜图) → ⑤ 视频(Seedance 逐段出片) → 导出成片
```
### 产品功能模块(用户能看到的) ↔ 后端 app
| 用户模块 | 是什么 | 后端 app |
|---|---|---|
| 商品库 | 选品 + 商品图(一切素材的源头) | `products` |
| 视频项目(流水线) | 5 阶段把商品做成短视频 | `projects` + `ai` |
| 图片创作 | 模特上身图 / 平台套图 / 自由创作 | `assets` + `ai` |
| 模特库 | 复用的真人模特(立绘+三视图+声线) | `assets` |
| 成品库(资产库) | 所有产出图片/视频成品,按项目打包 | `assets` |
| 团队 & 计费 | 成员/角色/额度/余额/流水 | `accounts` + `billing` |
| 平台超管后台 | 跨团队治理 | `adminpanel` |
### 功能模块间的架构(数据/依赖关系)
```
Team(团队 · 一切的归属)
┌───────────────┬───────────────┬──────────────┬───────────────┐
billing.Account 成员/邀请码 Product(商品) Asset(资产库) Model(模特库)
余额/预扣 owner/admin/member └─ 商品图 图片/视频成品 立绘+三视图+声线
│ │(源头) ▲ ▲
│ 每次生成:预扣→扣费/释放 ▼ │ │ 引用
│ Project(视频项目)────────┘ │
│ ├ ScriptVersion → ScriptSegment(脚本/分镜:narration·dialogue·entity_refs)
│ ├ BaseAssetGroup(角色/场景/商品 基础资产,含人脸的送审)
│ ├ StoryboardVersion → StoryboardFrame(分镜图,送审)
│ ├ VideoSegment → VideoSegmentVersion(每段视频,可多版本)
│ └ Timeline(拼接导出,V2 再启)
└────────────────── ai.services 编排所有 AI 调用 ──────────────────┘
ModelConfig/Provider(火山/中转站) · AITask(每次生成一条,挂计费) · PromptTemplate(提示词) · 火山人像审核
```
- **一切挂在 Team 下**(团队作用域)。`Product` 是源头;`Project` 串起脚本/资产/故事板/视频;`ai` 模块编排所有 AI 调用并挂计费;`assets` 管资产+审核+模特库;`billing` 管钱。
-**产品的主数据线**:项目脚本提取出 `script_entities`(角色/场景/商品) → 决定要做哪些**基础资产** → 基础资产**过人像审核**拿 `asset://` 引用 → **故事板/视频**引用它**锁脸锁商品**。接手要懂的就是这一条「实体 → 资产 → 引用」贯穿始终。
---
## 2. 视频生成流程现状:✅ 顺畅,已跑通 ## 2. 视频生成流程现状:✅ 顺畅,已跑通
实测 `电子吧唧 v3` 四段视频提交火山全部 ACCEPTED、正常出片。让它跑通的**关键认知**(接手必懂): 实测 `电子吧唧 v3` 四段视频提交火山全部 ACCEPTED、正常出片。让它跑通的**关键认知**(接手必懂):
@@ -136,6 +186,29 @@
--- ---
## 2.6 脚本 Agent 怎么运行(出稿 + 改稿一体,流式对话)
代码:[script_agent.py](core/backend/apps/ai/script_agent.py)。端点 `POST /api/projects/{id}/script-agent-stream/` → **SSE 流**`text/event-stream`DRF 必须挂 `ServerSentEventRenderer` 否则 406)。
**它不是「调一次函数返回 JSON」,而是一个边想边吐的流式 agent**:
1. **系统提示词 = 电商脚本 skill**:加载 [core/backend/skills/ecommerce-video-script/](core/backend/skills/ecommerce-video-script/) 的 `SKILL.md + references` 当领域知识(模型无关)。⚠️ **skill 必须在 `core/backend/` 内**,否则不在镜像构建上下文里 → 系统提示词为空 → 退化乱出(这就是之前线上提取/脚本翻车的根因之一)。
2. **3 种输入模式,收敛到同一份结构化 `ScriptDraft`**
- `auto` 全自动(只给商品 + 卖点)· `theme` 一句话主题 · `revise` 改稿(基于某个基准版)。
- 改稿带 `target_index` = **精准只改第 N 镜**,后端 `_merge_single_segment` **强制保留其余镜原样**`0` 是合法镜号,判断一律 `is None` 不用真值)。
3. **流式吐「工具卡 + 思考」给真 agent 体感**SSE 事件,见 script_agent.py 头部):
`tool`(加载skill→分析商品→生成分镜→提取实体)· `reasoning`(推理模型思考流,逐字、纯展示不进答案)· `delta`(自然语言前言)· `draft`(规范化后的稿)· `saved`(已落库)· `summary`(模型自己写的收尾交付语)· `done` / `error`。
> 其中 `reasoning` 是关键体验修复:推理模型出 JSON 前会先「想」很久,把思考逐字下发,避免前端「卡在生成分镜」假死。
4. **JSON 由后端可靠抽取,不靠模型排版**:`normalize_draft` / `_extract_json`(括号配平、字段模糊匹配 `_pick_field`、时长吸附到 `[15,30,60,90]`、抽实体)。模型排版再乱也能稳定拿到结构化稿。
5. **结构化 `ScriptDraft` 契约**`narration`(扁平口播兜底)+ `dialogue:[{speaker,line}]`(带说话人对白)+ `role/tone/product_exposure/entity_refs/total_duration`。
6. **落库 + 回填**`persist_script_draft`):写 `ScriptVersion.metadata`hook/tone/entities+ 逐镜 `ScriptSegment`,并把 `cast/scenes/script_entities` **回填 `project.metadata`** —— 下游(提取/资产/故事板/视频)全靠这份回填。
7. **计费 + 断连兜底**:走 `AITask` + 额度**预扣 → 成功扣费 / 失败释放**。客户端中途断连会抛 `GeneratorExit`(是 `BaseException`,普通 `except` 抓不到)→ 用 `try/finally` 释放预扣,**绝不冻结额度**。
8. **多模型可选**`model_config_id` 切不同脚本模型(默认豆包 doubao-seed-2.0-pro)。
> 一句话:**前端点「生成脚本」→ 后端起一个流式 agent,边加载 skill / 分析商品 / 出分镜,边把工具卡和思考推给前端;最后后端把模型输出可靠抽成结构化脚本、落库、回填给下游**。整条产线后续所有阶段都吃这份脚本回填的 `script_entities`。
---
## 3. 我们这一程做了什么(2026-06-22 ~ 06-24 ## 3. 我们这一程做了什么(2026-06-22 ~ 06-24
按模块归类(完整见 `git log`,均带 Claude 署名): 按模块归类(完整见 `git log`,均带 Claude 署名):