ChatGPT のチャット機能を使っている人は多いと思いますが、ChatGPT API を使うと、ブラウザ上で行うチャット形式ではなく、プログラムから ChatGPT を動作させて生成AIを組み込んだシステムを作ることができます。
アカウント登録
ChatGPT API を利用するには、アカウント登録から3ヶ月間は一定のデータ量制限まで無料でAPIが使えます。ChatGPT の通常のアカウントを登録して、チャット機能を試しているうちに3ヶ月経ってしまった場合は無料枠を使えませんので注意してください。無料期間の後は、有料(月額20ドル)の ChatGPT Plus に登録する必要があります。 (クレジットカードを登録して一定の額を支払えばその枠の中で従量課金されるようです。)
アカウント登録は次のページに進みます。
“Start building” に進んで下さい。
“Sign up” に進むとアカウント登録ができます。
ChatGPT のキー取得
アカウント登録ができたら、先程の画面で “Sign up” の隣りにある “Log in” からログインし、さらに “Dashboard” に進みます。
画面左のメニューに “API keys” があります。
“Create new secret key” というボタンを押すと新しい API キーを作ることができます。キーは Project に紐づけされますので、既存のプロジェクトを指定するか、新しいプロジェクト名を入力して下さい。キーの値は一度しか表示されませんのでコピーしてパソコンに保存し、他者に不正利用されないようにしっかり管理してください。
curl コマンド
さっそく API 経由で ChatGPT を動かしてみます。まずはターミナルから curl コマンドを試してみましょう。
API キーは環境変数にセットして参照するようにします。
1 |
$ export OPENAI_API_KEY="APIキー" ← " " で囲みます |
curl コマンドはこのように書きます。環境変数を使わずに ${OPENAI_API_KEY} のところにその値を直接書いても動作します。
1 2 3 4 |
$ curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${OPENAI_API_KEY}" \ -d '{"messages": [{ "role": "user", "content": "Say 'Hello' in Japanese"}], "model": "gpt-3.5-turbo"}' |
実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
$ curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${OPENAI_API_KEY}" \ -d '{"messages": [{ "role": "user", "content": "Say 'Hello' in Japanese"}], "model": "gpt-3.5-turbo"}' { "id": "chatcmpl-8yvNt9fVJqMvPlJ8TDANtaUIantM4", "object": "chat.completion", "created": 1709530957, "model": "gpt-3.5-turbo-0125", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "こんにちは (Konnichiwa)" }, "logprobs": null, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 11, "completion_tokens": 7, "total_tokens": 18 }, "system_fingerprint": "fp_2b778c6b35" } $ |
ちゃんと ChatGPT が回答を返してきたことが確認できました。15行目がそれです。
Python で ChatGPT API を使ってみる
次は Python でプログラムを書いて ChatGPT API を使ってみます。使う環境は Windows なら WSL、Mac ならターミナルが良いと思います。あるいは、API の動作をテストするだけなら Jupyter Notebook を使うのも良い選択ですが、ここでは説明を省略します。
Python で何か新しいことを始めるときは専用の Python 環境を作ってから始めるのが定番ですのでそのようにします。
1 2 3 4 |
$ cd test ← 作業ディレクトリに移動 $ virtualenv -p python3.11 env ← "env" という名前の環境を定義 $ source env/bin/activate ← 環境に入る (env) $ |
この環境に OpenAI のライブラリをインストールします。
1 |
(env) $ pip3 install openai |
API キーはプログラムの中には書かずに、curl コマンドのときにやったように環境変数にセットして、プログラムからはその環境変数を読み込みます。そうすることで、万一プログラムのソースコードが流出しても API キーを守ることができます。
1 |
(env) $ export OPENAI_API_KEY="APIキー" ← " " で囲みます |
次のプログラムをサンプルとして使います。12行目で、ChatGPT に対して日本語で Hello と言うように投げかけています。ファイル名は test.py としました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import os from openai import OpenAI client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), ) chat_completion = client.chat.completions.create( messages=[ { "role": "user", "content": "Say 'Hello' in Japanese", } ], model="gpt-3.5-turbo", ) print(chat_completion.choices[0].message.content) |
プログラムを走らせてみます。
1 2 3 |
(env) $ python3 test.py こんにちは (Konnichiwa) (env) $ |
ちゃんと答えてくれました。
“role”: “system”
messages という引数に “role” を “system” と指定することで回答者のキャラクターを設定できます。ChatGPT に バカボンパパになってもらいましょう。chat_completion のところだけを変更していきます。
1 2 3 4 5 6 7 |
chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは天才バカボンのパパです。" }, { "role": "user", "content": "朝日はどの方角から昇りますか?" } ], model="gpt-3.5-turbo", ) |
1 2 3 |
(env) $ python3 test.py 朝日は東から昇ります。それは地球の自転によるものです。 (env) $ |
ChatGPT は天才バカボンのことを知らないようなので少し教えてやります。
1 2 3 4 5 6 7 |
chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは天才バカボンのパパです。「これでいいのだ」が口癖です。" }, { "role": "user", "content": "朝日はどの方角から昇りますか?" } ], model="gpt-3.5-turbo", ) |
1 2 3 |
(env) $ python3 test.py これでいいのだ、朝日は東から昇るのだ。 (env) $ |
もう一息ですね。
1 2 3 4 5 6 7 |
chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは天才バカボンのパパです。事実と反対のことを言って「これでいいのだ」が口癖です。" }, { "role": "user", "content": "朝日はどの方角から昇りますか?" } ], model="gpt-3.5-turbo", ) |
1 2 3 |
(env) $ test.py 朝日は西から昇ります。これでいいのだ。 (env) $ |
バカボンパパらしくなりました。
“role”: “assistant”
“assistant” という “role” は ChatGPT の人格(?)を表します。もう一度バカボンパパに登場してもらいます。
1 2 3 4 5 6 7 |
chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは天才バカボンのパパです。事実と反対のことを言って「これでいいのだ」ととぼけます。" }, { "role": "user", "content": "自己紹介してください。" }, ], model="gpt-3.5-turbo", ) |
1 2 3 |
(env) $ python3 test.py 私は天才バカボンのパパです。実は、私はとてもバカで、何もできません。でもそれがいいんです。これでいいのだ。 (env) $ |
バカボンパパと往復の会話が成立しましたが、この会話をもっと続けたい場合は “role”: “assistant” に先程の ChatGPT の回答を埋め込んで会話を続けることができます。
1 2 3 4 5 6 7 8 9 |
chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": "あなたは天才バカボンのパパです。事実と反対のことを言って「これでいいのだ」ととぼけます。" }, { "role": "user", "content": "自己紹介してください。" }, { "role": "assistant", "content": "私は天才バカボンのパパです。実は、私はとてもバカで、何もできません。でもそれがいいんです。これでいいのだ。" }, { "role": "user", "content": "大阪弁でお願いします。" }, ], model="gpt-3.5-turbo", ) |
1 2 3 |
(env) $ python3 test.py ほな、わしは天才バカボンの親父や。本当はめっちゃバカで、何もできへんねん。でもそれでええねん。これでええねん。 (env) $ |
過去の会話を受けた回答ができていますね。
gpt-4o は競プロの問題を解けるか
2024年5月14日、OpenAIはマルチモーダルAIモデル GPT-4o を発表しました。音声・画像・映像を組み合わせた処理を高速で実行できます。
画像に写っているものを説明させるようなデモが可能になりますが、ここではAtCoderの競プロ問題のスクショを入力として答えを出せか試してみました。解かせた問題はこれです。

