爆款结构迁移引擎 — 技术架构与协议文档 上 整体AI架构
爆款结构迁移引擎 — 技术架构与协议文档
文档性质:项目技术说明文档
适用读者:架构师、后端开发工程师、安全审计工程师、系统集成工程师
目录
- 第一部分整体AI架构
- 1.1 系统概述
- 1.2 架构拓扑
- 1.3 核心组件与模块划分
- 1.4 全链路数据流
- 1.5 关键技术栈
- 1.6 组件间交互关系
- 第二部分:工具协议
- 2.1 API 设计规范
- 2.2 数据交换格式定义
- 2.3 接口调用流程与状态机
- 2.4 LLM 通信协议
- 2.5 配置文件规范
- 第三部分:安全边界
- 3.1 数据安全策略
- 3.2 访问控制与身份认证
- 3.3 加密方案与密钥管理
- 3.4 输入验证与注入防护
- 3.5 安全风险评估矩阵
- 3.6 安全配置最佳实践
第一部分:整体AI架构
1.1 系统概述
爆款结构迁移引擎是一个基于大语言模型(LLM)驱动的全栈AI视频创作平台。系统采用前后端分离的 B/S 架构,以FastAPI 异步 Web 服务为后端枢纽,集成云端的Doubao-Seed-2.0-lite大模型作为核心推理引擎,辅以OpenCV 本地视频分析管线,打通"样例视频上传 → LLM 结构拆解 → LLM 缺口识别 → LLM 时间线编译 → 导出/预览"的全链路闭环。
业务目标
| 阶段 | 输入 | 处理引擎 | 输出 |
|---|---|---|---|
| ① 样例解析 | 爆款视频文件(MP4/MOV) | OpenCV 管线 | sample_data(fps/时长/分辨率/关键帧/镜头切换点) |
| ② 结构分析 | sample_data(压缩后) | Doubao-Seed-2.0-lite | structure_template(脚本/节奏/包装三重结构) |
| ③ 缺口识别 | 目标主题 + 已有素材清单 | Doubao-Seed-2.0-lite | gap_analysis(identified_gaps槽位清单) |
| ④ 时间线编译 | 结构模板 + 缺口分析 + 版本类型 | Doubao-Seed-2.0-lite | SVT-JSON 视频时间线 |
| ⑤ 输出 | SVT-JSON | — | 浏览器下载 / 弹窗预览 |
1.2 架构拓扑
┌─────────────────────────────────────────────────────────────────────────┐ │ 用户浏览器 (User Agent) │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ frontend/index.html (SPA: TailwindCSS + Marked.js) │ │ │ │ upload-sample │ analyze-structure │ identify-gaps │ generate-svt│ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ HTTP/HTTPS (fetch) │ └────────────────────────────────┼────────────────────────────────────────┘ │ ┌────────────────────────────────┼────────────────────────────────────────┐ │ 应用服务器层 (FastAPI) │ │ ┌─────────────────────────────┴────────────────────────────────────┐ │ │ │ backend/main.py │ │ │ │ CORS 中间件 │ 9个 RESTful 端点 │ 全局异常捕获 │ │ │ └───────┬──────────────────┬──────────────────┬─────────────────────┘ │ │ │ │ │ │ │ ┌───────▼─────────┐ ┌──────▼──────┐ ┌───────▼────────────┐ │ │ │ video_processor │ │ llm_client │ │ gap_completion │ │ │ │ (OpenCV) │ │ () │ │ (策略引擎) │ │ │ └─────────────────┘ └──────┬───────┘ └────────────────────┘ │ │ │ │ │ ┌─────────▼──────────┐ │ │ │ config.py │ │ │ │ (YAML + 环境变量) │ │ │ └────────────────────┘ │ └──────────────────────────────┼──────────────────────────────────────────┘ │ HTTPS (OpenAI-compatible API) ┌──────────────────────────────┼──────────────────────────────────────────┐ │ 云服务 (VolcEngine Ark) │ │ ┌───────────────────────────▼──────────────────────────────────┐ │ │ │ POST /api/v3/chat/completions │ │ │ │ Provider: volcengine | Model: ep-* │ │ │ │ 认证: Bearer Token (api_key) │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘
部署拓扑说明
- 单进程部署:
main.py→uvicorn.run("backend.main:app", host="0.0.0.0", port=8000, reload=True) - 前端通过文件协议 (
file://) 或静态托管打开frontend/index.html,通过fetch连接后端 - 后端可直接访问互联网(调用API),无需额外代理
1.3 核心组件与模块划分
模块依赖关系图
main.py (启动入口) └── backend/ ├── main.py ← 依赖 → config.py, video_processor, llm_client, gap_completion ├── config.py ← 无内部依赖(仅依赖 yaml / os) ├── video_processor.py ← 无内部依赖(仅依赖 cv2 / numpy) ├── llm_client.py ← 依赖 → config.py │ ├── VolcEngineLLMClient ← HTTP 客户端封装 │ ├── DoubaoSeed2LiteEngine ← 业务语义层 │ ├── fix_incomplete_json() ← JSON 修复引擎 │ ├── normalize_*() ← 智能归一化引擎 │ └── compact_*() ← 数据压缩工具 └── gap_completion.py ← 依赖 → llm_client.py └── GapCompletionEngine ← 策略补全 + 多版本生成
各模块详细职责
1.3.1main.py— 服务启动入口
| 属性 | 值 |
|---|---|
| 框架 | Uvicorn ASGI Server |
| 监听 | 0.0.0.0:8000 |
| 热重载 | reload=True |
| 入口 | uvicorn.run("backend.main:app", ...) |
关键行为:
- 通过
sys.path.insert将项目根目录加入 Python 路径 - 以
backend.main:app模块路径启动(FastAPI app 实例)
1.3.2backend/config.py— 全局配置管理
设计模式:YAML 持久化 + 环境变量覆盖(层次化优先级配置)
优先级链:环境变量 > config.yaml > 默认硬编码值配置项一览:
| 配置键 | YAML 路径 | 环境变量 | 默认值 | 用途 |
|---|---|---|---|---|
SECRET_KEY | secret_key | SECRET_KEY | "your-secret-key-here" | 应用签名密钥 |
DEBUG | debug | DEBUG | true | 调试模式开关 |
VOLCENGINE_API_KEY | volcengine.api_key | VOLCENGINE_API_KEY | "" | API Key(Bearer Token) |
VOLCENGINE_BASE_URL | volcengine.base_url | VOLCENGINE_BASE_URL | API基础地址 | |
DOUBAO_SEED_2_LITE_MODEL_EP | doubao_seed_2_lite.model_ep | DOUBAO_SEED_2_LITE_MODEL_EP | "" | Doubao-Seed-2.0-lite 的 Endpoint ID |
LLM_TIMEOUT | llm_timeout | LLM_TIMEOUT | 120 | LLM API 调用超时(秒) |
MAX_FILE_SIZE | — (硬编码) | — | 500 * 1024 * 1024(500MB) | 最大上传文件大小 |
UPLOAD_DIR | — (硬编码) | — | {BASE_DIR}/uploads/ | 上传文件存储目录(自动创建) |
OUTPUT_DIR | — (硬编码) | — | {BASE_DIR}/outputs/ | 输出结果目录(自动创建) |
TEMP_DIR | — (硬编码) | — | {BASE_DIR}/temp/ | 临时文件目录(自动创建) |
YAML 加载流程:
① 读取 {BASE_DIR}/config.yaml ② yaml.safe_load() 反序列化 ③ 读取失败则降级为空 dict,仅使用环境变量 ④ Settings 类属性初始化时统一执行 os.getenv() → yaml_config 降级链 ⑤ UPLOAD_DIR / OUTPUT_DIR / TEMP_DIR 自动 mkdir1.3.3backend/video_processor.py— 视频解析引擎
| 属性 | 值 |
|---|---|
| 技术 | OpenCV 4.8.1(cv2) |
| 运行位置 | 本地 CPU(非云端) |
| 实例化 | 全局单例VideoProcessor() |
核心方法:
| 方法 | 输入 | 输出 | 算法 |
|---|---|---|---|
extract_basic_info() | Path(视频文件路径) | {fps, duration, total_frames, resolution, width, height} | cv2.VideoCapture逐属性读取 |
extract_key_frames() | Path,num_frames=10 | List[str](Base64 JPEG) | numpy.linspace均匀采样 →cv2.imencode('.jpg') |
detect_shot_changes() | Path,threshold=30.0 | List[float](切换时间点) | 逐帧灰度直方图比对(cv2.HISTCMP_CORREL),差异 >threshold时记录镜头切换 |
process_sample_video() | Path | {basic_info, key_frames, shot_changes, estimated_script} | 编排调用上述三个方法,附加预估 Hook/Body/CTA 三段时间分配建议 |
性能特征:
- 关键帧提取:O(n),均匀采样固定 10 帧
- 镜头检测:O(n),逐帧比对,30fps 视频每秒处理约 10-15 帧
- Base64 编码开销:关键帧 Base64 编码直接嵌入 JSON 返回,对前端透明
1.3.4backend/llm_client.py— LLM 服务对接层(核心模块)
本模块是系统的最核心组件,包含两个类 + 四个辅助引擎:
A.VolcEngineLLMClient— HTTP 客户端
封装对OpenAI-compatible API的异步 HTTP 调用:
| 属性 | 值 |
|---|---|
| 协议 | HTTPS REST |
| 认证头 | Authorization: Bearer {api_key} |
| Content-Type | application/json |
| 超时 | settings.LLM_TIMEOUT(默认 120s) |
| 重定向 | follow_redirects=True |
| HTTP 库 | httpx.AsyncClient |
API 端点构造:{base_url}/chat/completions
Payload 结构(OpenAI 兼容):
{ "model": "{model_ep}", "messages": [ {"role": "system", "content": "..."}, {"role": "user", "content": "..."} ], "temperature": 0.3, "max_tokens": 1024 }B.DoubaoSeed2LiteEngine— 业务语义引擎
包装了结构分析、缺口识别、SVT 生成三类业务语义的 LLM 调用。
| 方法 | 功能 | temperature | max_tokens | 兜底行为 |
|---|---|---|---|---|
analyze_sample_structure() | 爆款结构分析 | 0.3 | 1024 | _get_fallback_structure() |
generate_material_gap_analysis() | 素材缺口识别 | 0.2 | 512 | _get_fallback_gap_analysis() |
generate_svt_json() | SVT 时间线生成 | 0.7 | 1024 | _get_fallback_svt_json() |
统一执行流程(每个方法均遵循):
① 构建 messages (system + user) ② 检查 api_key_provided() → 否则直接返回兜底模板 ③ await llm_client.chat_completion(...) ④ raw = result["choices"][0]["message"]["content"].strip() ⑤ self.last_raw_llm_output = raw ← 原始文本存档,供前端 Markdown 审计 ⑥ parsed = fix_incomplete_json(raw) ← JSON 修复 ⑦ 归一化处理(analyze / gaps 方法) ⑧ 返回处理结果 或 兜底模板关键属性last_raw_llm_output:每次 LLM 调用后立即存入原始返回文本,通过 API 响应传回前端,用于 Markdown 代码块渲染(可审计 LLM 输出)。
C. JSON 修复引擎 (fix_incomplete_json+ 4 策略修复器)
设计目标:LLM 返回的 JSON 常因截断、尾随逗号、未引用键名、Python 布尔值(True/False/None)等问题无法被json.loads()直解。
4 策略累积式修复管道:
原始文本 ↓ strip() + 去 Markdown 代码块包裹 (```json ... ```) ↓ json.loads() 直解 ──成功→ 返回 ↓ 失败 ↓ _repair_json_text() │ ├─ 策略1: _repair_trailing_commas() — ,} → } ,] → ] │ ├─ 策略2: _repair_unquoted_keys() — key: → "key": + True→true │ ├─ 策略3: _repair_nested_truncation() — 补全缺失的 } │ └─ 策略4: _repair_truncated_braces() — 按花括号栈截断到最后一个完整对象 │ 累积策略结果(策略间不重置文本) ↓ json.loads() 验证 ──成功→ 返回 ↓ 失败 ↓ 返回 {}(空 dict,触发兜底模板)关键片段— 花括号栈截断算法(_repair_truncated_braces):
伪代码: 遍历字符 text[i] if c == '{' → brace_stack.push(i) if c == '}' 且 brace_stack 非空 → brace_stack.pop() if brace_stack 变为空 → last_object_pos = i (记录最后一个完整 JSON 对象结束位置) 返回 text[:last_object_pos + 1]D. 智能归一化引擎 (normalize_llm_output_to_structure+normalize_gap_analysis)
设计目标:解耦 LLM 自由输出格式与系统标准数据结构。LLM 的输出字段名可能因 prompt 调优、模型升级而变化——归一化引擎在此处充当适配器。
结构归一化映射表(normalize_llm_output_to_structure):
| LLM 输出字段 | 目标字段 | 映射逻辑 |
|---|---|---|
basic_video_attribute.total_duration_sec | script_structure.{hook/body/cta}.duration | 按 20%-60%-20% 比例分配 |
basic_video_attribute.content_form_attribute | tempo_structure.overall_rhythm | 直接赋值 |
explosive_structure_evaluation.hook_part.rationality_comment | script_structure.hook.content | 直接赋值 |
explosive_structure_evaluation.hook_part.actual_duration_sec | script_structure.hook.duration | 覆盖默认 20% 分配 |
explosive_structure_evaluation.main_content_part.* | script_structure.body.segments[0].* | 直接映射 |
explosive_structure_evaluation.cta_conversion_part.* | script_structure.cta.* | 直接映射 |
overall_structure_score | tempo_structure.overall_score | 直接赋值 |
optimization_tip | packaging_structure.optimization_suggestion | 直接赋值 |
缺口归一化映射表(normalize_gap_analysis):
| LLM 输出字段 | 目标字段 |
|---|---|
缺口明细列表[].缺口分类 | identified_gaps[].slot_name |
缺口明细列表[].缺口优先级 | identified_gaps[].gap_type |
缺口明细列表[].缺口描述 | identified_gaps[].suggested_completion_strategy |
如果 LLM 直接返回
identified_gaps字段(已是标准格式),归一化器会原样透传。
E. 数据压缩工具 (compact_*)
| 函数 | 压缩对象 | 压缩后大小 | 目的 |
|---|---|---|---|
compact_sample_data_for_llm() | 视频样例数据(含关键帧 Base64) | 仅保留 fps, duration, resolution + 脚本预估 | 避免 token 超限 |
compact_structure_for_svt() | 结构模板(完整三层结构) | 仅保留 hook_dur, body_dur, cta_dur, rhythm, total_score | 压缩后注入 SVT prompt |
compact_gaps_for_svt() | 缺口分析(完整 identified_gaps) | 取前 5 条,每条策略截取 60 字符 | 压缩后注入 SVT prompt |
1.3.5backend/gap_completion.py— 缺口补全引擎
| 属性 | 值 |
|---|---|
| 内部依赖 | 持有独立的DoubaoSeed2LiteEngine实例 |
| 设计模式 | 策略模式 |
策略分发逻辑(_apply_completion_strategy):
| 策略关键词 | 补全方法 | 输出类型 |
|---|---|---|
subtitle/文案 | _generate_subtitle_completion() | 字幕文案文本 |
card/卡片 | _generate_sales_card() | 卖点卡片数据结构 |
animation/动画 | _generate_animation_template() | 动画模板参数 |
| 其他 | _generate_generic_completion() | 简单文本叠加 |
多版本生成(generate_multiple_versions):遍历["high_click", "high_conversion", "high_rhythm", "high_quality"],每个版本独立调用llm.generate_svt_json(),失败时降级为base_svt。
1.3.6backend/main.py— FastAPI 路由层
| 属性 | 值 |
|---|---|
| 框架 | FastAPI 0.109.0 |
| 中间件 | CORS(allow_origins=["*"]) |
| 实例化 | 全局单例:VideoProcessor(),DoubaoSeed2LiteEngine(),GapCompletionEngine() |
REST 端点清单(9 个):
| 方法 | 路径 | 参数来源 | Content-Type |
|---|---|---|---|
| GET | / | — | application/json |
| POST | /api/upload-sample | UploadFile(multipart) | multipart/form-data |
| POST | /api/analyze-structure | Form(urlencoded) | application/x-www-form-urlencoded |
| POST | /api/identify-gaps | Form(urlencoded) | application/x-www-form-urlencoded |
| POST | /api/complete-gaps | Form(urlencoded) | application/x-www-form-urlencoded |
| POST | /api/generate-svt | Form(urlencoded) | application/x-www-form-urlencoded |
| POST | /api/generate-multiple-versions | Form(urlencoded) | application/x-www-form-urlencoded |
| POST | /api/adjust-manually | Form(urlencoded) | application/x-www-form-urlencoded |
| GET | /api/config-status | — | application/json |
为什么用application/x-www-form-urlencoded而非multipart/form-data:除上传端点(需要传输二进制文件)外,其余端点传输的均为纯文本 JSON 字符串(structure_template_json、gap_analysis_json等),使用 urlencoded 避免 FastAPI multipart 解析器对纯文本字段的不稳定处理。
1.3.7frontend/index.html— 前端单页应用
| 属性 | 值 |
|---|---|
| 架构 | 原生 HTML5 SPA(无框架) |
| CSS 框架 | TailwindCSS(CDN) |
| 图标库 | FontAwesome 4.7(CDN) |
| Markdown 渲染 | Marked.js(CDN) |
| 通信 | fetch()API →http://localhost:8000/api/* |
| 主题色 | primary#6366f1, secondary#ec4899, accent#10b981, dark#1e1b4b |
核心全局状态:
| 变量 | 类型 | 初始值 | 写入时机 |
|---|---|---|---|
currentTaskId | string | null | 视频上传成功 |
currentSampleData | object | null | 视频上传成功 |
currentStructureTemplate | object | null | 结构分析返回 |
currentGapAnalysis | object | null | 缺口识别返回 |
currentSvt | object | null | 多版本生成返回 |
currentRawLlmOutput | string | "" | 结构分析返回 |
currentRawGapOutput | string | "" | 缺口识别返回 |
1.4 全链路数据流
完整时序图
User Browser FastAPI Backend VolcEngine Ark Filesystem │ │ │ │ │ ① POST /api/upload-sample (multipart video) │ │ │────────────────────────▶│ │ │ │ │── save to uploads/ │ │ │ │── VideoProcessor. │ │ │ │ process_sample_video()│ │ │ ② 200 {task_id, │ │ │ │ sample_data} │ │ │ │◀────────────────────────│ │ │ │ │ │ │ │ ③ POST /api/analyze-structure │ │ │ (task_id, sample_data_json) │ │ │────────────────────────▶│ │ │ │ │── compact_sample_data_for_llm() │ │ │── POST /chat/completions ────────────────────▶│ │ │ │ Doubao-Seed-2.0- │ │ │ │ lite 推理 │ │ │◀── 200 {choices[...]} ────────────────────────│ │ │── fix_incomplete_json() │ │ │── normalize_llm_output_to_structure() │ │ ④ 200 {task_id, │ │ │ │ structure_template, │ │ │ │ raw_llm_output} │ │ │ │◀────────────────────────│ │ │ │ │ │ │ │ ⑤ POST /api/identify-gaps │ │ │ (task_id, target_topic, │ │ │ new_materials_text, │ │ │ structure_template_json) │ │ │────────────────────────▶│ │ │ │ │── POST /chat/completions ────────────────────▶│ │ │◀── 200 {choices[...]} ────────────────────────│ │ │── fix_incomplete_json() │ │ │── normalize_gap_analysis() │ │ ⑥ 200 {gap_analysis, │ │ │ │ raw_gap_output} │ │ │ │◀────────────────────────│ │ │ │ │ │ │ │ ⑦ POST /api/generate-svt │ │ │ (task_id, structure_template_json, │ │ │ gap_analysis_json, target_topic, │ │ │ version_type) │ │ │────────────────────────▶│ │ │ │ │── compact_structure_for_svt() │ │ │── compact_gaps_for_svt() │ │ │── POST /chat/completions ────────────────────▶│ │ │◀── 200 {choices[...]} ────────────────────────│ │ │── fix_incomplete_json() │ │ ⑧ 200 {svt_json} │ │ │ │◀────────────────────────│ │ │ │ │ │ │ │ ⑨ [前端] exportSvtJson() / previewVideo() │ │ │ Blob 下载 / 模态弹窗 │ │
关键数据转换节点
| 节点 | 输入 | 转换 | 输出 |
|---|---|---|---|
| T1 | 原始视频文件 (MP4) | OpenCV 解析 | sample_data(含 Base64 关键帧) |
| T2 | sample_data | compact_sample_data_for_llm() | 压缩后的视频摘要 |
| T3 | LLM 原始返回文本 | fix_incomplete_json() | Python dict |
| T4 | Python dict (LLM 自由字段) | normalize_llm_output_to_structure() | 标准structure_template |
| T5 | structure_template | compact_structure_for_svt() | 结构摘要(5 字段) |
| T6 | gap_analysis | compact_gaps_for_svt() | 缺口摘要(≤5 条) |
| T7 | 结构摘要 + 缺口摘要 + 版本特征 | LLM SVT 编译 | SVT-JSON |
| T8 | SVT-JSON | JSON.stringify()+Blob | 浏览器下载文件 |
| T9 | SVT-JSON | 前端 DOM 计算 | 时间线可视化弹窗 |
1.5 关键技术栈
服务端(Python 3.10+)
| 技术 | 版本 | 用途 | 许可证风险 |
|---|---|---|---|
| FastAPI | 0.109.0 | 异步 Web 框架 | MIT |
| Uvicorn | 0.27.0 | ASGI 服务器 | BSD-3 |
| OpenCV-Python | 4.8.1.78 | 视频帧读取/分析 | Apache 2.0 |
| NumPy | 1.26.3 | 数组运算与均匀采样 | BSD-3 |
| httpx | 0.26.0 | 异步 HTTP 客户端 | BSD-3 |
| PyYAML | 6.0.1 | YAML 配置文件解析 | MIT |
| Pydantic | 2.5.3 | 数据验证与序列化 | MIT |
| python-multipart | 0.0.6 | multipart 文件上传解析 | Apache 2.0 |
前端(浏览器端)
| 技术 | 版本/来源 | 用途 |
|---|---|---|
| 原生 HTML5 | — | 页面结构与 DOM API |
| TailwindCSS | CDN (cdn.tailwindcss.com) | 原子化 CSS |
| FontAwesome 4.7 | CDN (cdn.jsdelivr.net) | 图标字体 |
| Marked.js | CDN (cdn.jsdelivr.net) | Markdown → HTML 渲染 |
| Fetch API | 浏览器原生 | HTTP 异步通信 |
| URLSearchParams | 浏览器原生 | urlencoded 表单编码 |
| Blob / URL.createObjectURL | 浏览器原生 | 文件下载 |
1.6 组件间交互关系
依赖注入(隐式单例模式)
项目中未使用正式的 DI 容器,而是通过模块级全局变量实现单例:
# backend/main.py (L22-L24) video_processor = VideoProcessor() llm_client = DoubaoSeed2LiteEngine() gap_engine = GapCompletionEngine()影响:
- 优点:简单直接,无额外依赖
- 缺点:模块加载顺序敏感;测试时难以 mock;
GapCompletionEngine内部又持有独立的DoubaoSeed2LiteEngine实例
模块间调用关系(矩阵)
| 调用者 \ 被调用者 | config | video_processor | VolcEngineLLMClient | DoubaoSeed2Lite | GapCompletion |
|---|---|---|---|---|---|
main.py(入口) | — | — | — | — | — |
backend/main.py | ✓ | ✓ | — | ✓ | ✓ |
config.py | — | — | — | — | — |
video_processor.py | — | — | — | — | — |
llm_client.py | ✓ | — | ✓ | ✓ | — |
gap_completion.py | — | — | ✓ | ✓ | — |