RubyLLM: A Ruby LLM Framework for Every Provider
RubyLLM gives Ruby developers one chat API for OpenAI, Anthropic, Gemini, xAI, Bedrock, Ollama, and other providers, so switching models means changing a string, not rewriting client code. It backs that with tool calling, agents, structured output, and embeddings, built on just three dependencies: Faraday, Zeitwerk, and Marcel. Reach for it in a Ruby or Rails app that wants that flexibility; skip it if your stack isn't Ruby at all.
What is RubyLLM?
RubyLLM is a Ruby framework and gem for building AI features — chats, agents, tools, and multi-step workflows — behind one interface instead of a different client per provider. It talks to OpenAI, xAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible endpoint, per its README, and ships with a Rails-friendly acts_as_chat integration for persisting conversations.
Core Capabilities
- ✓Unified chat API — RubyLLM.chat and chat.ask — that works the same across OpenAI, xAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible endpoint, per the README.
- ✓Multimodal input through the with: option on chat.ask, accepting images, video, audio, PDFs, code files, or an array of several files in one call.
- ✓Streaming responses by passing a block to chat.ask and printing chunk.content as tokens arrive.
- ✓Tool calling: subclass RubyLLM::Tool, define an execute method, and attach it with chat.with_tools(YourTool).
- ✓Agents: RubyLLM::Agent subclasses bundle a model, instructions, and a list of tools into a reusable assistant class.
- ✓Structured output: RubyLLM::Schema subclasses declare fields (string, number, array), and chat.with_schema(YourSchema).ask returns matching JSON.
- ✓Standalone generation calls — RubyLLM.paint for images, RubyLLM.animate for video, RubyLLM.embed for embeddings, RubyLLM.transcribe and RubyLLM.speak for audio, RubyLLM.ocr for document-to-markdown, and RubyLLM.moderate for content safety.
- ✓Rails integration via acts_as_chat on an ActiveRecord model, plus generators for install, migrations, model-registry loading, and an optional chat UI.
Practical AI Applications
- •Adding a chat feature to a Rails app with acts_as_chat on an ActiveRecord model, so conversations persist without hand-writing the storage layer.
- •Building tool-using agents — the README's own example wires a Weather tool into a WeatherAssistant agent that calls a real HTTP API through RubyLLM::Tool#execute.
- •Running multimodal analysis by passing images, video, audio, PDFs, or code files straight into chat.ask via the with: option instead of writing separate extraction code.
- •Generating embeddings with RubyLLM.embed for search or retrieval-style lookups across a provider you already use for chat.
- •Pulling structured JSON out of unstructured input by defining a RubyLLM::Schema and calling chat.with_schema(...).ask on a document or file.
- •Running large jobs at lower cost through RubyLLM.batch, which the README describes as provider-side batch processing at half price.
Getting Started with RubyLLM
RubyLLM installs like any other gem: add gem 'ruby_llm' to your Gemfile and run bundle install. Configure provider API keys in an initializer — the README's example is config/initializers/ruby_llm.rb with RubyLLM.configure { |config| config.openai_api_key = ENV['OPENAI_API_KEY'] }. In a Rails app, the README adds a generator step: bin/rails generate ruby_llm:install, then bin/rails db:migrate, then bin/rails ruby_llm:load_models (noted in the README as available from v1.13+) to populate the model registry; an optional bin/rails generate ruby_llm:chat_ui scaffolds a chat interface reachable at /chats. Full documentation lives at rubyllm.com; the README itself doesn't state a minimum Ruby or Rails version.
RubyLLM Code Examples
The basic pattern is chat = RubyLLM.chat, then chat.ask "your question". File analysis goes through the same with: option — chat.ask "What's in this image?", with: "photo.jpg" — and the README shows it accepting video, audio, PDF, code files, or an array of several files at once. Streaming swaps the plain call for a block: chat.ask("Tell me a story") { |chunk| print chunk.content }. Tool calling means subclassing RubyLLM::Tool with a description and an execute method, then calling chat.with_tools(YourTool).ask(...); RubyLLM::Agent wraps a model, instructions, and tools into a class you instantiate and ask directly, as in the README's WeatherAssistant example. Structured output works by subclassing RubyLLM::Schema to declare fields, then calling chat.with_schema(YourSchema).ask(...) to get a response shaped to match. Standalone calls cover the rest: RubyLLM.paint for images, RubyLLM.animate for video, RubyLLM.embed for embeddings, RubyLLM.transcribe and RubyLLM.speak for audio, RubyLLM.ocr for document-to-markdown, and RubyLLM.moderate for content safety checks.
Strengths
- ✓One chat interface — RubyLLM.chat, chat.ask — works the same across OpenAI, Anthropic, Gemini, xAI, Bedrock, Ollama, and the rest of the listed providers, per the README.
- ✓Only three runtime dependencies (Faraday, Zeitwerk, Marcel), so adding it doesn't drag in a large dependency tree.
- ✓Multimodal input and generation go past plain text: images, video, audio, PDFs, and code files as chat input, plus RubyLLM.paint, RubyLLM.animate, RubyLLM.transcribe, RubyLLM.speak, and RubyLLM.ocr as standalone calls.
- ✓Rails integration is a first-class path — acts_as_chat plus generators for install, migrations, model loading, and an optional chat UI, not something bolted on after the fact.
- ✓MIT license, so there's no copyleft obligation or vendor lock-in coming from the framework itself.
Considerations for RubyLLM
- △The README doesn't state a minimum Ruby or Rails version, so compatibility with an older app isn't something you can confirm without trying it.
- △The bin/rails ruby_llm:load_models generator is marked 'v1.13+' in the README, but the README gives no overall current version number to check your install against.
- △Async support appears only as 'Fiber-based concurrency' in the feature list; the README doesn't say what runtime or scheduler that depends on or how you opt into it.
- △RubyLLM.batch is described as running 'at half price,' but the README doesn't say which of the listed providers actually support provider-side batching.
- △Detailed usage docs live off-repo at rubyllm.com — the README itself covers the basics, so anything past the core API means leaving GitHub.
- △The one named production user in the README is chatwithwork.com; there's no broader adopter list or scale figures to gauge production maturity from.
Other Ruby AI Options
Common Questions
RubyLLM's README lists OpenAI, xAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible API as supported providers.
RubyLLM ships Rails-specific generators — bin/rails generate ruby_llm:install adds the integration, and acts_as_chat on an ActiveRecord model persists conversations, with an optional chat UI generator too.
RubyLLM is released under the MIT License, as listed on its GitHub repository.
RubyLLM lists Ollama among its supported providers in the README, so local models run through Ollama work through the same RubyLLM.chat interface as the hosted providers.
RubyLLM's chat.ask accepts images, video, audio, PDFs, and code files via its with: option, and separate calls cover image generation (RubyLLM.paint), video generation (RubyLLM.animate), transcription (RubyLLM.transcribe), and text-to-speech (RubyLLM.speak).
RubyLLM includes a RubyLLM.moderate method, listed in the README's feature set as a way to check content for safety.
The problem it solves
Every AI provider ships its own Ruby client with its own request shape, response format, and streaming convention, so a Rails app built against OpenAI has to rewrite its integration layer, not just swap a model string, if it wants to try Claude. RubyLLM's README frames its reason for existing around exactly that: one interface — RubyLLM.chat, chat.ask, chat.with_tools — that behaves the same whether the backend is GPT, Claude, or a local Ollama model, so switching providers becomes a config change instead of a rewrite.
Who should try it — and who should skip
Try RubyLLM if you're building inside a Ruby or Rails app and want one interface for chat, tools, agents, and multimodal calls across providers like OpenAI, Anthropic, and Gemini instead of hand-writing a client per vendor. Skip it if your stack isn't Ruby — the whole point is fitting AI calls into idiomatic Ruby and Rails patterns, so there's nothing here for a Python or Node project — or if you need deep usage documentation sitting inside the repo itself, since the README defers detail to rubyllm.com.
Related repositories
Curious whether ruby_llm is right for you?
Let ChatGPT, Claude, or Perplexity look into it — click below and see what AI actually says about ruby_llm.
