Supershipの名畑です。GW中に島本和彦先生 画業40周年突破記念『炎の原画展』を見に行ったので、心が熱い。
はじめに
ネットだけではなくテレビだ雑誌だといたるところでChatGPTの話題だらけで今更感ありまくりですが、自環境でOpenAIのChat API(Chat completions)を試した際の諸々を書き残しておきます。
ライブラリのインストール、アカウント作成から始まってChat APIとの会話の実装までの記録です。目新しいことはなにもないですが、少なくとも未来の自分の役には立ちそう。
大体の内容は公式のAPI ReferenceとGuideのままです。
自環境
macOS(Monterey)です。
Pythonはすでにインストール済みでした。3.10.7です。
$ python --version
Python 3.10.7
OpenAIのライブラリ(Pythonバインディング)をインストールしておきます。
$ pip install openai
今のバージョンは0.27.6でした。
$ openai --version
openai 0.27.6
OpenAIのアカウント作成
OpenAI platformでアカウント作成をします。
メールアドレス(電話での認証あり)、Google、Microsoft Accountのいずれかが使えます。
無料クレジットの範囲であれば支払い設定は不要です。
API key発行
サインイン後のAPI keysのページで行えます。Create new secret keyを押して、名前(optional)をつけるだけです。
API keyは作成時しか画面に表示されませんので気をつけてください。
他人とのシェアはしないこと、リークを検知した場合は自動でrotationされること等が注意書きされています。
取得したAPI keyはハードコーディングを避けるため環境変数にでも設定します。
公式に倣いOPENAI_API_KEYという環境変数名としました。
export OPENAI_API_KEY=ここに取得したAPI keyを書く
organization毎の使用量も取得できるのですが、今回は割愛します(Organization IDはOrganization settingsのページでわかります)。
APIの使用は従量課金なので要注意です(現時点では無料クレジットあり)。
価格はPricingのページでわかります。使用量はログイン後にUsageのページでわかります。
どれだけのトークンを処理したかで金額が決まります。英語であれば目安としては1000トークンは大体750単語に相当するそうです(言語によって異なります)。
今回用いるgpt-3.5-turboだと1000トークンで0.002米ドルです。1ドル135円換算だと0.27円ですね。(価格改定がありました)
PythonでのAPI keyのセット
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
# openai.organization = "organizationを紐づけるなら記載"
提供されているAPI
- Models
- Completions
- Chat
- Edits
- Images
- Embeddings
- Audio
- Files
- Fine-tunes
- Moderations
- Engines ※deprecated
今回はChat APIを使ってみます。
Chat APIとは
Given a list of messages describing a conversation, the model will return a response.
会話を示すメッセージ配列をモデルに渡し、応答を受け取ります。
Chat APIのリクエストパラメータ
APIにセットできるリクエストパラメータは下記です。
- model
-
messages
- role
- content
- name
- temperature
- top_p
- n
- stream
- stop
- max_tokens
- presence_penalty
- frequency_penalty
- logit_bias
- user
このうちrequiredなのは、太字にしたmodelとmessages(の配下のroleとcontent)のみです。
今回はrequiredの項目のみを使って呼び出しを行います。
model
使えるmodelはModelsに記載されています。
Chat APIで使えるmodelは下記です。
- gpt-4
- gpt-4-0314
- gpt-4-32k
- gpt-4-32k-0314
- gpt-3.5-turbo
- gpt-3.5-turbo-0301
modelによって扱える最大トークン数やいつまでの学習データを用いたかも異なります。
今回はgpt-3.5-turboを用います。
GPT-3.5 models can understand and generate natural language or code. Our most capable and cost effective model in the GPT-3.5 family is gpt-3.5-turbo which has been optimized for chat but works well for traditional completions tasks as well.
MAX TOKENSは4,096 tokensで、TRAINING DATAはUp to Sep 2021です。
余談ですがGPT-4を使うためにはGPT-4 API waitlistへの登録を行い、招待される必要があります。
messages
roleとcontentをセットにしてmessagesという配列に順番に格納します。
公式例は下記です。
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
roleにはsystem、user、assistantの三種類があります(詳しくはIntroductionをご覧ください)。
userは自分、assistantは相手(API)です。
systemはassistantの行動を設定します。
The system message helps set the behavior of the assistant. In the example above, the assistant was instructed with "You are a helpful assistant."
つまりは
{"role": "system", "content": "You are a helpful assistant."}
この記載であれば「あなたは有能なアシスタントです」という設定をしたことになります。
レスポンスのフォーマット
公式例は下記です。
{
'id': 'chatcmpl-6p9XYPYSTTRi0xEviKjjilqrWU2Ve',
'object': 'chat.completion',
'created': 1677649420,
'model': 'gpt-3.5-turbo',
'usage': {'prompt_tokens': 56, 'completion_tokens': 31, 'total_tokens': 87},
'choices': [
{
'message': {
'role': 'assistant',
'content': 'The 2020 World Series was played in Arlington, Texas at the Globe Life Field, which was the new home stadium for the Texas Rangers.'},
'finish_reason': 'stop',
'index': 0
}
]
}
choicesという配列配下にmessageがあり、そのcontentの中に応答の文章が格納されています。
質問してみる
質問を投げて応答を表示してみます。
ここからはわかりやすいように日本語のメッセージを投げてみます(品質的にもトークン数的にも本来は英語が良いのでしょうが)。
質問内容は「私がこれから英語を身に付けたいのならどの国で学習するのが良いと思いますか?」です。
まずはコードです。
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "非常に頭が良さそうな秘書としての回答をしてください"},
{"role": "user", "content": "私がこれから英語を身に付けたいのならどの国で学習するのが良いと思いますか?"}
]
)
print(completion["choices"][0]["message"]["content"])
実行すると応答は下記でした。
英語を身に付けるためには、英語の母国語話者と接する機会が最も効果的です。そのため、英語を話す国々に滞在し、その国の文化に触れることで、英語のスキルを向上させることができます。英語を話す国は多数ありますが、特にアメリカ、イギリス、カナダ、オーストラリア、ニュージーランドなどが英語学習に最適です。それぞれの国には独自のアクセントや文化がありますので、自分に合ったものを選ぶことが大切です。また、英語教育に力を入れている大学や語学学校がある都市を選ぶこともお勧めします。
systemを変えてみます。
{"role": "system", "content": "箇条書きで回答してください"},
その際の応答は下記です。
以下はいくつかのオプションです:
アメリカ合衆国 - アメリカ英語を学ぶには最適な場所であり、世界中の学生が選ぶ人気の留学先の一つです。
カナダ - 英語が第一言語として話されるため、アメリカ英語とは異なるアクセントやスラングが学べます。
イギリス - イギリス英語を最も正確に学ぶことができ、フィールドで使用されるビジネス英語の習得にも役立ちます。
オーストラリア - オーストラリア英語を学び、ネイティブスピーカーと接触することで、より自然な英語力を身に付けることができます。
以上の4つの国は、英語を身に付けるのに最適な場所であり、それぞれ異なるアクセントや文化を経験できます。あなたの学習目的や好みに応じて、最適な場所を選んで下さい。
会話をしてみる
最後に会話を実装してみます。つまりは「ユーザーの言葉」と「APIからの応答」を相互に行なっていくということです。
- userの入力
- assistantの応答
この二つをmessagesに随時追加して都度APIを呼び出せば会話になります。会話が続くに連れて必要なトークン数が増えていくことにご注意ください。
コードは下記です。
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
messages = [{"role": "system", "content": "くだけた言葉遣いで短めに話してください"}
]
while True:
# 入力 / messagesへの追加
your_message = input("あなたの番です: ")
if your_message == "quit": # quitと入力されたら終了
exit()
messages.append({"role": "user", "content": your_message})
# API呼び出し
try:
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages
)
except (openai.error.RateLimitError, openai.error.InvalidRequestError) as e:
print(e.user_message)
exit()
# 応答の取得 / 表示 / messagesへの追加
res_message = completion["choices"][0]["message"]["content"]
print("OpenAIの応答です: " + res_message)
messages.append({"role": "assistant", "content": res_message})
# token数の取得と表示
tokens = completion["usage"]["total_tokens"]
print("今回のToken数: " + str(tokens))
InvalidRequestError(MAX TOKENSを超えた時など)と、支払い設定をしていないと発生しやすいRateLimitError(呼び出し上限、1分あたり3回)を拾っています。本当は前者はmessagesの内容を減らしてのリトライ、後者は時間を置いてのリトライをしてあげた方が親切ですね。
やりとりは下記のようになりました。
「あなたの番です: 」の後ろが私の入力した内容です。ドラゴンボールについて聞いて、次は応答をさらに短くしてもらっています。
あなたの番です: ドラゴンボールって何?
OpenAIの応答です: ドラゴンボールは、日本の漫画家・鳥山明さんによって創作された、人気のある漫画・アニメのシリーズだよ!主人公・孫悟空が、悪を倒して世界を守る冒険が描かれているんだ。各キャラには特徴的な技や個性があり、バトルシーンは熱い!アニメや映画もあるから、見たことある人も多いかもね!
今回のToken数: 197
あなたの番です: もっと短い文章でお願い
OpenAIの応答です: ドラゴンボールは、鳥山明さんが作った人気の漫画・アニメだよ!主人公の孫悟空が悪と戦って世界を守る話だよ。
今回のToken数: 282
あなたの番です: quit
最後に
OpenAI関係の情報はインターネット上にいくらでも溢れてはいるのですが、今後も継続的に自分の手で試して残していこうとは思います。触ってみないと肌感が掴めないため。
宣伝
SupershipのQiita Organizationを合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。
Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方はSupership株式会社 採用サイトよりご確認ください。