はじめに
こんにちは、エンジニア3年目の嶋田です。
この記事を開いていただきありがとうございます!
今回の記事では、RailsアプリケーションでGPT APIを利用する方法についてまとめました。
AIがますます注目される中、GPT APIをアプリケーションに統合して自然な会話や高度なテキスト生成を行うことが可能です。
この技術は、テキスト要約、質問応答、自然な会話生成などに応用できます。
今回は、私自身が業務で取り組んだ実装方法の一例を少し変えて、実例を用いながら
RailsアプリケーションにGPTを統合する際の基本的な実装方法を紹介していきます!
私も実際に実装する上で勉強になったので備忘録としてまとめました。
参考にしていただければ幸いです。
目次
GPT APIとは
GPT APIとは、OpenAIが提供する高度な言語モデル(GPTシリーズ)を外部から利用できるAPIです。このAPIを利用することで、アプリケーションでテキスト生成、要約、翻訳、質問応答などを行うことが可能です。
GPT APIはREST形式で、POSTリクエストを送信し、JSON形式の応答を受け取ります。利用できるモデルには複数のバージョンがあり、主に最新のGPT-4や、安価で高速なGPT-3.5が使われています。
詳しくはこちら👉 OpenAI API Documentation
RailsでAPIを利用するための準備
APIキーの取得
まず、GPT APIを使用するためには、OpenAIからAPIキーを取得する必要があります。
公式サイトでアカウントを作成し、APIキーを取得してください。
次に、RailsアプリケーションでAPIキーをどのように管理するかを決定します。主に以下の2つの方法があります。
.env
ファイルを使用する方法- Railsの
credentials
を使用する方法
この2つの方法について、メリット・デメリットを踏まえながら、それぞれの手順を説明します。
.env
ファイルでの管理
Railsで環境変数を管理するためには、dotenv-rails
というGemを使用して、.env
ファイルを活用する方法があります。これは開発初期の段階では簡単にセットアップできるため、よく使われる手法です。
メリット
- セットアップが非常に簡単で、環境変数の追加や変更が手軽です。
- 環境ごとに異なる
.env
ファイルを用意することで、開発環境や本番環境を簡単に切り替えられます。
デメリット
-
.env
ファイルは誤って漏洩するリスクがあり、セキュリティ面では脆弱です。 - 本番環境では
.env
ファイルを管理する手間がかかり、漏洩リスクが高まる可能性があります。
手順
1. Gemfileにdotenv-rails
とruby-openai
を追加
gem 'dotenv-rails'
gem 'ruby-openai'
- dotenv-railsは、Railsで環境変数を管理するためのGemです。これを使うことで、環境ごとに異なる設定を簡単に行えます。
-
ruby-openaiは、OpenAIのAPIにアクセスするための公式Rubyクライアントです。このGemを使って、APIとやり取りできます。
- README
2. .env
ファイルにAPIキーを追加
プロジェクトのルートに.env
ファイルを作成し、APIキーを追加します。
OPENAI_API_KEY=your_openai_api_key_here
3. config/initializers/openai.rb
でAPIキーを読み込む
APIキーを使用して、OpenAI APIクライアントを初期化するための処理を行います。
require 'openai'
OpenAI.configure do |config|
config.access_token = ENV['OPENAI_API_KEY']
config.log_errors = true
end
これにより、.env
ファイルに保存されたAPIキーを使用してOpenAIのクライアントを初期化します。
credentials
での管理
credentials
を使用する方法は、APIキーやその他の機密情報を暗号化して安全に管理するための方法です。Railsの標準機能として提供されており、セキュリティ面で非常に優れています。
メリット
- APIキーが暗号化されるため、セキュリティが高く、情報漏洩のリスクが低いです。
- Railsの標準機能として一貫して利用でき、変更履歴や管理がシンプルです。
デメリット
-
rails credentials:edit
コマンドを使うため、設定がやや複雑で、チーム内での共有や変更時に手間がかかることがあります。 - 複数の環境(開発・本番)に対応する際、少し手間が増えます。
手順
1. エディタの設定
まず、rails credentials:edit
コマンドを実行するためには、環境変数EDITOR
またはVISUAL
に使用するテキストエディタを設定する必要があります。以下のようにコマンドを実行して設定してください。
-
nanoを使用する場合:
EDITOR="nano" bin/rails credentials:edit
-
Vimを使用する場合:
EDITOR="vim" bin/rails credentials:edit
2. APIキーを追加
エディタが開いたら、次のようにAPIキーを追加してください。config/credentials.yml.enc
に追記されます。
openai:
development:
api_key: your_openai_dev_key_here
production:
api_key: your_openai_prod_key_here
3. Gemfileにruby-openai
を追加
RailsアプリケーションでOpenAIを使用するために、Gemfileに以下を追加しbundle install
を実行します。
gem 'ruby-openai'
#### 4. **`config/initializers/openai.rb`でAPIキーを読み込む**
APIキーを使用して、OpenAI APIクライアントを初期化するための処理を行います。
```ruby
require 'openai'
OpenAI.configure do |config|
config.access_token = Rails.application.credentials.openai[Rails.env.to_sym][:api_key]
config.log_errors = true
end
.env
ファイルとcredentials
の比較
管理方法 | メリット | デメリット |
---|---|---|
.env ファイル |
セットアップが簡単で、開発環境での運用に便利。 | セキュリティリスクがある。ファイルの漏洩や誤操作に注意が必要。 |
credentials |
機密情報が暗号化されるため、セキュリティが非常に強い。 | 設定や変更時にコマンドが必要で、複数環境の設定に手間がかかる。 |
credentials
はセキュリティを重視する本番環境での運用に適しており、dotenv-rails
を使用した.env
ファイルは開発環境や簡易なプロジェクトに適しています。どちらを選ぶかは、プロジェクトの規模や運用方針に応じて決定してください。
要約生成機能の実装
ここからは、GPT APIを使ってURLの内容を要約する機能を実装していきます。
1. ルーティング設定
まず、config/routes.rb
でルーティングを設定します。
Rails.application.routes.draw do
get 'summary/new', to: 'summary#new', as: 'new_summary'
post 'summary/create', to: 'summary#create', as: 'create_summary'
root 'summary#new'
end
2. フォームクラスの作成
次に、app/forms/summary_form.rb
でフォームオブジェクトを作成し、要約生成のロジックを定義します。
class SummaryForm
include ActiveModel::Model
attr_accessor :url, :result
def initialize(params)
@url = params[:url]
@result = nil
end
def generate_summary
prompt = build_prompt_from_url
@result = generate_results(prompt)
@result.present?
end
private
def build_prompt_from_url
<<~PROMPT
以下のURLの内容を要約してください。
URL: #{@url}
要約を3つのポイントに分けて、簡潔にまとめてください。
PROMPT
end
def generate_results(prompt)
GptService.new(prompt).call
rescue StandardError => e
errors.add(:base, "要約生成に失敗しました: #{e.message}")
nil
end
end
3. サービスクラスの作成
次に、app/services/gpt_service.rb
でGPT APIにリクエストを送信し、要約を生成するクラスを実装します。
※ エラーメッセージはユーザーに合わせて変えて下さい。
class GptService
def initialize(prompt)
@prompt = prompt
end
def call
client = OpenAI::Client.new
response = client.chat(
parameters: {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: @prompt }]
}
)
if response['choices'] && response['choices'].any?
response['choices'][0]['message']['content']
else
'GPTからの応答がありません'
end
rescue OpenAI::Error => e
handle_openai_error(e)
rescue StandardError => e
"システムエラーが発生しました。エラー内容: #{e.message}"
end
def handle_openai_error(error)
case error
when OpenAI::QuotaExceededError
'GPTのクォータが超過しました。プランと請求情報を確認してください。'
when OpenAI::AuthenticationError
'GPTへの認証に失敗しました。APIキーを確認してください。'
when OpenAI::ConnectionError
'GPTサーバーとの通信に失敗しました。インターネット接続を確認してください。'
else
"OpenAIのエラーが発生しました: #{error.message}"
end
end
end
4. コントローラーの作成
app/controllers/summary_controller.rb
で、フォームからの入力を処理し、要約結果を表示します。
class SummaryController < ApplicationController
def new
end
def create
url = params[:url]
summary_form = SummaryForm.new(url:)
if summary_form.generate_summary
session[:summary_result] = summary_form.result
redirect_to new_summary_path, notice: '要約が正常に作成されました'
else
flash[:alert] = '要約作成に失敗しました'
redirect_to new_summary_path
end
end
end
5. ビューの作成
app/views/summary/new.html.erb
で、ユーザーがURLを入力するフォームと結果表示を作成します。
<div class="wrapper">
<h1 class="summary-title">サイト要約生成</h1>
<%= form_with url: create_summary_path, method: :post, class: "summary-form" do %>
<div class="form-group">
<div class="input-group">
<%= text_field_tag :url, params[:url], placeholder: "要約したいサイトのURLを入力してください", class: "url-input" %>
<%= submit_tag "要約を生成", class: "submit-button" %>
</div>
</div>
<% end %>
<% if session[:summary_result].present? %>
<h2 class="summary-result-title">要約結果</h2>
<div class="summary-result-container">
<ul class="summary-result">
<% session[:summary_result].split(/\r?\n/).each do |item| %>
<li><%= item.strip %></li>
<% end %>
</ul>
</div>
<% session.delete(:summary_result) %>
<% end %>
</div>
スタイルの設定
最後に、画面のスタイルを設定します。
.wrapper {
width: 80%;
max-width: 900px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.summary-title {
text-align: center;
margin-top: 30px;
margin-bottom: 30px;
font-size: 24px;
}
.input-group {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
width: 100%;
}
.url-input {
flex-grow: 1;
padding: 10px;
border-radius: 5px;
border: 1px solid #ccc;
}
.submit-button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.summary-result-title {
text-align: center;
margin-top: 100px;
margin-bottom: 30px;
font-size: 20px;
}
.summary-result-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.summary-result {
background-color: #fff;
padding: 15px;
border-radius: 5px;
border: 1px solid #ccc;
width: 100%;
line-height: 1.6;
font-size: 1.1em;
}
完成画面
まとめ
最後までお付き合いいただきありがとうございました。
この記事では、RailsアプリケーションにGPT APIを統合し、入力したURLの内容を要約する機能の実装方法を解説しました。GPT APIを使うことで、テキスト生成や要約機能を簡単にアプリケーションに統合できるため、さまざまなプロジェクトで応用できます。今後AIを実装する機会は増えていくかもしれないので、もっといい方法があればコメントにて教えて下さい。