doc-parser-architecture.md
15.1 KB
文档解析系统架构文档
版本: 1.0 创建日期: 2026-02-25 维护者: Development Team
📋 目录
系统概述
文档解析系统是计划书配置自动化的核心工具,用于从保险产品文档(PDF、DOCX)中智能提取配置字段,并自动生成计划书模板配置。
核心能力
| 能力 | 描述 | 状态 |
|---|---|---|
| 多格式解析 | 支持 PDF、DOCX、TXT、MD | ✅ 已实现 |
| 多产品识别 | 自动识别包含多个产品的文档并分割 | ✅ 已实现 |
| 智能字段提取 | 使用正则和启发式规则提取8个核心字段 | ✅ 已实现 |
| 人工审核流程 | 生成人类可读的审核文件 | ✅ 已实现 |
| AI 增强解析 | 支持接入 AI 服务进行智能解析 | 🚧 已配置,未启用 |
| 配置自动应用 | 支持自动将审核通过的配置应用到代码 | ✅ 已实现 |
文件结构
scripts/doc-parser/
├── parse-docs.js # 主脚本 (1876 行) - 文档解析和配置生成
├── smart-field-extractor.js # 智能字段提取器 (905 行) - 从文档中提取表单字段
├── product-splitter.js # 产品分割器 (290 行) - 识别和分割多产品文档
├── parse-config.js # 配置文件 (197 行) - markitdown 和 AI 服务配置
├── parse-docs.test.js # 测试文件
├── .env.example # 环境变量示例
├── README.md # 使用说明
└── QUICKSTART.md # 快速开始指南
核心架构
架构图
┌─────────────────────────────────────────────────────────────────┐
│ 文档解析系统 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ 文档输入 │───▶│ 文档转换层 │───▶│ 内容解析层 │ │
│ │ docs/to- │ │ │ │ │ │
│ │ parse/ │ │ • markitdown │ │ • 产品分割器 │ │
│ │ │ │ • mammoth │ │ • 字段提取器 │ │
│ └─────────────┘ │ • pdf-parse │ │ • 类型推断 │ │
│ └──────────────┘ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ 配置生成层 │ │
│ │ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ 字段校验 │ │ 代码生成 │ │ │
│ │ └────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ 审核输出层 │ │
│ │ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ 待审核文件 │ │ 配置文件更新 │ │ │
│ │ │ (pending/) │ │ (plan-templates)│ │ │
│ │ └────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
三层架构
| 层级 | 职责 | 核心模块 | 输入 | 输出 |
|---|---|---|---|---|
| 转换层 | 将文档转换为可解析的文本 | markitdown, mammoth, pdf-parse | PDF/DOCX | 纯文本 |
| 解析层 | 从文本中提取结构化数据 | product-splitter, smart-field-extractor | 纯文本 | 字段配置对象 |
| 输出层 | 生成审核文件和配置代码 | parse-docs | 字段配置对象 | Markdown + JavaScript |
数据流程
完整流程
1. 文档扫描
└─> 扫描 docs/to-parse/ 目录
└─> 过滤支持的格式 (.pdf, .docx, .doc, .txt, .md)
2. 文档转换
└─> PDF: markitdown CLI 或 pdf-parse
└─> DOCX: mammoth 库
└─> TXT/MD: 直接读取
3. 多产品检测
└─> 使用正则表达式识别产品标题
└─> 如果检测到多个产品,按位置分割内容
4. 字段提取
└─> 对每个产品内容应用字段提取规则
└─> 使用 8 种匹配模式(正则、内容匹配、计数等)
└─> 应用后处理函数标准化结果
5. 配置校验
└─> 使用 AJV 校验必需字段
└─> 生成校验报告
6. 审核文件生成
└─> 生成人类可读的 Markdown 文件
└─> 包含配置预览、匹配报告、检查清单
7. 配置应用
└─> 从审核文件提取配置代码
└─> 备份现有配置
└─> 插入新配置到 plan-templates.js
8. 文档归档
└─> 将已处理文档移动到 archived/YYYY-MM-DD/
字段提取规则
| 字段 | 优先级 | 匹配模式 | 默认值 | 必填 |
|---|---|---|---|---|
| product_name | 1 | 标题正则、Markdown标题 | null | ✅ |
| product_type | 2 | 内容关键词、标题匹配 | savings | ✅ |
| currency | 3 | 货币符号统计 | USD | ✅ |
| payment_periods | 4 | 智能列表提取 | ['整付', '3年', '5年'] | ✅ |
| age_range | 5 | 范围提取正则 | {min: 0, max: 75} | ✅ |
| insurance_period | 6 | 直接匹配 | '终身' | ✅ |
| withdrawal_modes | 7 | 列表提取 | ['年龄指定金额', '最高固定金额'] | ❌ |
| withdrawal_periods | 8 | 列表提取 | ['1年', '3年', '5年', '10年'] | ❌ |
模块详解
1. parse-docs.js - 主脚本
职责: 编排整个解析流程
核心函数:
| 函数 | 行数 | 职责 |
|---|---|---|
parseSingleFile() |
708-806 | 解析单个文档(支持多产品) |
parseDocumentWithAI() |
506-641 | AI 解析入口(调用分割器和字段提取器) |
generateConfigCode() |
259-310 | 生成配置代码片段 |
generateAuditFile() |
819-1038 | 生成审核 Markdown 文件 |
applyAuditFile() |
1430-1602 | 应用审核通过的配置 |
updateConfigContent() |
1044-1069 | 更新配置文件内容 |
关键设计:
- 支持单产品和多产品文档的统一处理
- 多产品文档返回结果数组,单产品返回单个结果
- 自动归档已处理文档到
docs/to-parse/archived/YYYY-MM-DD/
2. smart-field-extractor.js - 智能字段提取器
职责: 从文档内容中提取结构化字段
8 种匹配模式:
| 模式 | 用途 | 示例 |
|---|---|---|
content_match |
关键词内容匹配 | 储蓄 → savings |
title_match |
标题行匹配 | 壽險計劃 → life-insurance |
count_match |
统计符号出现次数 | $ 出现最多 → USD |
list_extract |
列表项提取 | • 3年, • 5年 |
smart_list_extract |
智能列表提取(支持不规则格式) | 缴费年期列表 |
range_extract |
范围值提取 | 0-75岁 |
options_extract |
选项段落提取 | 基本人壽保障選項 |
| 正则表达式 | 直接匹配 | 产品名称: xxx |
缴费年期智能识别:
// 支持的格式
- "3年", "5年", "10年" // X年格式
- "至55岁", "至60岁" // 至X岁格式
- "整付", "趸交", "躉繳" // 一次性缴费
- "- 3年", "• 5年" // 列表项格式
3. product-splitter.js - 产品分割器
职责: 识别并分割包含多个产品的文档
产品标题识别策略:
// 策略 1: 优先匹配产品代码前缀
GS宏摯傳承保障計劃 → code: GS, name: 宏摯傳承保障計劃
LV3 长宁終身壽險計劃3 → code: LV3, name: 长宁終身壽險計劃3
// 策略 2: 通用模式匹配
計劃、保障、保险、壽險、壽险
// 策略 3: 纯计划书名称
宏摯傳承保障計劃
产品代码前缀:
GS, GC, FA, LV2, LV3, LV, CR, HR, PR, SR,
TR, UR, WR, XR, YR, ZR
4. parse-config.js - 配置管理
职责: 管理 markitdown 和 AI 服务配置
支持的服务类型:
| markitdown | 说明 | 优先级 |
|---|---|---|
cli |
命令行工具(本地 Python) | 高 |
docker |
Docker 容器 | 中 |
http |
HTTP API 服务 | 低 |
disabled |
禁用,使用本地库 | 回退 |
| AI 服务 | 说明 | 状态 |
|---|---|---|
openai |
OpenAI GPT-4 | 🚧 未启用 |
anthropic |
Anthropic Claude | 🚧 未启用 |
openrouter |
OpenRouter 聚合 | 🚧 未启用 |
disabled |
禁用 AI 解析 | ✅ 当前状态 |
优缺点分析
✅ 优点
| 类别 | 优点 | 影响 |
|---|---|---|
| 架构设计 | 模块化清晰,职责分离 | 易于维护和扩展 |
| 多产品支持 | 自动识别和分割多产品文档 | 减少人工处理成本 |
| 智能提取 | 8 种匹配模式,覆盖多种格式 | 提取准确率高 |
| 容错机制 | 多级回退(markitdown → 本地库) | 解析稳定性高 |
| 审核流程 | 生成人类可读的审核文件 | 降低错误风险 |
| 备份保护 | 自动备份配置文件 | 可回滚 |
| 标准化 | 生成符合规范的配置代码 | 直接可用 |
⚠️ 缺点与限制
| 类别 | 缺点 | 影响 | 优先级 |
|---|---|---|---|
| AI 服务 | AI 解析未启用,仅用规则 | 复杂文档处理能力有限 | P0 |
| 格式支持 | .doc 格式不支持 | 需要手动转换 | P1 |
| 扫描件 | 无 OCR 能力 | 扫描件无法处理 | P2 |
| 规则维护 | 正则规则需要持续维护 | 新产品格式需要更新 | P1 |
| 错误处理 | 部分错误提示不够友好 | 调试困难 | P2 |
| 性能 | 大文件处理可能较慢 | 用户体验 | P3 |
| 测试覆盖 | 缺少自动化测试 | 回归风险 | P1 |
优化建议
🔴 P0 - 高优先级
1. 启用 AI 服务增强解析
现状: AI_SERVICE_TYPE 默认为 disabled
建议:
# 1. 安装依赖
pnpm add openai anthropic
# 2. 配置 .env
AI_SERVICE_TYPE=openai
OPENAI_API_KEY=sk-xxx
OPENAI_MODEL=gpt-4-turbo
# 3. 修改 parse-docs.js 启用 AI 调用
效果: 复杂文档解析准确率提升 30%+
2. 添加字段提取失败的人工辅助
现状: 提取失败只能使用默认值
建议:
// 在审核文件中生成交互式提示
### ❌ product_name 未匹配
**请选择产品名称**:
- [ ] 从文档标题: "GS宏摯傳承保障計劃"
- [ ] 手动输入: ___________
🟡 P1 - 中优先级
3. 完善错误处理和日志
现状: 部分错误只有 console.error
建议:
// 添加结构化日志
const logger = {
error: (code, message, context) => {
fs.appendFileSync('parse-errors.logl', JSON.stringify({
timestamp: new Date().toISOString(),
code,
message,
context
}) + '\n')
}
}
4. 增加自动化测试
现状: parse-docs.test.js 存在但内容不完整
建议:
// 测试用例示例
describe('产品分割器', () => {
it('应正确识别 GS 和 GC 产品', () => {
const content = 'GS宏摯傳承保障計劃\n\nGC宏摯家傳承保險計劃'
const products = splitByProducts(content)
expect(products).toHaveLength(2)
expect(products[0].code).toBe('GS')
})
})
5. 支持 .doc 格式
现状: 返回"暂不支持 .doc"
建议: 使用 antiword 或 LibreOffice 转换
🟢 P2 - 低优先级
6. 添加 OCR 能力
建议: 集成 Tesseract.js
import Tesseract from 'tesseract.js'
async function extractTextFromScannedPDF(filePath) {
const { data: { text } } = await Tesseract.recognize(filePath, 'chi_tra+eng')
return { text, warnings: ['使用 OCR,可能存在识别错误'] }
}
7. 性能优化
建议:
- 使用 Worker 线程处理大文件
- 添加缓存机制(避免重复解析)
- 流式处理超大文档
8. 增强 CLI 体验
建议:
# 添加交互式模式
pnpm parse:docs -- --interactive
# 添加进度条
pnpm parse:docs -- --progress
# 添加详细日志
pnpm parse:docs -- --verbose
附录
目录结构
项目根目录/
├── docs/
│ ├── to-parse/ # 待解析文档输入目录
│ │ └── archived/ # 已解析文档归档(按日期)
│ ├── parse-audit/ # 审核文件目录
│ │ ├── pending/ # 待审核(按原始文档名分目录)
│ │ └── approved/ # 已通过审核
│ └── parsed-backup/ # 配置文件备份
├── src/config/
│ └── plan-templates.js # 计划书模板配置(输出目标)
└── scripts/doc-parser/ # 解析器脚本
使用命令
# 解析所有待处理文档
pnpm parse:docs
# 解析指定文件
pnpm parse:docs -- --file=产品说明书.pdf
# 查看待处理文档列表
pnpm parse:docs -- --list
# 查看配置状态
pnpm parse:docs -- --status
# 应用审核通过的配置
pnpm parse:docs -- --apply=计划书模版4
# 预览应用配置(不实际修改)
pnpm parse:docs -- --apply=计划书模版4 --dry-run
# 回滚配置
pnpm parse:docs -- --rollback=plan-templates.backup.1234567890.js
文档维护: 本文档应随系统迭代同步更新