4 điểm bởi GN⁺ 2025-03-17 | 1 bình luận | Chia sẻ qua WhatsApp
  • Thư viện AI hợp nhất dựa trên Ruby, đẹp và giàu tính biểu đạt
  • Mỗi nhà cung cấp AI đều có thư viện client, định dạng phản hồi và cách xử lý streaming khác nhau; nếu muốn dùng nhiều mô hình AI thì phải xử lý các API không tương thích và phụ thuộc phức tạp
  • RubyLLM cung cấp một API hợp nhất để giải quyết những vấn đề này

Tính năng chính

  • Hội thoại: hỗ trợ các mô hình OpenAI, Anthropic, Gemini, DeepSeek
  • Thị giác và âm thanh: hiểu hình ảnh và âm thanh
  • Phân tích PDF: tóm tắt và phân tích tài liệu
  • Tạo ảnh: hỗ trợ nhiều mô hình như DALL-E
  • Tạo embedding: tìm kiếm vector và phân tích ngữ nghĩa
  • Cung cấp tool: có thể tích hợp Ruby code với AI
  • Tích hợp Rails: có thể lưu lịch sử chat bằng ActiveRecord
  • Streaming: hỗ trợ xử lý phản hồi thời gian thực

Ưu điểm của RubyLLM

# Đặt câu hỏi một cách đơn giản  
chat = RubyLLM.chat  
chat.ask "Cách tốt nhất để học Ruby là gì?"  
  
# Phân tích hình ảnh  
chat.ask "Trong hình ảnh này có gì?", with: { image: "ruby_conf.jpg" }  
  
# Phân tích âm thanh  
chat.ask "Trong cuộc họp này đã nói về điều gì?", with: { audio: "meeting.wav" }  
  
# Tóm tắt tài liệu  
chat.ask "Hãy tóm tắt hợp đồng này", with: { pdf: "contract.pdf" }  
  
# Tạo hình ảnh  
RubyLLM.paint "Hãy vẽ cảnh hoàng hôn trên núi theo phong cách màu nước"  
  
# Tạo vector embedding  
RubyLLM.embed "Ruby thanh lịch và giàu tính biểu đạt"  
  
# AI có thể sử dụng code  
class Weather < RubyLLM::Tool  
  description "Cung cấp thời tiết hiện tại của một vị trí cụ thể"  
  param :latitude, desc: "Vĩ độ (ví dụ: 52.5200)"  
  param :longitude, desc: "Kinh độ (ví dụ: 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 "Thời tiết ở Berlin thế nào? (52.5200, 13.4050)"  

Cách cài đặt

# Thêm vào Gemfile  
gem 'ruby_llm'  
  
# Cài đặt  
bundle install  
  
# Hoặc cài đặt trực tiếp  
gem install ruby_llm  

Thiết lập API key

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'] # tùy chọn  
end  

Xử lý hội thoại tự nhiên

# Bắt đầu chat với mô hình mặc định (GPT-4o-mini)  
chat = RubyLLM.chat  
  
# Dùng mô hình khác  
chat = RubyLLM.chat(model: 'claude-3-7-sonnet-20250219')  
  
# Câu hỏi đơn giản  
chat.ask "Sự khác nhau giữa attr_reader và attr_accessor là gì?"  
  
# Xử lý hội thoại nhiều lượt  
chat.ask "Bạn có thể cho ví dụ được không?"  
  
# Phản hồi streaming  
chat.ask "Hãy kể một câu chuyện về lập trình viên Ruby" do |chunk|  
  print chunk.content  
end  
  
# Hỗ trợ nhiều dạng đầu vào khác nhau  
chat.ask "Hãy so sánh hai sơ đồ này", with: { image: ["diagram1.png", "diagram2.png"] }  
chat.ask "Hãy tóm tắt tài liệu này", with: { pdf: "contract.pdf" }  
chat.ask "Hãy cho tôi biết trong audio này đã nói gì", with: { audio: "meeting.wav" }  
  
# Có thể đổi mô hình trong khi hội thoại  
chat.with_model('gemini-2.0-flash').ask "Thuật toán yêu thích của bạn là gì?"  

Hỗ trợ tích hợp 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  
  
# Ví dụ sử dụng trong controller  
chat = Chat.create!(model_id: "gpt-4o-mini")  
chat.ask("Gem hữu ích nhất trong Ruby là gì?") do |chunk|  
  Turbo::StreamsChannel.broadcast_append_to(  
    chat,  
    target: "response",  
    partial: "messages/chunk",  
    locals: { chunk: chunk }  
  )  
end  
  
# Lịch sử chat được lưu tự động  

Ví dụ viết tool

class Search < RubyLLM::Tool  
  description "Thực hiện tìm kiếm trong knowledge base"  
  
  param :query, desc: "Từ khóa tìm kiếm"  
  param :limit, type: :integer, desc: "Số lượng kết quả tối đa", required: false  
  
  def execute(query:, limit: 5)  
    Document.search(query).limit(limit).map(&:title)  
  end  
end  
  
# Sử dụng tool từ AI  
chat.with_tool(Search).ask "Hãy tìm tài liệu về các tính năng mới của Ruby 3.3"  

1 bình luận

 
GN⁺ 2025-03-17
Ý kiến trên Hacker News
  • Giao diện này cần cải thiện cách xử lý với streaming. Phản hồi luôn có độ trễ, và nhiều người sẽ muốn streaming trên luồng không chặn thay vì chờ phản hồi rồi làm gián đoạn tiến trình. Đây có thể là vấn đề tài liệu, nhưng dù sao thì streaming là tính năng hạng nhất trong mọi thứ mất hơn vài giây và dùng IO
    • Ngoài ra thì DSL khá tuyệt
  • Cần cẩn thận khi dùng các ví dụ: liên kết
  • So với các thư viện DX khó chịu kiểu như langchain thì nó mang lại cảm giác như luồng không khí trong lành
  • Liệu đây có phải thứ cuối cùng khiến tôi thử Rails không? Cú pháp Ruby thực sự rất đẹp
  • Ruby vẫn sống khỏe
  • Đây là một trong những API ngắn gọn nhất để tương tác với LLM
    • Mong dự án tiếp tục phát triển! Thật vui khi thấy ollama hỗ trợ PR
  • Tôi đang viết app script dựa trên LLM, và cái này cho cảm giác thực sự dễ dàng
  • Wow. Thật sự rất chu đáo
  • Ruby: đến bữa tiệc muộn, nhưng mang theo cả thùng bia
  • Có ai giải thích giúp tôi vì sao package này lại tốt đến vậy không? Trông nó chỉ như gọi API thôi. Không phải chê bai gì, chỉ là tôi chưa hiểu rõ lĩnh vực này nên thực sự tò mò
  • Wow, cú pháp thật đẹp