I found Ruby LLM to be surprisingly good - in terms of usability it's close to Vercel's AI framework.
It tries to strike a balance between working out of the box and being flexible... which has its challenges, still nice overall.
One big real-life pain I experienced is that caches don't always work, e.g. for xAI, since it only supports completions API and thought signatures are returned wrong.
We use RubyLLM in production too, the most elegant library in this space I've seen so far.
I also liked how they run the issue tracker. If you select "Feature Request", it makes you explain how you explored workarounds, why you believe it belongs in RubyLLM etc to prevent scope creep.
RubyLLM is very easy to use. Made extensive use of it for a project last year. Drawbacks are it was difficult to instrument for true trace observability and it has a pattern where retries will delete the underlying models so the history you see is clean but not necessarily great for seeing exactly what the sequence of API calls was.
It is quite nice, but not as nice as you'd want. You still have to set platform specifics when running completions when you want to tune things like temperature, effort, max tokens, etc.
Hi! Valid challenge, I am probably misremembering. We were playing with various 'one-interface to all providers' solutions and I might have mixed up RubyLLM there. Sorry for that.
I will have a deep dive into which things I felt we needed to adapt per provider.
I didn't mean to imply that you have to solve all of our wants of course.
One thing we did do was monkey-patch the spot where tool_calls are performed by RubyLLM. We had our own mechanism for that and were able to skip RubyLLM's and still extract the tool calls and run them through our own tool harness. That all worked beautifully. I don't know if that type of stuff is something you want PRs on or that you want to keep steering towards the route that does everything within RubyLLM classes. Happy to contribute some of that.
Why would anyone still build in dynamically typed languages in 2026? Why relinquish the crystal clear signals that static typing is able to provide to the LLM?