Ruby on Rails AI integration: start with the boring stack
Everyone integrating AI into Rails is being told they need a new stack. They need about none of it.
Ruby on Rails AI integration does not require a new stack. A production LLM feature is an ordinary software problem, and Rails already solves most of it: background jobs for slow calls, ActiveRecord for state, service objects for tools, PORO validation for inputs and outputs.
The pressure to believe otherwise is commercial. Vector database vendors, orchestration platforms, and agent frameworks all need Rails teams to feel behind. The result is teams bolting a Python sidecar service onto a healthy monolith to do something a Sidekiq job could do with an HTTP call.
Here is the whole architecture for most Rails AI features:
- A background job makes the model call and handles retries.
- A service object wraps each capability the model can use.
- A plain Ruby validator checks everything the model returns before it touches your data.
- Postgres stores the transcript, the tokens spent, and the outcome.
That is it. No new infrastructure, no second language, no platform subscription.
The advantage is not just cost. It is legibility. When the AI feature misbehaves at 2am, the person on call reads ordinary Rails: a job, a service, a validation, a row in a table. They can fix it with the skills they already have. A five-service Python constellation with a message queue between your app and the model is a system nobody on your team can debug under pressure.
Boring is not timid. Boring is the production advantage.
Over the next ten posts I will walk through the whole approach: why model calls never belong in a request, tools as service objects, validation against a caller that hallucinates, evals, circuit breakers, and what gems you actually need.
We build these systems inside client teams for a living. If you want senior help shipping AI in a Rails codebase, that is literally our deepest specialization: Forward Deployed AI Engineer.