4 pontos por GN⁺ 2025-03-17 | 1 comentários | Compartilhar no WhatsApp
  • Biblioteca unificada de IA baseada em Ruby, bonita e expressiva
  • Cada provedor de IA tem bibliotecas cliente, formatos de resposta e formas de lidar com streaming diferentes; para usar vários modelos de IA, é preciso lidar com APIs incompatíveis e dependências complexas
  • RubyLLM fornece uma API unificada para resolver esses problemas

Principais recursos

  • Conversa: suporte a modelos OpenAI, Anthropic, Gemini e DeepSeek
  • Visão e áudio: compreensão de imagens e áudio
  • Análise de PDF: resumo e análise de documentos
  • Geração de imagens: suporte a diversos modelos, como DALL-E
  • Geração de embeddings: busca vetorial e análise semântica
  • Fornecimento de ferramentas: permite integrar código Ruby com IA
  • Integração com Rails: permite salvar o histórico de chat com ActiveRecord
  • Streaming: suporte ao processamento de respostas em tempo real

Vantagens do RubyLLM

# Fazer uma pergunta de forma simples  
chat = RubyLLM.chat  
chat.ask "Qual é a melhor maneira de aprender Ruby?"  
  
# Análise de imagem  
chat.ask "O que aparece nesta imagem?", with: { image: "ruby_conf.jpg" }  
  
# Análise de áudio  
chat.ask "O que foi discutido nesta reunião?", with: { audio: "meeting.wav" }  
  
# Resumo de documento  
chat.ask "Resuma este contrato", with: { pdf: "contract.pdf" }  
  
# Geração de imagem  
RubyLLM.paint "Pinte um pôr do sol sobre a montanha em estilo aquarela"  
  
# Geração de embedding vetorial  
RubyLLM.embed "Ruby é elegante e altamente expressiva"  
  
# A IA pode usar código  
class Weather < RubyLLM::Tool  
  description "Fornece o clima atual de uma localização específica"  
  param :latitude, desc: "Latitude (ex: 52.5200)"  
  param :longitude, desc: "Longitude (ex: 13.4050)"  
  
  def execute(latitude:, longitude:)  
    url = "https://api.open-meteo.com/v1/forecast/…;  
  
    response = Faraday.get(url)  
    JSON.parse(response.body)  
  rescue => e  
    { error: e.message }  
  end  
end  
  
chat.with_tool(Weather).ask "Como está o clima em Berlim? (52.5200, 13.4050)"  

Como instalar

# Adicionar ao Gemfile  
gem 'ruby_llm'  
  
# Instalar  
bundle install  
  
# Ou instalar diretamente  
gem install ruby_llm  

Configuração da chave de API

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.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] # opcional  
end  

Processamento de conversa natural

# Iniciar chat com o modelo padrão (GPT-4o-mini)  
chat = RubyLLM.chat  
  
# Usar outro modelo  
chat = RubyLLM.chat(model: 'claude-3-7-sonnet-20250219')  
  
# Pergunta simples  
chat.ask "Qual é a diferença entre attr_reader e attr_accessor?"  
  
# Processar conversa com múltiplos turnos  
chat.ask "Você pode dar um exemplo?"  
  
# Resposta em streaming  
chat.ask "Conte uma história sobre um programador Ruby" do |chunk|  
  print chunk.content  
end  
  
# Suporte a outros formatos de entrada  
chat.ask "Compare estes dois diagramas", with: { image: ["diagram1.png", "diagram2.png"] }  
chat.ask "Resuma este documento", with: { pdf: "contract.pdf" }  
chat.ask "Diga o que foi falado neste áudio", with: { audio: "meeting.wav" }  
  
# É possível trocar de modelo durante a conversa  
chat.with_model('gemini-2.0-flash').ask "Qual é o seu algoritmo favorito?"  

Suporte à integração com Rails

# app/models/chat.rb  
class Chat < ApplicationRecord  
  acts_as_chat  
  
  broadcasts_to ->(chat) { "chat_#{chat.id}" }  
end  
  
# app/models/message.rb  
class Message < ApplicationRecord  
  acts_as_message  
end  
  
# app/models/tool_call.rb  
class ToolCall < ApplicationRecord  
  acts_as_tool_call  
end  
  
# Exemplo de uso no controller  
chat = Chat.create!(model_id: "gpt-4o-mini")  
chat.ask("Qual é a gem mais útil no Ruby?") do |chunk|  
  Turbo::StreamsChannel.broadcast_append_to(  
    chat,  
    target: "response",  
    partial: "messages/chunk",  
    locals: { chunk: chunk }  
  )  
end  
  
# O histórico do chat é salvo automaticamente  

Exemplo de criação de ferramenta

class Search < RubyLLM::Tool  
  description "Executa busca na base de conhecimento"  
  
  param :query, desc: "Termo de busca"  
  param :limit, type: :integer, desc: "Número máximo de resultados", required: false  
  
  def execute(query:, limit: 5)  
    Document.search(query).limit(limit).map(&:title)  
  end  
end  
  
# Uso da ferramenta pela IA  
chat.with_tool(Search).ask "Encontre documentos sobre os novos recursos do Ruby 3.3"  

1 comentários

 
GN⁺ 2025-03-17
Comentários do Hacker News
  • Essa interface precisa melhorar a relação com streaming. Sempre há latência na resposta, e muita gente vai querer streaming em uma thread não bloqueante em vez de interromper o processo esperando a resposta. Isso pode ser um problema de documentação, mas, de qualquer forma, streaming é algo de primeira classe em qualquer coisa que leve mais de alguns segundos e use IO
    • Fora isso, a DSL é muito boa
  • É preciso cuidado ao usar os exemplos: link
  • Comparado a bibliotecas de DX desajeitadas como langchain, parece um sopro de ar fresco
  • Será que isso finalmente vai me fazer experimentar Rails? A sintaxe do Ruby é realmente legal
  • Ruby ainda está muito vivo
  • É uma das APIs mais concisas para interagir com LLMs
    • Espero que continuem! Fico feliz em ver o ollama aceitando PRs
  • Estou escrevendo scripts de apps baseados em LLM, e isso parece realmente muito tranquilo
  • Uau. Muito bem pensado
  • Ruby: chegou atrasado à festa, mas trouxe o barril de chope
  • Alguém pode explicar por que esse pacote é tão bom? Parece só fazer chamadas de API. Não é uma crítica, eu realmente só não entendo muito bem essa área e estou genuinamente curioso
  • Uau, a sintaxe é linda