Skip to content

Build AI features the Ruby way

RubyLLM is the Ruby-native AI framework. Work with models, tools, and agents through one consistent API, in plain Ruby or Rails.

bundle add ruby_llm --version 2.0.0.rc1

Coming soon

17 providers. One Ruby API.

Build with the models you want. Move between hosted and local providers without rewriting your application, or connect an OpenAI-compatible endpoint.

chat = RubyLLM.chat(model: "claude-opus-5")
chat.ask "Hello!"

Browse models and pricing · Track usage and costs

Missing a provider?

Connect another AI service to Ruby and Rails. Generate a provider gem with configuration, tests, and release setup, then adapt it to the service's API.

Provider gem guide
gem install ruby_llm --pre
ruby_llm provider-gem Acme \
  --api-base https://api.acme.example/v1

Start with one line.
Add files, tools, and agents

Just ask

Ask a question. The chat keeps the conversation history, so you can follow up.

Chat guide
RubyLLM.chat.ask "What's the best way to learn Ruby?"

Send files

Ask about an image, a recording, or a PDF. Pass your files with with: and RubyLLM prepares them for the model.

Attachments guide
chat = RubyLLM.chat(model: "gemini-3.7-flash")
chat.ask "What's in this image?", with: "ruby_conf.jpg"
chat.ask "Describe this meeting", with: "meeting.wav"
chat.ask "Summarize this document", with: "contract.pdf"

Stream responses

Pass a block to display the response as it arrives, in your terminal or a Rails view.

Streaming guide
chat.ask "Tell me a story about Ruby" do |chunk|
  print chunk.content
end

Give the model tools

Describe a tool in a Ruby class and implement execute. RubyLLM runs the tool calls and sends the results back to the model.

Tools guide
class Weather < RubyLLM::Tool
  description "Get current weather"

  def execute(latitude:, longitude:)
    url = "https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}&current=temperature_2m,wind_speed_10m"
    JSON.parse(Faraday.get(url).body)
  end
end

chat.with_tools(Weather).ask "What's the weather in Berlin?"

Get structured output

Define the fields you want in a Ruby schema. Read the result as a Hash with response.parsed.

Structured output guide
class ProductSchema < Schematist::Schema
  string :name
  number :price
  array :features do
    string
  end
end

response = chat.with_schema(ProductSchema).ask "Analyze this product", with: "product.txt"

Define an agent

Give an agent its model, instructions, and tools in a Ruby class. Create an instance whenever you need it.

Agents guide
class WeatherAssistant < RubyLLM::Agent
  model "gpt-5.6-luna"
  instructions "Be concise and always use tools for weather."
  tools Weather
end

WeatherAssistant.new.ask "What's the weather in Berlin?"

A complete AI framework for Ruby

Agents, workflows, RAG, images, audio, and video. Built in, with usage tracking and Rails integration to bring them into your app.

class IssueRefund < RubyLLM::Tool
  description "Issues a refund for an order"
  requires_approval

  def execute(order_id:) = Refunds.issue!(order_id)
end
chats = documents.map do |doc|
  RubyLLM.chat(model: "claude-sonnet-5")
    .with_instructions("Summarize in one paragraph.")
    .ask_later(doc.text)
end

batch = RubyLLM.batch(chats)
chat = RubyLLM.chat.with_caching
chat.with_instructions "You are a careful code reviewer."
chat.ask "Review this diff", with: "large_diff.patch"
response = RubyLLM.chat
  .with_server_tools(:web_search)
  .ask "What's the latest stable Ruby? Cite sources."

response.citations
documents = ["Ruby is expressive", "Python uses indentation"]
embeddings = RubyLLM.embed(documents)
ranked = RubyLLM.rerank("Ruby language", documents, model: "rerank-v3.5")
response = chat.ask "Explain embeddings"
response.tokens.output
response.cost.total
transcript = RubyLLM.transcribe "meeting.wav"
RubyLLM.speak(transcript.text).save "transcript.mp3"
document = RubyLLM.ocr "scanned-contract.pdf"
puts document.markdown
RubyLLM.paint "a sunset over mountains in watercolor style"
RubyLLM.animate "a paper boat sailing down a rainy gutter"
RubyLLM.moderate("Some user-generated content").flagged?

Coordinate agents with workflows, give them memory, and resume their work across jobs and deploys. Use separate configurations for each tenant and retries and fallbacks when requests fail. Follow requests with instrumentation, or explore community gems for MCP and monitoring dashboards.

Feels at home in Rails

Save conversations with Active Record and stream replies with Hotwire. The generators give you a working chat UI. Watch the two-minute demo.

chat = Chat.create! model: "claude-opus-5"
chat.ask "What's in this file?", with: "report.pdf"
bin/rails generate ruby_llm:agent Support
bin/rails generate ruby_llm:tool Weather
bin/rails generate ruby_llm:schema Product

Keep your agents, tools, and schemas in app/. Store files with Active Storage and write your prompts in ERB templates. Use Turbo Streams to show replies and Active Job to run agents in the background.

Built with RubyLLM

Used in production by the teams behind these products.

Using RubyLLM? Get featured or Sponsor us

Gold sponsors

Their support helps fund RubyLLM's development. Thank you for investing in AI for Ruby.

Become a sponsor

Why Rubyists choose RubyLLM

Jorge ManrubiaJorge ManrubiaPrincipal Programmer, 37signals

We are using OpenAI API using the fantastic RubyLLM gem from @paolino.

Nick WarwickNick WarwickFounding Engineer, Nodal Networks

Our Langgraph agent was failing. I took a gamble and rebuilt it using RubyLLM. Not only was it far simpler, it performed better.

Brendan SamekBrendan SamekFounding Software Engineer, Build Canada

It feels natural. At Yuma, serving over 100,000 end users, our unified AI interface had accumulated so much cruft. RubyLLM is so much nicer than all of that.

Aaron SnyderAaron SnyderCTO / Co-founder, Corepilot

We got our proof of concept up in one day and the first beta in about a week. Really impressive.

Joe LeoJoe LeoFounder/CEO, Def Method

Most tools add layers. This one removes them. It keeps the mental load low.

Cole RobertsonCole RobertsonCo-founder and CTO, dScribe AI

The speed of development and the closest thing to the AI SDK in JavaScript land. Easiest Rails integration.

Philippe LehouxPhilippe LehouxCEO, Missive

Multi-provider support. Agentic loop support. Can we sponsor?

Hamid SiddiquiHamid SiddiquiFounder, ReelMoney

I replaced my internal provider implementation with RubyLLM and it just worked nicely. Deleted a lot of code.

Marc KöhlbruggeMarc KöhlbruggeFounder/CEO, Startup Jobs

Ruby-esque DSL and the right level of abstraction: composable, flexible on architecture, opinionated on lower-level implementation.

Using RubyLLM? Share your story! Takes 5 minutes.

Give it a try

RubyLLM.chat.ask "Hello, Ruby!"