class RubyLLM::Tool
A Tool is an action an AI model can call during a chat. Subclasses describe themselves with ::description, declare their arguments, and implement execute:
class Weather < RubyLLM::Tool description "Gets current weather for a location" def execute(latitude:, longitude:) response = Faraday.get "https://api.open-meteo.com/v1/forecast", latitude: latitude, longitude: longitude, current: "temperature_2m,wind_speed_10m" JSON.parse(response.body) end end chat.with_tools(Weather).ask "What's the weather in Berlin?"
When no parameters are declared, the argument schema is inferred from execute’s keyword arguments: required keywords become required string parameters and optional keywords become optional ones. Use ::parameter or ::parameters when arguments need explicit types, descriptions, or structure.
Public Class Methods
# File lib/ruby_llm/tool.rb, line 56 def description(text = nil) return @description unless text @description = text end
Sets the description the model sees for this tool, or returns the current description when called without an argument.
class Weather < RubyLLM::Tool description "Gets current weather for a location" end
Source
# File lib/ruby_llm/tool.rb, line 73 def parameter(name, **options) declared_parameters[name] = Parameter.new(name, **options) end
Declares a parameter for the tool. options accepts type: (defaults to 'string'), description:, and required: (defaults to true).
class Distance < RubyLLM::Tool description "Calculates distance between two cities" parameter :origin, description: "Origin city name" parameter :destination, description: "Destination city name" parameter :units, type: :string, description: "metric or imperial", required: false end
# File lib/ruby_llm/tool.rb, line 98 def parameters(schema = nil, &block) if schema.nil? && block.nil? raise ArgumentError, 'parameters requires a schema or a block; declare single arguments with parameter' end @parameters_schema_definition = SchemaDefinition.new(schema:, block:) self end
Sets the JSON Schema for the tool’s arguments. Accepts a schema hash, a RubyLLM::Schema class or instance, or a block written in the ruby_llm-schema DSL. Returns self.
class Scheduler < RubyLLM::Tool description "Books a meeting" parameters do object :window, description: "Time window to reserve" do string :start, description: "ISO8601 start time" string :finish, description: "ISO8601 end time" end array :participants, of: :string end end
Raises ArgumentError when called without a schema or a block.
# File lib/ruby_llm/tool.rb, line 118 def provider_options(options = (get = true)) return @provider_options ||= {} if get raise ArgumentError, 'provider_options does not accept nil' if options.nil? @provider_options = options.to_h self end
Sets provider-specific metadata, such as Anthropic’s cache_control hints, merged verbatim into the tool payload sent to the provider. Without an argument, returns the current options.
provider_options cache_control: { type: "ephemeral" }
Raises ArgumentError if options is nil.
Public Instance Methods
Source
# File lib/ruby_llm/tool.rb, line 171 def description self.class.description end
Returns the tool description declared on the class with ::description.
Source
# File lib/ruby_llm/tool.rb, line 214 def execute(...) raise NotImplementedError, 'Subclasses must implement #execute' end
Runs the tool with the arguments chosen by the model. Subclasses must implement this method; the base implementation raises NotImplementedError. The return value is sent back to the model. Return a Hash like { error: "..." } to report a recoverable failure.
Source
# File lib/ruby_llm/tool.rb, line 163 def name klass_name = self.class.name normalized = klass_name.to_s.dup.force_encoding('UTF-8').unicode_normalize(:nfkd) ascii_name = normalized.encode('ASCII', replace: '').gsub(/[^a-zA-Z0-9_-]/, '-') Utils.underscore(ascii_name).delete_suffix('_tool') end
Returns the name the model calls this tool by, derived from the class name: underscored, reduced to ASCII, with a trailing “_tool” removed. Override this method to choose a different name.
WeatherLookup.new.name # => "weather_lookup"