使用 Instructor 将 Markdown 表格直接提取为 Pandas DataFrame
使用 Instructor 将 Markdown 表格直接提取为 Pandas DataFrame【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor本文讲解如何在 instructor 项目中利用 Pydantic 的类型注解体系定义一个名为MarkdownDataFrame的自定义类型让 LLM 输出的 Markdown 表格在返回时被自动解析成pandas.DataFrame从而直接在数据分析、报表生成等场景中无缝衔接。读完本文你将掌握BeforeValidator、PlainSerializer、WithJsonSchema的组合用法能实现单表提取带标题的复合结构提取以及一次响应提取多张表三类实战方案。问题的切入点LLM 输出的是 Markdown你要的是 DataFrameLLM 天然擅长以 Markdown 表格的文本形式组织数据但数据分析链路里我们真正需要的是结构化的pandas.DataFrame。手工写解析逻辑既繁琐又脆弱。instructor 的做法是把字符串 → DataFrame的转换逻辑封装进类型本身让response_model一旦声明为 DataFrame模型返回的 Markdown 文本就会在验证阶段被自动转换成 DataFrame 对象。核心武器用Annotated编排一个自带转换逻辑的类型MarkdownDataFrame本质上是 Pydantic 的Annotated元数据组合体它把四种元数据叠加在InstanceOf[pd.DataFrame]上声明如下完整代码见 docs/examples/pandas_df.mdfrom io import StringIO from typing import Annotated, Any from pydantic import ( BaseModel, BeforeValidator, PlainSerializer, InstanceOf, WithJsonSchema, ) import pandas as pd import instructor def md_to_df(data: Any) - Any: # Convert markdown to DataFrame if isinstance(data, str): return ( pd.read_csv( StringIO(data), # Process data sep|, index_col1, ) .dropna(axis1, howall) .iloc[1:] .applymap(lambda x: x.strip()) ) return data MarkdownDataFrame Annotated[ # Validates final type InstanceOf[pd.DataFrame], # Converts markdown to DataFrame BeforeValidator(md_to_df), # Converts DataFrame to markdown on model_dump_json PlainSerializer(lambda df: df.to_markdown()), # Adds a description to the type 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, } ), ]各组成部分的职责分工如下组件作用InstanceOf[pd.DataFrame]声明最终通过验证后的对象类型必须是pd.DataFrame实例作为类型约束的锚点BeforeValidator(md_to_df)在标准验证之前运行转换函数把模型返回的 Markdown 字符串解析成 DataFramePlainSerializer(lambda df: df.to_markdown())反向序列化当调用model_dump_json()或把模型写入 JSON 时把 DataFrame 还原成 Markdown 字符串保证可序列化性WithJsonSchema({...})覆盖该字段在发给 LLM 的 JSON Schema 中的表示告诉模型这里要输出一段字符串Markdown 表格并给出语义提示md_to_df逐行拆解pd.read_csv(StringIO(data), sep|, index_col1)以|为分隔符解析 Markdown 表格文本并把第 1 列索引列通常为表头前的空列或首列作为行索引.dropna(axis1, howall)丢弃全空的列Markdown 表格边缘的|会产生空列.iloc[1:]跳过分隔行---|---那一行.applymap(lambda x: x.strip())去除每个单元格两端的空白字符。这套解析逻辑在同一仓库的 examples/extract-table/run_vision.py 中也有几乎完全一致的实现仅将applymap换成了等价写法.map可以对照查看。完整实战一直接提取原始 DataFrame有了MarkdownDataFrame客户端初始化与提取函数非常简洁。注意当前仓库推荐使用instructor.from_provider(provider/model-name)这种统一入口创建客户端client instructor.from_provider(openai/gpt-5-nano) def extract_df(data: str) - pd.DataFrame: return client.create( modelgpt-5.4-mini, response_modelMarkdownDataFrame, messages[ { role: system, content: You are a data extraction system, table of writing perfectly formatted markdown tables., }, { role: user, content: fExtract the data into a table: {data}, }, ], ) if __name__ __main__: df extract_df( Create a table of the last 5 presidents of the United States, including their party and the years they served. ) assert isinstance(df, pd.DataFrame) print(df) Party Years Served President Joe Biden Democrat 2021 - Present Donald Trump Republican 2017 - 2021 Barack Obama Democrat 2009 - 2017 George W. Bush Republican 2001 - 2009 Bill Clinton Democrat 1993 - 2001 assert isinstance(df, pd.DataFrame)保证了解析结果一定是 DataFrame随后的print(df)即可直接输出格式化表格。完整实战二提取标题 DataFrame复合结构很多时候我们不仅需要表格数据还需要标题等上下文信息。此时只需把MarkdownDataFrame作为 Pydantic 模型的一个字段class Table(BaseModel): title: str data: MarkdownDataFrame def extract_table(data: str) - Table: return client.create( modelgpt-5.4-mini, response_modelTable, messages[ { role: system, content: You are a data extraction system, table of writing perfectly formatted markdown tables., }, { role: user, content: fExtract the data into a table: {data}, }, ], )运行效果table extract_table( Create a table of the last 5 presidents of the United States, including their party and the years they served. ) assert isinstance(table, Table) assert isinstance(table.data, pd.DataFrame) print(table.title) # Last 5 Presidents of the United States print(table.data) Party Years Served President Joe Biden Democratic 2021-2025 Donald Trump Republican 2017-2021 Barack Obama Democratic 2009-2017 George W. Bush Republican 2001-2009 Bill Clinton Democratic 1993-2001 可以看到字段级title与data协同工作标题走普通字符串验证data字段则走md_to_df转换路径互不干扰。更复杂的MultipleTablestables: list[Table]组合方式同样出现在 examples/extract-table/run_vision.py 中可作为参考。进阶一次响应提取多张表Iterable[Table]原文档明确指出还可以请求Iterable[Table]一次获得多张表格。这依赖 instructor 的 Iterable DSL。其底层实现位于 instructor/v2/dsl/iterable.py核心机制是通过IterableModel(subtask_class)动态生成一个包装类内部包含tasks: list[Table]字段并自动命名为Iterable{Table}tasks_from_chunks/extract_cls_task_type负责从模型返回的 JSON 流中逐段切分出每个Table对象逐条yield支持普通create与流式from_streaming_response两种消费方式。典型用法示意from typing import Iterable def extract_tables(data: str) - Iterable[Table]: return client.create( modelgpt-5.4-mini, response_modelIterable[Table], messages[{role: user, content: fExtract all tables: {data}}], ) for table in extract_tables(...): print(table.title, table.data)注意Iterable[Table]要求Table是 PydanticBaseModel子类MarkdownDataFrame作为其字段会自然继承转换逻辑因此每个table.data仍然是解析好的 DataFrame。底层原理instructor 如何驱动这套转换整个流程可以概括为三步对应 instructor/v2/core/client.py 中client.create的处理链路Schema 生成instructor 依据response_model生成 JSON Schema 并注入 prompt。WithJsonSchema覆盖后LLM 看到的MarkdownDataFrame就是一个type: string且带markdown representation of the table描述的字段从而稳定输出 Markdown 表格文本响应验证拿到模型输出后Pydantic 按字段执行验证BeforeValidator(md_to_df)在类型检查前把字符串解析为 DataFrame随后InstanceOf[pd.DataFrame]做最终类型断言序列化还原当结果需要model_dump_json()例如返回给 FastAPI 或写入日志时PlainSerializer(lambda df: df.to_markdown())又把 DataFrame 序列化为 Markdown 字符串保证 JSON 可持久化。from_provider入口的模型字符串要求provider/model-name格式例如openai/gpt-5-nanoprovider 不支持时会抛出ConfigurationErrorOpenAI 系默认采用Mode.TOOLS相关逻辑见 instructor/v2/auto_client.py。对于不支持 function calling 的视觉模型可显式指定modeinstructor.Mode.MD_JSON具体参考 docs/examples/extracting_tables.md。环境依赖与使用前提需要安装pandas与tabulatedf.to_markdown()依赖 tabulate 提供 Markdown 渲染。仓库 pyproject.toml 中声明了tabulate1.0.0,0.9.0的依赖范围文档 docs/examples/tables_from_vision.md 也注明pip install pandas tabulate本模式对纯文本 LLM 与视觉模型配合图片输入均适用当数据中夹杂多张独立表格时务必在 schema 描述中要求每张表保持整洁、不要强行合并正如WithJsonSchema中do not try to join tables that should be separate的提示所强调的。小结通过MarkdownDataFrame这一个类型定义instructor 把Markdown → DataFrame的转换下沉到了 Pydantic 验证管线中使得下游代码拿到的不再是待解析的字符串而是立即可用的pandas.DataFrame。你可以在此基础上自由组合出Table复合模型、Iterable[Table]批量提取乃至视觉表格提取见 docs/examples/extracting_tables.md 与 docs/examples/tables_from_vision.md等方案让 LLM 的结构化输出与数据科学工作流无缝衔接。关于自定义类型的更多玩法可继续阅读 docs/concepts/types.md。【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

