OpenAI APIを用いてChatBotを作ってみました!この記事では、特にOpenAI APIの使用部分に焦点を当てて説明をしていきます。
上記の実装をするための詳細なコードは以下をご覧ください。
OpenAI API とは?
OpenAI API とは OpenAI APIが提供するAPIで、ChatGPTに使用されている生成モデルにアクセスをすることができるAPIです。
このAPIを用いることで、簡単にチャットボットを作ることが出来ます!
APIキーの取得
まず、OpenAI APIを利用するには、APIキーを取得する必要があります。
APIキーを取得するためには、最低5ドル(およそ770円)のクレジットを購入する必要があります。APIキーの取得方法については、こちらの動画がとても参考になりますので、ぜひご覧ください。
コードの解説
OpenAI API の処理を実装しているクラスはChatViewModelです。
このクラスを3ステップに分けて解説していきます。
ステップ1: APIキーの設定
最初のコードでは主に、APIキーの取得を行っています。APIキーを直接コードに書くこともできますが、今回はセキュリティを考慮して、環境変数を使用する方法を紹介します。
APIキーの設定方法
- Xcodeのプロジェクトを開く
- 上部のメニューから
Product
>Scheme
>Edit Scheme...
を選択 - 左側のメニューで
Run
を選択 - 上部のタブで
Arguments
を選択 -
Environment Variables
セクションに以下を追加- Name:
OPENAI_API_KEY
- Value: ご自身で取得したAPIキー
- Name:
import Foundation
import OpenAI
import SwiftUI
class ChatViewModel: ObservableObject {
// チャットメッセージのリスト
@Published var messages: [ChatMessage] = [ChatMessage(role: .assistant, content: "こんにちは!")]
// ユーザーが入力中の新しいメッセージ
@Published var newMessage: String = ""
// characterプロパティを初期化するためのイニシャライザ
let character: CharacterType
// OpenAIのインスタンスをプロパティとして保持
private var openAI: OpenAI?
init(character: CharacterType) {
self.character = character
// 環境変数からAPIキーを取得
if let apiKey = ProcessInfo.processInfo.environment["OPENAI_API_KEY"] {
// OpenAIのインスタンスを作成
self.openAI = OpenAI(apiToken: apiKey)
print("APIキーが設定されました。")
} else {
print("APIキーが設定されていません。環境変数の設定をしてください")
}
}
ステップ2: メッセージ送信機能の実装
この関数では、role
と content
を引数として渡す ChatMessage
オブジェクトを定義します。そのオブジェクトを fetchOpenAIResponse
メソッドに渡して、返答を待ちます。
userMessageという定数を定義
func sendMessage() {
guard !newMessage.isEmpty else { return }
let userMessage = ChatMessage(role: .user, content: newMessage)
messages.append(userMessage)
newMessage = ""
// fetchOpenAIResponseメソッドを非同期タスクで呼び出し、OpenAIからの応答を取得。
Task {
await fetchOpenAIResponse(for: userMessage)
}
}
ステップ3: OpenAIからの応答を取得するメソッドの実装
この関数は、OpenAI APIにユーザーメッセージを送信し、取得した応答をチャットメッセージリストに追加する非同期処理を実行します。
ここでは、ユーザーメッセージとシステムメッセージの設定を行います。それぞれのメッセージは role と content の引数を持ちます。
contentには、ユーザーメッセージの場合、ユーザーが入力した文章が設定され、システムメッセージの場合は、キャラクター設定のプロンプトが与えられます。キャラクター設定のプロンプトは、別のクラスで定義されています。
@MainActor
private func fetchOpenAIResponse(for userMessage: ChatMessage) async {
guard let openAI = openAI else {
let errorResponse = ChatMessage(role: .assistant, content: "APIキーが設定されていません")
messages.append(errorResponse)
return
}
// ユーザーのメッセージ
guard let message = ChatQuery.ChatCompletionMessageParam(role: .user, content: userMessage.content),
// システムメッセージ(キャラクターのプロンプト)
let systemMessage = ChatQuery.ChatCompletionMessageParam(role: .system, content: character.prompt) else { return }
// 使用するモデルを指定
let query = ChatQuery(messages: [systemMessage, message], model: .gpt3_5Turbo)
do {
// クエリをOpenAIに送信し、応答を取得
let result = try await openAI.chats(query: query)
// 返された応答メッセージ
if let firstChoice = result.choices.first {
switch firstChoice.message {
// 応答メッセージがアシスタントからのものである場合、その内容をassistantMessageとして取得
case .assistant(let assistantMessage):
// 取得したアシスタントのメッセージをChatMessageオブジェクトに変換し、内容が空の場合はデフォルトで「がんばって!」というメッセージを設定
let assistantResponse = ChatMessage(role: .assistant, content: assistantMessage.content ?? "がんばって!")
messages.append(assistantResponse)
default:
break
}
}
} catch {
let errorResponse = ChatMessage(role: .assistant, content: "エラー: \(error.localizedDescription)")
messages.append(errorResponse)
}
}
終わりに
初めて、OpenAI API を使ってみましたが、思ったよりも簡単に出来たことに驚きました!特にサーバーサイドのシンプルさが際立っていました。
複数のユーザー間のメッセージングアプリを作るとなると、データベース管理や認証などがとても大変ですが、今回のChatBotアプリでは、OpenAIのライブラリが用意されているおかげで、とてもシンプルな記述でコーディングできたのがよかったです!
リンク