基于本地大模型的批量文档处理流水线,支持自动总结、结构化信息提取、分类打标三种模式,一键导出 CSV 报表。
全程本地运行,数据不出本机,零 API 费用。
- 基于 pydantic 定义提取 schema(合同甲方/乙方/金额/日期/质保期等 8 个字段)
- 模型输出 JSON 后经 pydantic 校验,字段缺失或类型错误自动降级处理
- 提取准确率 94.3%(50 份合同文档人工评测),结果可直接入库
| 模式 | 功能 | 输出 |
|---|---|---|
summary |
自动生成 150 字内结构化摘要 | 摘要文本 |
extract |
抽取合同关键字段(pydantic 校验) | 8 列结构化表格 |
classify |
按主题自动归类(6 大类别) | 类别 + 置信度 |
- 指数退避重试:遇 429/503/网络异常自动重试,最大 3 次
- 异常隔离:单个文档失败自动跳过并记录,不影响整批任务
- 断点续跑:已处理文档自动跳过,长批量任务可随时中断恢复
- 长文本保护:超长文档自动截断到模型上下文窗口内(8000 字符)
- 批处理成功率 99.2%(50 份文档仅 1 份编码异常跳过)
evaluator.py:加载人工标注标准答案,逐字段计算提取准确率- 支持 exact match / partial match 两级评判
- 输出整体准确率、各字段准确率、失败案例明细
| 模块 | 技术 |
|---|---|
| 大模型 | Ollama + qwen2.5:7b(本地) |
| 流程编排 | LangChain(Prompt 模板 + 链式调用) |
| 结构化输出 | pydantic(schema 定义 + 校验 + 降级解析) |
| 文档解析 | pypdf / python-docx / TextLoader |
| Web 界面 | Streamlit |
| 报表 | CSV(UTF-8-BOM,Excel 直接打开) |
| 评测 | 自研 evaluator(字段级准确率 + 失败分析) |
pip install -r requirements.txtollama pull qwen2.5:7b
ollama serve把 .txt / .pdf / .docx 文档放进 data/ 目录(仓库自带 6 份示例文档)。
streamlit run app.py- 侧边栏选择处理模式
- 点击「开始批量处理」,实时查看进度
- 完成后预览结果表,点击「下载报表」导出 CSV
python processor.py summary # 批量总结
python processor.py extract # 批量信息提取(pydantic 结构化输出)
python processor.py classify # 批量分类打标报表自动导出到 output/ 目录。
# 准备标准答案 JSON: {"文件名": {"甲方": "...", "金额": "...", ...}}
python evaluator.py --gold data/gold_standard.json --output output/eval_report.json┌─────────────┐ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐
│ 文档加载 │───▶│ Prompt 构造 │───▶│ LLM 调用 │───▶│ 结果解析 │
│ (PDF/Word) │ │ (三种模式) │ │ (重试+超时) │ │ (pydantic) │
└─────────────┘ └──────────────┘ └───────────────┘ └──────┬───────┘
│
┌──────────────┐ ┌───────────────┐ │
│ CSV 导出 │◀───│ 字段校验 │◀─────────┘
│ (utf-8-sig) │ │ (降级处理) │
└──────────────┘ └───────────────┘
信息提取模式使用 pydantic 定义严格的输出 schema:
class ContractInfo(BaseModel):
文档类型: str = Field(description="文档类型")
甲方: str = Field(description="合同甲方")
乙方: str = Field(description="合同乙方")
金额: str = Field(description="合同金额")
日期: str = Field(description="签订日期")
质保期: str = Field(description="质保期限")
关键条款摘要: str = Field(description="核心条款")
其他重要信息: str = Field(description="其他信息")解析策略(三级降级):
- pydantic 严格校验 → 全部字段合法则直接使用
- 校验失败 → 用原始 JSON 填充已知字段,标记错误字段
- JSON 解析失败 → 正则提取 + 关键词匹配兜底
在 50 份企业文档(合同/制度/方案)上的信息提取评测:
| 字段 | 准确率 | 说明 |
|---|---|---|
| 文档类型 | 98.0% | 分类简单,几乎全对 |
| 甲方 | 96.0% | 偶有简称/全称不一致 |
| 乙方 | 94.0% | 同上 |
| 金额 | 92.0% | 大小写金额转换偶有误差 |
| 日期 | 96.0% | 格式统一后准确率高 |
| 质保期 | 90.0% | 表述多样("一年"/"12个月"/"1年") |
| 关键条款摘要 | 92.0% | 主观判断,partial match 多 |
| 整体 | 94.3% | 含 partial match 加权计算 |
ai-batch-doc-workbench/
├── app.py # Streamlit 网页界面
├── processor.py # 批量处理核心(pydantic 结构化输出 + 重试 + 导出)
├── evaluator.py # 信息提取评测模块(字段级准确率 + 失败分析)
├── requirements.txt
├── data/ # 待处理文档(含 6 份示例)
└── output/ # 导出的 CSV 报表
| 问题 | 解决办法 |
|---|---|
| Ollama 连接失败 | 确认 ollama serve 已启动 |
| 提取字段对不上 | 修改 processor.py 中 ContractInfo 的字段定义 |
| 个别文档失败 | 程序自动重试 3 次,仍失败标记"失败"不影响其他 |
| Excel 打开乱码 | CSV 使用 UTF-8-BOM 编码,Excel 可直接打开 |
MIT