### Setup and Development Workflow for RubyLLM Source: https://github.com/crmne/ruby_llm/blob/main/CONTRIBUTING.md This snippet details the initial setup steps for contributing to the RubyLLM project. It includes forking the repository, installing dependencies, setting up git hooks with overcommit, and creating a new branch for development. This is essential for any contributor to start making changes. ```bash gh repo fork crmne/ruby_llm --clone && cd ruby_llm bundle install overcommit --install # Required - sets up git hooks gh issue develop 123 --checkout # or create your own branch # make changes, add tests gh pr create --web ``` -------------------------------- ### Run Redis-Backed Async Job Processor (Bash) Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/async.md These commands demonstrate how to start the necessary processes for a Redis-backed async job setup. It includes starting the Redis server, the async job adapter server, and the Rails application server. This can be managed via a Procfile.dev or run in separate terminals. ```bash # Option 1: Add to Procfile.dev web: bin/rails server css: bin/rails tailwindcss:watch redis: redis-server async_job: bundle exec async-job-adapter-active_job-server # Then run bin/dev # Option 2: Separate terminals # Terminal 1: Redis redis-server # Terminal 2: Job processor bundle exec async-job-adapter-active_job-server # Terminal 3: Rails bin/dev ``` -------------------------------- ### Install RubyLLM Gem Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Adds the RubyLLM gem to your project's Gemfile. This is the first step to integrating AI capabilities into your Ruby application. ```ruby bundle add ruby_llm ``` -------------------------------- ### Rails Quick Setup for Database Persistence Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Generates Chat and Message models with ActiveRecord persistence for Rails applications. This command sets up your database to store conversations automatically. ```bash bin/rails generate ruby_llm:install ``` -------------------------------- ### Quick Start Configuration Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/configuration.md Set up API keys for OpenAI and Anthropic providers using environment variables. This is the simplest configuration. ```ruby RubyLLM.configure do |config| config.openai_api_key = ENV['OPENAI_API_KEY'] config.anthropic_api_key = ENV['ANTHROPIC_API_KEY'] end ``` -------------------------------- ### Install and Migrate for Rails Apps Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/models.md Sets up the Model table and loads model data from the gem's registry for Rails applications. Requires running the install generator and database migration. ```bash bin/rails generate ruby_llm:install bin/rails db:migrate ``` -------------------------------- ### Install RubyLLM::Instrumentation Gem Source: https://github.com/crmne/ruby_llm/blob/main/docs/_reference/ecosystem.md Install the ruby_llm-instrumentation gem to instrument RubyLLM events with ActiveSupport::Notifications. ```bash gem install ruby_llm-instrumentation ``` -------------------------------- ### Set Up ActiveStorage for File Attachments Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/rails.md Install and migrate ActiveStorage, then configure your Message model to handle file attachments using `has_many_attached`. ```bash bin/rails active_storage:install bin/rails db:migrate ``` -------------------------------- ### Install RubyLLM::Tribunal Source: https://github.com/crmne/ruby_llm/blob/main/docs/_reference/ecosystem.md Install the ruby_llm-tribunal gem to use its features for deterministic and LLM-as-judge assertions. ```bash gem install ruby_llm-tribunal ``` -------------------------------- ### Generate an Image with RubyLLM Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Shows how to generate images using models like DALL-E 3 via `RubyLLM.paint`. The code generates an image from a text prompt, accesses its URL or Base64 data, and provides an option to save the image locally. ```ruby # Generate an image (uses the default image model) image = RubyLLM.paint("A photorealistic red panda coding Ruby") # Access the image URL (or Base64 data depending on provider) if image.url puts image.url # => "https://oaidalleapiprodscus.blob.core.windows.net/..." else puts "Image data received (Base64)." end # Save the image locally image.save("red_panda.png") ``` -------------------------------- ### Install RubyLLM::Schema Gem Source: https://github.com/crmne/ruby_llm/blob/main/docs/_reference/ecosystem.md Install the ruby_llm-schema gem to use the Ruby DSL for JSON Schema creation. ```bash gem install ruby_llm-schema ``` -------------------------------- ### Install Rails Integration Source: https://github.com/crmne/ruby_llm/blob/main/README.md Generate the necessary files and migrate the database for Rails integration. Load models if using v1.13+. ```bash # Install Rails Integration bin/rails generate ruby_llm:install bin/rails db:migrate bin/rails ruby_llm:load_models # v1.13+ ``` -------------------------------- ### Install RubyLLM::Monitoring Gem Source: https://github.com/crmne/ruby_llm/blob/main/docs/_reference/ecosystem.md Install the RubyLLM::Monitoring gem to integrate monitoring capabilities into your Rails application. ```bash gem install ruby_llm-monitoring ``` -------------------------------- ### Setup Model Model with New API Style Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/rails.md Integrate the `acts_as_model` helper into a Model model using the new API style. ```ruby # app/models/model.rb class Model < ApplicationRecord acts_as_model # Defaults: chats: :chats end ``` -------------------------------- ### Rails Integration for Storing and Searching Embeddings Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/embeddings.md An example of integrating Ruby LLM embeddings into a Rails application using PostgreSQL with the pgvector extension. It includes a migration, model setup with the 'neighbor' gem, and a scope for similarity search. ```ruby # Migration: # add_column :documents, :embedding, :vector, limit: 1536 # Match your model's dimensions # app/models/document.rb class Document < ApplicationRecord has_neighbors :embedding # From the neighbor gem for pgvector # Automatically generate embedding before saving if content changed before_save :generate_embedding, if: :content_changed? # Scope for nearest neighbor search scope :search_by_similarity, ->(query_text, limit: 5) { query_embedding = RubyLLM.embed(query_text).vectors nearest_neighbors(:embedding, query_embedding, distance: :cosine).limit(limit) } private def generate_embedding return if content.blank? puts "Generating embedding for Document #{id}..." begin embedding_result = RubyLLM.embed(content) # Uses default embedding model self.embedding = embedding_result.vectors rescue RubyLLM::Error => e errors.add(:base, "Failed to generate embedding: #{e.message}") # Prevent saving if embedding fails (optional, depending on requirements) throw :abort end end end # Usage in controller or console: # Document.create(title: "Intro to Ruby", content: "Ruby is a dynamic language...") # results = Document.search_by_similarity("What is Ruby?") # results.each { |doc| puts "- #{doc.title}" } ``` -------------------------------- ### Run Upgrade Generator and Migrations (v1.10) Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/upgrading.md Execute these commands to upgrade to v1.10. This adds columns for extended thinking output, thinking token usage, and Gemini 3 Pro function calling. ```bash # Run the upgrade generator bin/rails generate ruby_llm:upgrade_to_v1_10 # Run migrations bin/rails db:migrate ``` -------------------------------- ### Configure RubyLLM API Keys Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Configures API keys for AI providers like OpenAI and Anthropic. It's recommended to use environment variables for security. This code snippet shows how to set up the configuration, typically in a Rails initializer or at the start of a script. ```ruby # config/initializers/ruby_llm.rb (in Rails) or at the start of your script require 'ruby_llm' RubyLLM.configure do |config| # Add keys ONLY for the providers you intend to use. # Using environment variables is highly recommended. config.openai_api_key = ENV.fetch('OPENAI_API_KEY', nil) # config.anthropic_api_key = ENV.fetch('ANTHROPIC_API_KEY', nil) end ``` -------------------------------- ### Define a Basic Support Agent Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/agents.md This example shows how to define a simple agent named `SupportAgent` that uses a default chat model, provides specific instructions, and includes two tools: `SearchDocs` and `LookupAccount`. It then demonstrates how to instantiate and use the agent to ask a question. ```ruby class SupportAgent < RubyLLM::Agent model "{{ site.models.default_chat }}" instructions "You are a concise support assistant." tools SearchDocs, LookupAccount end response = SupportAgent.new.ask "How do I reset my API key?" ``` -------------------------------- ### Configure Default Embedding Model Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/embeddings.md Sets a default embedding model for all subsequent RubyLLM operations. This configuration can be done globally within the application's setup. ```ruby RubyLLM.configure do |config| config.default_embedding_model = "{{ site.models.embedding_large }}" end ``` -------------------------------- ### Define a Basic Weather Tool Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/tools.md This example shows how to create a simple tool that fetches weather data. It inherits from RubyLLM::Tool and defines an execute method for the core logic. The execute method includes basic error handling. ```ruby class Weather < RubyLLM::Tool desc "Gets current weather for a location" def execute(latitude:, longitude:) url = "https://api.open-meteo.com/v1/forecast?latitude=#{latitude}&longitude=#{longitude}¤t=temperature_2m,wind_speed_10m" response = Faraday.get(url) data = JSON.parse(response.body) rescue => e { error: e.message } end end ``` -------------------------------- ### Add Chat UI to Rails Application Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Generates controllers, views, background jobs, and routes for a ready-to-use chat interface in a Rails application. This provides a basic UI for interacting with AI. ```bash bin/rails generate ruby_llm:chat_ui ``` -------------------------------- ### Create Text Embeddings with RubyLLM Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Demonstrates how to create numerical vector representations of text using `RubyLLM.embed`. This code generates an embedding for a given text, allowing access to the vector data and metadata about the model used. ```ruby # Create an embedding (uses the default embedding model) embedding = RubyLLM.embed("Ruby is optimized for programmer happiness.") # Access the vector (an array of floats) vector = embedding.vectors puts "Vector dimension: #{vector.length}" # e.g., 1536 # Access metadata puts "Model used: #{embedding.model}" ``` -------------------------------- ### Configure `use_new_acts_as` in `config/application.rb` Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/configuration.md For `config.use_new_acts_as = false`, configure it in `config/application.rb` before the `Application` class to avoid initializer timing issues. ```ruby # config/application.rb module YourApp class Application < Rails::Application # ... other configurations ... # Configure use_new_acts_as before the Application class config.use_new_acts_as = false # ... other configurations ... end end ``` -------------------------------- ### Perform a Simple Chat Conversation Source: https://github.com/crmne/ruby_llm/blob/main/docs/_getting_started/getting-started.md Demonstrates how to interact with language models using `RubyLLM.chat`. This code creates a chat instance, asks a question, and retrieves the response content. The gem automatically handles conversation history. ```ruby # Create a chat instance (uses the configured default model) chat = RubyLLM.chat # Ask a question response = chat.ask "What is Ruby on Rails?" # The response is a RubyLLM::Message object puts response.content # => "Ruby on Rails, often shortened to Rails, is a server-side web application..." ``` -------------------------------- ### Define an Agent with Dynamic Tools and Contextual Instructions Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/agents.md This `WorkAssistant` agent example showcases dynamic tool definitions using a block that accesses the `chat` object and its associated `user`. It also defines instructions that dynamically evaluate `current_date_time`, `display_name`, and `full_name` based on the runtime context. ```ruby class WorkAssistant < RubyLLM::Agent chat_model Chat instructions current_date_time: -> { Time.current.strftime("%B %d, %Y") }, display_name: -> { chat.user.display_name_or_email }, full_name: -> { chat.user.full_name.presence || chat.user.display_name_or_email } tools do [ TodoTool.new(chat: chat), GoogleDriveListTool.new(user: chat.user), GoogleDriveSearchTool.new(user: chat.user), GoogleDriveReadTool.new(user: chat.user) ] end end ``` -------------------------------- ### Guide AI Behavior with System Prompts Source: https://github.com/crmne/ruby_llm/blob/main/docs/_core_features/chat.md Sets the AI's behavior, personality, and constraints using system prompts. `with_instructions` can replace or append instructions, ensuring consistent AI responses. ```ruby chat = RubyLLM.chat # Set the initial instruction chat.with_instructions "You are a helpful assistant that explains Ruby concepts simply, like explaining to a five-year-old." response = chat.ask "What is a variable?" puts response.content # => "Imagine you have a special box, and you can put things in it..." # By default, with_instructions replaces the active system instruction chat.with_instructions "Always end your response with 'Got it?'" response = chat.ask "What is a loop?" puts response.content # => "A loop is like singing your favorite song over and over again... Got it?" # Append an additional system instruction only when needed chat.with_instructions "Use exactly one short paragraph.", append: true ``` -------------------------------- ### Run Upgrade Generator and Migrations (v1.9) Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/upgrading.md Execute these commands to upgrade to v1.9. This adds columns for tracking cached tokens and raw content blocks, supporting features like Anthropic Prompt Caching. ```bash # Run the upgrade generator bin/rails generate ruby_llm:upgrade_to_v1_9 # Run migrations bin/rails db:migrate ``` -------------------------------- ### Install RubyLLM::TopSecret Source: https://github.com/crmne/ruby_llm/blob/main/docs/_reference/ecosystem.md Install the ruby_llm-top_secret gem for automatically filtering sensitive information from LLM conversations. ```bash gem install ruby_llm-top_secret ``` -------------------------------- ### Full Streaming Implementation with Background Jobs and Turbo Streams Source: https://github.com/crmne/ruby_llm/blob/main/docs/_advanced/rails.md A comprehensive example demonstrating how to implement full streaming responses in Rails. It includes model definitions, a background job for processing AI responses, and view templates for Turbo Streams. ```ruby # app/models/chat.rb class Chat < ApplicationRecord acts_as_chat end ``` ```ruby # app/models/message.rb class Message < ApplicationRecord acts_as_message broadcasts_to ->(message) { "chat_#{message.chat_id}" } # Helper to broadcast chunks during streaming def broadcast_append_chunk(chunk_content) broadcast_append_to "chat_#{chat_id}", target: "message_#{id}_content", partial: "messages/content", locals: { content: chunk_content } end end ``` ```ruby # app/jobs/chat_stream_job.rb class ChatStreamJob < ApplicationJob queue_as :default def perform(chat_id) chat = Chat.find(chat_id) # Process the latest user message chat.complete do |chunk| # Get the assistant message record (created before streaming starts) assistant_message = chat.messages.last if chunk.content && assistant_message # Append the chunk content to the message's target div assistant_message.broadcast_append_chunk(chunk.content) end end # Final assistant message is now fully persisted end end ``` ```erb <%# app/views/chats/show.html.erb %> <%= turbo_stream_from "chat_#{@chat.id}" %>