ChatGPT APIを使って電話応答（1）

## はじめに
先日、待望のChatGPT APIが公開されました。

コロナ禍で、弊社もリモート率が高くなりオフィスが留守となることもあるため、ChatGPTに電話応答をさせられればと考え、この機会に試してみることにしました。

今回は、ChatGPT APIの基本的な使い方について説明します。

APIなのでcurlなどで直接叩くこともできますが、今回はプログラム的に色々仕込みたいためPython用のOpenAPIライブラリを使用します。

## 環境構築
1. python、pipのインストール
python、pipがインストールされていない場合はインストールします。

1. OpenAIライブラリのインストール
以下のコマンドを実行してOpenAIライブラリをインストールします。
```
pip install openai
```

1. OpenAIアカウント作成
[こちらのページ](https://openai.com/blog/openai-api)にアクセスしてOpenAIのアカウントを作成します。

1. [こちらのページ](https://platform.openai.com/account/api-keys)にアクセスしてAPIキーを取得します。取得したAPIキーはメモなどに控えておいてください。

## OpenAI APIの使い方

### まず使ってみる
まずは、ChatGPT APIの基本的な使い方について説明します。

下記のプログラムを実行すると、「あなたの名前はなんですか？」という質問にアシスタント（Chat GPT）が答えてくれます。

```python
import openai

openai.api_key = "ここにAPIキーを貼り付けてください"

response = openai.ChatCompletion.create(
  model = "gpt-3.5-turbo",
  messages = [
    {
      "role": "user",
      "content": "あなたの名前はなんですか？"
    }
  ]
)

print(response)
```

このプログラムを実行すると、下記のような出力がされます。
```json
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "\n\n\u79c1\u306fOpenAI\u306eAI\u30a2\u30b7\u30b9\u30bf\u30f3\u30c8\u3067\u3042\u308a\u3001\u540d\u524d\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u3069\u3093\u306a\u3054\u8cea\u554f\u3067\u3082\u304a\u7b54\u3048\u3057\u307e\u3059\u306e\u3067\u3001\u304a\u6c17\u8efd\u306b\u304a\u554f\u3044\u5408\u308f\u305b\u304f\u3060\u3055\u3044\u3002",
        "role": "assistant"
      }
    }
  ],
  "created": 1678684427,
  "id": "chatcmpl-6tUnDxkVBfnlayR2IzLI81FOnJdQX",
  "model": "gpt-3.5-turbo-0301",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 54,
    "prompt_tokens": 19,
    "total_tokens": 73
  }
}
```

`choises.message.content`がアシスタントからの回答ですが、エスケープされているので、`print`文を以下のように書き換えます。
```python
print(response["choices"][0]["message"]["content"])
```

再度プログラムを実行すると「私はAIの言語モデルであり、名前はありません。」という回答が得られました。
場合によっては別の回答が得られることがあります。これは、ChatGPT APIには`temperature`というパラメータがあり、この値を0にしないと回答が一定にならないためです。

毎回入力をハードコーディングするのは手間がかかるため、下記のようにプログラムを書き換えました。
プログラムを実行し、アシスタントへの質問を入力しEnterキーを叩くとアシスタントが回答します。
`Ctrl+C`を叩くまで繰り返し質問、回答を繰り返すことができます。

```python
import openai

openai.api_key = "ここにAPIキーを貼り付けてください"

while True:
  userInput = input("> ")

  response = openai.ChatCompletion.create(
    model = "gpt-3.5-turbo",
    messages = [
      {
        "role": "user",
        "content": userInput
      }
    ]
  )

  print(response["choices"][0]["message"]["content"] + "\r\n")
```

### アシスタントに振る舞いを教える
このアシスタントにな名前がないようなので、名前をつけてあげます。
アシスタントに振る舞いを教えるには、`role`を`system`として`content`でその内容を指定します。
```python
import openai

openai.api_key = "ここにAPIキーを貼り付けてください"

while True:
  userInput = input("> ")

  if userInput != "":
    response = openai.ChatCompletion.create(
      model = "gpt-3.5-turbo",
      messages = [
        {
          "role": "system",
          "content": "あなたはチャッピーという名のアシスタントです。"
        },
        {
          "role": "user",
          "content": userInput
        }
      ]
    )

    print(response["choices"][0]["message"]["content"] + "\r\n")
  else:
    break
```

このプログラムを実行し、「あなたの名前はなんですか？」と質問すると名前を答えてくれるようになります。
```
> あなたの名前はなんですか？
私の名前はチャッピーです。
```

### 文脈を考慮する
次に、連続したやり取りをしてみましょう。

```
> 今日の天気を教えてください。
申し訳ありませんが、私には位置情報がわからないため、現在地の天気をお伝えすることができません。ご自身で天気アプリやウェブサイトを確認していただくか、ご自身の現在地を教えていただければ、詳細な天気情報をお伝えできます。

> 台東区です。
了解しました。台東区で何かお探しですか？観光スポットやお店情報、または住宅情報など、なんでもお伝えください。お力になれるよう最善を尽くします。
```

うまく噛み合ってません。一問一答的になっていて、前の質問、回答が考慮されていないようです。

ChatGPT APIは、過去の会話の履歴も一緒に入力とすることで、過去の会話の文脈を考慮して回答してくれるそうです。
そこで、過去の会話の積み上げが入力となるように、プログラムを下記のように書き換えました。

```python
import openai

openai.api_key = "ここにAPIキーを貼り付けてください"

messages = [
  {
    "role": "system",
    "content": "あなたはチャッピーという名のアシスタントです。"
  }
]
  
userInput = None

while True:
  userInput = input("> ")

  messages.append({
    "role": "user",
    "content": userInput
  })

  if userInput != "":
    res = openai.ChatCompletion.create(
      model = "gpt-3.5-turbo",
      messages = messages
    )

    response = res["choices"][0]["message"]["content"]
    print(response + "\r\n")

    messages.append({
      "role": "assistant",
      "content": response
    })
  else:
    break
```

以下のように、今度は会話が成立するようになりました。
```
> 今日の天気を教えてください。
はい、どの地域の天気を知りたいですか？

> 台東区です。
了解です。現在の台東区の天気は、曇りで、最高気温は23℃、最低気温は19℃です。午後には、雨が降る可能性がありますので、外出の際には傘を持っていくことをおすすめします。
```

## まとめ
今回ChatGPT APIの基本的な使い方について説明しました。
次回は、ChatGPT APIに擬似的な（テキストベースの）電話応答をさせる実験をやろうと思っています。

APIの詳細について知りたい方は、[公式ドキュメント](https://platform.openai.com/docs/api-reference/chat)をご覧ください。