Scott Werner (founder of Sublayer and organizer of Artificial Ruby) told me something that stuck with me:
“The first version of the sublayer gem was actually a coding agent, but it was coming together so quickly… I was like, wait… if this is so easy for me, it’s going to be easy for everybody, and everybody is going to be making these…”
Last week, we open-sourced a minimal but feature-packed coding agent. We were after the simplest, straightforward, stupidly effective agent possible, so we named it Detritus, after Lance Constable Detritus of the Ankh-Morpork City Watch from Discworld (thanks for so much and so many, Sir Terry).
Detritus is built in just 250 lines of code, yet it packs a CLI with history, custom slash commands and skills (sort of), save/resume chats, subagents, and a two-level configuration (project and global). A full-featured coding agent.
While building this basic agent, we confirmed, firsthand, what Scott had said. And I kept wondering:
Why? What makes it so easy?
Is it the LLMs? Is it Ruby? Is it that it’s fun, so you don’t really feel the pain? Or is it something else?
After giving it some thought and talking about this with teammates, we converged on two key factors:
The first key: general availability of LLMs
General availability of LLMs changed the nature of the problem of building something like Detritus. Before, building a coding AI was unthinkable, but current LLMs made impossible things almost trivial:
Code some utility functions for the LLM to call (one for editing files, one for bash commands), hook up an LLM via API, put it all in a loop, and that’s it. You have a coding agent.
What used to be a research problem is now an integration problem. The problem migrated from the lab to the workshop.
The second key: Ruby’s power
Ruby is well known for its historical focus on developer happiness: “A programmer’s best friend”. I think this is a fundamental characteristic of the language, but sometimes I feel it’s a little superficial, and it doesn’t tell you why.
I think Ruby brings something else that is a much more fundamental property that emerges out of its design and philosophy: Power.
Originally, the idea of “powerful programming languages” came to me via Amir Rajan, creator of DragonRuby, when he shared this article from Paul Graham, “Beating the averages”. We talked about how and why Lisp was the most powerful language, with Ruby being a close second. Graham’s key insight — what he calls the “Blub paradox” — is that power in programming languages sits on a continuum, and you can only recognize a more powerful language from above, never from below.
Any general-purpose programming language is nowadays more or less equivalent, equally capable. You can build Detritus with the exact same features in Python, Go, JavaScript, or even in C. And yet, the experience of building this in Ruby feels fluid and frictionless. Like cutting a wooden block with a hand saw or a circular saw. Both will cut the wood just fine (they are equally capable), and you can probably enjoy both (personal taste is not the matter here), but one will make you feel more powerfully invested than the other.
I think power in programming languages is not just capability, but the relation between using the capability and the effort the developer has to invest in wielding it.
In this sense, Ruby has the ability to maximize the capability/effort ratio. The amount of power condensed in a few lines of code feels extraordinary.
If you take a look at Detritus’ source code, this is how you set up the agent:
def create_chat(instructions: state.instructions, tools: [EditFile, Bash, WebSearch, SubAgent], persist: true)
chat = RubyLLM::Chat.new(model: state.model, provider: $state.provider)
chat.with_instructions(instructions) if instructions
chat.on_end_message { |msg| save_chat } if persist
chat.with_tools(*tools)
end
Five lines of RubyLLM set the model, system prompt, and tools. That’s all you need to set the agentic loop ready to go.
And the rest of the code is the same: chat persistence is Marshal.dump. The CLI router is a case statement. The subagent is a tool that calls create_chat. None of this code is clever or magical; it’s just plain Ruby. That’s exactly the point. When the language is powerful enough, building an AI agent doesn’t require anything special, just the mundane. And Ruby makes the mundane exquisite, short.
Detritus’ history started when Thorsten Ball published The Emperor Has No Clothes, a guide to building a super basic coding agent in Go. My immediate thought after the head explosion was: if we did this in Ruby, it would take a fraction of the code and give us twice the features. So, as Thorsten suggested, “I went and tried how far I could get”. I got this far.
Raised to the power
LLMs’ general availability turned AI from a “research problem” into an “integration problem”. The nature of the work changed to match Ruby’s strengths: orchestration, expressiveness, and fast iteration.
When you combine Ruby with LLMs, you get compounding power. Power * Power. Power squared.
The key to building an agent is defining what to delegate to the LLM and what to handle in code. For example, Detritus’ skills feature: the code just provides a list of instructions and scripts. The actual skill, knowing when to use each one, how to combine them, that’s all the LLM.
This is where both keys meet. LLMs do the hard part; our job is orchestration. And Ruby makes the orchestration so clean you can see just how little code is actually needed. Compounding power.
The Opportunity
The Ruby AI ecosystem is young, but it’s growing fast. RubyLLM, the gem that powers Detritus, is already spawning its own ecosystem: MCP support, monitoring, agent frameworks, etc. Andrew Kane has quietly built an entire ML infrastructure layer for Ruby: transformers, torch, embeddings, vector search, and ONNX runtime. Officially supported SDKs from OpenAI, Anthropic, and MCP. The foundations are being laid right now, the Ruby way: simple, expressive, and delightful to use.
In the coming years, most of us, Ruby developers, won’t be training models. We will be orchestrating API calls, building agents, capabilities, features, and designing systems. Building products on top of a dynamic, ever-changing landscape. We’ll be doing what Ruby does best: making powerful capabilities accessible through elegant, expressive interfaces. And because of Ruby’s power, we can do those things naturally, frictionlessly, easily.
The same things that made Ruby great for web development 15 years ago are perfectly aligned again, but now with a more mature, faster, and modern Ruby. The potential is huge.
The Ruby community has decades of experience building products and delightful tools. The AI landscape is wide open, the tools are here, and the problem fits like a glove. So… what are we, Rubyists, going to do?