AnthropicProvider

Use Anthropic Claude with native API support – structured output is guaranteed, never falling back to free-form prose.

Use Anthropic Claude with native API support. The provider handles Anthropic's distinct wire format – top-level system field, tool-use-based structured output – so you call it with the same messages interface as every other provider. Retry is delegated to the official anthropic-ai/sdk.

Construction

public function __construct(
    ProviderConfig $config,
    AnthropicClient|null $client = null,
)
config
ProviderConfig
Resolved per-provider configuration.
client
\\Anthropic\\Client | null
Inject a custom Anthropic client. Defaults to new AnthropicClient(apiKey: ..., baseUrl: ...).

Methods

generateObject

Splits incoming messages into system parts (concatenated and forwarded as the top-level system field) and chat turns. Registers a single tool structured_response with the user-supplied JSON Schema as input_schema, forces it via toolChoice, and returns the input of the first ToolUseBlock in the response.

$provider->generateObject(
    messages: [
        ['role' => 'system', 'content' => 'Return JSON only.'],
        ['role' => 'user', 'content' => 'Pick three colors.'],
    ],
    schema: [
        'type' => 'object',
        'properties' => ['colors' => ['type' => 'array', 'items' => ['type' => 'string']]],
        'required' => ['colors'],
    ],
);

Throws ProviderException on upstream APIException (with httpCode set to the status), or when the response contains no tool_use block. Forcing a tool guarantees the response shape – Claude can't fall back to prose.

generateText

Sends a messages.create request without tools or toolChoice and returns the concatenated text of every TextBlock in the response.

$provider->generateText(
    messages: [
        ['role' => 'user', 'content' => 'Describe three primary colors.'],
    ],
);

Throws ProviderException on upstream APIException, or when the response contains no text block.

Provider-Specific Options

Anything in providers.anthropic that isn't apiKey, model, or baseUrl is spread into the messages.create request:

'providers' => [
    'anthropic' => [
        'apiKey' => env('ANTHROPIC_API_KEY'),
        'maxTokens' => 8000,
        'temperature' => 0.7,
        'thinking' => ['type' => 'enabled', 'budgetTokens' => 4000],
    ],
],
Anthropic requires max_tokens on every request. The provider sends DEFAULT_MAX_TOKENS (32000) by default – override via providers.anthropic.maxTokens when you need a tighter cap.

Option names use the SDK's camelCase convention (maxTokens, topP), not the snake_case wire format. The SDK handles the conversion.