文档处理已成为各个机构日常运营中不可或缺的一部分。从合同审核到客户身份验证,从财务报告分析到交易记录审查,文档智能技术的应用极大地提高了工作效率和准确性。然而,如何在保障数据安全的前提下,充分利用LLMs的强大能力,一直是一大难题。本文介绍一个基于 Docling、Ollama、Phi-4 与 ExtractThinker构建企业级文档智能处理的解决方案。
一、ExtractThinker框架概述
ExtractThinker是一个开源框架,旨在协调OCR(光学字符识别)、分类和数据提取等流程,为LLMs提供强大的支持。它通过将不同的组件集成到一个统一的平台中,使得用户可以轻松地构建自定义的文档智能解决方案。ExtractThinker的核心优势在于其高度的灵活性和可扩展性,用户可以根据自己的需求选择适合的组件和配置,以构建最适合自己的文档智能堆栈。
二、选择合适的模型:文本模型与视觉模型
在搭建文档智能处理栈的初始阶段,精准判定所需模型类型至关重要。对于本地部署方案而言,纯文本模型因其广泛的可用性和相对宽松的限制条件,常常成为首选。例如,在处理大量常规文本文件时,纯文本模型能够高效地进行文本分析与提取任务,无需复杂的视觉处理能力。然而,在某些特定场景下,具备视觉处理能力的模型则不可或缺。当文档的理解和处理高度依赖于视觉线索,如页面布局、色彩模式或独特格式时,视觉模型便能发挥关键作用。在处理包含图表、复杂排版的财务报告或设计图纸等文档时,视觉模型能够识别并解析其中的关键信息,为后续的分析和提取奠定基础。
在实际应用中,根据不同任务阶段灵活搭配不同模型是一种高效的策略。一些大型机构会选择部署如 Llama 3.3 或 Qwen 2.5 等强大的单一模型,以应对各种复杂的用例,凭借其高参数和强大的学习能力,实现从文档分类到信息提取的全流程处理。而对于某些特定需求,如仅需处理英语为主的智能文档处理(IDP)任务,Phi4 模型在多数情况下表现出色,同时可配备轻量级的 moondream 模型作为备用,用于处理边缘情况的分割任务,确保在不同场景下都能实现高效、准确的文档处理。
三、文档处理:Docling与MarkItDown的比较
在文档解析方面,Docling和MarkItDown是两个备受推崇的库。MarkItDown以其简单直观、广泛支持Microsoft的特点而著称,非常适合直接基于文本的任务,且不需要多个OCR引擎。而Docling则以其多OCR支持(包括Tesseract、AWS Textract、Google Document AI等)和适用于扫描工作流程或从图像PDF中进行稳健提取的能力而脱颖而出。Docling还提供了详细的文档和灵活的复杂布局处理能力。ExtractThinker允许用户根据自己的需求,在DocumentLoaderMarkItDown和DocumentLoaderDocling之间进行选择,以满足简单数字PDF或多引擎OCR的需求。
四、本地模型运行:Ollama与其他解决方案
Ollama作为本地托管 LLMs 的热门工具,以其便捷的设置和简单的命令行界面(CLI)深受用户喜爱。通过 Ollama,用户能够轻松地在本地部署语言模型,如 Phi-4 或 Llama 3.x 等,并快速搭建起本地的文档智能处理环境。然而,在企业级或高性能计算(HPC)场景下,其他解决方案也各有优势。
LocalAI 是一个开源平台,它能够在本地模拟 OpenAI 的 API,这使得其在与现有基于 OpenAI 接口的应用程序集成时具有天然的优势。尤为突出的是,它可以在消费级硬件上运行 LLMs,甚至在仅配备 CPU 的设备上也能实现一定程度的模型运行,如运行 Llama 2 或 Mistral 模型,为资源有限的企业或个人提供了一种低成本的本地模型运行方案,并通过提供简单的端点连接方式,方便用户进行模型调用和管理。
OpenLLM 由 BentoML 开发,通过 OpenAI 兼容的 API 暴露 LLMs,在吞吐量和低延迟方面进行了深度优化。这种优化使其在本地部署和云端环境中都能表现出色,能够满足企业对高效文档处理的需求。同时,它支持广泛的开源 LLMs,为用户提供了丰富的模型选择空间,用户可根据具体任务和性能需求,灵活选用不同的模型进行文档智能处理。
Llama.cpp 则采用了一种较低级别的方法来运行 Llama 模型,它允许用户进行高级的自定义配置,适用于对模型运行有精细控制需求的场景,如在 HPC 设置中,用户可以根据硬件资源和任务特点,对模型的运行参数进行深度调整,以实现最佳的性能表现。尽管其管理复杂度相对较高,但在特定的高性能计算和专业领域应用中,能够发挥出独特的优势。
在实际应用中,企业可根据自身的场景需求和技术能力,选择最合适的本地模型运行方案,并通过简单的配置,将其与 ExtractThinker 进行无缝集成。只需在代码中将本地 LLM 端点指向相应的环境变量或基础 URL,即可实现 ExtractThinker 与不同本地模型运行工具的协同工作,构建起强大的本地文档智能处理系统。
五、处理小上下文窗口的策略
在使用具有有限上下文窗口(如约 8K 令牌或更少)的本地模型时,有效的管理策略至关重要。其中,文档分割是避免超出模型输入容量的关键环节。Lazy Splitting 策略通过增量式比较页面的方式,实现了高效且内存友好的文档分割。与一次性摄入整个文档不同,它逐页或逐段地比较相邻页面,判断它们是否属于同一子文档。如果属于同一子文档,则将其合并为下一步处理的单元;如果不属于,则开启新的片段。这种方式在处理大型 PDF 文档时优势显著,每次仅需加载和分析少量页面,极大地降低了内存压力,确保模型能够稳定运行,即使面对数百页甚至上千页的大型文档,也能有条不紊地进行处理。
在处理部分响应时,由于本地小型模型在面对较大提示时可能会截断响应,PaginationHandler 提供了一种有效的解决方案。它将文档页面分割为单独的请求,每次仅向模型发送一页内容,避免了因输入过长导致的响应截断问题。在获取各个页面的结果后,PaginationHandler 会对页级结果进行合并,并在必要时处理不同页面之间在某些字段上的冲突,确保最终提取的信息完整、准确。例如,在处理包含多页表格数据的文档时,可能会出现不同页面上相同字段的格式或内容略有差异的情况,PaginationHandler 能够通过智能的冲突解决机制,生成一致且准确的最终结果。
一个典型的工作流程示例如下:首先,使用 Lazy Split 技术将 PDF 文档分割为多个小块或页面,确保每个块都在模型的容量限制之内;然后,通过分页方式(Paginate)向模型发送请求,获取每个块的单独结果;最后,将这些部分页面结果合并为最终的结构化数据。这种简洁而高效的方法从输入和输出两个维度确保了不会超出本地模型的上下文窗口,保障了文档智能处理的准确性和稳定性。
六、ExtractThinker:构建文档智能处理的核心框架实践示例
安装ExtractThinker
pip install extract-thinker
加载文档
from extract_thinker import DocumentLoaderMarkItDown, DocumentLoaderDocling`` ``# DocumentLoaderDocling or DocumentLoaderMarkItDown``document_loader = DocumentLoaderDocling()
实体定义
from extract_thinker.models.contract import Contract``from pydantic import Field`` ``class InvoiceContract(Contract):` `invoice_number: str = Field(description="Unique invoice identifier")` `invoice_date: str = Field(description="Date of the invoice")` `total_amount: float = Field(description="Overall total amount")`` ``class DriverLicense(Contract):` `name: str = Field(description="Full name on the license")` `age: int = Field(description="Age of the license holder")` `license_number: str = Field(description="License number")
分类:
`from extract_thinker import Classification`` ``TEST_CLASSIFICATIONS = [` `Classification(` `name="Invoice",` `description="This is an invoice document",` `contract=InvoiceContract` `),` `Classification(` `name="Driver License",` `description="This is a driver license document",` `contract=DriverLicense` `)``]`` `
提取
import os``from dotenv import load_dotenv`` ``from extract_thinker import (` `Extractor,` `Process,` `Classification,` `SplittingStrategy,` `ImageSplitter,` `TextSplitter``)`` ``# Load environment variables (if you store LLM endpoints/API_BASE, etc. in .env)``load_dotenv()`` ``# Example path to a multi-page document``MULTI_PAGE_DOC_PATH = "path/to/your/multi_page_doc.pdf"`` ``def setup_local_process():` `"""` `Helper function to set up an ExtractThinker process` `using local LLM endpoints (e.g., Ollama, LocalAI, OnPrem.LLM, etc.)` `"""`` ` `# 1) Create an Extractor` `extractor = Extractor()`` ` `# 2) Attach our chosen DocumentLoader (Docling or MarkItDown)` `extractor.load_document_loader(document_loader)`` ` `# 3) Configure your local LLM` `# For Ollama, you might do:` `os.environ["API_BASE"] = "http://localhost:11434" # Replace with your local endpoint` `extractor.load_llm("ollama/phi4") # or "ollama/llama3.3" or your local model`` ` `# 4) Attach extractor to each classification` `TEST_CLASSIFICATIONS[0].extractor = extractor` `TEST_CLASSIFICATIONS[1].extractor = extractor`` ` `# 5) Build the Process` `process = Process()` `process.load_document_loader(document_loader)` `return process`` ``def run_local_idp_workflow():` `"""` `Demonstrates loading, classifying, splitting, and extracting` `a multi-page document with a local LLM.` `"""` `# Initialize the process` `process = setup_local_process()`` ` `# (Optional) You can use ImageSplitter(model="ollama/moondream:v2") for the split` `process.load_splitter(TextSplitter(model="ollama/phi4"))`` ` `# 1) Load the file` `# 2) Split into sub-documents with EAGER strategy` `# 3) Classify each sub-document with our TEST_CLASSIFICATIONS` `# 4) Extract fields based on the matched contract (Invoice or DriverLicense)` `result = (` `process` `.load_file(MULTI_PAGE_DOC_PATH)` `.split(TEST_CLASSIFICATIONS, strategy=SplittingStrategy.LAZY)` `.extract(completion_strategy=CompletionStrategy.PAGINATE)` `)`` ` `# 'result' is a list of extracted objects (InvoiceContract or DriverLicense)` `for item in result:` `# Print or store each extracted data model` `if isinstance(item, InvoiceContract):` `print("[Extracted Invoice]")` `print(f"Number: {item.invoice_number}")` `print(f"Date: {item.invoice_date}")` `print(f"Total: {item.total_amount}")` `elif isinstance(item, DriverLicense):` `print("[Extracted Driver License]")` `print(f"Name: {item.name}, Age: {item.age}")` `print(f"License #: {item.license_number}")`` ``# For a quick test, just call run_local_idp_workflow()``if __name__ == "__main__":` `run_local_idp_workflow()
通过将 ExtractThinker 与本地 LLM(如 Ollama、LocalAI、OnPrem.LLM)以及灵活的文档加载器(Docling 或 MarkItDown)相结合,企业能够构建一个安全、高效的本地文档智能处理工作流。在监管要求严格、强调数据隐私和最小化外部调用的场景下,这一技术栈为企业提供了强大的文档处理能力,同时确保数据在内部安全存储和处理,有效解决了银行及金融机构等在利用 LLMs 技术时面临的隐私和合规性难题。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。