Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6e70111
feat(v2/anthropic): implement provider with mode registry integration
jxnl Nov 12, 2025
45df965
fix(v1/anthropic): correct Mode enum usage in deprecation warning
jxnl Nov 12, 2025
e5032ae
feat(v2/anthropic): merge reasoning tools into TOOLS mode with thinki…
jxnl Nov 12, 2025
f65eee5
feat(mode): deprecate ANTHROPIC_REASONING_TOOLS in favor of TOOLS wit…
jxnl Nov 12, 2025
81a1a8e
feat(auto_client): migrate Anthropic provider to v2 registry
jxnl Nov 12, 2025
bf6f002
docs(anthropic): update to Mode.TOOLS and claude-4-5-haiku
jxnl Nov 12, 2025
d6930ff
feat(v2/anthropic): auto-detect parallel tools mode from Iterable[Uni…
jxnl Nov 12, 2025
84c7f10
feat(v2/anthropic): add real API tests and fix parallel handler
jxnl Nov 12, 2025
2cc18d9
docs(anthropic): update with auto-detection features
jxnl Nov 12, 2025
743d009
feat(v2/anthropic): implement provider with mode registry integration
jxnl Nov 12, 2025
267282f
feat(v2): introduce core architecture documentation and exception han…
jxnl Nov 12, 2025
609f3a9
refactor(anthropic): clean up deprecated from_anthropic() usage and u…
jxnl Nov 12, 2025
ff8b66e
Update image base URL in ipnb tutorials (#1922)
jxnl Nov 12, 2025
0846c04
Refactor Anthropic v2 handlers to use registry streaming pipeline (#1…
jxnl Nov 19, 2025
50b73db
feat(v2): migrate anthropic handlers to use generic modes
jxnl Nov 19, 2025
f380f9d
Merge remote-tracking branch 'origin/main' into feat/v2-anthropic-pro…
jxnl Nov 19, 2025
292b558
feat(anthropic): add structured outputs coverage
jxnl Nov 19, 2025
d9495fa
fix(v2): restore AnthropicParallelModel and fix test configuration
jxnl Nov 19, 2025
d62c8ac
Cursor/migrate genai client to v2 d24d (#1934)
jxnl Nov 19, 2025
0693be8
feat(v2): fix GenAI provider integration and consolidate tests
jxnl Nov 20, 2025
faaddb0
docs(v2): add comprehensive system documentation, testing guide, and …
jxnl Nov 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 70 additions & 29 deletions docs/integrations/anthropic.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
title: "Anthropic Claude Tutorial: Structured Outputs with Instructor"
description: "Complete guide to using Anthropic's Claude models with Instructor for structured data extraction. Learn how to use Claude 3 Opus, Sonnet, and Haiku for type-safe outputs in Python."
description: "Complete guide to using Anthropic's Claude models with Instructor for structured data extraction. Learn how to use Claude Haiku for type-safe outputs in Python."
---

# Anthropic Claude Tutorial: Structured Outputs with Instructor

Learn how to use Anthropic's Claude models (Claude 3 Opus, Sonnet, and Haiku) with Instructor to extract structured, validated data. This tutorial covers everything from basic setup to advanced patterns for production use.
Learn how to use Anthropic's Claude Haiku models with Instructor to extract structured, validated data. This tutorial covers everything from basic setup to advanced patterns for production use.

## Quick Start: Install Instructor for Claude

Expand Down Expand Up @@ -46,8 +46,8 @@ class User(BaseModel):
properties: List[Properties] = Field(description="List of user properties")

client = instructor.from_provider(
"anthropic/claude-3-5-haiku-latest",
mode=instructor.Mode.ANTHROPIC_TOOLS
"anthropic/claude-4-5-haiku-latest",
mode=instructor.Mode.TOOLS
)

try:
Expand Down Expand Up @@ -97,9 +97,9 @@ except Exception as e:
import asyncio

async_client = instructor.from_provider(
"anthropic/claude-3-5-haiku-latest",
"anthropic/claude-4-5-haiku-latest",
async_client=True,
mode=instructor.Mode.ANTHROPIC_TOOLS,
mode=instructor.Mode.TOOLS,
)

async def extract_user():
Expand All @@ -114,6 +114,11 @@ print(user)

### Parallel Tool Calling

Parallel tool mode is automatically detected when your response model is `Iterable[Union[Model1, Model2, ...]]`. Just use `Mode.TOOLS` (or let it default) and the handler will automatically:
- Set tool_choice to "auto" (required for parallel)
- Generate schemas for all union members
- Return a generator yielding each tool result

```python
from typing import Iterable, Literal
from pydantic import BaseModel
Expand All @@ -129,9 +134,10 @@ class GoogleSearch(BaseModel):
query: str


# No need to specify Mode.PARALLEL_TOOLS - it's auto-detected!
client = instructor.from_provider(
"anthropic/claude-3-5-haiku-latest",
mode=instructor.Mode.ANTHROPIC_PARALLEL_TOOLS,
mode=instructor.Mode.TOOLS, # or just omit and use default
)

results = client.chat.completions.create(
Expand All @@ -142,13 +148,19 @@ results = client.chat.completions.create(
"content": "What is the weather in toronto and dallas and who won the super bowl?",
},
],
response_model=Iterable[Weather | GoogleSearch],
response_model=Iterable[Weather | GoogleSearch], # Auto-detects parallel mode
)

for item in results:
print(item)
```

**How it works**: When Instructor detects `Iterable[Union[...]]`, it automatically:
1. Sets `tool_choice` to `"auto"` (allows model to call any tool)
2. Generates tool schemas from all union members
3. Returns a generator that yields each extracted tool call
4. Each yielded item is validated against its corresponding Pydantic model

## Multimodal

> We've provided a few different sample files for you to use to test out these new features. All examples below use these files.
Expand Down Expand Up @@ -185,7 +197,7 @@ class ImageDescription(BaseModel):
colors: list[str] = Field(..., description="The colors in the image")


client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
client = instructor.from_provider("anthropic/claude-4-5-haiku-latest")
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/image.jpg"
# Multiple ways to load an image:
response = client.chat.completions.create(
Expand Down Expand Up @@ -239,7 +251,7 @@ class Receipt(BaseModel):
items: list[str]


client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
client = instructor.from_provider("anthropic/claude-4-5-haiku-latest")
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/invoice.pdf"
# Multiple ways to load an PDF:
response = client.chat.completions.create(
Expand Down Expand Up @@ -281,7 +293,7 @@ class Receipt(BaseModel):
items: list[str]


client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
client = instructor.from_provider("anthropic/claude-4-5-haiku-latest")
url = "https://raw.githubusercontent.com/instructor-ai/instructor/main/tests/assets/invoice.pdf"
# Multiple ways to load an PDF:
response, completion = client.chat.completions.create_with_completion(
Expand Down Expand Up @@ -338,8 +350,8 @@ from pydantic import BaseModel, Field

# Initialize client with explicit mode
client = instructor.from_provider(
"anthropic/claude-3-5-haiku-latest",
mode=instructor.Mode.ANTHROPIC_TOOLS,
"anthropic/claude-4-5-haiku-latest",
mode=instructor.Mode.TOOLS,
)

# Define your model with proper annotations
Expand Down Expand Up @@ -387,7 +399,7 @@ from pydantic import BaseModel, Field

# Initialize client with explicit mode
client = from_provider(
mode=instructor.Mode.ANTHROPIC_TOOLS
mode=instructor.Mode.TOOLS
)

# Define your model with proper annotations
Expand Down Expand Up @@ -434,11 +446,22 @@ except Exception as e:

We provide several modes to make it easy to work with the different response models that Anthropic supports

1. `instructor.Mode.ANTHROPIC_JSON` : This uses the text completion API from the Anthropic API and then extracts out the desired response model from the text completion model
2. `instructor.Mode.ANTHROPIC_TOOLS` : This uses Anthropic's [tools calling API](https://docs.anthropic.com/en/docs/build-with-claude/tool-use) to return structured outputs to the client
3. `instructor.Mode.ANTHROPIC_PARALLEL_TOOLS` : Runs multiple tools in parallel and returns a list of tool calls
1. `instructor.Mode.JSON` : This uses the text completion API from the Anthropic API and then extracts out the desired response model from the text completion model
2. `instructor.Mode.TOOLS` : This uses Anthropic's [tools calling API](https://docs.anthropic.com/en/docs/build-with-claude/tool-use) to return structured outputs. Automatically detects parallel tools from `Iterable[Union[...]]` response models.
3. `instructor.Mode.PARALLEL_TOOLS` : **Deprecated** - Use `Mode.TOOLS` with `Iterable[Union[Model1, Model2, ...]]` instead. Auto-detected automatically.

In general, we recommend using `Mode.ANTHROPIC_TOOLS` because it's the best way to ensure you have the desired response schema that you want.
### Mode Auto-Detection

`Mode.TOOLS` now intelligently adapts based on your response model and parameters:

| Response Model | Parameters | Behavior |
|---|---|---|
| `Model` | Regular | Single tool (forced) |
| `Model` | `thinking={...}` | Single tool with extended thinking (auto) |
| `Iterable[Union[Model1, Model2]]` | Regular | Parallel tools (auto) |
| `Iterable[Union[Model1, Model2]]` | `thinking={...}` | Parallel with thinking |

In general, we recommend using `Mode.TOOLS` because it automatically handles all these cases and is the best way to ensure you have the desired response schema.

## Caching

Expand Down Expand Up @@ -469,8 +492,9 @@ class Character(BaseModel):
description: str = Field(description="A description of the character")

# Initialize client with explicit mode and prompt caching
client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
mode=instructor.Mode.ANTHROPIC_TOOLS,
client = instructor.from_provider(
"anthropic/claude-4-5-haiku-latest",
mode=instructor.Mode.TOOLS,
)

try:
Expand Down Expand Up @@ -543,8 +567,9 @@ class ImageAnalyzer(BaseModel):
scene_type: str = Field(description="Type of scene shown in the images (indoor, outdoor, etc.)")

# Initialize client with explicit mode and image caching enabled
client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
mode=instructor.Mode.ANTHROPIC_TOOLS,
client = instructor.from_provider(
"anthropic/claude-4-5-haiku-latest",
mode=instructor.Mode.TOOLS,
)

try:
Expand Down Expand Up @@ -592,9 +617,11 @@ except Exception as e:
print(f"Error during image analysis: {e}")
```

## Thinking
## Thinking (Extended Thinking)

Anthropic recently released support for extended thinking with their `sonnet-3.7` model series. In instructor, we support getting a validated tool call with the `instructor.Mode.ANTHROPIC_REASONING_TOOLS` Mode as seen below.
Anthropic supports extended thinking with their Claude models, enabling the model to think through complex problems before providing structured outputs. In Instructor, use `Mode.TOOLS` with the `thinking` parameter to enable this feature.

### Using Extended Thinking with TOOLS

```python
from anthropic import Anthropic
Expand All @@ -607,24 +634,38 @@ class Answer(BaseModel):


client = Anthropic()
client = instructor.from_provider("anthropic/claude-3-5-haiku-latest")
client = instructor.from_provider(
"anthropic/claude-4-5-haiku-latest",
mode=instructor.Mode.TOOLS
)

response = client.chat.completions.create(
response_model=Answer,
messages=[
{
"role": "user",
"content": "Which is larger, 9.11 or 9.8",
"content": "Which is larger, 9.11 or 9.8?",
},
],
temperature=1,
max_tokens=2000,
thinking={"type": "enabled", "budget_tokens": 1024},
)


# Assertions to validate the response
# Response is a validated Answer object
assert isinstance(response, Answer)
assert response.answer == 9.8
```

This then returns the response as a validated `Answer` object.
### How It Works

When you provide the `thinking` parameter with `type: "enabled"`:

1. **Automatic Mode Detection**: `Mode.TOOLS` automatically detects the thinking parameter and adjusts the tool choice strategy to `auto` (required by Anthropic's API when thinking is enabled)
2. **Model Reasoning**: Claude uses the allocated `budget_tokens` to reason about the problem
3. **Structured Output**: After reasoning, the model returns a valid tool call with your response model
4. **Validation**: The response is automatically validated against your Pydantic model

### Deprecation Notice

`Mode.ANTHROPIC_REASONING_TOOLS` is deprecated. Use `Mode.TOOLS` with the `thinking` parameter instead. Both modes now support thinking, but using the standard `TOOLS` mode is preferred and more flexible.
43 changes: 38 additions & 5 deletions docs/integrations/genai.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ This guide demonstrates how to use Instructor with Google's `genai` SDK to extra

We currently have two modes for Gemini

- `Mode.GENAI_TOOLS` : This leverages function calling under the hood and returns a structured response
- `Mode.GENAI_STRUCTURED_OUTPUTS` : This provides Gemini with a JSON Schema that it will use to respond in a structured format with
- `Mode.TOOLS` : This leverages function calling under the hood and returns a structured response
- `Mode.JSON` : This provides Gemini with a JSON Schema that it will use to respond in a structured format with

!!! info "Gemini Thought Parts Filtering"

When using `Mode.GENAI_TOOLS`, Instructor automatically filters out thought parts from Gemini responses. Gemini 2.5 models include internal reasoning parts with `thought: true` by default, which cannot be disabled. Instructor removes these thought parts before processing the structured output to prevent runtime errors.
When using `Mode.TOOLS`, Instructor automatically filters out thought parts from Gemini responses. Gemini 2.5 models include internal reasoning parts with `thought: true` by default, which cannot be disabled. Instructor removes these thought parts before processing the structured output to prevent runtime errors.

This filtering happens automatically and requires no additional configuration. For more information about Gemini's thinking feature, see the [official documentation](https://ai.google.dev/gemini-api/docs/thinking).

!!! note "Backwards Compatibility"

The provider-specific modes (`Mode.GENAI_TOOLS`, `Mode.GENAI_JSON`, `Mode.GENAI_STRUCTURED_OUTPUTS`) are still supported for backwards compatibility and automatically map to the generic modes (`Mode.TOOLS`, `Mode.JSON`).

## Installation

```bash
Expand Down Expand Up @@ -65,6 +69,35 @@ response = client.chat.completions.create(
print(response) # User(name='Jason', age=25)
```

## Using the v2 GenAI client

If you prefer to work directly with the native `google.genai.Client`, the v2 helper keeps the Google request format intact while still giving you Instructor's structured outputs.

```python
from google.genai import Client
from instructor import Mode
from instructor.v2 import from_genai
from pydantic import BaseModel


class User(BaseModel):
name: str
age: int


raw_client = Client(api_key="YOUR_KEY")
client = from_genai(raw_client, mode=Mode.TOOLS)

result = client.chat.completions.create(
messages=[{"role": "user", "content": "Extract: Jason is 25 years old"}],
response_model=User,
)

print(result)
```

Behind the scenes the v2 client registers the correct mode handler, converts OpenAI-style messages to the GenAI `contents` format, and parses the response while filtering Gemini thought parts.

## Message Formatting

Genai supports multiple message formats, and Instructor seamlessly works with all of them. This flexibility allows you to use whichever format is most convenient for your application:
Expand Down Expand Up @@ -514,7 +547,7 @@ print(response)

**As of July 11, 2025, Google GenAI does not support streaming with tool/function calling or structured outputs for regular models.**

- `Mode.GENAI_TOOLS` and `Mode.GENAI_STRUCTURED_OUTPUTS` do not support streaming with regular models
- `Mode.TOOLS` and `Mode.JSON` do not support streaming with regular models
- To use streaming, you must use `Partial[YourModel]` explicitly or switch to other modes like `Mode.JSON`
- Alternatively, set `stream=False` to disable streaming

Expand All @@ -531,7 +564,7 @@ import instructor

client = instructor.from_provider(
"google/gemini-2.5-flash",
mode=instructor.Mode.GENAI_STRUCTURED_OUTPUTS,
mode=instructor.Mode.JSON,
)


Expand Down
8 changes: 6 additions & 2 deletions docs/integrations/google.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,12 @@ These limitations are specific to Google Gemini and do not affect other provider

We provide several modes to make it easy to work with the different response models that Gemini supports:

1. `instructor.Mode.GENAI_TOOLS` : This uses Gemini's tool calling API to return structured outputs (default)
2. `instructor.Mode.GENAI_STRUCTURED_OUTPUTS` : This uses Gemini's JSON schema mode for structured outputs
1. `instructor.Mode.TOOLS` : This uses Gemini's tool calling API to return structured outputs (default)
2. `instructor.Mode.JSON` : This uses Gemini's JSON schema mode for structured outputs

!!! note "Backwards Compatibility"

The provider-specific modes (`Mode.GENAI_TOOLS`, `Mode.GENAI_JSON`, `Mode.GENAI_STRUCTURED_OUTPUTS`) are still supported and automatically map to the generic modes.

!!! info "Mode Selection"
When using `from_provider`, the appropriate mode is automatically selected based on the provider and model capabilities.
Expand Down
Loading
Loading