微信扫码
添加专属顾问
当下文档处理的自动化需求日益增长,尤其是对于 PDF 文档的有效处理成为了关键任务(ParseStudio:使用统一语法简化PDF文档解析)。随着人工智能技术的迅猛发展,大型语言模型(LLMs)如 ChatGPT 等在自然语言处理领域取得了显著成果,而自动化文档处理也成为了这场技术革命的最大受益者之一。然而,传统的文本处理方式在面对 PDF 文档时面临诸多挑战,如非文本元素(如图像、表格等)的处理困难。今天我们聊一下如何利用 Gemini 构建针对 PDF 文档的 AI 管道,以实现高效、精准的文档处理与信息提取。
PDF(Portable Document Format)作为一种广泛使用的文档格式,其设计初衷是确保文档在不同平台和设备上的一致性和可读性。PDF文档由字符、图像、线条及其精确坐标的集合组成,没有固有的“文本”结构,而是被设计为按原样查看,而非作为文本处理。这导致了在处理PDF时(探索 Docling:高效且安全的 PDF 解析利器),仅使用文本方法会丢失大量的布局和视觉元素,从而损失重要的上下文和信息。
例如,PDF中的表格、图表和图像通常包含重要的数据和视觉线索,这些对于理解文档内容至关重要。然而,传统的文本处理工具无法有效提取和解释这些信息,导致信息的不完整和误解。
为了克服这些挑战,多模态大型语言模型应运而生。Gemini是其中之一,它能够处理包括文本、代码和图像在内的多种模态数据。这种能力为处理PDF文档提供了一种更简洁的解决方案,即使用一个模型同时完成所有任务。
与传统的基于文本的方法相比,Gemini能够理解和处理页面布局,识别表格、图像和文本块,并将它们转换为可用于下游任务的格式。这不仅提高了文档处理的准确性,还大大简化了管道的设计和实施。
pdf2image库将 PDF 文档的每一页提取为PIL图像格式,随后将图像编码为 Base64 格式,以便于添加到 LLM 请求中。这一步骤确保了文档的页面能够以适合模型处理的格式进行输入,为后续的分割和总结操作奠定基础。例如,在处理包含大量图表的财务报告 PDF 时,通过这一步骤能够准确地将每一页转换为图像格式,保留图表的完整性和清晰度(MinerU:精准解析PDF文档的开源解决方案)。from document_ai_agents.document_utils import extract_images_from_pdffrom document_ai_agents.image_utils import pil_image_to_base64_jpegfrom pathlib import Pathclass DocumentParsingAgent:@classmethoddef get_images(cls, state):"""Extract pages of a PDF as Base64-encoded JPEG images."""assert Path(state.document_path).is_file(), "File does not exist"# Extract images from PDFimages = extract_images_from_pdf(state.document_path)assert images, "No images extracted"# Convert images to Base64-encoded JPEGpages_as_base64_jpeg_images = [pil_image_to_base64_jpeg(x) for x in images]return {"pages_as_base64_jpeg_images": pages_as_base64_jpeg_images}
LayoutElements和DetectedLayoutItem等自定义类定义输出结构,明确每个布局元素的类型(如表格、图表、文本块等)及其对应的总结内容。from pydantic import BaseModel, Fieldfrom typing import Literalimport jsonimport google.generativeai as genaifrom langchain_core.documents import Documentclass DetectedLayoutItem(BaseModel):"""Schema for each detected layout element on a page."""element_type: Literal["Table", "Figure", "Image", "Text-block"] = Field(...,description="Type of detected item. Examples: Table, Figure, Image, Text-block.")summary: str = Field(..., description="A detailed description of the layout item.")class LayoutElements(BaseModel):"""Schema for the list of layout elements on a page."""layout_items: list[DetectedLayoutItem] = []class FindLayoutItemsInput(BaseModel):"""Input schema for processing a single page."""document_path: strbase64_jpeg: strpage_number: intclass DocumentParsingAgent:def __init__(self, model_name="gemini-1.5-flash-002"):"""Initialize the LLM with the appropriate schema."""layout_elements_schema = prepare_schema_for_gemini(LayoutElements)self.model_name = model_nameself.model = genai.GenerativeModel(self.model_name,generation_config={"response_mime_type": "application/json","response_schema": layout_elements_schema,},)def find_layout_items(self, state: FindLayoutItemsInput):"""Send a page image to the LLM for segmentation and summarization."""messages = [f"Find and summarize all the relevant layout elements in this PDF page in the following format: "f"{LayoutElements.schema_json()}. "f"Tables should have at least two columns and at least two rows. "f"The coordinates should overlap with each layout item.",{"mime_type": "image/jpeg", "data": state.base64_jpeg},]# Send the prompt to the LLMresult = self.model.generate_content(messages)data = json.loads(result.text)# Convert the JSON output into documentsdocuments = [Document(page_content=item["summary"],metadata={"page_number": state.page_number,"element_type": item["element_type"],"document_path": state.document_path,},)for item in data["layout_items"]]return {"documents": documents}
find_layout_items函数进行处理。这对于处理大型多页 PDF 文档尤为重要,能够显著缩短处理时间,提高整体效率。例如,在处理一本数百页的学术书籍 PDF 时,并行处理可以充分利用计算资源,快速完成页面分割和总结任务。from langgraph.types import Sendclass DocumentParsingAgent:@classmethoddef continue_to_find_layout_items(cls, state):"""Generate tasks to process each page in parallel."""return [Send("find_layout_items",FindLayoutItemsInput(base64_jpeg=base64_jpeg,page_number=i,document_path=state.document_path,),)for i, base64_jpeg in enumerate(state.pages_as_base64_jpeg_images)]
from langgraph.graph import StateGraph, START, ENDclass DocumentParsingAgent:def build_agent(self):"""Build the agent workflow using a state graph."""builder = StateGraph(DocumentLayoutParsingState)# Add nodes for image extraction and layout item detectionbuilder.add_node("get_images", self.get_images)builder.add_node("find_layout_items", self.find_layout_items)# Define the flow of the graphbuilder.add_edge(START, "get_images")builder.add_conditional_edges("get_images", self.continue_to_find_layout_items)builder.add_edge("find_layout_items", END)self.graph = builder.compile()
if __name__ == "__main__":_state = DocumentLayoutParsingState(document_path="path/to/document.pdf")agent = DocumentParsingAgent()# Step 1: Extract images from PDFresult_images = agent.get_images(_state)_state.pages_as_base64_jpeg_images = result_images["pages_as_base64_jpeg_images"]# Step 2: Process the first page (as an example)result_layout = agent.find_layout_items(FindLayoutItemsInput(base64_jpeg=_state.pages_as_base64_jpeg_images[0],page_number=0,document_path=_state.document_path,))# Display the resultsfor item in result_layout["documents"]:print(item.page_content)print(item.metadata["element_type"])
ChromaDB等向量数据库对 Agent 1 生成的文档总结进行索引。在索引过程中,不仅存储总结内容,还保留了文档路径、页面编号等重要元数据,以便后续检索和引用。例如,当用户查询特定信息时,这些元数据可以帮助快速定位相关文档页面,提供准确的上下文信息。在索引之前,会检查文档是否已被索引,避免重复操作,提高处理效率。class DocumentRAGAgent:def index_documents(self, state: DocumentRAGState):"""Index the parsed documents into the vector store."""assert state.documents, "Documents should have at least one element"# Check if the document is already indexedif self.vector_store.get(where={"document_path": state.document_path})["ids"]:logger.info("Documents for this file are already indexed, exiting this node")return # Skip indexing if already done# Add parsed documents to the vector storeself.vector_store.add_documents(state.documents)logger.info(f"Indexed {len(state.documents)} documents for {state.document_path}")
class DocumentRAGAgent:def answer_question(self, state: DocumentRAGState):"""Retrieve relevant chunks and generate a response to the user's question."""# Retrieve the top-k relevant documents based on the queryrelevant_documents: list[Document] = self.retriever.invoke(state.question)# Retrieve corresponding page images (avoid duplicates)images = list(set([state.pages_as_base64_jpeg_images[doc.metadata["page_number"]]for doc in relevant_documents]))logger.info(f"Responding to question: {state.question}")# Construct the prompt: Combine images, relevant summaries, and the questionmessages = ([{"mime_type": "image/jpeg", "data": base64_jpeg} for base64_jpeg in images]+ [doc.page_content for doc in relevant_documents]+ [f"Answer this question using the context images and text elements only: {state.question}",])# Generate the response using the LLMresponse = self.model.generate_content(messages)return {"response": response.text, "relevant_documents": relevant_documents}
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-06-28
Om AI第二弹!VLX-Seek来了:3B小模型,细粒度感知反超Gemini
2026-06-22
小参数,大能力 | 星际视觉语言大模型再进化,0.8B轻量版正式发布
2026-06-16
RapidOCR: 从 setup.py 迁移到 pyproject.toml 打包实践
2026-06-12
PaddleOCR 3.7 正式接入ONNX Runtime,一个参数换后端,轻量部署新选择
2026-06-11
本地部署OCR,可能是AI进单位的第一道门
2026-06-08
正式推出 Gemma 4 12B: 一款统一、免编码器的多模态模型
2026-05-30
还在用 MinerU 解析 PDF?这个 2B 小模型直接把 olmOCR-bench 刷到 87.6%,速度还快 3.68 倍
2026-05-30
Qwen-VLA:迈向通用具身智能的统一动作框架
2026-04-22
2026-04-27
2026-04-21
2026-04-09
2026-04-15
2026-04-26
2026-04-21
2026-05-30
2026-04-22
2026-05-25
2026-03-12
2025-12-31
2025-08-04
2025-05-26
2025-05-13
2025-04-08
2025-04-05
2025-03-30
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。