RubyLLM::Schema
A Ruby DSL for creating JSON schemas with a clean, Rails-inspired API. Perfect for defining structured data schemas for LLM function calling or structured outputs.
Use Cases
Structured output is a powerful tool for LLMs to generate consistent and predictable responses.
Some ideal use cases:
- Extracting metadata, topics, and summary from articles or blog posts
- Organizing unstructured feedback or reviews with sentiment and summary
- Defining structured actions from user messages or emails
- Extracting entities and relationships from documents
Simple Example
class PersonSchema < RubyLLM::Schema
string :name, description: "Person's full name"
number :age, description: "Age in years", minimum: 0, maximum: 120
boolean :active, required: false
object :address do
string :street
string :city
string :country, required: false
end
array :tags, of: :string, description: "User tags"
array :contacts do
object do
string :email, format: "email"
string :phone, required: false
end
end
any_of :status do
string enum: ["active", "pending", "inactive"]
null
end
end
# Usage
schema = PersonSchema.new
puts schema.to_json
Installation
Add this line to your application's Gemfile:
gem 'ruby_llm-schema'
And then execute:
bundle install
Or install it yourself as:
gem install ruby_llm-schema
Usage
Three approaches for creating schemas:
Class Inheritance
class PersonSchema < RubyLLM::Schema
string :name, description: "Person's full name"
number :age
boolean :active, required: false
object :address do
string :street
string :city
end
array :tags, of: :string
end
schema = PersonSchema.new
puts schema.to_json
Factory Method
PersonSchema = RubyLLM::Schema.create do
string :name, description: "Person's full name"
number :age
boolean :active, required: false
object :address do
string :street
string :city
end
array :tags, of: :string
end
schema = PersonSchema.new
puts schema.to_json
Global Helper
require 'ruby_llm/schema'
include RubyLLM::Helpers
person_schema = schema "PersonData", description: "A person object" do
string :name, description: "Person's full name"
number :age
boolean :active, required: false
object :address do
string :street
string :city
end
array :tags, of: :string
end
puts person_schema.to_json
Schema Property Types
A schema is a collection of properties, which can be of different types. Each type has its own set of properties you can set.
All property types can (along with the required name
key) be set with a description
and a required
flag (default is true
).
string :name, description: "Person's full name"
number :age, description: "Person's age", required: false
boolean :is_active, description: "Whether the person is active"
null :placeholder, description: "A placeholder property"
⚠️ Please consult the LLM provider documentation for any limitations or restrictions. For example, as of now, OpenAI requires all properties to be required. In that case, you can use the any_of
method to make a property optional.
any_of :name, description: "Person's full name" do
string
null
end
Strings
String types support the following properties:
enum
: an array of allowed values (e.g.enum: ["on", "off"]
)pattern
: a regex pattern (e.g.pattern: "\\d+"
)format
: a format string (e.g.format: "email"
)min_length
: the minimum length of the string (e.g.min_length: 3
)max_length
: the maximum length of the string (e.g.max_length: 10
)
Please consult the LLM provider documentation for the available formats and patterns.
string :name, description: "Person's full name"
string :email, format: "email"
string :phone, pattern: "\\d+"
string :status, enum: ["on", "off"]
string :code, min_length: 3, max_length: 10
Numbers
Number types support the following properties:
multiple_of
: a multiple of the number (e.g.multiple_of: 0.01
)minimum
: the minimum value of the number (e.g.minimum: 0
)maximum
: the maximum value of the number (e.g.maximum: 100
)
number :price, minimum: 0, maximum: 100
number :amount, multiple_of: 0.01
Booleans
boolean :is_active
Boolean types doesn't support any additional properties.
Null
null :placeholder
Null types doesn't support any additional properties.
Arrays
An array is a list of items. You can set the type of the items in the array with the of
option or by passing a block with the object
method.
An array can have a min_items
and max_items
option to set the minimum and maximum number of items in the array.
array :tags, of: :string # Array of strings
array :scores, of: :number # Array of numbers
array :items, min_items: 1, max_items: 10 # Array with size constraints
array :items do # Array of objects
object do
string :name
number :price
end
end
Objects
Objects types expect a block with the properties of the object.
object :user do
string :name
number :age
end
object :settings, description: "User preferences" do
boolean :notifications
string :theme, enum: ["light", "dark"]
end
Union Types (anyOf)
Union types are a way to specify that a property can be one of several types.
any_of :value do
string
number
null
end
any_of :identifier do
string description: "Username"
number description: "User ID"
end
Schema Definitions and References
You can define sub-schemas and reference them in other schemas, or reference the root schema to generate recursive schemas.
class MySchema < RubyLLM::Schema
define :location do
string :latitude
string :longitude
end
# Using a reference in an array
array :coordinates, of: :location
# Using a reference in an object via the `reference` option
object :home_location, reference: :location
# Using a reference in an object via block
object :user do
reference :location
end
# Using a reference to the root schema
object :ui_schema do
string :element, enum: ["input", "button"]
string :label
object :sub_schema, reference: :root
end
end
Nested Schemas
You can embed existing schema classes directly within objects or arrays for reusable schema composition.
class PersonSchema < RubyLLM::Schema
string :name
integer :age
end
class CompanySchema < RubyLLM::Schema
# Using 'of' parameter
object :ceo, of: PersonSchema
array :employees, of: PersonSchema
# Using Schema.new in block
object :founder do
PersonSchema.new
end
end
JSON Output
schema = PersonSchema.new
schema.to_json_schema
# => {
# name: "PersonSchema",
# description: nil,
# schema: {
# type: "object",
# properties: { ... },
# required: [...],
# additionalProperties: false,
# strict: true
# }
# }
puts schema.to_json # Pretty JSON string
License
The gem is available as open source under the terms of the MIT License.