PDFDocument AISummarizationRAGNbility

PDF 总结工作流:合同、论文、说明书怎么处理

第十六篇 AI Agent 上手系列:从 PDF 解析、OCR、分段、摘要 Prompt 到风险提示,搭一个适合合同、论文和说明书的文档总结工作流。

PDF 总结工作流:合同、论文、说明书怎么处理

很多人第一次让 AI 总结 PDF,会直接把文件丢给模型,然后问:“帮我总结一下。”这对短文档还行,但遇到合同、论文、说明书,很容易出现三个问题:

  • PDF 里的文字没有被正确解析,尤其是扫描件、双栏论文、复杂表格;
  • 文档太长,模型只能看到一部分内容;
  • 摘要看起来很顺,但没有页码、条款号或原文依据,无法复查。

一个可靠的 PDF 总结工作流,不应该从“总结”开始,而应该从“解析、分段、引用、风险边界”开始。

封面:PDF 总结工作流

这篇文章会按三个典型场景来讲:合同、论文、说明书。它们都叫 PDF,但处理目标完全不同。合同要抓义务和风险,论文要抓方法和结论,说明书要抓步骤、参数和警告。

先判断 PDF 类型

PDF 不是一种“文本格式”,更像一种页面容器。你拿到一个 PDF 后,先判断它是哪类:

  1. 原生文本 PDF:可以复制文字,通常来自 Word、LaTeX、网页导出;
  2. 扫描 PDF:本质是图片,需要 OCR;
  3. 混合 PDF:部分页面有文字,部分页面是图片;
  4. 复杂版式 PDF:双栏论文、表格、脚注、公式、图片说明很多;
  5. 表单/合同 PDF:包含签章、条款号、附件、表格和空白字段。

如果第一步判断错了,后面的摘要再漂亮也不可靠。比如扫描合同没有 OCR,模型可能只看到空文本;双栏论文按错误顺序解析,摘要会把左右栏内容混在一起。

推荐工作流

PDF 总结工作流图

通用流程可以拆成五步:

上传 PDF
  -> 解析文本 / OCR / 转 Markdown
  -> 按结构分段,保留页码和标题
  -> 分块摘要或检索式问答
  -> 输出摘要、风险点、引用和下一步行动

不要把所有 PDF 都走同一个 prompt。先把文档变成更适合模型阅读的结构化文本,再根据场景选择摘要模板。

方案一:Dify 低代码工作流

如果你希望先做一个不用写太多代码的版本,可以用 Dify 的 Document Extractor 节点。

Dify 官方文档说明,Document Extractor 用来把上传文档转换成模型可处理的文本,因为语言模型不能直接读取 PDF、DOCX、Excel、PPT 等文档格式。这个节点的输出变量是:

text

它支持的常见格式包括:

  • TXT、Markdown、HTML;
  • DOCX、DOC;
  • 文本型 PDF;
  • Excel、CSV,会转换为 Markdown 表格;
  • PPT、PPTX、邮件、EPUB、JSON、YAML 等。

基础工作流:

Start 节点启用文件上传
  -> Document Extractor 提取文本
  -> LLM 节点做摘要 / 风险分析 / 重点提取
  -> Answer 节点输出结果

如果要处理 DOC、PPT、复杂格式或外部解析能力,Dify 文档提到可以配置:

UNSTRUCTURED_API_URL
UNSTRUCTURED_API_KEY

这说明一个重点:文档处理不只是模型问题,解析器也很关键。

方案二:Python 处理 PDF,再调用模型

如果你要做更可控的工作流,建议用 Python 先把 PDF 转成 Markdown 或结构化文本,再调用 OpenAI-compatible API。

用 PyMuPDF / PyMuPDF4LLM 提取 Markdown

PyMuPDF 官方文档有专门的 “PyMuPDF, LLM & RAG” 页面,建议在 LLM / RAG 场景中使用 PyMuPDF4LLM 输出 Markdown,然后再分块。

安装:

pip install pymupdf pymupdf4llm openai

把 PDF 转成 Markdown:

import pathlib
import pymupdf4llm

md_text = pymupdf4llm.to_markdown("input.pdf")
pathlib.Path("output.md").write_text(md_text, encoding="utf-8")

如果只是原生文本 PDF,PyMuPDF 也可以直接逐页提取:

import pymupdf