LangChain4j 集成 Judge0:为 Java LLM 应用接入 JavaScript 代码执行引擎

LangChain4j 集成 Judge0:为 Java LLM 应用接入 JavaScript 代码执行引擎

LangChain4j 集成 Judge0:为 Java LLM 应用接入 JavaScript 代码执行引擎 【免费下载链接】langchain4j LangChain4j is an idiomatic, open-source Java library for building LLM-powered applications on the JVM. It offers a unified API over popular LLM pro…

2026/10/24 7:12:05 阅读更多 →
使用 Encore 将单体(Monolith)拆分为微服务:完整实战指南

使用 Encore 将单体(Monolith)拆分为微服务:完整实战指南

使用 Encore 将单体(Monolith)拆分为微服务:完整实战指南 【免费下载链接】encore The infrastructure platform for the intelligence era 项目地址: https://gitcode.com/GitHub_Trending/encor/encore 本指南基于 Encore Go 应用模型…

2026/10/24 17:34:17 阅读更多 →
ArduPilot 固定翼脚本化特技飞行(Scripted Aerobatics)完全指南:从特技表、AUTO 任务到“开关即用”的落地实战

ArduPilot 固定翼脚本化特技飞行(Scripted Aerobatics)完全指南:从特技表、AUTO 任务到“开关即用”的落地实战

ArduPilot 固定翼脚本化特技飞行(Scripted Aerobatics)完全指南:从特技表、AUTO 任务到“开关即用”的落地实战 【免费下载链接】ardupilot ArduPlane, ArduCopter, ArduRover, ArduSub source 项目地址: https://gitcode.com/GitHub_Trend…

2026/11/9 19:58:15 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