ChatGPT ウェブアプリがPython Chainlit でらくらく開発できるらしい

ChatGPT ウェブアプリがPython Chainlit でらくらく開発できるらしい

OpenAIのGPTを使ったチャットボットアプリが、色々登場しました。

とても美しい! という感じを求めているのではないなら、ぜひ自作してみましょう。

Chainlit(https://github.com/Chainlit/chainlit で簡単に自作できます。

語尾の似たようなPythonのWebアプリ開発フレームワークを思い出した方もいるかも知れません。

Streamlitです。StreamlitStreamlit_chatでも似たようなチャットボットアプリを作りますが、今回は触れません。

Chainlit で作る方が遥かに簡単です。

ちなみに使い方というか、扱い方も若干似ていて……

  1. streamlitと同じように、pyファイルにアプリの中身を記載
  2. コマンドプロンプト上で、そのpyファイルをロードし実行
  3. チャットボットアプリが立ち上がる(今回はローカル)

今回は、Chainlit でChatGPT ウェブアプリの簡単な作り方を説明します。

ちなみに、自作するのは以下のような感じのものです。

今回は触れませんが、ChainlitLangChainと連携することで色々なことができますので、そのあたりは別途お話しします。

インストール

先ずは、PythonのChainlitパッケージをインストールします。

以下、コードです。

pip install chainlit

 

OpenAIのGPTを使いますので、まだopenaiとlangchainをインストールしていない方は、インストールしましょう。

以下、コードです。

pip install openai
pip install langchain

 

また、OpenAIのOpenAI APIキーが必要となります。

以下の記事を参考に、OpenAIアカウントを作成し、OpenAI APIキーを取得しておいてください。

Jupyter Lab の AI 拡張「Jupyter AI」

 

AIチャットボットアプリのコード(app.py)

 コード(app.py)

それでは、ChatGPT APIを活用して最も基本的なAIチャットボットアプリを開発していきます。

以下のような、アプリの中身を記載したpyファイル(今回は、app.pyとして保存)を作ります。<OpenAI APIキー>には、あなたのOpenAI APIキーを設定してください。

# 必要なモジュールのインポート
import openai
import chainlit as cl

# 定数の定義

## OpenAIのAPIキー
API_KEY = "<OpenAI APIキー>" 

## 使用するOpenAIのモデル名
MODEL_NAME = "gpt-3.5-turbo"  

## 初期システムメッセージ
SYSTEM_START_MSG = "You are a helpful assistant."  

## 役割(role)定数
ROLE_SYSTEM = "system"
ROLE_USER = "user"
ROLE_ASSISTANT = "assistant"

# OpenAIのAPIキーの設定
openai.api_key = API_KEY

# メッセージ辞書(役割と内容の組み合わせ)を作成する関数
def create_message(role, content):
    return {"role": role, "content": content}

# メッセージ履歴に新しいメッセージを追加する関数
def update_message_history(message, role):
    message_history = cl.user_session.get("message_history")
    message_history.append(create_message(role, message))
    cl.user_session.set("message_history", message_history)

# 応答メッセージを生成する関数
def generate_reply(model, message_history):
    completion = openai.ChatCompletion.create(model=model, messages=message_history)
    return completion.choices[0].message.content

# チャットセッション初期化
@cl.on_chat_start
def start_chat():
    cl.user_session.set(
        "message_history",
        [create_message(ROLE_SYSTEM, SYSTEM_START_MSG)],
    )

# 新しいユーザーメッセージから応答生成
@cl.on_message
async def handle_user_message(message: str):
    
    # ユーザーメッセージをメッセージ履歴に追加します
    update_message_history(message, ROLE_USER)
    
    # 更新されたメッセージ履歴を取得します
    message_history = cl.user_session.get("message_history")
    
    # メッセージ履歴に基づいて応答を生成します
    reply = generate_reply(MODEL_NAME, message_history)
    
    # 生成された応答をメッセージ履歴に追加します
    update_message_history(reply, ROLE_ASSISTANT)
    
    # 生成された応答で新しいメッセージを作成して送信します
    msg = cl.Message(content=reply)
    await msg.send()  # メッセージを非同期に送信します

 

このコードは、OpenAIの人工知能モデル(この場合、”gpt-3.5-turbo”)との対話(チャット)アプリケーションを作成するものです。

chainlitというライブラリを使って、ユーザとAIアシスタントとの間でメッセージの交換を実施します。

このコードにより、ユーザとAIが対話することができます。

 

 コード解説

以下、このPythonコード(app.py)の説明です。気になる方は読んでみて下さい。

それぞれ分解して説明します。

 

先ずはじめに、必要なモジュールを読み込みます。

# 必要なモジュールのインポート
import openai
import chainlit as cl

 

次に、APIキー、モデル名、システムメッセージ、ロールの種類(システム、ユーザ、アシスタント)を定義します。

# 定数の定義

## OpenAIのAPIキー
API_KEY = "<OpenAI APIキー>" 

## 使用するOpenAIのモデル名
MODEL_NAME = "gpt-3.5-turbo"  

## 初期システムメッセージ
SYSTEM_START_MSG = "You are a helpful assistant."  

## 役割(role)定数
ROLE_SYSTEM = "system"
ROLE_USER = "user"
ROLE_ASSISTANT = "assistant"

 

<OpenAI APIキー>には、あなたのOpenAI APIキーを設定してください。

MODEL_NAMEには、使用するOpenAIのモデル名を設定してください。このコードでは、gpt-3.5-turboを設定しています。GPT4を設定するときは、gpt-4としてください。

 

3つの関数を定義します。

  • create_message関数
  • update_message_history関数
  • generate_reply関数

 

create_message関数は、チャットメッセージを表現する辞書を作成します。

# メッセージ辞書(役割と内容の組み合わせ)を作成する関数
def create_message(role, content):
    return {"role": role, "content": content}

この辞書は、送信者の役割(role)とメッセージの内容(content)のペアです。

  • role:メッセージの送信者の役割を表す文字列です。これは”system”、”user”、または”assistant”となります。
  • content:メッセージの具体的な内容を表す文字列です。

 

update_message_history関数は、現在のユーザセッションのメッセージ履歴に新しいメッセージを追加する役割を果たします。

# メッセージ履歴に新しいメッセージを追加する関数
def update_message_history(message, role):
    message_history = cl.user_session.get("message_history")
    message_history.append(create_message(role, message))
    cl.user_session.set("message_history", message_history)

 

具体的には次のような処理を行っています。

  • cl.user_session.get(“message_history”)を使って、現在のユーザセッションからメッセージ履歴を取得します。
  • create_message(role, message)関数を用いて新しいメッセージ(送信者の役割とメッセージ内容を含む辞書形式)を作成し、これをメッセージ履歴(リスト)の最後に追加します。
  • cl.user_session.set(“message_history”, message_history)を使って、更新されたメッセージ履歴をユーザセッションに保存します。

メッセージ履歴は、ユーザとAIの間の対話を記録するために使用され、それをOpenAI APIに渡すことで、AIの応答が以前のメッセージの文脈に基づいて生成されるようにします。これにより、会話の一貫性が保たれます。

 

generate_reply関数は、ユーザからのメッセージに対するAIモデルの応答を生成します。

# 応答メッセージを生成する関数
def generate_reply(model, message_history):
    completion = openai.ChatCompletion.create(model=model, messages=message_history)
    return completion.choices[0].message.content

 

具体的な流れは以下のようになります。

  • OpenAIのChatCompletion.createメソッドを使用して、指定されたモデル(model)とメッセージ履歴(message_history)を基にAIモデルからの応答を生成します。ここでのメッセージ履歴は、ユーザとAIの過去のメッセージのリストを含む辞書のリストです。
  • ChatCompletion.createメソッドは、生成された各応答オプションをchoicesというリストに格納して返します。このコードでは最初の選択肢(choices[0])を使用しています。
  • 最後に、選ばれた応答オプションからメッセージ内容(message.content)を抽出し、これを返します。

 

つまり、この関数はユーザからの最新のメッセージを考慮に入れて、AIモデルが生成する応答を取得する役割を果たします。

 

2つのデコレータで、AIの振る舞いを定義し機能追加します。

  • @cl.on_chat_start
  • @cl.on_message

 

@cl.on_chat_startデコレータを使用して、チャットが開始したときに実行するstart_chat関数を定義し機能追加します。

# チャットセッション初期化
@cl.on_chat_start
def start_chat():
    cl.user_session.set(
        "message_history",
        [create_message(ROLE_SYSTEM, SYSTEM_START_MSG)],
    )

 

この関数では、チャットの開始時に初期のシステムメッセージをセットアップします。

 

@cl.on_messageデコレータを使用して、新たなユーザメッセージを受け取ったときに実行するhandle_user_message関数を定義し機能追加します。

# 新しいユーザーメッセージから応答生成
@cl.on_message
async def handle_user_message(message: str):
    
    # ユーザーメッセージをメッセージ履歴に追加します
    update_message_history(message, ROLE_USER)
    
    # 更新されたメッセージ履歴を取得します
    message_history = cl.user_session.get("message_history")
    
    # メッセージ履歴に基づいて応答を生成します
    reply = generate_reply(MODEL_NAME, message_history)
    
    # 生成された応答をメッセージ履歴に追加します
    update_message_history(reply, ROLE_ASSISTANT)
    
    # 生成された応答で新しいメッセージを作成して送信します
    msg = cl.Message(content=reply)
    await msg.send()  # メッセージを非同期に送信します

 

この関数では、ユーザメッセージをメッセージ履歴に追加し、そのメッセージに対する応答をAIモデルから生成します。

生成された応答はメッセージ履歴に追加され、ユーザに送信されます。

 

アプリを起動し使ってみよう!

 アプリ起動

コマンドプロンプトに、以下のコードを入力し実行します。

chainlit run app.py

 

ローカルで実行されるので、URLはhttp://localhost:8000/です。

 

実行すると、chainlit.mdというファイルが生成されます。アプリを起動したときの初期画面で表示する内容を記載するファイルです。

chainlit.mdをメモ帳などで開き、すべて消すとアプリを起動したとき、次のように何も表示されません。

 

 高尾山について聞いてみる

では、高尾山について聞いてみます。

 

新しい会話を始めるときは、右上の「New Chat」をクリックします。

 

 Pythonのコーディングをお願いしてみる

次に、Pythonを使った予測モデルの構築をお願いしてみます。

 

このように、Python Chainlit でChatGPT ウェブアプリを、簡単に作ることができました。

 

まとめ

今回は、Chainlit でChatGPT ウェブアプリの簡単な作り方を説明しました。

ちなみに、Chainlit LangChainと連携することで色々なことができます

そのあたりは別途お話しします。

Python Chainlit × ChatGPTで作る PDFドキュメントAIチャットボット