4 points par GN⁺ 2025-03-17 | 1 commentaires | Partager sur WhatsApp
  • Bibliothèque IA unifiée basée sur Ruby, élégante et très expressive
  • Chaque fournisseur d’IA a sa propre bibliothèque cliente, son propre format de réponse et sa propre manière de gérer le streaming, et pour utiliser plusieurs modèles d’IA il faut gérer des API incompatibles et des dépendances complexes
  • RubyLLM fournit une API unifiée qui résout ces problèmes

Fonctionnalités principales

  • Conversation : prise en charge des modèles OpenAI, Anthropic, Gemini et DeepSeek
  • Vision et audio : compréhension d’images et d’audio
  • Analyse de PDF : résumé et analyse de documents
  • Génération d’images : prise en charge de divers modèles comme DALL-E
  • Création d’embeddings : recherche vectorielle et analyse sémantique
  • Outils : possibilité d’interfacer l’IA avec du code Ruby
  • Intégration Rails : possibilité d’enregistrer l’historique de chat avec ActiveRecord
  • Streaming : prise en charge du traitement des réponses en temps réel

Les atouts de RubyLLM

# Poser une question simplement  
chat = RubyLLM.chat  
chat.ask "Quelle est la meilleure façon d’apprendre Ruby ?"  
  
# Analyse d’image  
chat.ask "Que voit-on dans cette image ?", with: { image: "ruby_conf.jpg" }  
  
# Analyse audio  
chat.ask "De quoi a-t-on parlé dans cette réunion ?", with: { audio: "meeting.wav" }  
  
# Résumé de document  
chat.ask "Veuillez résumer ce contrat", with: { pdf: "contract.pdf" }  
  
# Génération d’image  
RubyLLM.paint "Dessine un coucher de soleil sur une montagne dans un style aquarelle"  
  
# Création d’embeddings vectoriels  
RubyLLM.embed "Ruby est élégant et très expressif"  
  
# L’IA peut utiliser du code  
class Weather < RubyLLM::Tool  
  description "Fournit la météo actuelle d’un lieu donné"  
  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 "Quel temps fait-il à Berlin ? (52.5200, 13.4050)"  

Installation

# Ajouter au Gemfile  
gem 'ruby_llm'  
  
# Installer  
bundle install  
  
# Ou installation directe  
gem install ruby_llm  

Configuration des clés 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'] # Optionnel  
end  

Gestion naturelle de la conversation

# Démarrer un chat avec le modèle par défaut (GPT-4o-mini)  
chat = RubyLLM.chat  
  
# Utiliser un autre modèle  
chat = RubyLLM.chat(model: 'claude-3-7-sonnet-20250219')  
  
# Question simple  
chat.ask "Quelle est la différence entre attr_reader et attr_accessor ?"  
  
# Gestion d’une conversation multi-tours  
chat.ask "Pouvez-vous donner un exemple ?"  
  
# Réponse en streaming  
chat.ask "Raconte-moi une histoire sur un programmeur Ruby" do |chunk|  
  print chunk.content  
end  
  
# Prise en charge de différentes formes d’entrée  
chat.ask "Compare ces deux diagrammes", with: { image: ["diagram1.png", "diagram2.png"] }  
chat.ask "Résume ce document", with: { pdf: "contract.pdf" }  
chat.ask "Dis-moi ce qui est dit dans cet audio", with: { audio: "meeting.wav" }  
  
# Changer de modèle en cours de conversation  
chat.with_model('gemini-2.0-flash').ask "Quel est ton algorithme préféré ?"  

Prise en charge de l’intégration 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  
  
# Exemple d’utilisation dans un contrôleur  
chat = Chat.create!(model_id: "gpt-4o-mini")  
chat.ask("Quel est le gem le plus utile en Ruby ?") do |chunk|  
  Turbo::StreamsChannel.broadcast_append_to(  
    chat,  
    target: "response",  
    partial: "messages/chunk",  
    locals: { chunk: chunk }  
  )  
end  
  
# L’historique du chat est enregistré automatiquement  

Exemple de création d’un outil

class Search < RubyLLM::Tool  
  description "Effectue une recherche dans la base de connaissances"  
  
  param :query, desc: "Terme de recherche"  
  param :limit, type: :integer, desc: "Nombre maximal de résultats", required: false  
  
  def execute(query:, limit: 5)  
    Document.search(query).limit(limit).map(&:title)  
  end  
end  
  
# Utilisation de l’outil par l’IA  
chat.with_tool(Search).ask "Trouve-moi des documents sur les nouveautés de Ruby 3.3"  

1 commentaires

 
GN⁺ 2025-03-17
Commentaires sur Hacker News
  • Cette interface aurait besoin d’une meilleure gestion du streaming. Il y a toujours une latence dans les réponses, et beaucoup de gens voudront probablement du streaming dans un thread non bloquant au lieu d’interrompre le processus en attendant la réponse. C’est peut-être un problème de documentation, mais dans tous les cas, le streaming est un citoyen de première classe pour tout ce qui utilise des E/S et prend plus de quelques secondes
    • À part ça, la DSL est plutôt excellente
  • Il faut faire attention en utilisant les exemples : lien
  • Comparé à des bibliothèques DX maladroites comme langchain, ça fait l’effet d’une bouffée d’air frais
  • Est-ce que c’est ce qui va enfin me faire essayer Rails ? La syntaxe de Ruby est vraiment élégante
  • Ruby est toujours bien vivant
  • C’est l’une des API les plus concises pour interagir avec des LLM
    • Continuez comme ça ! Ravi de voir qu’ollama accepte les PR
  • Je suis en train d’écrire des scripts d’apps basées sur des LLM, et ça donne vraiment une impression de fluidité
  • Waouh. C’est vraiment réfléchi
  • Ruby : arrivé tard à la fête, mais avec un fût de bière
  • Est-ce que quelqu’un peut m’expliquer pourquoi ce package est si bon ? On dirait juste qu’il fait des appels d’API. Ce n’est pas une critique, je comprends simplement mal ce domaine et je suis sincèrement curieux
  • Waouh, la syntaxe est magnifique