DEV Community

Michael Smith
Michael Smith

Posted on

RubyLLM: A Ruby AI Framework for All Major Providers

RubyLLM: A Ruby AI Framework for All Major Providers

Meta Description: Discover RubyLLM, the Ruby framework connecting all major AI providers in one elegant gem. Build smarter Ruby apps with OpenAI, Anthropic, Gemini & more.


TL;DR: RubyLLM is an open-source Ruby gem that gives developers a single, clean API to interact with all major AI providers — OpenAI, Anthropic, Google Gemini, and others — without juggling multiple SDKs. If you're building AI-powered Ruby or Rails applications, RubyLLM dramatically reduces boilerplate, standardizes error handling, and keeps your codebase maintainable as the AI landscape evolves.


Key Takeaways

  • One gem, all providers: RubyLLM abstracts OpenAI, Anthropic, Google Gemini, and other LLMs behind a unified interface
  • Rails-friendly: Designed with ActiveRecord integration and Rails conventions in mind
  • Streaming support: Built-in token streaming for real-time AI responses
  • Tool/function calling: Native support for AI tool use across providers
  • Actively maintained: Regular updates tracking the fast-moving AI provider landscape
  • Production-ready: Used in real Rails applications, not just a hobby project

What Is RubyLLM and Why Does It Matter?

If you've spent any time building AI features into Ruby applications, you know the pain. OpenAI has its SDK. Anthropic has its own. Google's Gemini requires yet another client library. Each has different authentication patterns, different response formats, different error types, and different streaming implementations. Switching providers — or even A/B testing them — means rewriting significant chunks of your integration code.

RubyLLM: A Ruby framework for all major AI providers solves this problem elegantly. Rather than maintaining separate integrations for each LLM provider, RubyLLM gives you one consistent, idiomatic Ruby API that works across the board.

Think of it like ActiveRecord for databases. You don't write PostgreSQL-specific SQL when you're using Rails — you write ActiveRecord queries and let the adapter handle the translation. RubyLLM does the same thing for AI providers.

# Without RubyLLM - OpenAI specific
client = OpenAI::Client.new
response = client.chat(
  parameters: {
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello!" }]
  }
)

# With RubyLLM - works with any provider
response = RubyLLM.chat("Hello!", model: "gpt-4o")
Enter fullscreen mode Exit fullscreen mode

That's the promise. Let's dig into whether it delivers.


How RubyLLM Works: Core Architecture

The Provider Abstraction Layer

RubyLLM's architecture centers on a provider abstraction layer. Each supported AI service has an adapter that translates the framework's standardized request format into whatever the provider's API actually expects, then normalizes the response back into a consistent structure.

This means your application code stays stable even when:

  • A provider changes their API (RubyLLM updates the adapter)
  • You want to switch from GPT-4o to Claude Sonnet (change one line)
  • You're testing which model performs better for your use case

Supported Providers (as of mid-2026)

Provider Models Supported Streaming Tool Calling Vision
OpenAI GPT-4o, GPT-4o-mini, o3, o4-mini
Anthropic Claude 3.5, Claude 3.7 Sonnet/Opus
Google Gemini Gemini 1.5 Pro/Flash, Gemini 2.0
Ollama Local models (Llama, Mistral, etc.) ⚠️
OpenAI-compatible Together AI, Groq, etc. Varies

Note: Provider support and model availability evolve rapidly. Always check the RubyLLM GitHub repository for the current compatibility matrix.


Getting Started with RubyLLM

Installation

Add it to your Gemfile:

gem 'ruby_llm'
Enter fullscreen mode Exit fullscreen mode

Then run bundle install. That's it — no complex dependencies.

Basic Configuration

RubyLLM.configure do |config|
  config.openai_api_key = ENV['OPENAI_API_KEY']
  config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
  config.gemini_api_key = ENV['GEMINI_API_KEY']
end
Enter fullscreen mode Exit fullscreen mode

You only need to configure the providers you actually use. Unused providers simply won't be available.

Your First Chat Completion

# Simple one-shot completion
response = RubyLLM.chat("What's the capital of France?")
puts response.content  # => "The capital of France is Paris."

# With a specific provider and model
response = RubyLLM.chat(
  "Explain quantum entanglement simply",
  model: "claude-3-7-sonnet-20250219",
  provider: :anthropic
)

# Multi-turn conversation
chat = RubyLLM::Chat.new(model: "gpt-4o")
chat.ask("What's the best way to learn Ruby?")
chat.ask("Can you give me a specific 30-day plan?")
Enter fullscreen mode Exit fullscreen mode

