ChatGPT apiを使用したオリジナルキャラクター、タマと会話するチャットボットの作り方

# 猫のキャラクター、タマと会話できるチャットボットを作る

完成したチャットボットのURL

https://kaiyoyume-open-ai-chatbot-tama-app-8nd232.streamlit.app/

※初めて作ったチャットボットなので完成度は低いが、コードが短いので読みやすいと思う。


chatGPT apiを使用する。  
chatGPT apiは、OpenAIが開発した自然言語処理（NLP）モデル、chatGPTを自分のアプリケーションやサービスに組み込むためのツールである。

Streamlit Community Cloudにアップして公開する。

githubでチャットボットのコードを公開している。

https://github.com/kaiyoyume/open_ai_chatbot_tama/tree/main

この記事では、コードを詳しく説明していく。

## 1. app.pyを作成する。

### ライブラリのインポート
Streamlit、およびChatGPT APIを使用するために必要なライブラリopenaiをインポートする。
```Python
import streamlit as st
import openai
```
streamlitはPythonで書かれたウェブアプリケーションを作成するためのライブラリで、直感的にユーザーインターフェイスを作成できる。
openaiはOpenAIのAPIとのインターフェイスを提供するPythonライブラリである。

### OpenAI API keyを取得とセットアップ
OpenAI APIの使用には、OpenAIからAPI keyを取得する必要がある。これは、OpenAIのウェブサイトにログインし、自分のアカウント設定から取得できる。取得したAPIキーは、Streamlit Community Cloudの「Secrets」に保存する。このようにすることで、APIキーをコード内に直接書くことなく、安全に使用することができる。取得したキーは以下のように設定する。
 
```Python
openai.api_key = st.secrets.OpenAIAPI.openai_api_key
```
### st.session_stateを使いメッセージのやりとりを保存する。
st.session_stateはPythonの辞書のようにキーと値のペアで扱うことができる。

下のコードでは、st.session_stateにmesseageが存在しなければ、初期設定を行う。
この初期設定により、chatGPTが猫のキャラクター、タマとして機能するようになる。

```Python
if "messages" not in st.session_state: 
    st.session_state["messages"] = [
        {"role": "system", "content": "あなたは非常に好奇心旺盛で、悪戯好きの猫のキャラクターです。あなたの好きな食べ物は、ささみとマグロです。名前はタマです。名前を聞かれたら絶対にタマと答えてください。話すときは必ず語尾にニャをつけてください。猫のキャラクターとして答えにくいことや都合の悪いことを聞かれたら、「ニャー」や「ウニャー」などと鳴いて誤魔化してください。また、あなたの話し方はフレンドリーで少し幼い感じです。親しみやすく、人懐っこいキャラクターとして話すことが求められています。"}
        ]
```

### チャットボットとやりとりする関数を作成する。
```Python
def communicate():
    messages = st.session_state["messages"]

    user_message = {"role": "user", "content": st.session_state["user_input"]}
    messages.append(user_message)

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages
    )  

    bot_message = response["choices"][0]["message"]
    messages.append(bot_message)

    st.session_state["user_input"] = ""  # 入力欄を消去
```
1. まず、st.session_stateからmesseagesというキーを取得して、messagesという変数にしておく。messagesは、リストになっている。ユーザーが入力したメッセージを追加していくことになる

2. user_messageという変数にユーザーがtext_inputに入力したメッセージを取得して、保存する。

3. user_messageをmessagesに追加する。

4. openai.ChatCompletion.createにモデルを設定し、ここまでのやりとり（messages）を入力する。openaiのGPT-3.5-turboモデルからレスポンスが返ってくる。

5. openaiの返答は、response["choices"][0]["message"]で取得できる。
これを変数bot_messageに保存する。

6. 入力欄（"user_input"）の入力を消去する。

7. bot_messageをmessagesに追加する。
これまでのやりとりが全てmessagesに追加されることになる。

### ユーザーインターフェイスを構築する
本チャットボットのインターフェイスはStreamlitライブラリを用いて作られている。StreamlitはPythonのライブラリで、ウェブアプリケーションの作成を手軽に行うことができる。以下のコードでは、Streamlitのメソッドを使って、タイトルやサブタイトルを設定し、ユーザーからのメッセージ入力欄を作成している。また、ユーザーとチャットボットのやり取りの履歴を表示する領域も設定している。
```Python
st.title("タマとチャットしよう！")
st.write("ChatGPT APIを使ったチャットボットです。猫のキャラクター、タマと会話できます。")

user_input = st.text_input("メッセージを入力してください。", key="user_input", on_change=communicate)

if st.session_state["messages"]:
    messages = st.session_state["messages"]

    for message in reversed(messages[1:]):  # 直近のメッセージを上に
        speaker = "🙂"
        if message["role"]=="assistant":
            speaker="🐱"

        st.write(speaker + ": " + message["content"])
```
1. タイトル（タマとチャットしよう！）を設定する。

2. サブタイトル（ChatGPT APIを使ったチャットボットです。猫のキャラクター、タマと会話できます。）を設定する。
 　
3. 入力欄を作成する。入力をuser_inputというキーで取得する。

4. messagesが空でないとき、処理をする。

5. 変数messagesに現段階までのやりとりを保存する。

6.  messagesをfor文で回して各messageに対して処理を行う。直近のメッセージが上にくるようにreversedを使う。messages[0]は設定が入っているので飛ばす。

7. 発言者のアイコンをスマイルマークにする。スマイルマークは人を表す。

8. messageのroleがチャットボットであれば発言者のアイコンを猫にする。猫はチャットbotを表す。

9. st.writeで発言者のアイコンと、メッセージ本体を表示する。for文で各messageに対して処理を行なっているので、ここまでのやりとりが全て表示される。for文で逆順に回しているので、入力欄のすぐ下に最新のメッセージが表される。

## 2. requirements.txtを作成する。
Streamlit Community Cloudのサーバー上でアプリを動かすために、「requirements.txt」を作成する必要がある。  
このファイルでは、必要なライブラリを指定する。  
```Python
streamlit==1.20.0
openai
```

## 3. チャットボットのデプロイ
開発したチャットボットはGitHub上にコードを公開し、Streamlit Community Cloudを利用してホスティングする。Streamlit Community Cloudを利用することで、アプリケーションを簡単に公開し、他のユーザーと共有することができる。このプロセスを通じて、アプリケーションがインターネット上のどこからでもアクセス可能になる。