ツール

PythonでChatGPTに質問(APIの使い方)

2023年8月8日

今回はAPIを使用してChatGPTをPythonで操作する方法について紹介します。
はじめにChatGPTのAPIについて説明し、その後にコードについて説明します。
コード解説まで飛びたい方はこちらへどうぞ。

ChatGPTのAPIについて

ChatGPTはGUIで質問文を入力することもできますが、APIを通してPythonでやり取りすることもできます。

2023年8月現在、GUIは登録すれば無料で使用することができますが、APIでは処理した文字数(トークン数)に応じて料金がかかります。
新規アカウント作成時は無料使用枠もありますが、あくまでクレジットカードの登録が前提です。
トークン数はChatGPTに投げた質問文とChatGPTからの回答の両方が課金対象です。
ただし、GPT3.5(無料版ChatGPTと同じ)で100字程度のやりとりをするには1回あたり1円以下しかからず、個人で短いやり取りをして遊ぶ分にはわずかな金額しかかかりません。
一方でGPT4.0を使うと単価が20倍に上がるので一気にコスト感が強くなります(2023年7月現在、GPT4.0はAPI使用料金支払い実績ある者のみ利用可)。

このようにAPIは料金がかかる代わりにできることの幅が広がります。
たとえば、Pythonのコードを組み合わせることでChatGPTへの質問を自動化したり、処理の結果をCSVに出力することができます。
GPT4.0を使うとより新しいデータに基づく回答を行ったり、画像の入力に対応するなど機能が進化しています。

次項では、APIを通してChatGPTに質問するコードを作成・解説していきます。

PythonでChatGPTのAPIを使用(コード解説)

ここからはPythonでAPIを使用してChatGPTに質問するコードを紹介していきます。

パッケージ

PythonでChatGPTのAPIを利用するにあたって以下のパッケージを使用しました。

Python
import openai

APIを実行するには、Open AIのアカウントにて作成したAPIキーが必要です。
APIキーは、Personal→View API keys→Create new secret keyで作成します。

作成したキーが漏洩すると他人が使用しているのに自分に支払い請求が来てしまいます。
今回は、漏洩を防ぐためにapikey.pyという別ファイルを作成してAPIキーを保存し、apikey.pyを関数として呼び出す形で使用しました。

Python
# APIキーは.pyファイルに記載
from apikey import APIKEY
# APIキーを取得
openai.api_key = APIKEY

なお、apikey.pyには次のような形でAPIキーを記述しています。

Python
APIKEY = 'sk-*************************'

関数定義:GPTへ質問

次にAPIで質問する関数を作成します。

