AI-video-lifeplan-demo/.qoder/repowiki/zh/content/架构设计/数据处理/PDF数据提取.md

312 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.

# PDF数据提取
<cite>
**本文引用的文件**
- [main.py](file://main.py)
- [backend/extractor.py](file://backend/extractor.py)
- [backend/scripter.py](file://backend/scripter.py)
- [backend/data_builder.py](file://backend/data_builder.py)
- [PROJECT_README.md](file://PROJECT_README.md)
- [.env.example](file://.env.example)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts)
- [tests/test_video_processor.py](file://tests/test_video_processor.py)
- [verify_structure.py](file://verify_structure.py)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [组件详解](#组件详解)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件聚焦于“PDF数据提取”能力,面向使用Google Gemini API从日语财务规划PDF报告中抽取结构化数据的场景。文档将系统阐述:
- PDFExtractor类的设计与实现机制:如何通过GEMINI_API_KEY进行身份验证、调用Gemini模型解析PDF并提取客户基本信息、财务数据、人生事件和保险信息。
- 在整体流水线中的调用时机与数据流转:结合main.py中的extract_pdf方法,说明从PDF上传到结构化JSON输出的完整过程。
- 针对初学者的流程图与针对高级开发者的提示工程策略、错误处理机制、数据验证模式及扩展支持新PDF模板的方法。
- 提供可直接参考的代码片段路径,帮助快速定位实现位置并进行定制化改造。
## 项目结构
该项目采用“Python后端 + TypeScript前端”的混合架构,围绕render_props.json作为前后端契约数据进行编排:
- 后端负责输入解析、数据提取、脚本生成、素材抓取与图表数据模拟。
- 前端基于Remotion渲染最终视频,类型定义由render-props-types.ts约束。
```mermaid
graph TB
A["main.py<br/>主入口与流水线编排"] --> B["backend/extractor.py<br/>PDF/视频提取器"]
A --> C["backend/scripter.py<br/>脚本生成器"]
A --> D["backend/data_builder.py<br/>图表数据模拟"]
A --> E["frontend/src/render-props-types.ts<br/>类型契约"]
B --> F["Google Gemini API<br/>PDF解析/视频理解"]
C --> F
D --> E
```
图表来源
- [main.py](file://main.py#L48-L199)
- [backend/extractor.py](file://backend/extractor.py#L15-L84)
- [backend/scripter.py](file://backend/scripter.py#L14-L68)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L132-L141)
- [main.py](file://main.py#L48-L199)
## 核心组件
- PDFExtractor:封装Gemini API调用,负责从PDF中抽取结构化数据(客户信息、财务数据、人生事件、保险信息)。
- ScriptGenerator:封装Gemini API调用,基于PDF与视频数据生成自然日语的叙述脚本。
- FinancialSimulator与data_builder:将PDF提取的参数转化为资产枯竭与现金流图表数据,形成render_props.json所需结构。
- main.py:流水线编排入口,按步骤执行PDF提取、视频提取、脚本生成、素材抓取、图表数据模拟、render_props.json生成与视频渲染。
章节来源
- [backend/extractor.py](file://backend/extractor.py#L15-L84)
- [backend/scripter.py](file://backend/scripter.py#L14-L68)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- [main.py](file://main.py#L48-L199)
## 架构总览
下图展示了从PDF上传到结构化JSON输出的关键交互与数据流:
```mermaid
sequenceDiagram
participant U as "用户"
participant M as "main.py<br/>VideoGeneratorPipeline"
participant X as "backend/extractor.py<br/>PDFExtractor"
participant G as "Google Gemini API"
participant S as "backend/scripter.py<br/>ScriptGenerator"
participant D as "backend/data_builder.py<br/>FinancialSimulator"
participant R as "frontend/src/render-props-types.ts<br/>类型契约"
U->>M : 运行命令行
M->>M : 解析参数/加载配置
M->>X : 调用extract_pdf()当前为占位
Note right of X : 实际实现应调用G,解析PDF并返回结构化数据
X-->>M : 返回pdf_datamock
M->>S : 生成脚本当前为占位
S-->>M : 返回scriptmock
M->>D : 构建图表数据基于pdf_data
D-->>M : 返回charts数据
M->>M : 组装render_props.json
M-->>U : 输出render_props.json
Note over M,R : render_props.json遵循前端类型契约
```
图表来源
- [main.py](file://main.py#L48-L199)
- [backend/extractor.py](file://backend/extractor.py#L15-L84)
- [backend/scripter.py](file://backend/scripter.py#L14-L68)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
## 组件详解
### PDFExtractor类设计与实现要点
- 身份验证:优先使用构造函数传入的api_key,否则从环境变量GEMINI_API_KEY读取;若两者均不可得则抛出异常。
- 数据结构:返回字典包含四类键:client_info、financial_data、life_events、insurance_data。
- 当前状态:方法体为占位实现,预留了后续接入Gemini API的步骤(上传PDF、提示工程抽取结构化JSON、Schema校验)。
```mermaid
classDiagram
class PDFExtractor {
+api_key : str
+__init__(api_key=None)
+extract(pdf_path) Dict
}
```
图表来源
- [backend/extractor.py](file://backend/extractor.py#L15-L43)
章节来源
- [backend/extractor.py](file://backend/extractor.py#L15-L43)
- [.env.example](file://.env.example#L7-L9)
### 在流水线中的调用时机与数据流转
- main.py的VideoGeneratorPipeline.run()按顺序执行:PDF提取、视频提取、脚本生成、素材抓取、图表数据模拟、render_props.json生成、视频渲染。
- extract_pdf()当前为占位实现,返回mock数据;实际实现应调用PDFExtractor.extract()并返回结构化结果。
- 该结构化数据随后被data_builder.build_chart_data()消费,生成资产枯竭与现金流图表数据,最终写入render_props.json。
```mermaid
flowchart TD
Start(["开始:main.run()"]) --> Step1["Step 1:extract_pdf()占位"]
Step1 --> Step2["Step 2:extract_video()可选"]
Step2 --> Step3["Step 3:generate_script()占位"]
Step3 --> Step4["Step 4:fetch_broll()占位"]
Step4 --> Step5["Step 5:build_render_props()占位"]
Step5 --> Step6["保存render_props.json"]
Step6 --> End(["结束:可选渲染视频"])
```
图表来源
- [main.py](file://main.py#L48-L199)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
章节来源
- [main.py](file://main.py#L48-L199)
### 结构化数据契约与验证
- render_props.json是前后端契约,前端通过Zod Schema进行运行时校验,确保数据一致性。
- YearlySnapshot与CashFlowData等核心类型在前端定义,后端data_builder.py需与之保持一致。
```mermaid
erDiagram
RENDER_PROPS {
object meta
object charts
array script
object assets
}
CHARTS {
object assetDepletion
object cashFlow
}
ASSET_DEPLETION {
array timeline
object meta
}
CASH_FLOW {
array timeline
object meta
}
YEARLY_SNAPSHOT {
number year
object ages
object financials
array events
boolean isCritical
}
CASHFLOW_DATA {
number year
number age
object income
object expenses
number totalExpense
number netCashFlow
number assetBalance
}
RENDER_PROPS ||--o{ CHARTS : "包含"
CHARTS ||--o{ ASSET_DEPLETION : "包含"
CHARTS ||--o{ CASH_FLOW : "包含"
ASSET_DEPLETION ||--o{ YEARLY_SNAPSHOT : "timeline"
CASH_FLOW ||--o{ CASHFLOW_DATA : "timeline"
```
图表来源
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
章节来源
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
### 提示工程策略(建议实践)
以下为通用提示工程最佳实践,便于在PDFExtractor中落地(具体提示词需根据目标PDF模板与字段进行定制):
- 明确角色与任务:指定模型扮演“财务规划报告解析专家”,职责是抽取结构化字段。
- 指定输出格式:要求返回JSON,字段名与类型明确,避免自由文本。
- 提供上下文与约束:包含PDF语言(日语)、单位(万円)、关键字段清单(姓名、年龄、退休年龄、寿命预期、资产、收入、支出、重大事件年份与金额、现有保险信息等)。
- 使用Few-shot示例:给出少量正确样例,提升抽取稳定性。
- 错误兜底:当某字段缺失时,返回空值或占位符,保证JSON结构完整。
- 分步抽取:先抽取客户与财务信息,再抽取人生事件,最后抽取保险信息,降低复杂度。
- 校验与重试:对返回的JSON进行Schema校验,失败则重试或回退到更保守的提示。
说明:以上为通用策略建议,具体提示词需结合实际PDF模板与字段进行定制。
### 错误处理机制
- API密钥缺失:PDFExtractor与ScriptGenerator在初始化时检查GEMINI_API_KEY或OPENAI_API_KEY,缺失时抛出异常,便于早期发现配置问题。
- PDF提取占位:main.py的extract_pdf()当前返回mock数据,便于前端联调;实际部署时应替换为PDFExtractor.extract()。
- 视频提取占位:同上,extract_video()当前返回mock数据。
- 渲染阶段:main.py的render_video()当前为占位,实际渲染逻辑已注释,便于调试。
章节来源
- [backend/extractor.py](file://backend/extractor.py#L15-L43)
- [backend/scripter.py](file://backend/scripter.py#L14-L49)
- [main.py](file://main.py#L85-L135)
### 扩展支持新PDF模板的方法
- 字段映射:在PDFExtractor中新增字段映射规则,将新模板中的关键词映射到标准字段(client_info、financial_data、life_events、insurance_data)。
- 提示词适配:针对新模板优化提示词,增加领域特定的few-shot示例与约束。
- Schema演进:若新增字段,需同步更新前端render-props-types.ts中的Schema与类型定义。
- 测试覆盖:使用tests/test_video_processor.py类似的风格编写单元测试,验证字段抽取稳定性与边界情况。
章节来源
- [backend/extractor.py](file://backend/extractor.py#L15-L43)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L1-L143)
## 依赖关系分析
- main.py依赖backend模块(extractor、scripter、data_builder),并通过render_props.json与前端类型契约对接。
- extractor与scripter依赖Gemini API;data_builder依赖后端财务模拟逻辑。
- 前端通过Zod Schema对render_props.json进行强类型校验,确保数据一致性。
```mermaid
graph LR
M["main.py"] --> E["backend/extractor.py"]
M --> S["backend/scripter.py"]
M --> D["backend/data_builder.py"]
E --> G["Google Gemini API"]
S --> G
D --> F["前端类型契约<br/>render-props-types.ts"]
```
图表来源
- [main.py](file://main.py#L48-L199)
- [backend/extractor.py](file://backend/extractor.py#L15-L84)
- [backend/scripter.py](file://backend/scripter.py#L14-L68)
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
章节来源
- [main.py](file://main.py#L48-L199)
- [PROJECT_README.md](file://PROJECT_README.md#L132-L141)
## 性能考量
- API调用成本:Gemini API按Token计费,建议在提示词中明确字段清单与输出格式,减少冗余内容,控制成本。
- 并发与批处理:若需要同时处理多份PDF,可在上游引入队列与并发控制,避免API限流。
- 缓存策略:对常见字段与few-shot示例进行缓存,减少重复请求。
- 本地预处理:在上传前对PDF进行OCR与清洗,提高抽取准确率,减少重试次数。
## 故障排查指南
- “API密钥未找到”
- 确认.GEMINI_API_KEY或.OPENAI_API_KEY存在于环境变量中,或在.env中配置。
- 参考.env.example进行配置。
- “PDF提取失败”
- 确保PDF可读且未加密;检查Gemini配额与限额。
- 参考PROJECT_README.md中的故障排查章节。
- “渲染失败”
- 确认前端依赖安装完成,render_props.json结构与前端Schema一致。
- “导入失败”
- 使用verify_structure.py检查目录与文件是否齐全,确认Python包导入正常。
章节来源
- [.env.example](file://.env.example#L7-L14)
- [PROJECT_README.md](file://PROJECT_README.md#L217-L233)
- [verify_structure.py](file://verify_structure.py#L1-L136)
## 结论
PDF数据提取是本项目的核心环节之一,它将静态PDF转化为结构化数据,驱动后续脚本生成、图表模拟与视频渲染。当前实现处于占位阶段,建议尽快完成PDFExtractor与ScriptGenerator的实际集成,并完善提示工程、Schema校验与错误处理,以支撑多样化的PDF模板与高质量的产出。
## 附录
### 关键实现片段路径(不展示具体代码内容)
- PDFExtractor类与初始化逻辑
- [backend/extractor.py](file://backend/extractor.py#L15-L23)
- PDF提取方法占位与待实现说明
- [backend/extractor.py](file://backend/extractor.py#L23-L43)
- main.py中extract_pdf占位实现
- [main.py](file://main.py#L85-L98)
- main.py中build_render_props占位实现
- [main.py](file://main.py#L145-L199)
- data_builder中图表数据构建
- [backend/data_builder.py](file://backend/data_builder.py#L150-L200)
- 前端类型契约(Zod Schema)
- [frontend/src/render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L232)
- 环境变量配置示例
- [.env.example](file://.env.example#L7-L14)
- 项目数据流说明
- [PROJECT_README.md](file://PROJECT_README.md#L132-L141)