class RubyLLM::Skill
A Skill is a folder of instructions, scripts, and reference files in the open Agent Skills format. Its SKILL.md starts with YAML front matter naming and describing the skill, followed by the instructions in Markdown.
Chat#with_skills gives skills to a chat. The model sees each skill’s name and description, and loads the instructions and files of the ones a task needs.
skill = RubyLLM::Skill.find(:invoices) skill.name # => "invoices" skill.description # => "Creates invoices as PDFs. Use when ..." skill.path # => #<Pathname:/app/app/skills/invoices>
Constants
- FILE
-
The file every skill folder holds.
- MAX_COMPATIBILITY
-
Characters the compatibility field may have at most.
- MAX_DESCRIPTION
-
Characters a description may have at most.
- MAX_NAME
-
Characters a name may have at most.
Attributes
The tools the front matter pre-approves, as an Array of Strings. RubyLLM reads the field but does not act on it.
The environment requirements the front matter states, or nil.
What the skill does and when to use it.
The Markdown instructions that follow the front matter.
The license the front matter names, or nil.
The front matter’s metadata, a Hash of Strings.
The skill’s name, matching its folder name.
The skill folder, as an absolute Pathname.
Public Class Methods
Source
# File lib/ruby_llm/skill.rb, line 87 def all folders = roots.flat_map { |root| skill_folders(Pathname.new(root)) } folders.uniq(&:basename).map { |folder| new(folder) } end
Returns every skill directly under the skill roots. A skill in an earlier root hides one with the same folder name in a later root. Raises InvalidSkillError when a skill’s SKILL.md is invalid.
Source
# File lib/ruby_llm/skill.rb, line 99 def find(name) folder = name.is_a?(Symbol) ? name.to_s.tr('_', '-') : name.to_s found = (roots.map { |root| Pathname.new(root).join(folder) } if folder.match?(NAME_FORMAT)) &.find { |path| path.join(FILE).file? } raise SkillNotFoundError, "No skill named #{folder} in #{roots.to_a.join(', ')}" unless found new(found) end
Returns the skill in the folder called name under the first skill root that has one. Underscores in a Symbol stand for hyphens, so :pdf_processing finds pdf-processing. Raises SkillNotFoundError when no root has it.
RubyLLM::Skill.find(:invoices)
Source
# File lib/ruby_llm/skill.rb, line 167 def initialize(path) @path = Pathname.new(File.realpath(path)) file = @path.join(FILE) raise SkillNotFoundError, "#{file} not found" unless file.file? front_matter, @instructions = parse(file.read(encoding: 'UTF-8')) assign(front_matter) rescue Errno::ENOENT, Errno::ENOTDIR raise SkillNotFoundError, "No skill folder at #{path}" end
Reads the skill in the folder at path. Raises SkillNotFoundError when the folder has no SKILL.md, and InvalidSkillError when its front matter breaks the Agent Skills specification. Front matter keys the specification does not define are ignored.
RubyLLM::Skill.new("vendor/skills/pdf")
Source
# File lib/ruby_llm/skill.rb, line 72 def roots @roots ||= Prompt::Roots.new { root } end
Returns the ordered skill directories. Append engine directories with +<<+:
initializer "my_engine.skills" do RubyLLM::Skill.roots << MyEngine::Engine.root.join("app/skills") end