AI-video-lifeplan-demo/.qoder/repowiki/zh/content/核心功能/AI解说脚本生成.md

351 lines
14 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.

# AI解说脚本生成
<cite>
**本文引用的文件列表**
- [main.py](file://main.py)
- [scripter.py](file://backend/scripter.py)
- [extractor.py](file://backend/extractor.py)
- [schemas.py](file://backend/video_processor/schemas.py)
- [render-props-types.ts](file://frontend/src/render-props-types.ts)
- [requirements.txt](file://requirements.txt)
- [.env.example](file://.env.example)
- [PROJECT_README.md](file://PROJECT_README.md)
- [investigate_video_extraction.py](file://backend/investigate_video_extraction.py)
- [investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py)
- [investigate_media_fetch.py](file://backend/investigate_media_fetch.py)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“AI解说脚本生成”模块,聚焦于如何基于结构化财务数据(来自PDF提取)与可选的视频转写结果,通过Google Gemini Pro API生成自然流畅的日语解说词。文档从提示工程设计、API调用流程、重试与解析策略、脚本段落结构与时间轴映射、调试技巧与多语言扩展等方面进行系统化阐述,帮助开发者快速实现并优化该模块。
## 项目结构
当前仓库采用“Python后端 + TypeScript前端”的混合架构:
- 后端负责:PDF与视频数据抽取、财务模拟、脚本生成、B-Roll抓取、渲染参数构建
- 前端使用Remotion渲染最终视频,类型定义由Zod校验
```mermaid
graph TB
A["main.py<br/>主入口与流水线编排"] --> B["backend/scripter.py<br/>脚本生成器"]
A --> C["backend/extractor.py<br/>PDF/视频抽取"]
A --> D["backend/data_builder.py<br/>财务模拟与图表数据"]
A --> E["backend/media_fetcher.py<br/>B-Roll抓取"]
A --> F["frontend/src/render-props-types.ts<br/>渲染参数类型定义"]
B --> G["google-generativeai<br/>Gemini API"]
C --> H["openai/whisper<br/>音频转写"]
D --> I["FFmpeg/媒体工具"]
E --> J["Pexels API"]
```
图示来源
- [main.py](file://main.py#L1-L120)
- [scripter.py](file://backend/scripter.py#L1-L69)
- [extractor.py](file://backend/extractor.py#L1-L84)
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L52-L120)
- [requirements.txt](file://requirements.txt#L1-L34)
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L1-L120)
- [main.py](file://main.py#L1-L120)
## 核心组件
- 脚本生成器(ScriptGenerator)
- 负责构建提示词、调用Gemini Pro API、解析响应并估算每段时长
- 当前为占位实现,尚未接入真实API
- 数据抽取器(PDFExtractor/VideoExtractor)
- PDFExtractor:计划使用Gemini Pro从PDF中抽取结构化数据
- VideoExtractor:计划使用Whisper进行音频转写与关键时间戳提取
- 视频处理数据结构(VideoSegment/KeyMoment/VideoAnalysisResult)
- 定义视频片段、关键时刻与完整分析结果的数据契约
- 渲染参数类型(ScriptSegment等)
- 定义脚本段落结构、图表同步、资产引用等前端消费所需字段
章节来源
- [scripter.py](file://backend/scripter.py#L1-L69)
- [extractor.py](file://backend/extractor.py#L1-L84)
- [schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L52-L120)
## 架构总览
脚本生成在整体流水线中的位置如下:
```mermaid
sequenceDiagram
participant CLI as "命令行(main.py)"
participant EX as "PDF/视频抽取(extractor.py)"
participant SG as "脚本生成(scripter.py)"
participant GEM as "Gemini Pro API"
participant CH as "图表数据(data_builder.py)"
participant OUT as "渲染参数(render-props-types.ts)"
CLI->>EX : 提取PDF/视频数据
EX-->>CLI : 返回结构化数据
CLI->>SG : 生成日语脚本
SG->>GEM : 发送提示词与上下文
GEM-->>SG : 返回JSON结构化脚本
SG-->>CLI : 返回脚本段落与同步点
CLI->>CH : 构建图表数据
CH-->>CLI : 返回图表数据
CLI->>OUT : 组装render_props.json
OUT-->>CLI : 类型校验通过
```
图示来源
- [main.py](file://main.py#L80-L160)
- [scripter.py](file://backend/scripter.py#L20-L69)
- [extractor.py](file://backend/extractor.py#L1-L84)
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L116-L140)
## 详细组件分析
### 脚本生成器(ScriptGenerator)设计
- 输入
- pdf_data:结构化财务数据(年龄、收入、支出、资产、重大事件等)
- video_data:可选的视频转写与时间戳(用于个性化叙述与同步)
- style:叙述风格(友好/专业/随意),用于提示词风格约束
- 输出
- segments:脚本段落列表(包含日语文本、时长、类型、可选图表同步)
- total_duration:预估总时长(秒)
- sync_points:建议的图表/视频同步点
- 当前状态
- 占位实现,未接入Gemini Pro API;需补充提示工程、API调用、重试与解析逻辑
```mermaid
classDiagram
class ScriptGenerator {
+api_key : string
+generate(pdf_data, video_data, style) Dict
-_build_prompt(pdf_data, style) str
}
class ScriptSegment {
+id : number
+text : string
+duration : number
+type : string
+assetUrl? : string
+chartSync? : object
}
ScriptGenerator --> ScriptSegment : "生成并返回"
```
图示来源
- [scripter.py](file://backend/scripter.py#L14-L69)
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L74-L93)
章节来源
- [scripter.py](file://backend/scripter.py#L14-L69)
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L74-L93)
### 提示工程(Prompt Engineering)设计原理
- 系统提示词(System Prompt)
- 明确角色:作为日语AI解说员,面向普通观众,语气自然、有亲和力
- 任务目标:将结构化财务数据转化为连贯、易懂的日语解说词
- 输出格式:严格要求JSON结构,包含segments数组、total_duration、sync_points
- 长度约束:目标3-5分钟,避免冗长或过短
- 上下文注入(Context Injection)
- 将pdf_data中的关键信息(年龄、收入、支出、资产、重大事件年份)注入提示词
- 可选地注入video_data(转写文本、关键词、时间戳),用于个性化与同步
- 输出格式控制(Output Formatting Control)
- 强制要求JSON,避免自然语言混入
- 对segments的字段进行白名单约束(id、text、duration、type、chartSync等)
- 示例流程(概念性)
```mermaid
flowchart TD
Start(["开始"]) --> BuildSys["构建系统提示词<br/>角色/目标/格式/长度约束"]
BuildSys --> InjectPDF["注入PDF结构化数据"]
InjectPDF --> InjectVideo["可选:注入视频转写与时间戳"]
InjectVideo --> BuildPrompt["组合最终提示词"]
BuildPrompt --> CallAPI["调用Gemini Pro API"]
CallAPI --> ParseResp["解析响应为JSON"]
ParseResp --> Validate["校验字段完整性"]
Validate --> |通过| Estimate["估算每段时长与总时长"]
Validate --> |失败| Retry["重试/修正提示词"]
Retry --> BuildPrompt
Estimate --> SyncPts["生成图表/视频同步点"]
SyncPts --> End(["结束"])
```
[此图为概念流程图,不直接映射具体源码,故无图示来源]
### Gemini API调用流程、重试机制与响应解析
- 调用流程(参考现有视频抽取实现)
- 初始化客户端与模型(例如使用gemini-3-pro-preview)
- 准备内容:媒体文件与提示词
- 发送请求并记录token用量
- 解析响应:优先从Markdown代码块中提取JSON
- 错误处理:捕获JSON解析异常,回退到原始文本并记录元数据
- 重试机制
- 建议在请求失败或解析失败时进行指数退避重试
- 设置最大重试次数与超时阈值
- 响应解析
- 严格按预期字段解包segments、total_duration、sync_points
- 对缺失字段进行默认值填充或抛出明确错误
```mermaid
sequenceDiagram
participant SG as "ScriptGenerator"
participant CL as "Gemini Client"
participant API as "Gemini API"
participant PARSE as "响应解析器"
SG->>CL : 初始化客户端与模型
SG->>CL : 组装contents(媒体/提示词)
CL->>API : 发送请求
API-->>CL : 返回响应
CL->>PARSE : 提取文本并尝试解析JSON
PARSE-->>SG : 返回segments/时长/同步点
alt 解析失败
PARSE-->>SG : 报错并返回原始文本
SG->>SG : 触发重试/修正提示词
end
```
图示来源
- [investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L232)
- [investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L228-L256)
- [investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L111-L136)
章节来源
- [investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L232)
- [investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L228-L256)
- [investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L111-L136)
### 脚本段落(ScriptSegment)结构与时间轴映射
- 结构设计
- 字段:id、text(日语)、duration(秒)、type(narration/chart_intro/chart_highlight/video_clip/transition)、assetUrl(可选)、chartSync(可选)
- chartSync:支持chartId(assetDepletion/cashFlow)、highlightYear、animationStart等
- 时间轴映射
- 每个ScriptSegment包含duration,便于与视频时间轴对齐
- 可通过chartSync将脚本与图表高亮帧对齐,提升叙事节奏感
- 与视频时间轴的关系
- 若存在video_data,可将脚本与视频转写的时间戳对齐,形成“字幕/旁白/画面”的三线同步
```mermaid
erDiagram
SCRIPT_SEGMENT {
number id
string text
number duration
string type
string assetUrl
object chartSync
}
RENDER_PROPS {
array script
object charts
object assets
}
SCRIPT_SEGMENT ||--o{ RENDER_PROPS : "组成"
```
图示来源
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L74-L120)
章节来源
- [render-props-types.ts](file://frontend/src/render-props-types.ts#L74-L120)
### 多语言支持与扩展路径
- 当前目标语言为日语,提示工程已体现“自然日语”与“友好语气”
- 扩展思路
- 在提示词中加入语言切换参数(如“输出为英语/中文”)
- 为不同语言维护独立的系统提示词模板
- 通过外部翻译服务或多语言模型实现跨语言生成
- 注意事项
- 不同语言的句式结构与停顿节奏差异较大,需分别训练与校准每段时长
- 图表标注与视觉元素需配合目标语言的表达习惯
[本节为概念性扩展说明,不直接分析具体源码,故无章节来源]
## 依赖分析
- 外部依赖
- google-generativeai:Gemini Pro API调用
- openai:Whisper音频转写(视频抽取阶段)
- ffmpeg-python:媒体处理
- requests:网络请求(B-Roll抓取等)
- 内部耦合
- main.py编排脚本生成与后续步骤
- scripter.py与extractor.py、data_builder.py共同构成数据-脚本-图表闭环
- frontend的类型定义确保前后端数据契约一致
```mermaid
graph LR
REQ["requirements.txt"] --> GEM["google-generativeai"]
REQ --> WHIS["openai"]
REQ --> FF["ffmpeg-python"]
REQ --> REQ2["requests"]
MAIN["main.py"] --> SCR["backend/scripter.py"]
MAIN --> EXT["backend/extractor.py"]
MAIN --> DAT["backend/data_builder.py"]
SCR --> GEM
EXT --> WHIS
DAT --> FF
```
图示来源
- [requirements.txt](file://requirements.txt#L1-L34)
- [main.py](file://main.py#L1-L120)
章节来源
- [requirements.txt](file://requirements.txt#L1-L34)
- [main.py](file://main.py#L1-L120)
## 性能考虑
- API调用成本控制
- 通过精简提示词与上下文注入,减少token用量
- 使用缓存策略(如翻译缓存)降低重复请求
- 响应解析效率
- 优先从代码块中提取JSON,避免全量字符串扫描
- 对大响应进行分段解析与字段校验
- 时长估算与同步
- 基于平均语速估算每段时长,结合chartSync进行微调
- 通过sync_points与视频转写时间戳对齐,减少后期调整工作量
[本节提供通用指导,不直接分析具体源码,故无章节来源]
## 故障排查指南
- API密钥问题
- 确认环境变量GEMINI_API_KEY/OPENAI_API_KEY已正确设置
- 检查密钥是否过期或被限制
- API限流与超时
- 实施指数退避重试,设置合理超时阈值
- 分批发送请求,避免突发流量
- JSON解析失败
- 捕获JSONDecodeError,记录原始响应与token用量
- 回退到原始文本并人工检查提示词格式
- 时长与同步偏差
- 校验segments的duration与chartSync字段
- 与视频转写时间戳进行交叉验证
章节来源
- [.env.example](file://.env.example#L1-L22)
- [investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L232)
- [investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L228-L256)
- [investigate_media_fetch.py](file://backend/investigate_media_fetch.py#L111-L136)
## 结论
脚本生成模块目前处于占位实现阶段,但其设计已清晰体现了提示工程、API调用、重试与解析、以及脚本段落与时间轴映射的核心要素。结合现有视频抽取与解析实现,可快速补齐Gemini Pro集成,完成从结构化财务数据到自然日语脚本的自动化生成,并为后续多语言扩展打下基础。
[本节为总结性内容,不直接分析具体源码,故无章节来源]
## 附录
- 环境变量与API密钥
- GEMINI_API_KEY:Gemini Pro
- OPENAI_API_KEY:Whisper
- PEXELS_API_KEY:B-Roll抓取
- 关键实现参考
- 视频抽取与JSON解析流程可作为Gemini脚本生成的参考模板
章节来源
- [.env.example](file://.env.example#L1-L22)
- [investigate_video_extraction.py](file://backend/investigate_video_extraction.py#L1-L232)
- [investigate_subtitle_extraction.py](file://backend/investigate_subtitle_extraction.py#L228-L256)