# 数据处理 **本文引用的文件** - [main.py](file://main.py) - [PROJECT_README.md](file://PROJECT_README.md) - [backend/extractor.py](file://backend/extractor.py) - [backend/data_builder.py](file://backend/data_builder.py) - [backend/scripter.py](file://backend/scripter.py) - [backend/media_fetcher.py](file://backend/media_fetcher.py) - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts) - [.env.example](file://.env.example) - [requirements.txt](file://requirements.txt) - [tests/test_video_processor.py](file://tests/test_video_processor.py) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件聚焦于数据处理子系统,围绕财务规划PDF与访谈视频的提取流程展开,解释以下要点: - extractor.py 模块如何通过 Google Gemini API 解析财务规划PDF报告,抽取客户基本信息、资产状况、收支数据等关键字段; - main.py 中的 extract_pdf 与 extract_video 方法在整体流水线中的协调机制; - 针对初学者的数据提取流程图,展示从原始文件到结构化数据的转换过程; - 面向高级开发者的提示工程策略、错误处理机制与数据验证模式; - 实际代码示例路径,帮助扩展支持新的PDF模板或处理不同格式的视频文件。 ## 项目结构 数据处理子系统位于 backend 目录,主要由以下模块组成: - extractor.py:负责 PDF 与视频的结构化提取(当前为占位实现,预留 API 调用与提示工程); - data_builder.py:基于提取结果进行财务模拟与图表数据构建; - scripter.py:基于 PDF 与视频内容生成日语叙述脚本(占位); - media_fetcher.py:基于关键词抓取 B-Roll 视频(占位); - video_processor:视频分析策略与数据结构定义(音频优先策略已实现,直接分析待实现)。 ```mermaid graph TB A["main.py
主入口与流水线编排"] --> B["backend/extractor.py
PDF/视频提取器"] A --> C["backend/data_builder.py
财务模拟与图表数据构建"] A --> D["backend/scripter.py
脚本生成器"] A --> E["backend/media_fetcher.py
B-Roll抓取器"] A --> F["backend/video_processor/__init__.py
视频分析策略入口"] F --> G["backend/video_processor/schemas.py
视频分析数据结构"] A --> H["frontend/src/render-props-types.ts
渲染契约类型定义"] ``` 图表来源 - [main.py](file://main.py#L33-L226) - [backend/extractor.py](file://backend/extractor.py#L1-L84) - [backend/data_builder.py](file://backend/data_builder.py#L1-L200) - [backend/scripter.py](file://backend/scripter.py#L1-L69) - [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72) - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L251) 章节来源 - [PROJECT_README.md](file://PROJECT_README.md#L132-L208) - [main.py](file://main.py#L33-L226) ## 核心组件 - PDFExtractor:封装 PDF 提取逻辑,初始化时校验 Gemini API 密钥,提供 extract 接口用于返回结构化数据字典(当前抛出未实现异常,留待实现)。 - VideoExtractor:封装视频提取逻辑,初始化时校验 OpenAI API 密钥,提供 extract 接口用于返回包含转录文本、时间戳与关键字的字典(当前抛出未实现异常,留待实现)。 - FinancialSimulator:根据提取参数进行年金现金流模拟,产出资产枯竭与现金流量两种图表数据,支持通胀、投资回报与赤字复利等参数。 - ScriptGenerator:封装脚本生成逻辑,初始化时校验 Gemini API 密钥,提供 generate 接口用于返回脚本段落与同步点(当前抛出未实现异常,留待实现)。 - MediaFetcher:封装 B-Roll 抓取逻辑,初始化时校验 Pexels API 密钥,提供 fetch_broll 接口用于返回按关键词分组的视频链接(当前抛出未实现异常,留待实现)。 - VideoProcessor:提供 analyze_video 入口,支持“音频优先”与“直接分析”两种策略;音频优先策略依赖 Whisper 进行转录与时间戳抽取,直接分析策略待实现。 章节来源 - [backend/extractor.py](file://backend/extractor.py#L1-L84) - [backend/data_builder.py](file://backend/data_builder.py#L1-L200) - [backend/scripter.py](file://backend/scripter.py#L1-L69) - [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72) - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91) ## 架构总览 数据处理子系统在 main.py 的流水线中承担“提取”阶段,随后进入“生成脚本”“抓取素材”“构建渲染参数”“渲染视频”的后续步骤。PDF 提取与视频提取分别由 extractor.py 中的 PDFExtractor 与 VideoExtractor 负责;最终的渲染参数由 data_builder.py 生成,前端通过 render-props-types.ts 的类型定义进行强约束。 ```mermaid sequenceDiagram participant CLI as "命令行" participant Main as "main.py" participant Ext as "backend/extractor.py" participant Sim as "backend/data_builder.py" participant Script as "backend/scripter.py" participant Media as "backend/media_fetcher.py" participant Render as "Remotion 前端" CLI->>Main : 启动流水线 Main->>Ext : extract_pdf() Ext-->>Main : 结构化PDF数据 Main->>Ext : extract_video() Ext-->>Main : 视频转录与时间戳 Main->>Script : generate_script(pdf_data, video_data) Script-->>Main : 叙述脚本 Main->>Media : fetch_broll(script) Media-->>Main : B-Roll资源 Main->>Sim : build_chart_data(pdf_data) Sim-->>Main : 图表数据 Main->>Render : 写入 render_props.json 并触发渲染 Render-->>CLI : 输出视频 ``` 图表来源 - [main.py](file://main.py#L48-L226) - [backend/extractor.py](file://backend/extractor.py#L1-L84) - [backend/data_builder.py](file://backend/data_builder.py#L150-L200) - [backend/scripter.py](file://backend/scripter.py#L1-L69) - [backend/media_fetcher.py](file://backend/media_fetcher.py#L1-L72) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L117-L135) ## 详细组件分析 ### PDF提取器(PDFExtractor) PDFExtractor 负责调用 Gemini API 对财务规划PDF进行解析,抽取客户基本信息、资产状况、收支数据等关键字段。当前实现为占位,抛出未实现异常,留待完成。 ```mermaid classDiagram class PDFExtractor { +api_key : str +extract(pdf_path) Dict } ``` 图表来源 - [backend/extractor.py](file://backend/extractor.py#L15-L43) 章节来源 - [backend/extractor.py](file://backend/extractor.py#L15-L43) ### 视频提取器(VideoExtractor) VideoExtractor 负责调用 Whisper API 对视频进行转录与时间戳抽取,返回包含转录文本、时间戳与关键字的结构化数据。当前实现为占位,抛出未实现异常,留待完成。 ```mermaid classDiagram class VideoExtractor { +api_key : str +extract(video_path) Dict } ``` 图表来源 - [backend/extractor.py](file://backend/extractor.py#L45-L72) 章节来源 - [backend/extractor.py](file://backend/extractor.py#L45-L72) ### 财务模拟与图表数据构建(FinancialSimulator) FinancialSimulator 基于提取参数进行年金现金流模拟,产出资产枯竭与现金流量两种图表数据。其核心逻辑包括: - 按年龄循环推进,计算每年收入、通胀调整支出、事件成本; - 当资产余额为正时应用投资回报,为负时应用赤字利息(复利); - 将年度快照转换为现金流量图表数据,便于前端可视化。 ```mermaid flowchart TD Start(["开始模拟"]) --> Init["读取参数
当前年龄/退休年龄/寿命预期/资产/收入/支出/事件"] Init --> Loop{"按年龄循环"} Loop --> |计算| Income["收入 = 年收入 或 0退休后"] Income --> Inflation["通胀调整支出"] Inflation --> Events["事件成本累加"] Events --> Net["净现金流 = 收入 - 支出 - 事件"] Net --> Balance{"资产余额 >= 0 ?"} Balance --> |是| Invest["正余额:应用投资回报"] Balance --> |否| Deficit["负余额:应用赤字利息"] Invest --> Snapshot["生成年度快照"] Deficit --> Snapshot Snapshot --> Next{"是否到达寿命预期?"} Next --> |否| Loop Next --> |是| Cashflow["转换为现金流量数据"] Cashflow --> End(["结束"]) ``` 图表来源 - [backend/data_builder.py](file://backend/data_builder.py#L15-L148) 章节来源 - [backend/data_builder.py](file://backend/data_builder.py#L15-L148) ### 渲染参数构建(build_chart_data) 该函数将 PDF 提取结果输入到 FinancialSimulator,得到两条时间线并打包为 render_props.json 的 charts 字段,供前端渲染使用。 ```mermaid sequenceDiagram participant Caller as "调用方" participant Builder as "build_chart_data" participant Simulator as "FinancialSimulator" Caller->>Builder : 传入 pdf_data Builder->>Simulator : simulate_timeline(...) Simulator-->>Builder : 年度快照列表 Builder->>Simulator : build_cashflow_data(timeline) Simulator-->>Builder : 现金流量数据 Builder-->>Caller : 返回 charts 对象 ``` 图表来源 - [backend/data_builder.py](file://backend/data_builder.py#L150-L200) 章节来源 - [backend/data_builder.py](file://backend/data_builder.py#L150-L200) ### 视频分析策略(video_processor) 视频分析模块提供两种策略: - 音频优先策略:先提取音频,再调用 Whisper 进行转录与时间戳抽取; - 直接分析策略:直接将视频送入 Gemini 进行分析(当前未实现)。 ```mermaid classDiagram class VideoProcessor { +analyze_video(video_path, strategy, config) VideoAnalysisResult } class AudioFirstStrategy { +analyze(video_path) VideoAnalysisResult } class DirectStrategy { +analyze(video_path) VideoAnalysisResult } class VideoAnalysisResult { +source_video : str +duration : float +strategy : str +segments : list +key_moments : list +metadata : dict +to_dict() dict +get_high_importance_segments() list +get_quotes() list } class VideoSegment { +start_time : float +end_time : float +description : str +transcript : str +importance : str +tags : list +speaker : str +duration : float +to_dict() dict } class KeyMoment { +timestamp : float +type : str +content : str +context : str +to_dict() dict } VideoProcessor --> AudioFirstStrategy : "音频优先" VideoProcessor --> DirectStrategy : "直接分析" AudioFirstStrategy --> VideoAnalysisResult DirectStrategy --> VideoAnalysisResult VideoAnalysisResult --> VideoSegment : "包含" VideoAnalysisResult --> KeyMoment : "包含" ``` 图表来源 - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L31-L60) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L12-L91) 章节来源 - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91) ### 主流水线中的协调机制(main.py) main.py 的 VideoGeneratorPipeline.run 负责串联各阶段: - Step 1:extract_pdf 调用 PDFExtractor(当前为占位),返回结构化数据; - Step 2:extract_video 调用 VideoExtractor(当前为占位),返回转录与时间戳; - Step 3:generate_script 调用 ScriptGenerator(当前为占位),返回脚本; - Step 4:fetch_broll 调用 MediaFetcher(当前为占位),返回 B-Roll; - Step 5:build_render_props 调用 data_builder.build_chart_data,生成图表数据; - Step 6:render_video 调用 Remotion 渲染引擎。 ```mermaid flowchart TD A["run()"] --> B["extract_pdf() 占位实现"] A --> C["extract_video() 占位实现"] A --> D["generate_script() 占位实现"] A --> E["fetch_broll() 占位实现"] A --> F["build_render_props() 调用 data_builder.build_chart_data()"] F --> G["写入 render_props.json"] A --> H["render_video() 调用 Remotion"] ``` 图表来源 - [main.py](file://main.py#L48-L226) - [backend/data_builder.py](file://backend/data_builder.py#L150-L200) 章节来源 - [main.py](file://main.py#L48-L226) ## 依赖关系分析 - 外部依赖:Google Gemini API(PDF解析、脚本生成)、OpenAI Whisper(音频转录)、Pexels API(B-Roll抓取)、FFmpeg(视频处理工具链)。 - 环境变量:GEMINI_API_KEY、OPENAI_API_KEY、PEXELS_API_KEY,以及默认财务参数(通胀率、赤字利率、投资回报率)。 - 类型契约:前端通过 render-props-types.ts 定义了严格的渲染参数结构,确保后端输出与前端消费一致。 ```mermaid graph TB Env[".env.example
环境变量"] --> Keys["API密钥"] Keys --> Gemini["Google Gemini API"] Keys --> OpenAI["OpenAI Whisper API"] Keys --> Pexels["Pexels API"] FF["FFmpeg"] --> VP["backend/video_processor"] VP --> Main["main.py"] Main --> Types["frontend/src/render-props-types.ts"] ``` 图表来源 - [.env.example](file://.env.example#L1-L23) - [requirements.txt](file://requirements.txt#L1-L34) - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60) - [main.py](file://main.py#L48-L226) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L117-L135) 章节来源 - [.env.example](file://.env.example#L1-L23) - [requirements.txt](file://requirements.txt#L1-L34) - [PROJECT_README.md](file://PROJECT_README.md#L132-L208) ## 性能考量 - API 调用成本控制:PDF 与视频提取均依赖外部 LLM 与转录服务,建议: - 批量请求与缓存重复任务结果; - 控制并发数量,避免触发配额限制; - 使用本地缓存翻译与关键词映射,减少重复 API 调用。 - 视频处理优化:音频优先策略可显著降低视频上传体积,建议优先采用该策略;同时合理设置语言与分段长度以提升转录质量。 - 模拟计算优化:FinancialSimulator 的循环次数与复杂度与寿命预期成线性关系,可通过参数裁剪或并行化(如多进程)加速大规模场景。 ## 故障排查指南 - API 密钥缺失 - 现象:初始化 PDFExtractor/VideoExtractor/ScriptGenerator/MediaFetcher 时抛出异常。 - 处理:复制 .env.example 到 .env 并填入有效密钥。 - PDF 提取失败 - 现象:extract_pdf 占位抛出未实现异常或外部 API 返回错误。 - 处理:检查 PDF 是否可读、网络连通性与配额;确认 Gemini API 版本与权限。 - 视频转录失败 - 现象:extract_video 占位抛出未实现异常或 Whisper 返回空结果。 - 处理:确认 FFmpeg 已安装且在 PATH 中;检查音频质量与语言设置。 - 渲染参数不匹配 - 现象:前端类型校验失败。 - 处理:对照 render-props-types.ts 的接口定义,逐项核对字段类型与必填项。 章节来源 - [backend/extractor.py](file://backend/extractor.py#L15-L43) - [backend/scripter.py](file://backend/scripter.py#L14-L49) - [backend/media_fetcher.py](file://backend/media_fetcher.py#L15-L42) - [PROJECT_README.md](file://PROJECT_README.md#L218-L233) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L117-L135) ## 结论 本数据处理子系统以 extractor.py 为核心入口,结合 data_builder.py 的财务模拟能力,形成从 PDF/视频到结构化数据再到渲染参数的完整链路。当前模块多为占位实现,建议优先完成 PDF 与视频提取的提示工程与错误处理,再逐步完善脚本生成、B-Roll 抓取与视频分析策略。通过严格的类型契约与环境配置管理,可确保前后端协作稳定可靠。 ## 附录 ### 初学者数据提取流程图(PDF → 结构化数据) ```mermaid flowchart TD A["输入:财务规划PDF"] --> B["上传至 Gemini API"] B --> C["提示工程:提取客户信息/资产/收支/事件"] C --> D["结构化JSON输出"] D --> E["main.py 接收并传递给后续模块"] ``` 图表来源 - [backend/extractor.py](file://backend/extractor.py#L15-L43) - [main.py](file://main.py#L85-L114) ### 初学者数据提取流程图(视频 → 结构化数据) ```mermaid flowchart TD A["输入:访谈视频"] --> B["音频优先策略:提取音频"] B --> C["Whisper 转录与时间戳抽取"] C --> D["结构化字典:转录文本/时间戳/关键字"] D --> E["main.py 接收并传递给脚本与素材模块"] ``` 图表来源 - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L31-L60) - [backend/extractor.py](file://backend/extractor.py#L45-L72) - [main.py](file://main.py#L99-L114) ### 高级开发者:提示工程策略与数据验证模式 - 提示工程策略(PDF) - 明确输出格式要求(JSON 字段清单),限定关键字段(客户姓名、年龄、退休年龄、寿命预期、资产、年收入、年支出、重大事件等); - 引入上下文约束(货币单位、时间起点、生命周期范围),减少歧义; - 使用示例与反例引导模型输出稳定结构。 - 提示工程策略(视频) - 在音频优先策略下,先用 Whisper 获取高置信度转录,再用 Gemini 进行摘要与关键帧标注; - 对时间戳与关键词进行一致性校验,避免漂移。 - 错误处理机制 - 初始化阶段严格校验 API 密钥是否存在; - 对外部 API 返回进行重试与降级策略(如缓存上次结果); - 对空结果与异常进行显式捕获与日志记录。 - 数据验证模式 - 前端使用 Zod Schema 对 render_props.json 进行运行时校验,保证字段类型与必填项一致; - 后端在构建图表数据时进行边界值与合理性检查(如资产为负时标记 isCritical)。 章节来源 - [backend/extractor.py](file://backend/extractor.py#L15-L72) - [backend/scripter.py](file://backend/scripter.py#L14-L49) - [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L140-L231) ### 实际代码示例(扩展新模板/新格式) - 扩展 PDF 模板支持 - 在 PDFExtractor.extract 中实现: - 上传 PDF 至 Gemini API; - 构建针对新模板的提示工程,明确字段映射; - 对输出进行模式匹配与校验,必要时回退到二次校正。 - 示例路径参考:[PDFExtractor.extract](file://backend/extractor.py#L23-L43) - 处理不同格式的视频文件 - 在 VideoExtractor.extract 中实现: - 通过 FFmpeg 提取音频并转码; - 调用 Whisper API 获取转录与时间戳; - 对多说话人场景增加 speaker 字段与分段策略。 - 示例路径参考:[VideoExtractor.extract](file://backend/extractor.py#L53-L71) - 视频分析策略扩展 - 在 video_processor 中新增策略类,复用 VideoAnalysisResult/VideoSegment/KeyMoment 数据结构; - 在 analyze_video 中注册新策略入口。 - 示例路径参考: - [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L31-L60) - [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L12-L91)