Anthropic
Using Anthropic Claude models with Flux — setup, API keys, model selection, streaming, structured output, and reasoning effort.
Flux talks to Anthropic through the anthropic Python SDK. The integration lives in flux/tasks/ai/anthropic.py and exposes Claude models through the same agent() factory as every other provider.
Install
The Anthropic SDK is an optional dependency. Install it directly:
pip install anthropic
Or bring in every supported LLM provider at once with the ai extra on flux-core:
pip install flux-core[ai]
The ai extra pulls ollama, openai, anthropic, and google-genai. There is no per-provider extra in 0.56.0 — either install the SDK directly or take the full bundle.
API key
Anthropic’s SDK reads its credential from the ANTHROPIC_API_KEY environment variable. Flux constructs AsyncAnthropic() with no arguments, so the SDK’s default lookup applies:
export ANTHROPIC_API_KEY="sk-ant-..."
If the variable is missing, the first agent call raises an authentication error from the Anthropic SDK rather than a Flux error.
Model string
Every agent() call takes a model parameter in "provider/model_name" format. For Anthropic, the prefix is anthropic/:
from flux.tasks.ai import agent
assistant = await agent(
"You are a helpful assistant.",
model="anthropic/claude-sonnet-4-20250514",
)
The model name is forwarded verbatim to client.messages.create(model=...). Use the model identifiers Anthropic publishes — claude-sonnet-4-20250514, claude-opus-4-20250514, claude-haiku-4-20250514, and earlier 3.x families are all valid. A typo lands as an HTTP 400 from the API, not a Flux registration error.
Streaming
Streaming is on by default. agent() accepts stream: bool = True; the Anthropic formatter uses client.messages.stream() and yields tokens through Flux’s progress() task. Streaming is disabled automatically whenever response_format is set.
assistant = await agent(
"You are a helpful assistant.",
model="anthropic/claude-sonnet-4-20250514",
stream=True,
)
See Streaming responses for the agent-loop details.
max_tokens
Anthropic requires max_tokens on every request. Flux defaults to 4096 and forwards the value as max_tokens to the Messages API. Raise it for long outputs:
assistant = await agent(
"Write detailed technical reports.",
model="anthropic/claude-sonnet-4-20250514",
max_tokens=8192,
)
max_tokens is honored by Anthropic, OpenAI, and Gemini. Ollama governs output length through the model’s num_predict setting instead. See the provider comparison for the full matrix.
Reasoning effort
Claude’s extended-thinking mode is exposed through the reasoning_effort parameter. The Anthropic formatter maps it to two API fields: thinking={"type": "adaptive"} and output_config={"effort": <level>}.
researcher = await agent(
"You are a careful researcher.",
model="anthropic/claude-sonnet-4-20250514",
reasoning_effort="high",
)
Valid values are "low", "medium", "high", or None. The formatter applies both fields whenever reasoning_effort is truthy (see anthropic.py::build_messages). Anthropic also supports reasoning streams: thinking-deltas arrive as separate thinking_delta events and are surfaced through the same agent-loop callbacks as text tokens.
Structured output
Pass a Pydantic BaseModel subclass as response_format and the agent returns an instance of that class:
from pydantic import BaseModel
class Sentiment(BaseModel):
label: str
confidence: float
classifier = await agent(
"Classify the sentiment of the text.",
model="anthropic/claude-sonnet-4-20250514",
response_format=Sentiment,
)
result: Sentiment = await classifier("This is great!")
Anthropic structured output is API-enforced. The Messages API has no response_format parameter, so Flux constrains the response shape with a forced tool call: apply_structured_output() registers a synthetic respond_with_structured_output tool whose input_schema is the requested model’s JSON schema, and sets tool_choice to require that tool. The API then guarantees the tool input matches the schema. Flux surfaces the tool input as the final answer text, which the agent loop validates with response_format.model_validate_json().
Because the forced tool call commandeers the tools and tool_choice request fields, structured output is mutually exclusive with caller-supplied tool use; the agent loop only applies it when no tools are configured. Forced tool use is also incompatible with extended thinking, so Flux drops the thinking and output_config fields when structured output is active.
What can go wrong
- Authentication errors —
anthropic.AuthenticationErrorfrom a missing or invalidANTHROPIC_API_KEY. The request never reaches Flux’s retry path; configure the key before starting the worker. - Rate limits — 429s surface as
anthropic.RateLimitError. Wrap the agent task withtask.with_options(retry_max_attempts=5, retry_delay=2, retry_backoff=2)to let Flux’s retry mechanism back off automatically. - Model name typos —
claude-sonet-...lands as an HTTP 400 from Anthropic, not a Flux error. The model string is only validated for the presence of/. - Token cap reached — when the response would exceed
max_tokens, Anthropic truncates the output and the response’sstop_reasonismax_tokens. Flux returns the truncated text. Tunemax_tokensif your outputs are getting cut. response_formatvalidation failures — the API enforces the schema via the forced tool call, but Pydantic’s localmodel_validate_json()still runs. A schema that disagrees with the runtime model raisespydantic.ValidationErroron the way out.
See also
- Choosing a provider — capability matrix across all four providers.
- Reasoning models —
reasoning_effortcost and latency comparison. - Tools and structured output — combining tools with
response_format. - Anthropic API docs — model identifiers, rate limits, and pricing.