Instructor 结构化输出核心:用 Pydantic Response Model 定义 LLM 输出模式

发布时间:2026/11/1 22:45:30

Instructor 结构化输出核心:用 Pydantic Response Model 定义 LLM 输出模式 Instructor 结构化输出核心用 Pydantic Response Model 定义 LLM 输出模式【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor本文以 Instructor 的 Models 概念文档 为核心骨架结合仓库源码instructor/v2/core/schema.py、instructor/v2/providers/openai/schema.py、instructor/v2/core/client.py与配套教程Response Models 教程、Fields 概念、Optional Fields 教程展开。读者将掌握如何用pydantic.BaseModel定义 LLM 输出结构、如何通过response_model让模型自动校验并返回类型化实例、如何利用 docstring 与字段注解进行提示词工程、如何处理可选字段、如何在运行时动态创建模型以及如何给模型挂载业务方法。什么是 Response ModelInstructor 的核心理念是用 Pydantic 模型定义你要什么让语言模型照着输出。在 Instructor 中这个用于描述输出结构的 Pydantic 模型就被称为Response Model。定义一个 Response Model 极其简单——它就是一个普通的pydantic.BaseModel子类from pydantic import BaseModel, Field class User(BaseModel): name: str Field(descriptionThe name of the user.) age: int Field(descriptionThe age of the user.)定义完成后把它作为response_model参数传给客户端例如client.create(...)Instructor 会在背后完成三件事定义 schema 与提示词把你的模型编译成 JSON Schema 并注入 prompt / 工具定义告诉语言模型应该输出什么形状的数据校验 API 返回对语言模型的原始输出进行解析与 Pydantic 校验类型不符或缺失字段都会触发重试详见 Retrying 概念返回模型实例最终交付的是一个已经通过校验的User实例而不是一坨需要手动解析的 JSON 字符串。对应到仓库源码响应处理的核心管线位于 instructor/v2/core/client.py其中create的签名里response_model: type[T]或None直接决定了本次调用是否走结构化输出分支而把模型变成发给 LLM 的 schema这一步在 v2 架构中按供应商拆分统一由 instructor/v2/core/schema.py 导出generate_openai_schema、generate_anthropic_schema、generate_gemini_schema三个兼容入口实际实现在各供应商目录下如 instructor/v2/providers/openai/schema.py。一个最小可用示例import instructor from pydantic import BaseModel, Field class User(BaseModel): name: str Field(descriptionThe name of the user.) age: int Field(descriptionThe age of the user.) client instructor.from_provider(openai/gpt-4o-mini) user client.create( response_modelUser, messages[{role: user, content: Extract: John is 30 years old}], ) print(user.name) # John print(user.age) # 30from_provider(openai/gpt-4o-mini)是 Instructor 提供的统一客户端创建接口支持 OpenAI、Anthropic、Gemini、Mistral、Cohere、Groq 等大量供应商完整列表见 Integrations 索引 与 from_provider 概念。用 docstring 与字段注解驱动提示词Response Model 不仅定义结构它本身还承载着提示词工程。Instructor 约定类的 docstring 就是发给语言模型的指令每个字段的类型注解与Field(description...)就是对该字段的说明。from pydantic import BaseModel, Field import instructor class User(BaseModel): This is the prompt that will be used to generate the response. Any instructions here will be passed to the language model. name: str Field(descriptionThe name of the user.) age: int Field(descriptionThe age of the user.) client instructor.from_provider(openai/gpt-4o-mini) user client.create( response_modelUser, messages[{role: user, content: Extract: John is 30 years old}], )源码层面的证据在 instructor/v2/providers/openai/schema.pygenerate_openai_schema用docstring_parser.parse(model.__doc__)解析类 docstring把其中的参数说明:param xxx: ...补进 JSON Schema 对应字段的description若整个模型没有 description则自动生成Correctly extracted \{model.name} with all the required parameters with correct types 作为工具描述。也就是说你写下的 docstring 与字段描述会被直接编译进发给 LLM 的 tool/function schema这就是用 Python 类型系统做提示词工程的原理。此外Pydantic 的Field还提供了更多可用于提示词工程的元数据详见 Fields 概念description字段语义说明title字段标题examples字段示例值可显著提升抽取准确性json_schema_extra向 JSON Schema 追加任意额外属性。这些都会进入model.model_json_schema()生成的 schema进而影响 LLM 的输出质量。让字段可选Optional 与默认值现实中的抽取任务经常遇到原文里没有这个信息的情况。此时可以把字段声明为Optional并给出默认值from pydantic import BaseModel, Field from typing import Optional import instructor class User(BaseModel): name: str Field(descriptionThe name of the user.) age: int Field(descriptionThe age of the user.) email: Optional[str] Field(descriptionThe email of the user., defaultNone) client instructor.from_provider(openai/gpt-4o-mini) user client.create( response_modelUser, messages[{role: user, content: Extract: John is 30 years old}], ) # user.email None需要注意两个关键点Optional[str]本身不产生默认值即使类型写成Optional[str]字段依然会被视为必填required。必须显式给出defaultNone或default_factory字段才会在发给 LLM 的 schema 中标记为可选。这一点在 Fields 概念 中也有明确提示。JSON Schema 层面可选字段意味着该字段允许为null同时Optional不改变类型的描述LLM 在信息缺失时倾向于返回null而不是凭空编造。关于可选值还有两套进阶工具Maybe[T]类型用于表达模型也不确定的字段返回值包裹在Maybe容器中可通过is_uncertain判断置信度详见 Maybe 概念 与 Optional Fields 教程SkipJsonSchema注解如果某个字段例如private_field、scratch_pad不想让语言模型看到可以用 Pydantic 的SkipJsonSchema[...]把它从发给 LLM 的 schema 中剔除并配合默认值使用见 Fields 概念中的对应小节。从源码看可选字段不进入 required 集合的行为是有意为之在 instructor/v2/providers/openai/schema.py 的注释中明确说明parameters[required]直接复用 Pydantic 自己计算出的schema.get(required, [])而 Pydantic 的 required 集合天然排除了带默认值无论是default还是default_factory的字段——这也解释了为什么只写Optional而不给默认值不生效。运行时动态创建模型当输出结构在编码期无法预知例如由数据库配置、用户配置或动态业务规则决定时可以使用 Pydantic 的create_model在运行时构造模型。基础用法from pydantic import BaseModel, create_model class FooModel(BaseModel): foo: str bar: int 123 BarModel create_model( BarModel, apple(str, russet), banana(str, yellow), __base__FooModel, ) print(BarModel) # class __main__.BarModel print(BarModel.model_fields.keys()) # dict_keys([foo, bar, apple, banana])create_model的字段参数形式为(类型, 默认值或 Field)同时可以用__base__继承已有模型实现字段的合并与复用。典型场景从数据库配置构建模型文档给出的典型场景是模型的结构保存在数据库中例如一张prompt表存有每个model_name对应的property_name / property_type / descriptionSELECT property_name, property_type, description FROM prompt WHERE model_name {model_name}拿到查询结果后用create_model一行代码完成模型构建from pydantic import BaseModel, create_model, Field from typing import List types { string: str, integer: int, boolean: bool, number: float, List[str]: List[str], } # Mocked cursor.fetchall() cursor [ (name, string, The name of the user.), (age, integer, The age of the user.), (email, string, The email of the user.), ] BarModel create_model( User, **{ property_name: (types[property_type], Field(descriptiondescription)) for property_name, property_type, description in cursor }, __base__BaseModel, ) print(BarModel.model_json_schema())输出正是标准 JSON Schema可作为response_model直接使用{ properties: { name: {description: The name of the user., title: Name, type: string}, age: {description: The age of the user., title: Age, type: integer}, email: {description: The email of the user., title: Email, type: string} }, required: [name, age, email], title: User, type: object }这套模式的价值在于同一个代码库可以为不同用户/场景生成字段相同、描述不同的模型——字段描述即提示词因此等于实现了同一结构、个性化 prompt。关于 JSON Schema 生成的更多细节Optional 允许 null、Decimal 序列化为字符串、子模型进入$defs等见 Fields 概念文档的附录。给模型添加行为让抽取结果会做事Pydantic 模型本质是 Python 类因此可以像普通类一样定义方法为抽取结果附加业务逻辑from pydantic import BaseModel from typing import Literal import instructor client instructor.from_provider(openai/gpt-4.1-mini) class SearchQuery(BaseModel): query: str query_type: Literal[web, image, video] def execute(self): print(fSearching for {self.query} of type {self.query_type}) # Searching for cat of type image return Results for cat query client.create( modelgpt-4.1-mini, messages[{role: user, content: Search for a picture of a cat}], response_modelSearchQuery, ) results query.execute() print(results) # Results for cat在这里Literal[web, image, video]让 LLM 的输出被约束到枚举取值内详见 Enums 概念而execute()方法则在抽取完成后原地执行后续动作。这种结构 行为一体的模式非常适合将 RAG 检索、SQL 执行、API 调用等副作用封装在模型内部——官方博客 RAG is more than embeddings 中有更多此模式的实际案例。类似地Pydantic 还支持用field_validator/model_validator挂载自定义校验逻辑使模型内部即可校验、失败则自动重试参考 Validation 概念 与 Custom Validators 教程。组合进阶从简单模型到复杂结构Response Model 的能力可以自由组合覆盖从简单到复杂的各类抽取需求详见 Response Models 教程嵌套模型addresses: List[Address]实现分层数据结构抽取列表字段tags: List[str]一次抽取多个同类条目字段校验price: float Field(gt0)、name: str Field(min_length3)让 Pydantic 在解析时完成边界校验文档即提示为模型写 docstring、为字段写 description让 LLM 与同事都能理解模型语义。一个综合示例结合 Simple Object Extraction 与 Nested Structure 教程from typing import List, Optional from pydantic import BaseModel, Field class Address(BaseModel): street: str city: str country: str class User(BaseModel): A user record extracted from unstructured text. name: str Field(descriptionFull name of the user.) age: Optional[int] Field(defaultNone, descriptionAge if mentioned.) addresses: List[Address] Field(descriptionAll known addresses.) # 作为 response_model 使用 # user client.create(response_modelUser, messages[...])常见问题与排查要点字段声明了Optional却仍被要求必填Optional不自动产生默认值请补上 None或default_factory。不想让 LLM 看到/生成某字段用SkipJsonSchema[...]从 schema 中剔除并给出默认值避免校验失败。抽取结果字段总是错误或缺失优先检查 docstring 与Field(description...)是否准确——它们直接编译进发给 LLM 的 schema源码见 instructor/v2/providers/openai/schema.py。结构在编码期未知用create_model从配置/数据库动态构建字段描述按需生成。希望失败自动重试Instructor 默认在响应校验失败时携带错误信息向 LLM 重试可参考 Retrying 概念 调整max_retries。参考与延伸阅读Response Models 教程创建响应模型的分步指南Simple Object Extraction基础抽取模式Nested Structures复杂层级模型Optional Fields可选数据的处理Types各类数据类型的使用Fields字段高级配置与 JSON Schema 定制Maybe 概念表达不确定的字段Fields 文档中的相关小节SkipJsonSchema用法【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/22 17:02:22

呼叫中心SIP中继对接实战:VOS与OKCC从路由配置到话单同步

接触呼叫中心业务的朋友都有体会,一套完整的外呼链路往往不是靠单个系统硬撑起来的。线路资源、语音网关、号码路由、并发控制这些东西,和坐席管理、客户资料、外呼任务、通话报表,天然属于两个不同的管理层次。如果硬要把它们塞在一个系统里…

2026/10/25 7:32:33

TypeScript接口重载实战:告别any,精确推导Web请求类型

做Web开发的人,尤其是用TypeScript写前端工程写了几年之后,多少都会遇到这样一个场景:同一个函数、同一个接口,入参不同,返回的类型也不同。用any吧,类型保护全丢了;用联合类型吧,每…

2026/11/2 15:57:41

《监狱模拟器》闪退卡顿启动报错全解析:从运行库到硬件的排查手册

游戏启动就闪退、点开图标转两圈直接回桌面、进到主菜单之前卡成幻灯片——这类问题在模拟经营类游戏里特别常见,《监狱模拟器》这种带大量AI角色、动态场景加载和复杂状态机的作品更是重灾区。我自己前前后后在这款游戏上折腾过三台不同配置的机器,从老…

2026/11/2 15:57:41

RAG数据集构建指南:148个实战资源与12项质量检测标准

1. RAG数据集全景解析:为什么开发者需要这份避坑指南? 在大模型应用开发领域,检索增强生成(RAG)技术已经成为连接私有数据与预训练大模型的关键桥梁。但许多团队在实施过程中常陷入"数据陷阱"——精心设计的…

2026/11/2 15:57:41

电动汽车V2G智能控制平台设计与优化实践

1. 电动汽车储能与用能协同优化平台概述电动汽车作为新型电力负荷和分布式储能单元的双重身份,正在重塑能源系统的运行模式。这个项目聚焦于开发一个智能控制平台,旨在协调优化电动汽车在交通运输和电网服务中的双重功能。简单来说,就是让电动…

2026/11/2 15:57:41

Simplex开源工具库深度解析:设计思路、核心模块与实操避坑指南

做开源项目最怕的一件事,就是拿到一个名字听起来很唬人的仓库,点进去发现文档只有三行,示例跑不起来,issue 区一片沉默。我这些年陆陆续续接触过不少以“Simplex”命名的开源项目——这个词本身在数学、通信、优化算法里都有特定含…

2026/11/2 15:57:41

4B小模型如何通过DASD技术逆袭32B大模型

1. 项目概述:当4B小模型逆袭32B巨无霸上周在GitHub Trending上看到一个震撼标题:清华代码熊团队用4B参数的蒸馏模型,在部分基准测试中超越了阿里Qwen3-32B的表现。这就像看到一辆微型电动车在直线加速赛上赢过了12缸超跑,立刻引起…

2026/11/2 15:52:36

AI前沿技术日更简报:高效筛选与验证机制解析

1. 项目概述:AI前沿技术日更简报的价值定位 每天清晨打开邮箱就能获取一份精心筛选的AI技术动态,这可能是2026年最有效率的行业信息获取方式。我们这个"AI前沿技术日更简报"项目,本质上是一个面向技术决策者、研发工程师和科技投资…

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

工业级SPI隔离设计:硬件抗扰与信号完整性实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

PLFM_RADAR:主动探测数据通道,构建低误报的数据感知系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 1:04:04

工业SPI隔离设计:MAX14431与STM32F746硬件抗干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

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

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