
使用 Instructor 从 Anthropic Claude 提取结构化输出完整实战指南【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor本文是基于开源仓库 instructor 的 Anthropic 集成实战指南。全文围绕docs/integrations/anthropic.md展开讲解如何用 Instructor 的from_provider一行代码接入 Claude 模型完成从基础工具调用、异步、并行工具、多模态、流式输出到 Prompt Caching 与 Extended Thinking 的完整结构化输出管线。读完本文你将掌握 Claude Pydantic 类型安全输出的全部核心用法并了解其底层模式处理器Mode Handler的实现原理。快速开始安装并创建 Claude 客户端使用 Claude 进行结构化输出的前提是安装带 Anthropic 扩展的 Instructor 包pip install instructor[anthropic]安装完成后通过from_provider方法即可快速创建已打补丁的客户端。传入anthropic/claude-sonnet-5这种provider/model格式的模型字符串Instructor 会根据 provider 前缀自动完成客户端初始化与模式选择instructor/v2/auto_client.py中维护了ALIAS_TO_PROVIDER别名表与supported_providers列表。其底层工厂函数是from_anthropic它接受anthropic.Anthropic、AsyncAnthropic、AnthropicBedrock、AnthropicVertex等同步/异步客户端并做了模式规范化ANTHROPIC_TOOLS → TOOLS与模式注册校验。# Standard library imports from typing import List # Third-party imports import instructor from pydantic import BaseModel, Field # Set up environment (typically handled before script execution) # os.environ[ANTHROPIC_API_KEY] your-api-key # Uncomment and replace with your API key if not set # Define your models with proper type annotations class Properties(BaseModel): Model representing a key-value property. name: str Field(descriptionThe name of the property) value: str Field(descriptionThe value of the property) class User(BaseModel): Model representing a user with properties. name: str Field(descriptionThe users full name) age: int Field(descriptionThe users age in years) properties: List[Properties] Field(descriptionList of user properties) client instructor.from_provider( anthropic/claude-sonnet-5, modeinstructor.Mode.TOOLS ) try: # Extract structured data user_response client.create( max_tokens1024, messages[ { role: system, content: Extract structured information based on the users request., }, { role: user, content: Create a user for a model with a name, age, and properties., }, ], response_modelUser, ) # Print the result as formatted JSON print(user_response.model_dump_json(indent2)) # Expected output: # { # name: John Doe, # age: 35, # properties: [ # { # name: City, # value: New York # }, # { # name: Occupation, # value: Software Engineer # } # ] # } except instructor.exceptions.InstructorError as e: print(fValidation error: {e}) except Exception as e: print(fUnexpected error: {e})从源码结构看Mode.TOOLS对应的AnthropicToolsHandler在prepare_request阶段会做三件事提取并合并 system 消息extract_system_messages/combine_system_messages、将 Pydantic 模型转为 Anthropic 工具 schematools[...]、根据场景设置tool_choice。其中 schema 生成由generate_anthropic_schema完成输出name、description、input_schema三个字段并使用functools.lru_cache(maxsize256)缓存避免重复计算相同模型。异步调用Instructor 对异步场景开箱即用只需在from_provider中传入async_clientTrueimport asyncio async_client instructor.from_provider( anthropic/claude-sonnet-5, async_clientTrue, modeinstructor.Mode.TOOLS, ) async def extract_user(): return await async_client.create( messages[{role: user, content: Extract: Jason is 25 years old}], response_modelUser, ) user asyncio.run(extract_user()) print(user)from_anthropic会依据传入客户端的类型自动返回同步Instructor或AsyncInstructor实例见 instructor/v2/providers/anthropic/client.py因此无需手工区分 API。并行工具调用Iterable[Union[...]] 自动检测当你的响应模型是Iterable[Union[Model1, Model2, ...]]时Instructor 会自动切换到并行工具模式——无需显式指定Mode.PARALLEL_TOOLS只要使用Mode.TOOLS或保持默认即可自动将tool_choice设为auto并行调用的必要条件为联合类型的每一个成员生成工具 schema返回一个生成器逐一产出每个工具调用的结果每个产出项都会用对应的 Pydantic 模型做校验。from typing import Iterable, Literal from pydantic import BaseModel import instructor class Weather(BaseModel): location: str units: Literal[imperial, metric] class GoogleSearch(BaseModel): query: str # No need to specify Mode.PARALLEL_TOOLS - its auto-detected! client instructor.from_provider( anthropic/claude-sonnet-5, modeinstructor.Mode.TOOLS, # or just omit and use default ) results client.create( messages[ {role: system, content: You must always use tools}, { role: user, content: What is the weather in toronto and dallas and who won the super bowl?, }, ], response_modelIterable[Weather | GoogleSearch], # Auto-detects parallel mode ) for item in results: print(item)源码中AnthropicToolsHandler.prepare_request通过get_origin(response_model) is typing.Iterable判断并行场景注意流式模式下Iterable[T]会被当作流式而非并行工具见 handlers.py。随后handle_parallel_model为联合类型每个成员生成 Anthropic 工具 schema。响应解析时handler 遍历消息中的tool_use块按工具名查注册表并用model_validate_json校验handlers.py。多模态图片与 PDFInstructor 提供统一的、与提供商无关的多模态接口支持从 URL、本地文件或 base64 字符串加载媒体并自动完成各提供商特有的格式转换保证代码整洁且面向未来兼容。仓库中的示例素材包括一张蓝莓植株图片 tests/assets/image.jpg 和一份包含假发票的 PDF tests/assets/invoice.pdf。分析图片下面的示例用Image.from_url加载图片同时也支持from_path本地文件和from_base64base64 字符串以及自动嗅探来源的autodetect方法from instructor.processing.multimodal import Image from pydantic import BaseModel, Field import instructor class ImageDescription(BaseModel): objects: list[str] Field(..., descriptionThe objects in the image) scene: str Field(..., descriptionThe scene of the image) colors: list[str] Field(..., descriptionThe colors in the image) client instructor.from_provider(anthropic/claude-sonnet-5) # Multiple ways to load an image: response client.create( response_modelImageDescription, max_tokens1000, messages[ { role: user, content: [ What is in this image?, # Option 1: Local file (samples included in this repo) Image.from_path(tests/assets/image.jpg), # Option 2: Direct URL # Image.from_url(https://.../image.jpg) # Option 3: Base64 string # Image.from_base64(base64_encoded_string_here) # Option 4: Autodetect # Image.autodetect(url|path|base64) ], }, ], ) print(response) # Example output: # ImageDescription( # objects[blueberries, leaves], # sceneA blueberry bush with clusters of ripe blueberries and some unripe ones against a cloudy sky, # colors[green, blue, purple, white] # )Image类定义在 instructor/v2/core/multimodal.pysource字段同时接受 URL、路径、base64 与原始字节。instructor.processing.multimodal作为兼容导出层把 v2 的实现重新导出multimodal.py。提取 PDF 内容PDF 的用法与图片完全对称同样是from_url/from_path/from_base64/autodetect四选一from instructor.processing.multimodal import PDF from pydantic import BaseModel import instructor class Receipt(BaseModel): total: int items: list[str] client instructor.from_provider(anthropic/claude-sonnet-5) # Multiple ways to load an PDF: response client.create( response_modelReceipt, max_tokens1000, messages[ { role: user, content: [ Extract out the total and line items from the invoice, # Option 1: Local file (samples included in this repo) PDF.from_path(tests/assets/invoice.pdf), # Option 2: Direct URL # PDF.from_url(https://.../invoice.pdf), # Option 3: Base64 string # PDF.from_base64(base64_encoded_string_here) # Option 4: Autodetect # PDF.autodetect(url|path|base64) ], }, ], ) print(response) # Receipt(total220, items[English Tea, Tofu])如果你想在多次请求间复用缓存同一份 PDF可以使用带缓存控制的PDFWithCacheControl类对应源码中的 PDFWithCacheControl结合create_with_completion获取原始 completion 以核对缓存命中情况from instructor.processing.multimodal import PDFWithCacheControl from pydantic import BaseModel import instructor class Receipt(BaseModel): total: int items: list[str] client instructor.from_provider(anthropic/claude-sonnet-5) response, completion client.create_with_completion( response_modelReceipt, max_tokens1000, messages[ { role: user, content: [ Extract out the total and line items from the invoice, PDFWithCacheControl.from_path(tests/assets/invoice.pdf), ], }, ], ) assert ( completion.usage.cache_creation_input_tokens 0 or completion.usage.cache_read_input_tokens 0 ) print(response) # Receipt(total220, items[English Tea, Tofu])PDFWithCacheControl底层会通过pdf_with_cache_control_to_anthropic位于 instructor/v2/providers/anthropic/multimodal.py把 PDF 转成带cache_control的 Anthropic 消息块。多模态的完整讲解见 docs/concepts/multimodal.md。流式输出Instructor 提供两种流式手段Iterables适合流式返回同类型对象的列表例如一次提取多个用户Partial Streaming适合流式返回单个对象边生成边处理。部分流式Partials使用create_partial流式产出单个对象。注意流式时不要在响应模型中声明 validator否则会破坏流式过程。# Third-party imports import instructor from pydantic import BaseModel, Field # Set up environment (typically handled before script execution) # os.environ[ANTHROPIC_API_KEY] your-api-key # Uncomment and replace with your API key if not set # Initialize client with explicit mode client instructor.from_provider( anthropic/claude-sonnet-5, modeinstructor.Mode.TOOLS, ) # Define your model with proper annotations class User(BaseModel): Model representing a user profile. name: str Field(descriptionThe users full name) age: int Field(descriptionThe users age in years) bio: str Field(descriptionA biographical description of the user) try: # Stream partial objects as theyre generated for partial_user in client.create_partial( messages[ { role: system, content: Create a detailed user profile based on the information provided., }, {role: user, content: Create a user profile for Jason, age 25}, ], response_modelUser, max_tokens4096, ): print(fCurrent state: {partial_user}) # Expected output: # Current state: nameJason ageNone bioNone # Current state: nameJason age25 bioJason is a 25-year-old with an adventurous spirit and a love for technology. He is # Current state: nameJason age25 bioJason is a 25-year-old with an adventurous spirit and a love for technology. He is always on the lookout for new challenges and opportunities to grow both personally and professionally. except Exception as e: print(fError during streaming: {e})流式解析依赖AnthropicHandlerBase中的extract_streaming_json在TOOLS/PARALLEL_TOOLS模式下读取chunk.delta.partial_json在JSON/JSON_SCHEMA模式下读取chunk.delta.texthandlers.py。Iterable 流式create_iterable用于从单次提示中提取多个同类型对象# Third-party imports from instructor import from_provider from pydantic import BaseModel, Field # Set up environment (typically handled before script execution) # os.environ[ANTHROPIC_API_KEY] your-api-key # Uncomment and replace with your API key if not set # Initialize client with explicit mode client from_provider(modeinstructor.Mode.TOOLS) # Define your model with proper annotations class User(BaseModel): Model representing a basic user. name: str Field(descriptionThe users full name) age: int Field(descriptionThe users age in years) try: # Create an iterable of user objects users client.create_iterable( messages[ { role: system, content: Extract all users from the provided text into structured format., }, { role: user, content: Extract users: 1. Jason is 25 years old 2. Sarah is 30 years old 3. Mike is 28 years old , }, ], max_tokens4096, response_modelUser, ) # Process each user as its extracted for user in users: print(user) # Expected output: # nameJason age25 # nameSarah age30 # nameMike age28 except Exception as e: print(fError during iteration: {e})在create_iterable非流式参数下中Iterable[T]同样会被识别为并行工具并逐个校验在流式场景则退化为StreamingModelState驱动的增量解析。两者完整语义见 docs/concepts/iterable.md 与 docs/concepts/partial.md。Instructor Modes模式选择与自动检测针对 Anthropic 支持的不同响应方式Instructor 提供多种模式instructor.Mode.JSON使用 Anthropic 的文本补全能力从纯文本回复中提取并解析目标响应模型instructor.Mode.TOOLS使用 Anthropic 的工具调用 API 返回结构化输出且能从Iterable[Union[...]]响应模型自动检测并行工具instructor.Mode.PARALLEL_TOOLS已废弃——请改用Mode.TOOLSIterable[Union[Model1, Model2, ...]]并行模式会自动被检测。从源码看Mode.JSON对应的AnthropicJSONHandler会把 Pydantic 模型的model_json_schema()以 JSON 形式注入 system 消息提示模型返回符合该 schema 的 JSON 实例而不是 schema 本身随后用extract_json_from_codeblock从回复中抽取 JSON 并校验。Mode 自动检测Mode.TOOLS会根据响应模型与参数智能调整行为Response ModelParametersBehaviorModelRegularSingle tool (forced)Modelthinking{...}Single tool with extended thinking (auto)Iterable[Union[Model1, Model2]]RegularParallel tools (auto)Iterable[Union[Model1, Model2]]thinking{...}Parallel with thinking建议一律使用Mode.TOOLS因为它自动覆盖上述所有场景是保证输出 schema 最稳妥的方式。源码中的判定逻辑位于AnthropicToolsHandler.prepare_requesthandlers.py普通模型走强制工具调用tool_choice{type: tool, name: ..., disable_parallel_tool_use: True}防止模型对同一工具发出多个tool_use块导致解析失败开启 thinking 或并行时则改为tool_choice{type: auto}。原生结构化输出JSON_SCHEMA此外仓库还实现了AnthropicStructuredOutputsHandlerMode.JSON_SCHEMA它走 Claude 的原生结构化输出强制即通过output_format{type: json_schema, schema: ...}参数下发 schema并自动追加structured-outputs-2025-11-13beta 头。注意其适用前提需要 Anthropic SDK 支持output_format参数建议anthropic0.71.0否则会发出警告并回退到 JSON 模式指令。缓存Prompt CachingInstructor 支持对文本输入和图片做 Anthropic Prompt Caching。仓库还提供了基于缓存实现 Anthropic Contextual Retrieval 的完整走读文章 docs/blog/posts/anthropic-prompt-caching.md。文本输入缓存假设你有一个很大的book.txt需要反复携带在上下文中可以在消息内容块上标记cache_control# Third-party imports import instructor from pydantic import BaseModel, Field # Set up environment (typically handled before script execution) # os.environ[ANTHROPIC_API_KEY] your-api-key # Uncomment and replace with your API key if not set # Define your Pydantic model with proper annotations class Character(BaseModel): Model representing a character extracted from text. name: str Field(descriptionThe characters full name) description: str Field(descriptionA description of the character) # Initialize client with explicit mode and prompt caching client instructor.from_provider( anthropic/claude-sonnet-5, modeinstructor.Mode.TOOLS, ) try: # Load your large context with open(./book.txt) as f: book f.read() # Make multiple calls using the cached context for _ in range(2): # The first time processes the large text, subsequent calls use the cache resp, completion client.create_with_completion( messages[ { role: system, content: Extract character information from the provided text., }, { role: user, content: [ { type: text, text: book book /book, cache_control: {type: ephemeral}, # Mark for caching }, { type: text, text: Extract a character from the text given above, }, ], }, ], response_modelCharacter, max_tokens1000, ) # Process the result print(fCharacter: {resp.name}) print(fDescription: {resp.description}) # The completion contains the raw response print(fRaw completion length: {len(completion)}) # Note: Second iteration should be faster due to cache hit except Exception as e: print(fError: {e})注意create_with_completion返回(响应模型实例, 原始 completion)二元组completion.usage中的cache_creation_input_tokens/cache_read_input_tokens字段可用于验证缓存是否生效前面PDFWithCacheControl示例正是用该字段做断言。图片缓存图片同样支持缓存对反复使用同一批图片的场景能显著降低成本。可以给type: image内容块附加cache_control并配合autodetect_imagesTrue自动处理图片内容# Third-party imports import instructor from pydantic import BaseModel, Field # Set up environment (typically handled before script execution) # os.environ[ANTHROPIC_API_KEY] your-api-key # Uncomment and replace with your API key if not set # Define your model for image analysis class ImageAnalyzer(BaseModel): Model for analyzing image content. content_description: str Field( descriptionDescription of what appears in the images ) objects: list[str] Field(descriptionList of objects visible in the images) scene_type: str Field( descriptionType of scene shown in the images (indoor, outdoor, etc.) ) # Initialize client with explicit mode and image caching enabled client instructor.from_provider( anthropic/claude-sonnet-5, modeinstructor.Mode.TOOLS, ) try: # Configure cache control for images cache_control {type: ephemeral} # Make a request with cached images response client.create( response_modelImageAnalyzer, messages[ { role: system, content: Analyze the content of the provided images in detail., }, { role: user, content: [ What is in these two images?, # Remote image with caching { type: image, source: https://example.com/image.jpg, cache_control: cache_control, }, # Local image with caching { type: image, source: path/to/image.jpg, cache_control: cache_control, }, ], }, ], autodetect_imagesTrue, # Automatically handle image content ) # Process the results print(fDescription: {response.content_description}) print(fObjects: {, .join(response.objects)}) print(fScene type: {response.scene_type}) # Subsequent identical requests will use cached images except Exception as e: print(fError during image analysis: {e})缓存的通用机制与更多实践可参考 docs/concepts/caching.md。扩展思考Extended ThinkingAnthropic 的 Claude 系列支持扩展思考让模型在处理复杂问题前先进行推理再给出结构化输出。在 Instructor 中使用Mode.TOOLS并传入thinking参数即可开启。在 TOOLS 模式下使用扩展思考import instructor from pydantic import BaseModel class Answer(BaseModel): answer: float client instructor.from_provider(anthropic/claude-sonnet-5) response client.create( response_modelAnswer, messages[ { role: user, content: Which is larger, 9.11 or 9.8?, }, ], max_tokens2000, thinking{type: adaptive}, tool_choice{type: auto}, ) # Response is a validated Answer object assert isinstance(response, Answer) assert response.answer 9.8工作原理当对 Sonnet 5 传入thinking{type: adaptive}时工具选择使用自适应思考时必须显式传tool_choice{type: auto}——思考模式不支持强制工具选择模型推理Claude 自行决定本次请求所需的推理量自适应思考不使用budget_tokens结构化输出推理结束后模型返回符合响应模型的合法工具调用校验返回内容自动按 Pydantic 模型完成校验。源码层面AnthropicToolsHandler.prepare_request检测到thinking.type enabled时会强制tool_choice{type: auto}并向 system 追加只返回工具调用、不要多余文本的指令handlers.py确保思考内容不会污染结构化输出。废弃说明Mode.ANTHROPIC_REASONING_TOOLS已废弃请改用Mode.TOOLSthinking参数。两种模式目前都支持思考但标准TOOLS模式更受推荐且更灵活。错误处理与自动重试结构化输出失败通常分两类模型输出不合法或输出在 Pydantic 校验阶段未通过。文档示例中统一捕获instructor.exceptions.InstructorError校验错误与兜底Exception。从源码看Anthropic handler 还会抛出更细粒度的异常IncompleteOutputException当stop_reason max_tokens或 OpenAI 风格的finish_reason length时抛出携带last_completion便于续写handlers.pyResponseParsingErrorJSON 模式下响应中没有可解析文本时抛出。校验失败时会触发 reask 机制AnthropicToolsHandler.handle_reask会把上一次回复中的每个tool_use块都收集起来并为每一个工具调用生成对应的tool_resultis_errorTrue回传避免并行工具场景因遗漏 tool_result 而收到 400 错误对应 issue #2485见 handlers.py。延伸阅读快速入门完整的上手指引from_provider 详解客户端配置与 provider 解析细节模式对比各模式下工具调用的行为差异多模态概念Image / PDF / Audio 的完整用法缓存概念Prompt Caching 原理与实践Anthropic Prompt Caching 实践用缓存实现 Contextual Retrieval 的深度走读Anthropic 网络搜索 结构化输出组合使用 Web Search 与结构化输出的示例。【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考