crmne/ruby_llm · 上手攻略
- 仓库:crmne/ruby_llm
- 链接:https://github.com/crmne/ruby_llm
- 分类:ai / framework · Ruby 原生多模态 LLM 调用框架
- 作者:spark
- 更新:2026-10-15
§0 自检:✅ GitHub README 已 fetch(HTTP 200,10899 字节);✅ 官方站 anchor rubyllm.com 已核(getting-started / whats-new-in-2-1 / available-models);✅ 关键子模块 anchor(Chat / Tool / Agent / Judge / Evaluation / Rails generator)已读。 ✅ 版本已 verbatim 核实:rubygems 当前版本 2.1.1(2026-10-11 发布,592 KB),README 引用的
bundle add ruby_llm --version 2.1.1与发布页一致。 ✅ 作者卡显示 Carmine Paolino(rubygems 页面),README "Battle tested at chatwithwork.com"。 ⚠️ README 示例中出现的模型名gpt-5.6-luna、gemini-3.7-flash等带有"未来感"字样,作者未声明这是真模型名还是占位,引用时一律加 ⚠️;实际可用模型清单以官方站/available-models为准。 ⚠️ README "Examples use 2.1.1" 提到 1.x 用户需去/v1文档路径——本攻略不覆盖 1.x。
§1 这是什么
ruby_llm(gem 名就是 ruby_llm,仓库 crmne/ruby_llm)是一个 Ruby 原生的 AI 框架,目标是把 chat / agent / tools / image / audio / video 这些 LLM 相关能力收敛成 一个一致的 API,让你在普通 Ruby 或 Rails 里写。
定位不是"包一下 OpenAI SDK",而是 跨 provider 统一抽象 + Rails 集成 + 评估 + 工作流。它把"换模型不换应用"当成一等公民来设计——同一份 chat.ask "..." 代码可以在 OpenAI、Azure、Anthropic、Gemini、Vertex、Bedrock、Cohere、DeepSeek、Mistral、Perplexity、OpenRouter、Hetzner、xAI、Ollama、Ollama Cloud、GPUStack、ElevenLabs、Deepgram、TypeSafe 之间切换,甚至接任何 OpenAI 兼容端点。
当前稳定版 2.1.1(2026-10-11),需要 Ruby ≥ 3.2(rubygems 页面声明)。
§2 解决什么问题
- 写 Rails / Ruby 服务时不想为每个 provider 维护一套 SDK;
- 同一段调用要能在多个 provider 间横跳(fallback / AB / 切到本地 Ollama);
- 想用 Active Record 持久化聊天记录,用 Active Storage 挂文件,用 Hotwire 流式回答;
- 想要 结构化输出、工具调用、带审批的工具、Agent Skills、评估(带数据集)、工作流 telemetry、用量/成本账本——一站式而非拼凑。
如果只是想要"裸 OpenAI 客户端",它会过重;如果要拼多模态 + 工具 + agent + Rails + 评估这一整套,2.x 是少见的"少即是多"选择。
§3 快速安装
3.1 装 gem
# 2.1.x(README 当前推荐版本)
bundle add ruby_llm --version 2.1.1
# 或者
gem install ruby_llm -v 2.1.1
要求 Ruby ≥ 3.2(rubygems 声明)。
3.2 配 provider
最少配一个 key 就能开跑:
# config/initializers/ruby_llm.rb (Rails)
require 'ruby_llm'
RubyLLM.configure do |config|
config.openai_api_key = ENV.fetch('OPENAI_API_KEY')
# 按需追加:anthropic_api_key / gemini_api_key / mistral_api_key / cohere_api_key ...
end
跑过 README 里"同时用图像 + 视频 + 文档 + OCR + 重排"那些示例,至少要配 OpenAI(chat)+ Gemini(文件)+ xAI(视频)+ Mistral(OCR)+ Cohere(rerank),详见官方 Getting Started。
§4 核心用法
4.1 统一 chat 接口
# 文字
RubyLLM.chat.ask "What's the best way to learn Ruby?"
# 多模态(图片 / 视频 / 音频 / PDF / 代码文件)
chat = RubyLLM.chat(model: "⚠️gemini-3.7-flash") # 模型名以官方 available-models 为准
chat.ask "What's in this image?", with: "ruby_conf.jpg"
chat.ask "What's happening in this video?", with: "video.mp4"
chat.ask "Describe this meeting", with: "meeting.wav"
chat.ask "Summarize this document", with: "contract.pdf"
chat.ask "Explain this code", with: "app.rb"
# 流式
chat.ask "Tell me a story about Ruby" do |chunk|
print chunk.content
end
⚠️ 上述
gemini-3.7-flash之类字样来自 README 示例原文,仓库未声明它们是否真实存在;建议跑前在官方available-models页面交叉核对。
4.2 多模态输出(生成 / 重排 / 转写 / OCR)
image = RubyLLM.paint "a sunset over mountains in watercolor style"
image.save "sunset.png"
video = RubyLLM.animate "a paper boat sailing down a rainy gutter"
video.save "paper_boat.mp4"
embedding = RubyLLM.embed "Ruby is elegant and expressive"
embedding.vectors
ranked = RubyLLM.rerank("How do I reset my password?",
["Reset your password in Settings.", "Invoices arrive by email."],
model: "rerank-v3.5")
ranked.results.first.document
RubyLLM.transcribe "meeting.wav" # -> #text
RubyLLM.speak "Hello, welcome to RubyLLM!" # -> .save "welcome.mp3"
RubyLLM.ocr "contract.pdf" # -> #markdown
RubyLLM.moderate("...").flagged?
4.3 结构化输出 + 工具 + Agent
# 结构化
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"
response.parsed
# 工具
class Weather < RubyLLM::Tool
description "Get current weather"
def execute(latitude:, longitude:)
JSON.parse(Faraday.get(
"https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}¤t=temperature_2m,wind_speed_10m"
).body)
end
end
chat.with_tools(Weather).ask "What's the weather in Berlin?"
# Agent
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?"
4.4 评估(dataset + Ruby assertion + LLM judge)
# app/agents/support_agent.rb
class SupportAgent < RubyLLM::Agent
instructions "Accept returns of unopened items within 30 days."
end
# app/evals/support_evaluation.rb
class SupportEvaluation < RubyLLM::Evaluation
def perform(input)
SupportAgent.new.ask(input)
end
end
# app/evals/support_evaluation.yml
cases:
- name: within_return_window
inputs: Can I return an unopened item after 14 days?
expected_output: Yes, unopened items can be returned within 30 days.
- name: past_return_window
inputs: Can I return an unopened item after 45 days?
expected_output: No, the 30-day return window has passed.
report = SupportEvaluation.run
report.passed?
report.cost.total
默认用"语义判定"(LLM judge),也可以加 Ruby 断言或自带 evaluator agent。
4.5 Rails 集成
bin/rails generate ruby_llm:install
bin/rails db:migrate
bin/rails ruby_llm:load_models
bin/rails generate ruby_llm:chat_ui # 可选:自带 chat UI
class Chat < ApplicationRecord
acts_as_chat
end
chat = Chat.create! model: "gpt-4o-mini" # 用真模型名替换
chat.ask "What's in this file?", with: "report.pdf"
启动 Rails 后访问 http://localhost:3000/chats。
4.6 给 Coding Agent 的 skill
npx skills add "$(bundle show ruby_llm)" --skill rubyllm
让 Claude Code / Cursor 之类助手读 gem 自带的 skill 文档。
§5 典型适用场景
- Rails 应用内嵌 LLM 能力:聊天 + 文件问答 + 图像/音频/视频理解 + 生成 + embeddings + 重排,一份代码通吃。
- 多 provider 切换 / 兜底:用
with_fallbacks自动降级到备用模型;with_caching启用 provider prompt cache;with_compaction让 provider 压缩长对话。 - 需要"评估门"的产品:自带的
RubyLLM::Evaluation让 CI 里跑数据集,并暴露report.passed?+report.cost.total。 - AI Agent 加 Human-in-the-loop:
requires_approval把工具停在等人批;with_permissions给整个 chat 设权限模式。 - 可观测的 agentic loop:自己用
ask_later/step/complete?驱动回合,工作流级别用RubyLLM.workflow把多 agent 调用串起来做 telemetry。 - 本地模型:Ollama / Ollama Cloud / GPUStack 都在 provider 列表里,离线跑 demo 不烧 token。
§6 坑与注意(≥5 条现象/影响/修复)
-
模型名变更很常见 现象:README 例子里的
gpt-5.6-luna/gemini-3.7-flash等命名看起来不像已知发布名。 影响:直接 copy-paste 会报 model not found。 修复:去官方站available-models查当前活跃 provider/model,把示例代码里的占位名替换成真实名。 -
跨 provider 示例需要的 key 比想象中多 现象:单个示例可能同时调用 Gemini(文件)+ xAI(视频)+ Mistral(OCR)+ Cohere(rerank)。 影响:第一次跑演示就把 5 家 key 都得备齐。 修复:分阶段配 provider——先把 OpenAI key 跑通
chat.ask,再按需加;README 也建议 "configure as needed"。 -
2.x 与 1.x API 差异 现象:官方专门留了
/v1文档路径。 影响:老教程里的代码可能在 2.1.1 跑不起来。 修复:升级走官方Upgrading指南;本攻略不覆盖 1.x。 -
评估 / Agent / Workflow / Skills 标注
(main)现象:README 列表里部分能力被标(main),对应/next/...文档路径。 影响:意味着这些是 2.1.x 主干里的新东西,但接口可能在 2.2 之前小幅调整。 修复:依赖这些能力的代码先固定 gem 版本(--version 2.1.1),等 2.2 锁 API 后再升。 -
Rails generator 与 schema 迁移绑定 现象:
ruby_llm:install会生成db:migrate。 影响:在已有大表的项目里要 review 生成的 schema。 修复:装之前先 diff 一次,看新增的acts_as_chat表结构与项目既有约定是否冲突。 -
skill 安装是
npx skills add现象:要给 AI 编程助手喂文档用的命令是npx skills add "$(bundle show ruby_llm)" --skill rubyllm。 影响:在没有 Node 的环境跑不通。 修复:把bundle show ruby_llm的输出目录手动指给助手的 skill 加载路径。 -
价格 / token 计数依赖 provider 现象:
chat.cost.total/chat.tokens来自 provider 用量账本。 影响:本地 Ollama 不会返回真实金额;自建 OpenAI 兼容端点可能不返回完整 usage。 修复:评估/对账时把"provider 返回 usage"列入前置条件。
§7 与同类对比
| 维度 | ruby_llm 2.1.1 | LangChain.rb | ruby-openai(裸 SDK) |
|---|---|---|---|
| Provider 数 | 20+,含 OpenAI 兼容任意端 | 多但偏 Python 同步覆盖 | 仅 OpenAI 风格 |
| Rails 集成 | 一等公民(generator + Active Record + Hotwire) | 需手写 | 无 |
| 评估 / Dataset | 内置 RubyLLM::Evaluation |
无官方评估 | 无 |
| 工作流 telemetry | RubyLLM.workflow |
需外部编排 | 无 |
| 结构化输出 | with_schema + Schematist |
各自定义 | 无 |
| 流式 | 原生 | 有 | 有 |
| 多模态生成 | 图像/视频/音频/OCR/重排/embeddings | 分散 | 仅 chat |
| 体积 | 中等,依赖少 | 较重 | 极轻 |
§8 进阶:跨 provider 切换与评估数据形态
ruby_llm 的"换 provider 不换代码"在配置层一次性给齐:
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']
config.mistral_api_key = ENV['MISTRAL_API_KEY']
config.cohere_api_key = ENV['COHERE_API_KEY']
# 任何 OpenAI 兼容端点(含本地 Ollama、自建网关):
config.openai_api_base = ENV['OPENAI_API_BASE']
end
# 按 chat 切换
RubyLLM.chat(model: "gpt-4o-mini").ask "..."
RubyLLM.chat(model: "claude-3-5-sonnet-latest").ask "..."
RubyLLM.chat(model: "gemini-1.5-flash").ask "..."
# 兜底链
chat.with_fallbacks(["gpt-4o-mini", "claude-3-5-sonnet-latest"]).ask "..."
# provider-side batch(按 provider 计费打折)
RubyLLM.batch do |b|
b.chat.ask "task 1"
b.chat.ask "task 2"
end
评估报告里暴露出来的字段是产品层接入"成本门"的关键:
report = SupportEvaluation.run
report.passed? # true / false
report.cost.total # 累计花费(provider 返回 usage 才能精确)
report.cost.input_tokens
report.cost.output_tokens
# 个案级
report.results.first.passed?
report.results.first.actual_output
把 report.cost.total 接进 CI 预算报警,把 report.passed? 接进 PR check,就是一个不引入第三方框架的"AI 单元测试 + 成本上限"机制。
§9 一句话推荐结论
如果你的栈是 Rails/Ruby、又不想被某个 provider 锁死,ruby_llm 2.1.1 是当前 覆盖面最广 + Rails 集成最深 的选择;先用 RubyLLM.chat.ask 跑通一条主干,再按"评估 / Agent / Workflow"分阶段加上即可。