【Python】簡易なコマンドラインチャットインターフェースの例

  • 2023年3月3日
  • 2023年3月3日
  • Python

 ChatGPT APIが流行っているので Python でちょっとしたチャットプログラムの例を二つ紹介します。

 一つ目はコマンドラインで実行する一行でやりとりするチャットです。

if __name__ == '__main__':
    response = "何か入力してください"  # 初期メッセージ
    while True:
        print(response)  # 返答表示兼初期メッセージ表示
        send = input() # 標準入力を受け取って送信するメッセージ変数に格納
        # 送信するメッセージをチャット関数に渡す
        # チャット関数は返答を文字列で返す
        response = chat(send)

 大分シンプルです。対話のためにインストールするパッケージもありません。必要なのはチャット本体のみです。このプログラムを終了する場合は Ctrl+C などでプロセスキルする必要があります。

 この例でchat(send)としている部分に次リンクなどで紹介されている ChatGPT API との通信処理を入れると ChatGPT API とのチャットができます。

ChatGPT APIを使ってAIキャラクターを作ってみる! – Qiita

 Python の input 関数は手軽にユーザーからの入力を受け付けられる点で便利ですが、複数行メッセージを送ることを考えると少し面倒です。input 関数自体では一行しか読み込めないため発言の末尾の文字などで調整する必要があります。

 二つ目は複数行対応のコマンドラインで実行するチャットです。

if __name__ == '__main__':
    print("何か入力してください。\\で行を終えると複数行入力になります")
    send_msg = ''
    while True:
        send_input = input('あなた: ')
        # 複数行対応。末尾が \ なら次の行も今のメッセージに含める
        while send_input.endswith('\\'):
            send_input = input('     ')
            send_msg += send_input[:-1] + '\n'
        send_msg += send_input
        # チャットAPIなどにメッセージを投げる
        response = chat(send_msg)
        if '\n' in response:  # 返事が複数行ならインデントを揃えて表示
            print('あいて: ')
            for line in response.splitlines():
                print('     ' + line)
        else:
            print('あいて: ' + response)
        send_msg = ''

 \ でメッセージが終わらない様にする形です。これも同様に chat 関数部を ChatGPT API とつなげると面白くなります。これは例えば次の様に動きます。

 これらを先述した ChatGPT とアクセスするAPIとつないだ場合のソースコードが次です。

クリックでソースコードを展開
# どこからこのファイルを読んでも動くようにパス指定
import os
__dir__ = os.path.dirname(os.path.abspath(__file__))
# pip install openai でインストール
import openai

# このファイルと同ディレクトリ内に api-key.txt という名前で OpenAI のAPIキーを書いたファイルを置きます
with open(f'{__dir__}/api-key.txt', 'r') as f:
    openai.api_key = f.read()


# https://qiita.com/sakasegawa/items/db2cff79bd14faf2c8e0 より引用した関数
def completion(new_message_text: str, settings_text: str = '', past_messages=None):
    """
    This function generates a response message using OpenAI's GPT-3 model by taking in a new message text,
    optional settings text and a list of past messages as inputs.

    Args:
    new_message_text (str): The new message text which the model will use to generate a response message.
    settings_text (str, optional): The optional settings text that will be added as a system message to the past_messages list. Defaults to ''.
    past_messages (list, optional): The optional list of past messages that the model will use to generate a response message. Defaults to [].

    Returns:
    tuple: A tuple containing the response message text and the updated list of past messages after appending the new and response messages.
    """
    if past_messages is None:
        past_messages = []
    if len(past_messages) == 0 and len(settings_text) != 0:
        system = {"role": "system", "content": settings_text}
        past_messages.append(system)
    new_message = {"role": "user", "content": new_message_text}
    past_messages.append(new_message)

    result = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=past_messages
    )
    response_message = {"role": "assistant", "content": result.choices[0].message.content}
    past_messages.append(response_message)
    response_message_text = result.choices[0].message.content
    return response_message_text, past_messages


if __name__ == '__main__':
    # このファイルから見て system_settings/tsunko.txt の部分にAIアシスタントの設定などを記述を置きます
    with open(f'{__dir__}/system_settings/tsunko.txt', 'r', encoding='utf-8') as f:
        system_settings = f.read()
    past_messages = []
    print("何か入力してください。\\で行を終えると複数行入力になります")
    send_msg = ''
    while True:
        send_input = input('あなた: ')
        # 複数行対応。末尾が \ なら次の行も今のメッセージに含める
        while send_input.endswith('\\'):
            send_input = input('     ')
            send_msg += send_input[:-1] + '\n'
        send_msg += send_input

        if send_msg == 'exit':
            exit(0)
        # チャットAPIなどにメッセージを投げる
        response, messages = completion(send_msg, system_settings, past_messages)
        if '\n' in response:  # 返事が複数行ならインデントを揃えて表示
            print('あいて: ')
            for line in response.splitlines():
                print('     ' + line)
        else:
            print('あいて: ' + response)
        send_msg = ''

 Python組み込みでざっくり作るなら例の様な感じで十分です。もしリッチなものを作るのであれば、fire、clickあたりのライブラリを利用した方が楽です。

google/python-fire: Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.
Welcome to Click — Click Documentation (8.1.x)

 ChatGPT は API が作られたことにより、大分開放的になりました。今後はこれを利用したサービスも多く出そうです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG