Anthropic
The Anthropic provider (rig::providers::anthropic) connects Rig to Claude through Anthropic’s Messages API. The same client also reaches vendors that serve an Anthropic-format endpoint (MiniMax, Moonshot, Xiaomi MiMo, Z.AI).
Capabilities
Section titled “Capabilities”| Capability | Supported | Notes |
|---|---|---|
| Completion | Yes | client.completion(id); max_tokens defaults to the model’s output limit |
| Streaming | Yes | agent.prompt(p).stream(), or model.stream(request) |
| Tools | Yes | Any Rig tool; strict tool schemas with with_strict_tools() |
| Structured output | Yes | Extractors and output_schema |
| Image and PDF input | Yes | Image and document content blocks |
| Extended thinking | Yes | GenerationOptions::reasoning; thinking blocks are kept across turns |
| Prompt caching | Yes | CacheRetention, or explicit breakpoints with with_prompt_caching() |
| Embeddings | No | Pair Claude with another provider’s embedding model, such as OpenAI or Voyage AI |
Basic usage
Section titled “Basic usage”use rig::prelude::*;use rig::providers::anthropic::{self, Anthropic};
// Reads ANTHROPIC_API_KEY (and ANTHROPIC_BASE_URL, if set).let client = Anthropic::from_env()?;
let agent = AgentBuilder::new(client.completion(anthropic::CLAUDE_SONNET_5_5)) .preamble("You are a helpful assistant.") .build();
let answer = agent.prompt("Hello!").await?.output();println!("{answer}");Anthropic requires max_tokens on every request. For a model Rig knows, it defaults to that model’s output limit, so you only set .max_tokens(n) (on the agent builder or the request) to cap it. A model id Rig doesn’t know has no default: set max_tokens yourself, or give the model a default with model.wire = model.wire.with_default_max_tokens(n). A request without one fails before it is sent.
Configuring the client
Section titled “Configuring the client”use rig::providers::anthropic::{Anthropic, AnthropicConfig};use rig::providers::anthropic::extension::CONTEXT_MANAGEMENT_BETA;
// From ANTHROPIC_API_KEY and the optional ANTHROPIC_BASE_URL.let client = Anthropic::from_env()?;
// From an explicit key.let client = Anthropic::new("your-api-key");
// From a configuration: pin the API version, opt into beta features,// or point at another API root.let client = AnthropicConfig::new("your-api-key") .with_version("2023-06-01") .with_beta(CONTEXT_MANAGEMENT_BETA) .with_base_url("https://anthropic-proxy.example.com") .client();The anthropic-version header defaults to ANTHROPIC_VERSION_LATEST (2023-06-01). Beta flags are sent in anthropic-beta; the extension module exports constants for the betas its options need (FAST_MODE_BETA, TASK_BUDGETS_BETA, CONTEXT_MANAGEMENT_BETA, MCP_CLIENT_BETA, …).
For a vendor’s Anthropic-format endpoint, use its module: minimax::anthropic_from_env()?, moonshot::anthropic_from_env()?, xiaomimimo::anthropic_from_env()?, zai::anthropic_from_env()?. Each returns an Anthropic client.
Models
Section titled “Models”The module exports constants for Claude models, such as anthropic::CLAUDE_OPUS_5_5, anthropic::CLAUDE_SONNET_5_5, anthropic::CLAUDE_FABLE_5_1 and anthropic::CLAUDE_HAIKU_4_5. Any model id string works too. client.list_models().await? lists the models your key can use, and client.verify().await? checks the key.
Extended thinking
Section titled “Extended thinking”Set reasoning with the provider-neutral reasoning option. Rig translates it into the shape the model takes: adaptive thinking with an effort level on newer models, or a thinking token budget on older ones.
use rig::completion::{Effort, Reasoning};use rig::prelude::*;use rig::providers::anthropic::{self, Anthropic};
let client = Anthropic::from_env()?;
// An effort level, for models that take one.let agent = AgentBuilder::new(client.completion(anthropic::CLAUDE_OPUS_4_8)) .reasoning(Effort::High) .build();
// An explicit thinking budget, for models that take one.let budgeted = AgentBuilder::new(client.completion(anthropic::CLAUDE_HAIKU_4_5)) .reasoning(Reasoning::Budget { tokens: 8_000 }) .build();Claude has no Effort::Minimal, and a model that can’t take the form you asked for fails the request with ProviderError::UnsupportedOption (use .on_unsupported(OnUnsupported::Ignore) to skip it instead). Thinking and redacted-thinking blocks come back as reasoning content and are sent back with their signatures on the next turn, so multi-turn tool use keeps working.
Prompt caching
Section titled “Prompt caching”There are two ways to cache with Anthropic.
Automatic caching with CacheRetention. Setting cache sends a top-level cache_control marker, and Anthropic caches the prompt up to the last cacheable block. Short is the five-minute cache, Long the one-hour cache:
use rig::completion::CacheRetention;use rig::prelude::*;use rig::providers::anthropic::{self, Anthropic};
let agent = AgentBuilder::new(Anthropic::from_env()?.completion(anthropic::CLAUDE_SONNET_5_5)) .preamble("A long, stable system prompt...") .cache(CacheRetention::Short) .build();Explicit breakpoints on the model. with_prompt_caching() places cache_control breakpoints on the system prompt, the last tool definition, and the last content block of the conversation. with_static_prefix_cache_ttl caches the tools and system prompt for longer than the conversation tail:
use rig::completion::CacheRetention;use rig::prelude::*;use rig::providers::anthropic::{self, Anthropic, completion::CacheTtl};
let mut model = Anthropic::from_env()?.completion(anthropic::CLAUDE_SONNET_5_5);model.wire = model .wire .with_prompt_caching() .with_static_prefix_cache_ttl(CacheTtl::OneHour);
let agent = AgentBuilder::new(model) .preamble("A long, stable system prompt...") .cache(CacheRetention::Long) // the conversation tail's TTL .build();One-hour markers must come before five-minute ones, so a five-minute static prefix under CacheRetention::Long fails when the request is built. Each cached prefix must meet the model’s minimum cacheable length.
Cache activity shows up on the response’s Usage, the same fields every provider fills:
| Field | Meaning |
|---|---|
input_tokens | All input tokens, including cache reads and writes |
cached_input_tokens | The part of input_tokens read from the cache |
cache_creation_input_tokens | The part of input_tokens written to the cache |
output_tokens | All output tokens, thinking included |
The per-lifetime split of cache writes (five-minute vs one-hour) is in the reply extras below.
Anthropic-only options and reply fields
Section titled “Anthropic-only options and reply fields”Fields only Anthropic’s own API takes are typed in anthropic::extension::AnthropicOptions: top_k, metadata_user_id, inference_geo, speed (fast mode), task_budget, fallbacks, container (skills), context_management and mcp_server (the MCP connector). Several need a beta flag on the client, noted on each field. The options are only sent to Anthropic itself, never to an Anthropic-format gateway.
use rig::prelude::*;use rig::providers::anthropic::extension::{AnthropicOptions, InferenceGeo};use rig::providers::anthropic::{self, Anthropic};
let options = AnthropicOptions::default() .metadata_user_id("user-7") .inference_geo(InferenceGeo::Us);
let agent = AgentBuilder::new(Anthropic::from_env()?.completion(anthropic::CLAUDE_SONNET_5_5)) .provider_option(options) .build();The reply fields only Anthropic returns (stop_reason, stop_details, cache_creation, service_tier, inference_geo, speed, server tool usage, container, fallback_model) are read with extras::<AnthropicExt>():
use rig::completion::CompletionRequest;use rig::providers::anthropic::extension::AnthropicExt;use rig::providers::anthropic::{self, Anthropic};
let model = Anthropic::from_env()?.completion(anthropic::CLAUDE_HAIKU_4_5);let response = model.call(CompletionRequest::new("Say hi.")).await?;
println!("{}", response.text());println!("cache reads: {:?}", response.usage.cached_input_tokens);if let Some(Ok(extras)) = response.extras::<AnthropicExt>() { println!("stop reason: {:?}", extras.stop_reason);}ServiceTier::Auto and ServiceTier::Default map to Anthropic’s auto and standard_only tiers; Anthropic has no flex or priority-only tier.
Claude calls any tool you register on an agent. Rig converts tool definitions to Anthropic’s format and parses tool_use blocks back into Rig’s tool calls. model.wire.with_strict_tools() asks Anthropic to hold every tool call to its schema. See Tools.
See also
Section titled “See also”- Model Providers: every provider and the shared patterns
- Agents and Tools
- Completions