Python
# 関数定義:ChatGPTに文章生成指示
def get_gpt_res(model, sys_txt, usr_txt, ass_txt):
    response = openai.ChatCompletion.create(
        model=model,
        messages=[
            {"role": "system", "content": sys_txt},
            {"role": "user", "content": usr_txt},
            {"role": "assistant", "content": ass_txt}
            ],
        temperature=0.5
    return(response)

openai.ChatCompletion.create関数がAPIを通してChatGPTに質問を投げる関数です。

"model"はGPTのモデルの指定です。
同じGPTのバージョンでも複数のモデルがあり、たとえばGPT3.5であれば"gpt-3.5-turbo"、GPT4.0であれば"gpt-4"などを指定します。

"messages"はChatGPTに投げる質問文の指定です。
辞書型での入力になっており、"content"に文章を入れます。
”role”では"content"に入れる文章の役割を指定します。

rolecontentの文章の解釈指示文の例
userGPTへの質問文日本の首都はどこ?
systemGPTが質問に回答する際の制約条件100字以内で回答せよ。
assistant質問に至るまでの会話内容・文脈等(翻訳をする場合は翻訳したい文章を入力)

"role":"user"の”content”の文章はChatGPTへの質問文であると解釈されます。
一方、"role":"sysytem"の場合、"content"の文章はChatGPTが質問に回答する際に課す制約条件を与えることができます。
たとえば、"role":"userに「日本の魅力を教えて下さい」と入力し、"role":"sysytem"に「100字以内で回答せよ」と入力すると100字以内で日本の魅力について回答してくれます(うまくいかないこともあります)。

GPTに質問を投げる

次のコードでは、"role":"sysytem"(下記コードのsys_txt)に回答に対する制約条件と質問の回答に必要な情報を入れた上で質問しています。

Python
model = "gpt-3.5-turbo"
sys_txt = "語尾に!をつけて回答せよ。栃木県芳賀町には鉄道は通っていませんでしたが、2023年8月26日に宇都宮ライトレールが開業し、宇都宮駅との間に新しい鉄道路線ができました。"
ass_txt = ""

# 質問文
usr_txt = "栃木県芳賀町には鉄道は通っていますか。路線名を教えてください。"
res = get_gpt_res(model=model, sys_txt=sys_txt, usr_txt=usr_txt, ass_txt=ass_txt)

# 回答文面
print(res["choices"][0]["message"]["content"])

ChatGPTの回答は次のようになりました。

Python
# いいえ、栃木県芳賀町には鉄道は通っていませんでした!しかし、2023年8月26日に宇都宮ライトレールが開業し、宇都宮駅との間に新しい鉄道路線ができましたよ!

ちなみに、"role":"sysytem"(上記コードのsys_txt)に何も入力せずに質問した場合は次のような回答になりました。

Python
# 栃木県芳賀町には鉄道は通っていません。芳賀町には鉄道駅は存在しません。最寄りの鉄道駅は、JR東北本線の小山駅や、東武伊勢崎線の新大平下駅などがあります。

宇都宮ライトレールにふれない回答を返してきました(最寄り駅は誤答ですが…)。
"role":"sysytem"(上記コードのsys_txt)に文章を入力すると、それの内容をふまえた上で回答していることがわかります。

文脈をふまえた回答

文脈をふまえた回答が欲しい場合は過去のやり取りを入力します。この際、messagesには"role":"user"に自分の応答、"role":"assistant"にChatGPTの応答を入力します。
応答を複数回繰り返した場合は、それぞれの応答回数分messagesの引数を追加します。

Python
model = "gpt-3.5-turbo"

# 文脈をふまえた回答
response = openai.ChatCompletion.create(
        model=model,
        messages=[
            {"role": "system", "content": "語尾に「!」とつけて10字以内で答えて下さい。"},
            {"role": "user", "content": "くまモンはどこのゆるキャラですか?"},
            {"role": "assistant", "content": "熊本県です。"},
            {"role": "user", "content": "その県はどこにありますか?"},
            ],
        temperature=0.5
    )
print(response["choices"][0]["message"]["content"])

「その県はどこにありますか」という質問に対し、その県が熊本県であることを理解した上で回答を返してくれます。

Python
# 九州地方にあります!

このように"role":"assistant"はChatGPTが回答する際に考慮すべき文脈として処理されます。
そのため、翻訳や要約を依頼する場合には"role":"user"に「日本語に翻訳して下さい」と入力し、"role":"assistant"には翻訳してほしい英文を入力すると、"role":"assistant"に入力した英文を日本語に翻訳した結果を返してくれます。

Python
model = "gpt-3.5-turbo"
sys_txt = ""
ass_txt = "Japan is an island country in East Asia." # 翻訳してほしい文章

# 質問文
usr_txt = "次の文章を日本語に翻訳して下さい。" # ChatGPTへの指示
res = get_gpt_res(model=model, sys_txt=sys_txt, usr_txt=usr_txt, ass_txt=ass_txt)

# 回答文面
print(res["choices"][0]["message"]["content"])

ChatGPTは"role":"assistant"(上記コードのass_text)に入力した英文を日本語に翻訳して返してくれました。

Python
# 日本は東アジアにある島国です。

以上のように、APIを通して単にChatGPTに質問するだけではなく、色々な指示をしたり回答に必要な情報を与えた上で質問することができます。
GUIでこのような指示を毎回行うのは面倒ですが、コードで実行することで簡単に処理できます。

今回は1つの質問に対して回答を得るコードを紹介しました。
1回のやりとりで終わらず、ChatGPTと会話を続けるコードについては以下のページで紹介しています。

参考PythonでChatGPTと会話を楽しむ(API使用)

前回はAPIを使ってPythonでChatGPTに質問をして回答をもらう関数を作成しました。今回は1回のやりとりで終わるのではなく、会話を続けられる関数を作成してChatGPTと会話を楽しめるコードを ...

続きを見る

参考文献

OpenAI API, OpenAI 2023/8/6閲覧
Pricing, OpenAI 2023/8/6閲覧
中山茂「ChatGPT API 生成AIプログラミング入門」 Independently published (2023) p40-47
ChatGPT API(gpt-3.5-turbo)のメッセージオブジェクトのroleパラメータを徹底解説 株式会社SiNCE 2023/8/6閲覧
API Reference, OpenAI 2023/8/7閲覧

-ツール
-,