with pymupdf.open("input.pdf") as doc:
    pages = []
    for i, page in enumerate(doc, start=1):
        text = page.get_text()
        pages.append(f"\n\n--- page {i} ---\n{text}")

open("output.txt", "w", encoding="utf-8").write("\n".join(pages))

注意:page.get_text() 适合原生文本 PDF;扫描件仍然需要 OCR。

长文档不要一次塞给模型

长 PDF 应该先分块。一个简单做法:按页或标题分段,然后分别生成局部摘要,最后再生成总摘要。

from pathlib import Path
from openai import OpenAI

client = OpenAI(
    api_key="[REDACTED]",
    base_url="https://api.nbility.dev/v1",
)

text = Path("output.md").read_text(encoding="utf-8")
chunks = [text[i:i+6000] for i in range(0, len(text), 6000)]

partial_summaries = []
for idx, chunk in enumerate(chunks, start=1):
    resp = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "你是文档分析助手。请保留页码、标题和原文依据。"},
            {"role": "user", "content": f"这是第 {idx} 段文档,请总结要点、风险和待确认事项:\n\n{chunk}"},
        ],
        temperature=0.2,
    )
    partial_summaries.append(resp.choices[0].message.content)

final_resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "你是文档总结助手。请基于局部摘要生成最终摘要,不要加入无依据内容。"},
        {"role": "user", "content": "\n\n".join(partial_summaries)},
    ],
    temperature=0.2,
)

print(final_resp.choices[0].message.content)

这里用的是 Nbility 的 OpenAI-compatible Chat Completions API:

Base URL: https://api.nbility.dev/v1
Authorization: Bearer [REDACTED]
Endpoint: POST /v1/chat/completions

Nbility 适合放在这个环节:统一 API Key、模型、日志和消耗记录。解析 PDF 是你本地或 Dify 的工作,模型总结和多轮分析再走统一模型入口。

方案三:直接用模型文件输入

OpenAI 官方文件输入文档说明,Responses API 可以把 PDF 作为 input_file 传给模型,文件可以来自 URL、Files API 上传后的 file ID,或 Base64 数据。文档也明确提到:Chat Completions 不支持 file URL,文件 URL 方式应使用 Responses API。

这个方式适合:

  • 快速分析单个 PDF;
  • 你不想自己写解析和 OCR;
  • 文档长度、权限和成本都可控;
  • 你能接受模型平台负责文件解析。

但如果你需要企业级流程,我仍然建议保留自己的解析层,因为你需要:

  • 控制 OCR;
  • 保留页码和段落;
  • 做缓存,避免同一文件重复消耗;
  • 处理隐私和合规;
  • 输出可追溯引用。

合同怎么总结

合同总结最重要的是“不要替代法务”。AI 可以帮你快速读,但不能给最终法律意见。

建议输出结构:

## 一句话结论
这份合同主要约定了……需要重点关注付款、交付、违约和终止条款。

## 合同基本信息
- 合同主体:
- 合同金额:
- 生效日期:
- 期限:
- 交付物:

## 关键义务
- 甲方义务:
- 乙方义务:

## 风险条款
- 违约责任:引用第 X 条 / 第 Y 页
- 付款条件:引用第 X 条 / 第 Y 页
- 终止条件:引用第 X 条 / 第 Y 页

## 待人工确认
- 是否存在补充协议?
- 附件是否完整?
- 签章页是否齐全?

合同 Prompt 示例:

你是合同阅读助手,不提供法律意见。请基于文档内容输出:
1. 合同基本信息;
2. 双方核心义务;
3. 付款、交付、验收、违约、终止、保密条款摘要;
4. 可能需要法务确认的风险点;
5. 每个重要结论后标注页码、条款号或原文片段。

如果文档中没有明确依据,请写“文档中未找到明确依据”,不要猜测。

论文怎么总结

论文摘要不能只读 abstract。真正有价值的是:研究问题、方法、实验设置、结果、局限和可复现性。

建议输出:

## 论文解决什么问题

## 核心贡献
- 贡献 1:
- 贡献 2:

## 方法概述

## 实验设计
- 数据集:
- Baseline:
- 指标:

## 主要结论

## 局限性

## 我应该重点读哪几页

论文处理要特别注意:

  • 双栏排版可能导致解析顺序错乱;
  • 公式和表格可能丢失;
  • 图表结论不要只靠图片标题猜;
  • arXiv 论文可以优先找 HTML、LaTeX 源或官方页面辅助核对。

