8.1 配置清单
在 application.yml(或配置中心)中配置:
java
pdf:
baidu:
ocr:
api-key: 你的百度应用 API Key
secret-key: 你的百度应用 Secret Key
# token-url / doc-parse-task-url / doc-parse-query-url 一般用默认
doc-parse-poll-interval-ms: 5000
doc-parse-max-attempts: 40
expire-buffer: 86400 # Token 提前 1 天刷新
ai:
api-key: "{id}.{secret}" # 大模型 API Key
model: glm-4-flash # 性价比;要更准用 glm-4-plus
base-url: https://open.bigmodel.cn/api/paas/v4/chat/completions
temperature: 0.1
stream: true
use-file: false # true=文件抽取路径
max-tokens: 16384 # 大表防截断
timeout: 300000 # 单次调用超时 5 分钟
concurrency: 4 # 并行线程数
chunk-page-size: 2
chunk-char-threshold: 2147483647 # 默认不分块
poll-interval-ms: 8000 # 异步结果轮询间隔
pdf-save-dir: D:/files/ai-split
data-json-dir: D:/files/ai-json
ocr-json-dir: D:/files/ocr-json
schema-path: # 外部字段定义文件(可选,优先于内置)
split-headings: # 除了按照表号外 按照标题也分割
- 补充说明
- 附录信息
8.2 运维要点
- Redis 必须可用 :Access Token 缓存依赖
RedisCache。 @Scheduled必须开启 :启动类加@EnableScheduling,否则异步抽取结果永远停在「抽取中」。- 落盘目录需有写权限 :生产建议挂持久卷;
pdf-save-dir / data-json-dir / ocr-json-dir三处。 - 超时联动 :百度大文件解析慢,
doc-parse-max-attempts × interval决定最长等待;大模型长输出时timeout与max-tokens要同步放大。 - 字段定义可热调 :把
schema-path指到外部文件,改字段不必重启/重打包。
8.3 实操:如何新增一张表的抽取
抽取与还原(第 3、5、6 章)是通用 的,新增一张表通常只动下面五处:
- 加字段定义 :
table-schema.json增加以「表标题」为 key 的example(或fields),决定 AI 输出结构。 - 建业务 VO + 库表 :
domain/写XxxImportVo,resources/sql/加建表脚本,mapper/+resources/mapper/加 Mapper。 - 写装配器 :
convert/新增XxxImportAssembler.assemble(dataJson),解包rootKey、归并明细、字段别名兜底,输出 VO。 - 加导入方法 :
IImportService/ImportServiceImpl增加importXxx(vo)落库。 - 接分派 :
ExtractionRecordServiceImpl.importToLibrary的表号switch接上新装配器与导入方法。
验证:上传含该表的 PDF → ocr-parse(百度 OCR 识别成 JSON)→ 调AI → 看 data_json → importToLibrary。
8.4 常见问题与排错
| 现象 | 可能原因 | 处理 |
|---|---|---|
百度OCR鉴权失败:未配置 apiKey/secretKey |
配置缺失 | 补 pdf.baidu.ocr.api-key/secret-key |
| 文档解析一直超时 | 文件过大或网络慢 | 调大 doc-parse-max-attempts / interval |
调接口报 error_code=110/111 |
Token 失效 | 已自动刷新重试一次;持续失败检查 Key 是否被禁用 |
AI输出超长被截断(finish_reason=length) |
大表 JSON 超 max-tokens |
调大 max-tokens,或对该表降低 chunk-char-threshold 启用分块 |
| 抽取结果列名/层级与库不符 | 模型输出波动 | 在 table-schema.json 补/收紧 example,或在装配器加兜底映射 |
| 状态一直「抽取中」 | 未开启定时任务 | 启动类加 @EnableScheduling;检查 poll-interval-ms |
| 合并单元格只有首行有值 | 提示词未生效或 OCR 识别结构丢失 | 检查 SYSTEM_PROMPT 第 4 条;核对 OCR 识别 JSON 是否还原了合并结构 |
| 标题未被识别为表 | 标题不匹配 ^表\d+ |
检查 PDF 文本提取结果;必要时用 split-headings 配关键词 |
| 同一张表被切成多段 | 跨页标题去重失效 | 检查 normalizeTitle 是否覆盖该标题格式 |
8.5 全系列回顾
| 章 | 一句话 |
|---|---|
| 01 总览 | 两模块组成「PDF → 结构化数据」流水线,按表为最小单元 |
| 02 选型 | baiduocr 零额外依赖;pdf-extraction 用 PDFBox + 模型SDK(Tabula 已废弃) |
| 03 PDF切分 | PDFBox 按「表N」切段(Markdown 还原已废弃) |
| 04 百度OCR | 提前过期缓存 Token + 异步任务轮询 + 失效重试 |
| 05 提示词 | 铁律定下限、结构示例定上限、对齐输入降难度 |
| 06 抽取 | 客户端四形态 + 切表/并行/合并编排,失败隔离 |
| 07 入库 | 异步提交 + 定时轮询 + 按表号装配器落库 |
| 08 运维 | 配置、新增表五步、排错对照表 |
核心立场:没有银弹。模型、OCR、技术栈都可替换,真正沉淀下来的是这套「切分 → 提示 → 抽取 → 装配」的处理范式。
替换方案与测试方式
经过测试可替换的方案有 paddleocr 开源模型 + DeepSeek模型组合
1、paddleocr 识别pdf文件输出json
2、将json与关键词发送给deepseek模型
3、输出结果