ruby-openai は GitHub で10,000スター以上を獲得している人気の OpenAI クライアント gem です。

GPT-4o はもちろん、GPT-5 や Realtime API にも対応しています。

本記事では Rails で実用的なチャットボットを作る手順を解説します。



インストール


# Gemfile
gem 'ruby-openai'

bundle install

config/initializers/openai.rb に API キーを設定します。


OpenAI.configure do |config|
config.access_token = ENV['OPENAI_API_KEY']
end


基本的なチャット


client = OpenAI::Client.new

response = client.chat(
parameters: {
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'あなたは親切なアシスタントです。' },
{ role: 'user', content: 'Rubyの魅力を教えてください' }
]
}
)
puts response.dig('choices', 0, 'message', 'content')


ストリーミング対応(リアルタイム表示)


長い回答をリアルタイムで表示するには stream オプションを使います。


client.chat(
parameters: {
model: 'gpt-4o',
stream: proc { |chunk, _bytesize|
content = chunk.dig('choices', 0, 'delta', 'content')
print content if content
},
messages: [{ role: 'user', content: '長い文章を書いてください' }]
}
)

Rails + ActionCable と組み合わせると、WebSocket 経由でリアルタイム表示ができます。



会話履歴の管理


複数ターンの会話を扱うには、messages 配列に履歴を蓄積します。


class ConversationService
def initialize
@messages = [
{ role: 'system', content: 'あなたは親切なアシスタントです。' }
]
@client = OpenAI::Client.new
end

def chat(user_input)
@messages << { role: 'user', content: user_input }

response = @client.chat(
parameters: { model: 'gpt-4o', messages: @messages }
)

answer = response.dig('choices', 0, 'message', 'content')
@messages << { role: 'assistant', content: answer }
answer
end
end


Function Calling(ツール使用)


AI に外部関数を呼ばせることもできます。天気取得の例です。


response = client.chat(
parameters: {
model: 'gpt-4o',
messages: [{ role: 'user', content: '東京の天気は?' }],
tools: [{
type: 'function',
function: {
name: 'get_weather',
description: '指定した都市の天気を取得する',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: '都市名' }
},
required: ['city']
}
}
}]
}
)


画像生成(DALL-E)


response = client.images.generate(
parameters: {
model: 'dall-e-3',
prompt: 'Rubyのロゴをサイバーパンク風に描いてください',
size: '1024x1024'
}
)
puts response.dig('data', 0, 'url')


まとめ


ruby-openai は薄いラッパーなので OpenAI の公式ドキュメントをそのまま参照しながら実装できます。

ストリーミング・Function Calling・画像生成まで1つの gem で対応できるのが強みです。