如果你要做论文库,而不是单篇论文摘要,就应该考虑 RAG:先把论文转 Markdown,按标题层级分块,建立向量索引,再按问题检索相关段落。

说明书怎么总结

说明书最重要的是“步骤不能乱,警告不能省”。尤其是硬件、药品、设备、软件部署文档,AI 摘要如果漏掉前置条件,可能带来真实风险。

建议输出:

## 适用对象

## 快速开始步骤
1.
2.
3.

## 参数表
| 参数 | 默认值 | 作用 | 风险 |

## 安全警告

## 常见故障排查
- 现象:
- 可能原因:
- 处理步骤:

Prompt 要求:

请总结说明书,但不得省略安全警告、前置条件、参数单位和顺序依赖。
如果步骤之间有先后顺序,请保持原文顺序。
如果某个参数缺少单位或范围,请标记为“需回看原文确认”。

不同 PDF 的处理策略

什么时候需要 OCR 或更强解析器

如果出现这些情况,普通文本提取可能不够:

  • 复制 PDF 文本为空;
  • 页眉页脚混入正文;
  • 双栏顺序错乱;
  • 表格变成一长串无结构文本;
  • 扫描件、拍照件、盖章页;
  • 公式、脚注、图片说明很多。

可选工具:

  • PyMuPDF / PyMuPDF4LLM:适合快速、本地、可控地把 PDF 转文本或 Markdown;
  • Unstructured:适合多格式文档解析、partition、chunking,也可配合 API;
  • Marker:开源 PDF 转 Markdown / JSON / HTML / chunks 工具,适合复杂文档和 RAG 前处理,但要注意其代码和模型许可;
  • Dify Document Extractor:适合低代码工作流里的文件上传和文本提取。

实际项目里可以从简单到复杂:

原生 PDF -> PyMuPDF4LLM
扫描 PDF -> OCR / Unstructured / Marker
低代码上传总结 -> Dify Document Extractor
企业知识库 -> 解析后入库,再用检索增强回答

成本控制

PDF 总结非常容易烧 token,因为用户会上传几十页甚至几百页文档。建议:

  1. 先解析后缓存:同一个文件不要每次重新解析和总结;
  2. 先局部后全局:长文档用 map-reduce,不要一次塞满;
  3. 按场景选模型:普通摘要用性价比模型,合同风险/复杂论文再用强模型复核;
  4. 输出引用而不是全文:减少把大段原文反复塞回模型;
  5. 限制上传大小和页数:公开入口必须做限制;
  6. 记录消耗和失败原因:用 Nbility 的日志和额度管理按项目观察成本。

常见问题

1. 为什么模型总结漏掉了重要条款?

通常不是模型“没认真读”,而是解析或分块阶段丢了内容。先检查输出的 Markdown / TXT 是否包含该条款,再检查 chunk 是否被送进模型。

2. 扫描件怎么处理?

扫描件需要 OCR。不要指望普通 get_text() 能读出图片里的文字。可以使用 OCR 工具、Unstructured、Marker 或带 OCR 能力的文档处理服务。

3. 表格总结总是不准怎么办?

先把表格转成 Markdown 表格或 CSV,再让模型总结。不要把错乱的纯文本表格直接丢给模型。

4. 合同摘要可以直接给客户吗?

不建议。合同摘要应标注“辅助阅读,不构成法律意见”,并保留页码、条款号和待法务确认项。

5. RAG 和摘要有什么区别?

摘要是把整份或部分文档压缩成短文本;RAG 是根据问题检索相关片段再回答。如果用户经常围绕同一批 PDF 反复提问,应考虑 RAG;如果只是读完一份文件,摘要就够了。

参考链接

小结

PDF 总结不是“把文件交给模型”这么简单。真正稳定的流程是:先判断 PDF 类型,再选择解析器,保留结构和页码,按场景写摘要 Prompt,最后用引用和风险提示保证结果可复查。

合同、论文、说明书都可以用 AI 提高阅读效率,但它们的摘要目标不同。合同看风险,论文看方法,说明书看步骤和警告。只要把这点设计清楚,Nbility 这样的 OpenAI-compatible 模型入口就可以自然成为文档工作流里的统一调用层。

相关文章

用 Nbility 跑通你的 Agent 工作流

获取 API Key,统一接入 OpenAI 兼容模型和开发工具。

管理 API Key