Providers · 03
Anthropic Provider
The Anthropic provider connects to Claude models via the Anthropic API.
Installation
Add the Anthropic gem to your Gemfile:
gem 'anthropic'
Configuration
Configure your Anthropic API key:
Riffer.configure do |config|
config.anthropic.api_key = ENV['ANTHROPIC_API_KEY']
end
For anything beyond the API key — timeouts, retries, proxies — supply your own Anthropic::Client:
Riffer.configure do |config|
config.anthropic.client = Anthropic::Client.new(
api_key: ENV['ANTHROPIC_API_KEY'],
timeout: 60
)
end
The setting accepts a client instance or a no-argument Proc, resolved on every LLM call — see Configuration → Provider Clients.
Supported Models
Use Anthropic model IDs in the anthropic/model format:
model 'anthropic/claude-haiku-4-5-20251001'
model 'anthropic/claude-sonnet-4-5-20250929'
model 'anthropic/claude-opus-4-5-20251101'
Model Options
temperature
Controls randomness:
model_options temperature: 0.7
max_tokens
Maximum tokens in response:
model_options max_tokens: 4096
top_p
Nucleus sampling parameter:
model_options top_p: 0.95
top_k
Top-k sampling parameter:
model_options top_k: 250
thinking
Enable extended thinking (reasoning) for supported models. Pass the thinking configuration hash directly as Anthropic expects:
# Enable with budget tokens
model_options thinking: {type: "enabled", budget_tokens: 10000}
web_search
Enable server-side web search using Anthropic’s web_search_20250305 tool. Pass true to use defaults or a hash to merge with the tool definition:
# Enable with defaults
model_options web_search: true
# With custom configuration
model_options web_search: {max_uses: 3}
Example
Riffer.configure do |config|
config.anthropic.api_key = ENV['ANTHROPIC_API_KEY']
end
class AssistantAgent < Riffer::Agent
model 'anthropic/claude-haiku-4-5-20251001'
instructions 'You are a helpful assistant.'
model_options temperature: 0.7, max_tokens: 4096
end
agent = AssistantAgent.new
puts agent.generate("Explain quantum computing")
Streaming
agent.stream("Tell me about Claude models").each do |event|
case event
when Riffer::StreamEvents::TextDelta
print event.content
when Riffer::StreamEvents::TextDone
puts "\n[Complete]"
when Riffer::StreamEvents::ReasoningDelta
print "[Thinking] #{event.content}"
when Riffer::StreamEvents::ReasoningDone
puts "\n[Thinking Complete]"
when Riffer::StreamEvents::ToolCallDone
puts "[Tool: #{event.name}]"
end
end
Tool Calling
Anthropic provider converts tools to the Anthropic tool format:
class WeatherTool < Riffer::Tool
description "Gets the current weather for a location"
params do
required :city, String, description: "The city name"
optional :unit, String, description: "Temperature unit (celsius or fahrenheit)"
end
def call(context:, city:, unit: "celsius")
# Implementation
text("It's 22 degrees #{unit} in #{city}")
end
end
class WeatherAgent < Riffer::Agent
model 'anthropic/claude-haiku-4-5-20251001'
uses_tools [WeatherTool]
end
Extended Thinking
Extended thinking enables Claude to reason through complex problems before responding. This is available on supported models (Claude 3.7+).
class ReasoningAgent < Riffer::Agent
model 'anthropic/claude-haiku-4-5-20251001'
model_options thinking: {type: "enabled", budget_tokens: 10000}
end
When streaming with extended thinking enabled, you’ll receive ReasoningDelta events containing the model’s thought process, followed by a ReasoningDone event when thinking completes:
agent.stream("Solve this complex math problem").each do |event|
case event
when Riffer::StreamEvents::ReasoningDelta
# Model's internal reasoning
print "[Thinking] #{event.content}"
when Riffer::StreamEvents::ReasoningDone
puts "\n[Thinking complete]"
when Riffer::StreamEvents::TextDelta
# Final response
print event.content
end
end
Web Search
Web search allows Claude to search the web for up-to-date information. When enabled, the provider injects the web_search_20250305 server tool into the request.
class SearchAgent < Riffer::Agent
model 'anthropic/claude-haiku-4-5-20251001'
model_options web_search: true
end
agent = SearchAgent.new
agent.stream("What happened in tech news today?").each do |event|
case event
when Riffer::StreamEvents::WebSearchStatus
puts "[search: #{event.status}]"
puts " query: #{event.query}" if event.query
when Riffer::StreamEvents::WebSearchDone
puts "[search complete: #{event.query}]"
event.sources.each { |s| puts " - #{s[:title]}: #{s[:url]}" }
when Riffer::StreamEvents::TextDelta
print event.content
end
end
Anthropic emits sources with title and url on the WebSearchDone event.
Message Format
The provider converts Riffer messages to Anthropic format:
| Riffer Message | Anthropic Format |
|---|---|
System |
Added to system array as {type: "text", text: ...} |
User |
{role: "user", content: "..."} |
Assistant |
{role: "assistant", content: [...]} with text/tool_use blocks |
Tool |
{role: "user", content: [{type: "tool_result", ...}]} |
Direct Provider Usage
provider = Riffer::Providers::Anthropic.new
response = provider.generate_text(
prompt: "Hello!",
model: "claude-haiku-4-5-20251001",
temperature: 0.7
)
puts response.content
With extended thinking:
response = provider.generate_text(
prompt: "Explain step by step how to solve a Rubik's cube",
model: "claude-haiku-4-5-20251001",
thinking: { type: "enabled", budget_tokens: 10000 }
)
puts response.content