The API is genuinely clean. If you've written Ruby for any length of time, this feels natural immediately.


Key Features That Make RubyLLM Worth Using

1. Streaming Responses

Nobody wants to stare at a spinner for 15 seconds waiting for a complete AI response. RubyLLM's streaming support lets you deliver tokens to users as they're generated:

RubyLLM.chat("Write me a short story") do |chunk|
  print chunk.content
  $stdout.flush
end
Enter fullscreen mode Exit fullscreen mode

In a Rails application with ActionCable or Server-Sent Events, this becomes the foundation for ChatGPT-style streaming interfaces. The implementation is consistent across providers — you write the streaming code once.

2. Tool Calling (Function Calling)

Tool calling is where AI gets genuinely useful for complex applications. RubyLLM provides a clean DSL for defining tools that AI models can invoke:

class WeatherTool < RubyLLM::Tool
  name "get_weather"
  description "Get current weather for a location"

  param :location, type: :string, description: "City name", required: true
  param :units, type: :string, description: "celsius or fahrenheit"

  def call(location:, units: "celsius")
    # Your actual weather API call here
    WeatherService.fetch(location, units)
  end
end

chat = RubyLLM::Chat.new(model: "gpt-4o", tools: [WeatherTool])
response = chat.ask("What's the weather in Berlin right now?")
Enter fullscreen mode Exit fullscreen mode

The model decides when to call the tool, calls it with appropriate parameters, and incorporates the result into its response. RubyLLM handles the back-and-forth automatically.

3. Rails and ActiveRecord Integration

This is where RubyLLM really shines for Rails developers. The gem includes optional Rails integration that lets you persist conversations to your database with minimal setup:

# In your migration
create_table :chats do |t|
  t.string :model
  t.timestamps
end

create_table :messages do |t|
  t.references :chat
  t.string :role
  t.text :content
  t.timestamps
end

# In your models
class Chat < ApplicationRecord
  acts_as_chat
end

class Message < ApplicationRecord
  acts_as_message
end

# Usage
chat = Chat.create!(model: "gpt-4o")
chat.ask("Tell me about Ruby on Rails")
chat.messages  # => Persisted Message records
Enter fullscreen mode Exit fullscreen mode

For anyone building a customer support bot, coding assistant, or any application where conversation history matters, this integration saves hours of boilerplate work.

4. Vision and Multimodal Support

Modern AI isn't just text. RubyLLM handles image inputs across providers that support them:

response = RubyLLM.chat([
  { type: :text, text: "What's in this image?" },
  { type: :image, url: "https://example.com/photo.jpg" }
], model: "gpt-4o")
Enter fullscreen mode Exit fullscreen mode

The same code structure works whether you're sending to GPT-4o, Claude, or Gemini — each of which has slightly different underlying API requirements that RubyLLM abstracts away.


RubyLLM vs. Alternatives: Honest Comparison

[INTERNAL_LINK: Ruby AI libraries comparison]

vs. Using Provider SDKs Directly

Aspect Direct SDKs RubyLLM
Setup complexity High (multiple gems) Low (one gem)
Provider switching Major refactor One line change
Streaming consistency Varies by provider Unified API
Maintenance burden High Shared with community
Control/flexibility Maximum Very high (escape hatches exist)
Learning curve Per-provider Once

Verdict: Unless you're doing something extremely provider-specific, RubyLLM wins on developer productivity.

vs. Langchain.rb

Langchain.rb is another popular Ruby AI framework. The key differences:

  • Langchain.rb is more opinionated and feature-rich (agents, RAG pipelines, vector stores)
  • RubyLLM is more focused and lightweight, prioritizing clean LLM interaction over a full AI application framework
  • If you need RAG or complex agent workflows, Langchain.rb may be better suited
  • If you want clean LLM access with Rails integration, RubyLLM is more elegant

They're not mutually exclusive — some teams use RubyLLM for direct LLM calls while using other tools for vector search and retrieval.


Real-World Use Cases

Customer Support Automation

A typical Rails-based support app might use RubyLLM to:

  1. Classify incoming tickets by category and urgency
  2. Generate draft responses for human review
  3. Maintain conversation context across sessions (via ActiveRecord integration)
  4. Switch to a cheaper/faster model for simple queries, premium model for complex ones

Code Review Assistance

class CodeReviewer
  def review(pull_request_diff)
    RubyLLM.chat(
      "Review this code diff and identify potential bugs, security issues, and style problems:\n\n#{pull_request_diff}",
      model: "claude-3-7-sonnet-20250219",
      system: "You are an expert Ruby developer focused on security and maintainability."
    )
  end
end
Enter fullscreen mode Exit fullscreen mode

