使用 Instructor 与 GPT-4 Vision 从图片中提取表格:MarkdownDataFrame 结构化输出的完整实战指南

发布时间:2026/9/15 18:28:25

使用 Instructor 与 GPT-4 Vision 从图片中提取表格:MarkdownDataFrame 结构化输出的完整实战指南 使用 Instructor 与 GPT-4 Vision 从图片中提取表格MarkdownDataFrame 结构化输出的完整实战指南【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor本文基于 docs/examples/tables_from_vision.md结合 examples/vision/run_table.py 与 instructor/v2/core/multimodal.py 源码完整讲解如何借助 Instructor 的响应模型response model机制让视觉语言模型从图片中直接提取出结构化的 Markdown 表格并转换为可分析的 pandas DataFrame。读完本文你将掌握自定义 Pydantic 类型AnnotatedBeforeValidatorPlainSerializer的编排技巧、多模态消息的构造方式以及 Instructor 中 TOOLS 与 MD_JSON 两种模式的适用场景。为什么需要从图片中提取表格报表、截图、图表和数据看板中的表格信息往往以像素形式存在无法直接被程序读取。传统方案依赖 OCR 后的人工清洗不仅耗时而且面对复杂表格时准确率不稳定。借助 GPT-4 系列视觉模型如gpt-4o我们可以直接向模型发送图片 URL并要求它返回结构化的 Markdown 表格再由 Instructor 在客户端完成校验与反序列化最终得到可以直接用于数据分析的 pandas DataFrame。这一思路的核心难点在于模型输出的是 Markdown 字符串而我们需要的是 DataFrame 对象。Instructor 的响应模型机制允许我们定义自定义类型在模型输出字符串与最终 Python 对象之间架起一座转换桥梁——这正是本文要深入讲解的MarkdownDataFrame类型。环境准备运行本示例前需要安装 Instructor 及其依赖pip install instructor pandas tabulatepandas用于承载解析后的表格数据tabulate提供DataFrame.to_markdown()所需的 Markdown 渲染能力。完整可运行的示例代码位于 examples/vision/run_table.py同一主题的进阶版本见 docs/examples/extracting_tables.md。定义 MarkdownDataFrame 自定义类型图片中的表格经视觉模型识别后会以 Markdown 表格字符串的形式返回。为了把这个字符串直接变成 pandas DataFrame我们定义如下自定义类型from io import StringIO from typing import Annotated, Any, List from pydantic import ( BaseModel, BeforeValidator, PlainSerializer, InstanceOf, WithJsonSchema, ) import instructor import pandas as pd from rich.console import Console console Console() client instructor.from_provider(openai/gpt-4o, modeinstructor.Mode.TOOLS) def md_to_df(data: Any) - Any: if isinstance(data, str): return ( pd.read_csv( StringIO(data), # Get rid of whitespaces sep|, index_col1, ) .dropna(axis1, howall) .iloc[1:] .map(lambda x: x.strip()) ) # type: ignore return data MarkdownDataFrame Annotated[ InstanceOf[pd.DataFrame], BeforeValidator(md_to_df), PlainSerializer(lambda x: x.to_markdown()), WithJsonSchema( { type: string, description: The markdown representation of the table, each one should be tidy, do not try to join tables that should be separate, } ), ]这个类型通过四个 Pydantic 注解组件协同工作每一个都有明确的职责组件作用InstanceOf[pd.DataFrame]声明该字段最终必须是 pandas DataFrame 实例作为校验的最终目标类型BeforeValidator(md_to_df)在校验之前执行转换函数把模型输出的 Markdown 字符串解析成 DataFramePlainSerializer(lambda x: x.to_markdown())反向序列化当把对象编码回 JSON / API 请求时将 DataFrame 重新渲染为 Markdown 字符串WithJsonSchema({...})为模型生成 JSON Schema 提示告诉模型这是一个 Markdown 表格字符串每个表格应保持整洁不要强行合并本应分开的表格从源码看这种校验前转换 序列化的编排正是 Instructor 响应模型处理的核心机制之一Instructor 接收模型返回的原始文本后会依据 Pydantic 模型的定义执行字段级校验与类型转换相关逻辑可见 instructor/processing/response.py 与 instructor/processing/schema.py。BeforeValidator让字符串到 DataFrame 的转换发生在任何严格校验之前因此模型即使输出格式稍有偏差也能被宽容地清洗。md_to_df 解析管线拆解md_to_df是整条管线的关键它对一段典型的 Markdown 表格文本执行如下操作StringIO(data)把字符串包装成文件对象供pd.read_csv读取sep|按竖线分隔符切分 Markdown 表格的列Markdown 表格即管道表index_col1把第二列作为索引——因为首列通常是空的分隔占位列.dropna(axis1, howall)丢弃整列为空的分隔线列如---所在列.iloc[1:]跳过表头下方的分隔行| --- | --- |.map(lambda x: x.strip())去除每个单元格两侧的空白字符。最终得到一份干净、索引正确的 DataFrame。非字符串输入如已经是 DataFrame则原样返回保证类型转换的幂等性。定义 Table 与 MultipleTables 响应模型由于大部分复杂度已被MarkdownDataFrame类型吸收业务模型本身非常简洁class Table(BaseModel): caption: str dataframe: MarkdownDataFrame class MultipleTables(BaseModel): tables: List[Table]Table包含一个标题caption和一个 Markdown 表格数据框dataframeMultipleTables用于承接一张图片中可能包含的多张表格每张表格独立成一条记录避免模型把本应分开的表格强行拼接。这一点与WithJsonSchema中的描述each one should be tidy, do not try to join tables that should be separate相互呼应从提示层面约束模型保持表格边界清晰。我们可以先构造一个本地示例来验证类型的双向转换是否正常example MultipleTables( tables[ Table( captionThis is a caption, dataframepd.DataFrame( { Chart A: [10, 40], Chart B: [20, 50], Chart C: [30, 60], } ), ) ] )由于PlainSerializer的存在这个对象在需要发送给 API 时会把 DataFrame 自动序列化为 Markdown 字符串。构造多模态提取函数接下来定义extract函数把图片 URL 与指令文本一起通过多模态消息发送给视觉模型def extract(url: str) - MultipleTables: return client.create( modelgpt-5.4-mini, max_tokens4000, response_modelMultipleTables, messages[ { role: user, content: [ { type: image_url, image_url: {url: url}, }, { type: text, text: First, analyze the image to determine the most appropriate headers for the tables. Generate a descriptive h1 for the overall image, followed by a brief summary of the data it contains. For each identified table, create an informative h2 title and a concise description of its contents. Finally, output the markdown representation of each table. Make sure to escape the markdown table properly, and make sure to include the caption and the dataframe. including escaping all the newlines and quotes. Only return a markdown table in dataframe, nothing else. , }, ], } ], )关键点说明消息内容为列表content按顺序包含image_url与text两种类型的消息块这是 OpenAI 视觉接口的标准多模态格式提示词引导结构指令明确要求模型先确定表头、生成整体h1摘要再为每张表生成h2标题与说明最后输出 Markdown 表格且只输出表格的 markdown 表示不附带其他内容并提醒转义换行与引号max_tokens4000表格通常较长预留充足 token 防止输出被截断response_modelMultipleTablesInstructor 据此构建工具/模式并将模型原始输出校验并转换为MultipleTables对象。需要注意的是主文档示例使用instructor.from_provider(openai/gpt-4o, modeinstructor.Mode.TOOLS)初始化客户端而 examples/vision/run_table.py 中针对视觉模型使用instructor.from_openai(OpenAI(), modeinstructor.Mode.MD_JSON)MD_JSON 模式。可以推断当视觉模型不支持原生工具调用function calling时MD_JSON 模式是更稳妥的选择——它通过强约束 JSON 格式解析 Markdown 包裹的 JSON 输出来实现结构化而 TOOLS 模式则依赖模型的工具调用能力。实际使用时请根据所选模型的 API 能力在 docs/concepts/mode-migration.md 与 docs/modes-comparison.md 中确认对应模式的支持情况。批量运行与结果展示对多张图片批量调用extract并借助rich的Console美化输出urls [ https://a.storyblok.com/f/47007/2400x1260/f816b031cb/uk-ireland-in-three-charts_chart_a.png/m/2880x0, https://a.storyblok.com/f/47007/2400x2000/bf383abc3c/231031_uk-ireland-in-three-charts_table_v01_b.png/m/2880x0, ] for url in urls: for table in extract(url).tables: console.print(table.caption, \n, table.dataframe)MultipleTables.tables是List[Table]因此可以直接嵌套遍历逐张打印每张表的标题与 DataFrame。examples/vision/run_table.py 中展示了同一思路的完整运行结果示例数据来自公开图片示例非仓库生成数据模型从一张包含 iOS / Android 双平台榜单的截图中识别出两张独立表格并输出如下形式的 DataFrameRankApp NameCategory1Google OneProductivity2DisneyEntertainment3TikTok - Videos, Music LIVEEntertainment.........注意在 examples/vision/run_table.py 中还使用了client.chat.completions.create_iterable(response_modelTable)的迭代形式每次产出单个Table对象——与主文档的MultipleTables批量形式形成两种等价的组织方式读者可按需选择。深入Instructor 的多模态辅助能力主文档直接使用了 OpenAI 原生image_url消息块。若希望代码更简洁、跨提供商OpenAI / Anthropic / Gemini 等可移植Instructor 还提供了统一的多模态对象详见 docs/concepts/multimodal.mdimport instructor from instructor.processing.multimodal import Image from pydantic import BaseModel class ImageDescription(BaseModel): description: str items: list[str] client instructor.from_provider(openai/gpt-4.1-mini) response client.create( response_modelImageDescription, messages[ { role: user, content: [ What is in this image?, Image.from_url(url), ], } ], )Image类支持from_url()、from_gs_url()、from_path()、from_base64()与autodetect()五种构造方式底层会自动把图片转换为 base64 并拼装为提供商要求的消息格式。查看 instructor/v2/core/multimodal.py 的Image实现可以看到from_url()通过 URL 后缀推断 MIME 类型失败时回退到远程探测from_path()读取本地文件并编码为 base64autodetect()依次判断 base64 前缀、http(s)://、gs://、本地路径最终回退到原始 base64 解析实现给什么都能认的智能检测。如果希望把 URL / 路径直接作为普通字符串传入消息无需手动包装可以在create时开启autodetect_imagesTrueInstructor 会自动识别并转换图片、音频与 PDF 等媒体类型对应源码中的autodetect_media函数。这样本文的多模态消息甚至可以简化为client.create( response_modelMultipleTables, autodetect_imagesTrue, messages[ { role: user, content: [ Extract the tables from this image as markdown:, url, ], } ], )这对于从图片列表批量提取表格如报告截图、票据、排行榜的场景尤为实用。完整代码清单将上述片段合并即可得到一个自洽可运行的完整示例与 examples/vision/run_table.py 同源并扩展为多表格版本from io import StringIO from typing import Annotated, Any, List from pydantic import ( BaseModel, BeforeValidator, PlainSerializer, InstanceOf, WithJsonSchema, ) import instructor import pandas as pd from rich.console import Console console Console() client instructor.from_provider(openai/gpt-4o, modeinstructor.Mode.TOOLS) def md_to_df(data: Any) - Any: if isinstance(data, str): return ( pd.read_csv( StringIO(data), # Get rid of whitespaces sep|, index_col1, ) .dropna(axis1, howall) .iloc[1:] .map(lambda x: x.strip()) ) # type: ignore return data MarkdownDataFrame Annotated[ InstanceOf[pd.DataFrame], BeforeValidator(md_to_df), PlainSerializer(lambda x: x.to_markdown()), WithJsonSchema( { type: string, description: The markdown representation of the table, each one should be tidy, do not try to join tables that should be separate, } ), ] class Table(BaseModel): caption: str dataframe: MarkdownDataFrame class MultipleTables(BaseModel): tables: List[Table] def extract(url: str) - MultipleTables: return client.create( modelgpt-5.4-mini, max_tokens4000, response_modelMultipleTables, messages[ { role: user, content: [ {type: image_url, image_url: {url: url}}, { type: text, text: First, analyze the image to determine the most appropriate headers for the tables. Generate a descriptive h1 for the overall image, followed by a brief summary of the data it contains. For each identified table, create an informative h2 title and a concise description of its contents. Finally, output the markdown representation of each table. Make sure to escape the markdown table properly, and make sure to include the caption and the dataframe. including escaping all the newlines and quotes. Only return a markdown table in dataframe, nothing else. , }, ], } ], ) urls [ https://a.storyblok.com/f/47007/2400x1260/f816b031cb/uk-ireland-in-three-charts_chart_a.png/m/2880x0, https://a.storyblok.com/f/47007/2400x2000/bf383abc3c/231031_uk-ireland-in-three-charts_table_v01_b.png/m/2880x0, ] for url in urls: for table in extract(url).tables: console.print(table.caption, \n, table.dataframe)常见问题与调优建议输出被截断导致解析失败表格行数多或 token 不足时模型输出可能不完整。可将max_tokens调大如 4000或拆分为每次只提取一张表格参考 examples/vision/run_table.py 的create_iterable方式。模型返回纯文本而非严格 JSON选择支持的工具调用模式Mode.TOOLS或改用Mode.MD_JSON后者对纯文本模型更宽容。多张表被错误合并在WithJsonSchema描述与系统提示中反复强调不要合并本应分开的表格并尽量为每张表提供独立标题。本地图片image_url的url字段支持data:image/jpeg;base64,...形式的 base64 URI参考 examples/vision/run.py 中encode_image的用法也可借助Image.from_path()统一处理。延伸阅读docs/examples/extracting_tables.md使用Iterable[Table]与 MD_JSON 模式的进阶表格提取方案docs/concepts/multimodal.mdImage/Audio/PDF多模态对象的统一接口docs/examples/multi_modal_gemini.md使用 Gemini 完成视觉任务docs/examples/index.md更多视觉处理与表格提取示例的索引docs/concepts/validation.md 与 docs/concepts/reask_validation.md响应校验与自动重试机制可作为提升提取准确率的进阶手段。【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/15 18:23:24

Automatisch 集成 Twitter:OAuth 1.0a 连接配置完全指南

Automatisch 集成 Twitter:OAuth 1.0a 连接配置完全指南 【免费下载链接】automatisch The open source Zapier alternative. Build workflow automation without spending time and money. 项目地址: https://gitcode.com/GitHub_Trending/au/automatisch 本…

2026/9/15 18:38:25

中文字体子集化:精准裁剪而非压缩的工程实践

1. 为什么中文字体子集化不是“压缩”而是“外科手术式裁剪”很多人第一次听说“中文字体子集化”,下意识就联想到 ZIP 压缩、图片 WebP 转换——这是最典型的认知偏差。我去年给一个面向海外用户的中文内容平台做性能优化时,也犯过这个错:直…

2026/9/15 18:38:25

ZZULIOJ刷题全攻略:从入门基础到算法进阶的题解整合与避坑指南

我记得第一次在新生群里看到“ZZULIOJ”这五个字母时,整个人是懵的。页面白底黑字,左侧一排深色菜单,点进去是一道道看着都认识的题,但提交后不是“编译错误”就是“答案错误”。后来我在这套OJ上从大一刷到大四,从被s…

2026/9/15 18:38:25

北京学会网站建设避坑指南:小白不踩雷实操手册

北京学会网站建设避坑指南:小白不踩雷实操手册 想在北京做个像样的网站,心里没底?自己不会代码,又怕被坑?别慌。 这三年我在北京海淀、朝阳跑遍了各大软件园,见过太多初创团队花大价钱做了个“四不像”网站,最后因为服务器卡顿、SEO做废、备案拖延…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码