Rails Did Not Get Left Behind
Somewhere in 2024, a large number of Ruby developers made a decision they have never revisited. The SDKs shipped in Python first. The tutorials were in Python. Research teams published their reference implementations in Python. The conclusion followed on its own: if you want to build with these models, you leave Rails behind. Nobody announced that decision. It accumulated, one abandoned side project at a time, and most of the people who made it have not gone back to check whether it still holds.
It does not, and the gap between what people believe about Ruby and what is sitting in their Gemfile has gotten wide enough to cost them work.
I care about this because a stack choice made on a stale assumption is not an engineering decision. It is an inherited one. You should pick a language because of what the job in front of you needs, which means looking at what the tools do today rather than at what a blog post said two years ago.
So here is the state of it. The official Anthropic Ruby SDK passed version 1.59.0 in late July, runs on Ruby 3.2.0 or later, and gives you the full Claude API: structured tool definitions, streaming, and the tool runner patterns that make a multi-step agent something you configure rather than scaffold from scratch. RubyLLM, the community multi-provider framework, reached 1.16.0 in June and puts OpenAI, Anthropic, Gemini, Bedrock, Mistral, DeepSeek, OpenRouter, Perplexity, and Ollama behind one interface, plus anything that speaks an OpenAI-compatible API. Its Rails layer stores conversation history in ActiveRecord and handles streaming and context across sessions without you building persistence twice. These are not wrappers trailing the Python SDKs by six months. They are production tools with production adoption.
Choosing between them is a real decision with an easy answer most of the time. The official gem is right when your app talks only to Claude and you want new Claude features the day Anthropic ships them, because you get the exact API shape Anthropic intended. RubyLLM is right when you want provider switching and a chat history layer you did not have to design. A Gemfile carries both without conflict, the official gem handling the Claude-specific corner of the app while RubyLLM handles the multi-provider workflow.
Rails then does the thing it has always been good at, which is orchestration. The controller receives input and shapes it into a prompt. The model layer stores conversation history and tracks state across sessions. The service layer calls the provider, handles retries, and normalizes responses before anything reaches the controller. SolidQueue takes the long steps, the ones where an agent runs a sequence of tool calls across several minutes and has no business blocking a request. Request comes in, job is enqueued, agent runs, result comes back. That is not a workaround for Rails missing something. That is the framework doing its job.
The honest gap is the Agent SDK. Anthropic shipped the library that powers Claude Code’s internal loop, and it is programmable in Python and TypeScript only. A short Agent SDK program replaces hundreds of lines of custom scaffolding, because the context management, the tool runner loop, and interruption recovery are built in and hardened by every Claude Code user in the world. There is no official Ruby port. Nikita Sinenko laid out the three real options on July 1: hand-roll the agent loop over the official gem, use the community claude-agent-sdk gem that mirrors the Python surface by wrapping the CLI as a subprocess, or shell out to the Claude CLI yourself. All three work. None of them is the same thing as an SDK Anthropic maintains for you.
Whether that gap matters depends on what you are building, and for most teams it does not. Production Rails apps integrating AI are not building agents as complex as Claude Code. They are adding model capability at specific points in a workflow that already exists: summarize this document, classify this input, produce this structured output, run this research task from a background job. The Anthropic gem and RubyLLM cover all of it. The gap shows up at the top end, on long-horizon autonomous agents with complex state management, and if that is what you are building today, Python is the pragmatic call.
I built Rapidfy in Ruby. It generates full Rails applications from a spec using a model and a bash loop, with a verification layer between every step that checks the model’s proposed action against the constraints the spec defined. The Anthropic gem makes the API calls. SolidQueue runs the background steps. ActiveRecord holds the agent’s state between them. Nothing about that required leaving Ruby. The wall I hit was not language support. It was the same wall every agentic system hits: context budget management, where verification belongs, and what to do when the model proposes an action that contradicts something it established three steps ago.
Those are not language problems. They are harness problems, and they exist in every runtime. The Python Agent SDK makes them easier to manage in Python. The Ruby SDK makes the API calls easy and leaves the harness architecture to you. That is a real difference and it is worth naming, but it is the difference between a twenty-line setup and a two-hundred-line setup at the hardest end of the problem, not the difference between a viable AI language and a dead one.
The narrative that AI tooling passed Ruby by was never quite accurate. Python got the attention first, and the Agent SDK still has no Ruby port. Both of those are true, and the ecosystem for building real AI-augmented Rails applications is more complete than the people repeating that narrative have checked.
The developers who wrote Ruby off because the first tutorial they opened was in Python skipped the question worth asking: what does this job need, and what does this framework already do well? In 2026 the answer covers most of it, and the ones still waiting for permission to find out are the ones losing the time.
Be the first to comment
Thank you! Your comment will appear shortly, usually within a couple of minutes.
Something went wrong. Try again or contact me directly.