RubyLLM: 레일러스를 위한 통합 AI 인터페이스 가이드

RubyLLM: 레일러스를 위한 통합 AI 인터페이스 가이드

최근 AI 기능을 애플리케이션에 통합하는 것은 선택이 아닌 필수가 되었습니다. 하지만 OpenAI, Anthropic, Google 등 다양한 공급자(Vendor)의 API를 각각 호출하는 방식은 코드의 복잡도를 높이고 유지보수를 어렵게 만듭니다. 다행히 최근 Hacker News를 통해 화제가 된 RubyLLM 같은 도구가 등장하여, Ruby와 Rails 생태계에 통합된 AI 개발 환경을 제공하고 있습니다.

이번 포스트에서는 RubyLLM을 활용해 Ruby on Rails 애플리케이션에서 주요 LLM 공급자를 단일 인터페이스로 관리하고 실전에서 활용하는 방법을 알아보겠습니다.

RubyLLM이란?

RubyLLM은 Ruby 및 Rails 프레임워크에서 사용할 수 있는 경량화된 AI 클라이언트 라이브러리입니다. 이 라이브러리의 핵심 강점은 ‘Provider Agnostic(공급자 독립적)’ 설계입니다. 개발자는 특정 벤더의 SDK에 의존하지 않고, RubyLLM이 제공하는 표준화된 메서드를 통해 여러 AI 모델을 유연하게 호출할 수 있습니다.

주요 특징은 다음과 같습니다:

  1. 다양한 공급자 지원: OpenAI(GPT), Anthropic(Claude), Google(Gemini) 등 주요 모델을 단일 gem으로 관리
  2. Rails 친화적: ActiveRecord와 같은 친숙한 패턴의 API 제공
  3. 스트리밍 지원: 실시간 응답 생성을 위한 스트리밍 인터페이스 내장

프로젝트 설정

먼저 Gemfile에 RubyLLM을 추가하고 설치합니다. (현재 최신 버전을 가정합니다)

# Gemfile
gem 'ruby_llm'

번들로 설치한 후, 환경 변수를 통해 API 키를 설정합니다. Rails의 credentials.yml.enc.env 파일을 활용하는 것이 좋습니다.

# .env
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...

기본 사용법: Chat 인터페이스

RubyLLM을 사용하면 가장 기본적인 텍스트 생성 작업을 매우 직관적으로 구현할 수 있습니다. 다음은 Rails 컨트롤러나 서비스 객체 내에서 LLM을 호출하는 예제입니다.

1. OpenAI GPT-4o 호출

require 'ruby_llm'

# 클라이언트 초기화
client = RubyLLM::Client.new

response = client.chat(
  model: "gpt-4o",
  messages: [
    { role: "system", content: "당신은 친절한 어시스턴트입니다." },
    { role: "user", content: "Rust 언어의 주요 특징을 설명해주세요." }
  ]
)

puts response.content
# => "Rust는 메모리 안전성, 고성능, 그리고 안전한 동시성을 중점적으로 설계된 시스템 프로그래밍 언어입니다..."

2. 모델 간 간편 전환 (Vendor Lock-in 방지)

비즈니스 요구사항이 변경되어 OpenAI에서 Google의 Gemini로 전환해야 한다면, 모델 이름과 키만 변경하면 됩니다. 코드 구조는 그대로 유지됩니다.

# 기존 코드 유지, 모델명만 변경
gemini_response = client.chat(
  model: "gemini-1.5-pro",
  messages: [
    { role: "system", content: "당신은 기술 블로거입니다." },
    { role: "user", content: "ZeroClaw 아키텍처에 대해 요약해줘." }
  ]
)

실전 활용: 스트리밍 응답 구현하기

사용자 경험(UX)을 위해서는 생성형 AI의 답변을 한 번에 기다리는 것보다, 타자를 치듯이 실시간으로 보여주는 스트리밍 방식이 선호됩니다. RubyLLM은 블록(Proc)을 통해 이를 쉽게 구현합니다.

다음은 Rails의 Turbo Stream과 함께 사용하여 실시간으로 화면에 텍스트를 출력하는 서비스 클래스 예제입니다.

# app/services/ai_streaming_service.rb
class AiStreamingService
  def initialize(user_message)
    @user_message = user_message
  end

  def call
    client = RubyLLM::Client.new
    
    # OpenAI 스트리밍 호출
    client.chat(
      model: "gpt-4o-mini",
      messages: [{ role: "user", content: @user_message }],
      stream: proc { |chunk| 
        # 수신된 텍스트 덩어리(chunk)를 처리
        # 예: Rails 채널을 통해 클라이언트로 브로드캐스트
        ActionCable.server.broadcast "ai_channel", { content: chunk }
        
        # 또는 로그 출력
        print chunk
        $stdout.flush
      }
    )
  end
end

이 패턴을 사용하면 LLM이 토큰을 생성할 때마다 클라이언트 브라우저로 즉시 전송하여, 마치 ChatGPT를 사용하는 것과 같은 부드러운 경험을 제공할 수 있습니다.

결론: Ruby 생태계의 AI 개발 트렌드

과거 Ruby는 AI 개발 영역에서 파이썬(Python)에 비해 뒤처진다는 평가를 받기도 했습니다. 그러나 RubyLLM과 같은 프레임워크의 등장은 ‘AI 모델 자체를 개발하는 것’이 아니라 ‘AI 모델을 활용하는 애플리케이션’을 구축하는 데 있어 Ruby가 여전히 강력한 경쟁력을 가짐을 보여줍니다.

특히 우리 팀(ZeroClaw)이 추구하는 에이전트 런타임 구현에 있어, Ruby의 높은 생산성과 RubyLLM의 유연한 추상화 계층을 결합한다면, 복잡한 멀티 에이전트 시스템을 더 빠르게 프로토타이핑하고 구축할 수 있을 것입니다.

Python 생태계의 LangChain이나 LlamaIndex가 대중화된 것처럼, Ruby 생태계에서도 RubyLLM이 표준처럼 자리 잡을 가능성이 매우 높아 보입니다. Rails 개발자라면 지금 당장 테스트 프로젝트에서라도 이 도구를 적용해 보시길 권장합니다.

참고 자료

Hugo로 만듦
JimmyStack 테마 사용 중