Content Generation Pipelines

For teams generating content at scale, RubyLLM's provider flexibility means you can route different content types to the most cost-effective model — GPT-4o-mini for short descriptions, Claude for long-form content, Gemini Flash for bulk processing.

[INTERNAL_LINK: AI content generation with Ruby]


Performance and Production Considerations

Rate Limiting and Error Handling

RubyLLM includes built-in retry logic and standardized error types:

begin
  response = RubyLLM.chat("Hello!", model: "gpt-4o")
rescue RubyLLM::RateLimitError => e
  # Handle rate limiting
rescue RubyLLM::AuthenticationError => e
  # Handle auth issues
rescue RubyLLM::ProviderError => e
  # Handle general provider errors
end
Enter fullscreen mode Exit fullscreen mode

Having consistent error classes across providers is genuinely valuable — you write error handling once.

Cost Management

One underappreciated benefit of the abstraction layer: you can implement routing logic to optimize costs:

def choose_model(task_complexity)
  case task_complexity
  when :simple then "gpt-4o-mini"
  when :moderate then "claude-3-5-haiku"
  when :complex then "claude-3-7-sonnet-20250219"
  end
end
Enter fullscreen mode Exit fullscreen mode

[INTERNAL_LINK: AI API cost optimization strategies]

Caching Considerations

RubyLLM doesn't include built-in response caching (by design — it's not the framework's responsibility). For production applications, pair it with Redis for caching identical or similar requests, which can dramatically reduce API costs.


Honest Assessment: Limitations to Know About

No tool is perfect. Here's what to be aware of:

The good:

  • Excellent Rails integration
  • Clean, idiomatic Ruby API
  • Active maintenance and community
  • Solid documentation

The limitations:

  • Smaller ecosystem than Python's LangChain — fewer pre-built integrations
  • Provider parity isn't perfect — some advanced features of specific providers may not be exposed
  • Escape hatches exist but aren't always obvious — for very provider-specific features, you may need to drop down to the raw HTTP layer
  • Community size — the Python AI ecosystem dwarfs Ruby's, so finding answers to edge cases requires more digging

If your team is Python-first, the Python ecosystem genuinely has more mature AI tooling. But if you're a Ruby/Rails shop, RubyLLM is currently the most polished option available.


Getting Help and Contributing

  • GitHub: github.com/crmne/ruby_llm
  • Documentation: Comprehensive README with examples
  • Issues: Active issue tracker with responsive maintainers
  • Contributing: Well-documented contribution guide if you want to add provider support

The project welcomes contributions, particularly around new provider adapters and model updates.


Should You Use RubyLLM?

Use RubyLLM if:

  • You're building a Rails application with AI features
  • You want provider flexibility without code rewrites
  • You value clean, maintainable Ruby code
  • You're integrating conversational AI with database persistence

Consider alternatives if:

  • You need complex RAG pipelines (look at Langchain.rb or build custom)
  • You're doing one-off scripts where a direct SDK is simpler
  • You need maximum access to provider-specific experimental features

Start Building with RubyLLM Today

The best way to evaluate RubyLLM is to build something with it. Start with a simple prototype — a chatbot, a content classifier, a code reviewer. The installation takes minutes, and the clean API means you'll have something working quickly.

gem install ruby_llm
Enter fullscreen mode Exit fullscreen mode

Check out the official RubyLLM repository for the latest documentation, and join the Ruby AI community on Discord to connect with other developers building similar applications.

[INTERNAL_LINK: Getting started with AI in Ruby on Rails]


Frequently Asked Questions

Q: Is RubyLLM free to use?
A: RubyLLM itself is open-source and free. You'll pay the API costs of whichever AI provider you connect to (OpenAI, Anthropic, Google, etc.) based on their standard pricing.

Q: Does RubyLLM work with local models like Ollama?
A: Yes. RubyLLM supports Ollama for running models locally, which is useful for development, privacy-sensitive applications, or cost reduction. Performance depends on your hardware.

Q: How does RubyLLM handle breaking changes from AI providers?
A: The maintainers update provider adapters when APIs change. This is one of the core value propositions — you update the gem version rather than hunting through your codebase for provider-specific code. That said, major provider changes can cause temporary lag before the gem catches up.

Q: Can I use RubyLLM without Rails?
A: Absolutely. RubyLLM works in plain Ruby applications. The Rails/ActiveRecord integration is opt-in. The core gem has no Rails dependency.

Q: How does RubyLLM compare to using the OpenAI Ruby gem directly?
A: If you're certain you'll only ever use OpenAI and need access to every cutting-

Top comments (0)