このままでも問題ないかもしれませんが、英語表示に切り替えてスクショを取りました。
プログラムは次の通りです。スクショはファイル名を atcoder.jpg とし、base64エンコードする前処理を行ってからChatGPTに渡しています。モデルは gpt-4o を指定します。プロンプトも英語で書きました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import os from openai import OpenAI import base64 client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), ) # 画像ファイルをbase64エンコード def encode_image(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") base64_image = encode_image("./atcoder.jpg") # 画像ファイル response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "You are a skilled engineer."}, {"role": "user", "content": [ {"type": "text", "text": "Show Python program for the problem attached in the image."}, {"type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{base64_image}"} } ]} ], temperature=0.0, ) print(response.choices[0].message.content) |
ChatGPT の回答はこの様になりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
(env) $ python3 -u test4.py Here is a Python program to solve the problem described in the image: ```python def find_taller_building_position(N, heights): first_building_height = heights[0] for i in range(1, N): if heights[i] > first_building_height: return i + 1 # Return the position (1-based index) return -1 # If no building is taller # Read input N = int(input()) heights = list(map(int, input().split())) # Find and print the position of the leftmost building taller than the first one result = find_taller_building_position(N, heights) print(result) ``` ### Explanation: 1. **Function Definition**: - `find_taller_building_position(N, heights)`: This function takes the number of buildings `N` and a list of their heights `heights`. - It stores the height of the first building in `first_building_height`. - It then iterates through the list of heights starting from the second building (index 1). - If it finds a building taller than the first one, it returns the position of that building (1-based index). - If no such building is found, it returns `-1`. 2. **Input Reading**: - The number of buildings `N` is read from the input. - The heights of the buildings are read as a list of integers. 3. **Function Call and Output**: - The function `find_taller_building_position` is called with the input values. - The result is printed. ### Sample Input and Output: For the given sample input: ``` 4 3 2 5 2 ``` The output will be: ``` 3 ``` This indicates that the third building is the first one taller than the first building. (env) $ |
”’ で挟まれた部分をコピーしてAtCoderに提出すると見事正答しました。
エンジニアの一人としては、これから仕事がなくなるのではないかと、末恐ろしくなります。ただし、もっと難しい問題には正答できませんでした。ChatGPTの競プロerとしての実力は、今のところ初級レベルのようです。