Skip to content

Anthropic Provider ​

The Anthropic provider enables integration with Claude models including Claude Sonnet 4.5, Claude Haiku 4.5, Claude Opus 4.1, and the Claude 3.x family. It offers advanced reasoning capabilities, extended context windows, extended thinking mode, and strong performance on complex tasks.

Configuration ​

Basic Setup ​

Configure Anthropic in your agent:

ruby
class AnthropicAgent < ApplicationAgent
  generate_with :anthropic, model: "claude-sonnet-5"

  # @return [ActiveAgent::Generation]
  def ask
    prompt(message: params[:message])
  end
end

Basic Usage Example ​

ruby
response = AnthropicAgent.with(
  message: "What is the Model Context Protocol?"
).ask.generate_now
Response Example

Configuration File ​

Set up Anthropic credentials in config/active_agent.yml:

yaml
anthropic: &anthropic
  service: "Anthropic"
  access_token: <%= Rails.application.credentials.dig(:anthropic, :access_token) %>

Environment Variables ​

Alternatively, use environment variables:

bash
ANTHROPIC_API_KEY=your-api-key

Supported Models ​

Anthropic provides access to the Claude model family. For the complete list of available models, see Anthropic's Models Overview.

Claude 4.x Family (Latest) ​

FeatureClaude Sonnet 4.5Claude Haiku 4.5Claude Opus 4.1
DescriptionSmartest model for complex agents and codingFastest model with near-frontier intelligenceExceptional model for specialized reasoning
Pricing$3 / MTok input
$15 / MTok output
$1 / MTok input
$5 / MTok output
$15 / MTok input
$75 / MTok output
Extended Thinking✓✓✓
Priority Tier✓✓✓
LatencyFastFastestModerate
Context Window200K tokens
1M tokens (beta)
200K tokens200K tokens
Max Output64K tokens64K tokens32K tokens
Knowledge CutoffJan 2025Feb 2025Jan 2025
Training DataJul 2025Jul 2025Mar 2025

Recommended model identifiers:

  • claude-sonnet-4.5 - Best for complex reasoning and coding tasks
  • claude-haiku-4.5 - Best for speed with high intelligence
  • claude-opus-4.1 - Best for specialized reasoning tasks requiring deep analysis

Claude 3.5 Family ​

  • claude-3-5-sonnet-latest - Most intelligent Claude 3.5 model
  • claude-3-5-sonnet-20241022 - Specific version for reproducibility

Claude 3 Family ​

  • claude-3-opus-latest - Most capable Claude 3 model
  • claude-3-sonnet-20240229 - Balanced performance and cost
  • claude-3-haiku-20240307 - Fastest and most cost-effective

Provider-Specific Parameters ​

Required Parameters ​

  • model - Model identifier (e.g., "claude-3-5-sonnet-latest")
  • max_tokens - Maximum tokens to generate (default: 4096, minimum: 1)

Sampling Parameters ​

  • temperature - Controls randomness (0.0 to 1.0, default: varies by model)
  • top_p - Nucleus sampling parameter (0.0 to 1.0)
  • top_k - Top-k sampling parameter (integer ≥ 0)
  • stop_sequences - Array of strings to stop generation

System & Instructions ​

  • system - System message to guide Claude's behavior
  • instructions - Alias for system (for common format compatibility)

Tools & Functions ​

  • tools - Array of tool definitions for function calling
  • tool_choice - Control which tools can be used ("auto", "any", or specific tool)

Metadata & Tracking ​

  • metadata - Custom metadata for request tracking
    ruby
    generate_with :anthropic,
      metadata: {
        user_id: -> { Current.user&.id }
      }

Advanced Features ​

  • thinking - Enable Claude's thinking mode for complex reasoning (a json_object request with thinking is sent without its lead-in; see Emulated JSON Object Support)
  • context_management - Configure context window management
  • service_tier - Select service tier ("auto", "standard_only")
  • mcps - Array of MCP server definitions (max 20)

Client Configuration ​

  • api_key - Anthropic API key (also accepts access_token)
  • base_url - API endpoint URL (default: "https://api.anthropic.com")
  • timeout - Request timeout in seconds (default: 600.0)
  • max_retries - Maximum retry attempts (default: 2)
  • anthropic_beta - Enable beta features via header

Response Format ​

Streaming ​

  • stream - Enable streaming responses (boolean, default: false)

JSON Schema Support ​

ActiveAgent maps response_format: :json_schema (or the hash form) to Anthropic's native output_config.format API. JSON Schema Hashes are passed through as-is; ActiveAgent does not convert them to Anthropic::BaseModel.

Usage ​

ruby
class ColorsAgent < ApplicationAgent
  generate_with :anthropic, model: "claude-haiku-4-5"

  def primary_colors
    prompt(
      "Return the three primary colors.",
      response_format: :json_schema
    )
  end
end

Place a schema file at app/views/agents/colors_agent/primary_colors.json:

json
{
  "schema": {
    "type": "object",
    "properties": {
      "colors": { "type": "array", "items": { "type": "string" } }
    },
    "required": ["colors"],
    "additionalProperties": false
  }
}

ActiveAgent serializes the request as:

ruby
{
  output_config: {
    format: {
      type: "json_schema",
      schema: { ... }
    }
  }
}

Notes ​

  • name and strict from the common format are not forwarded; Anthropic's output_config.format does not use them.

  • additionalProperties: false is added when missing. Anthropic requires it on object schemas; an explicit value is preserved.

  • output_config keys are preserved. A schema derived from response_format is merged with your settings, which take precedence:

    ruby
    prompt(
      "Return the three primary colors.",
      response_format: :json_schema,
      output_config: { effort: "high" }
    )
  • JSON Schema support availability depends on model version. Check Anthropic's documentation for supported models.

  • json_object remains prompt-emulated; Anthropic's native output format requires a JSON Schema.

Emulated JSON Object Support ​

Anthropic has no schema-less JSON mode like OpenAI's json_object, so ActiveAgent emulates response_format: { type: "json_object" }. Whether the request carries a prefilled answer depends on the model and on thinking.

Models That Accept a Prefill ​

Claude Haiku 4.5, Sonnet 4.5, Opus 4.5, Opus 4.1, Opus 4, Sonnet 4 and the Claude 3 family accept a prefilled assistant response. For these models, with thinking off (thinking unset or { type: "disabled" }), the framework:

  1. Adds a lead-in assistant message containing "Here is the JSON requested:\n{" to prime Claude to output JSON
  2. Receives Claude's response which continues from the opening brace
  3. Reconstructs the complete JSON by prepending the { character
  4. Removes the lead-in message from the message stack for clean conversation history

The models are recognised in their Anthropic (claude-sonnet-4-5, claude-sonnet-4-5-20250929, claude-3-5-sonnet-latest), Amazon Bedrock (us.anthropic.claude-sonnet-4-5-20250929-v1:0) and Vertex AI (claude-sonnet-4-5@20250929) ids.

Usage Example ​

ruby
class DataExtractionAgent < ApplicationAgent
  generate_with :anthropic, model: "claude-haiku-4-5"

  def extract_colors
    prompt(
      "Return a JSON object with three primary colors in an array named 'colors'.",
      response_format: { type: "json_object" }
    )
  end
end
ruby
response = DataExtractionAgent.extract_colors.generate_now
colors = response.message.parsed_json # Parsed JSON hash
# => { colors: ["red", "blue", "yellow"] }

Every Other Request ​

Later models, from Claude Opus 4.6 and Sonnet 4.6 on (Opus 5, Sonnet 5 and Fable 5 among them), refuse a prefilled response with or without thinking, and no model accepts one while thinking is on. So a request for one of those models, for a model id the framework does not recognise, or with thinking set to anything but { type: "disabled" } (a manual { type: "enabled", budget_tokens: ... } budget or { type: "adaptive" }) is sent without the lead-in. The framework:

  1. Sends the conversation as written, so the request ends on your message
  2. Reads the JSON from Claude's answer: parsed_json takes the text from the first { or [ to the last } or ], so an object inside a Markdown code fence parses too

Streamed requests behave the same way. Nothing but your prompt asks for JSON here, so ask for it explicitly:

ruby
class ColorsAgent < ApplicationAgent
  generate_with :anthropic, model: "claude-sonnet-5"

  def primary_colors
    prompt(
      "Return a JSON object with the three primary colors in an array named 'colors'.",
      response_format: :json_object
    )
  end
end

Retries ​

When parsed_json cannot parse the answer, the request is sent again:

  • With the lead-in, the unparseable answer stays in the conversation and a new lead-in follows it
  • Without it, the unparseable answer is dropped and the same request is repeated, because a request that ended on that answer would be a prefill

When the retries run out, the last answer is returned and parsed_json returns nil.

Best Practices ​

  • Be explicit in your prompt: Ask Claude to "return a JSON object" or "respond with valid JSON"
  • Specify the schema: Describe the expected structure in your prompt for better results
  • Validate the output: While Claude is reliable, always validate parsed JSON in production

Limitations ​

Unlike OpenAI's native JSON mode:

  • No schema enforcement: Claude is not forced to conform to a specific schema
  • Prompt-dependent reliability: Success depends on clear prompt instructions
  • No strict mode: Cannot guarantee specific field requirements

For applications requiring guaranteed schema conformance, use the Structured Output feature with response_format: :json_schema. Anthropic natively supports JSON schema validation via output_config.format on supported Claude models.

Constitutional AI ​

Claude is trained with Constitutional AI, making it particularly good at:

  • Following ethical guidelines
  • Refusing harmful requests
  • Providing balanced perspectives
  • Being helpful, harmless, and honest

Error Handling ​

Handle Anthropic-specific errors:

ruby
class ResilientAgent < ApplicationAgent
  generate_with :anthropic,
    model: "claude-3-5-sonnet-latest",
    max_retries: 3

  rescue_from Anthropic::RateLimitError do |error|
    Rails.logger.warn "Rate limited: #{error.message}"
    sleep(error.retry_after || 60)
    retry
  end

  rescue_from Anthropic::APIError do |error|
    Rails.logger.error "Anthropic error: #{error.message}"
    fallback_to_cached_response
  end
end