🛠️

SlackとChatGPT APIでチャットボットを作る パート5(番外編/Gradioインターフェイス)

2023/08/28に公開

(2023-12-13 追記)最近のOpenAI SDKは仕様が変わっており、現在載せているコードは動かないので互換性のある古いOpenAI SDKを含むrequirents.txtを掲載します。Pythonコードも細部を少し修正しました。

requirements.txt
wheel
tenacity
slack_bolt
openai==0.28.1
tiktoken
pandas
matplotlib
japanize_matplotlib
seaborn
scikit-learn
ipykernel

SlackとChatGPT APIでチャットボットを作る パート5(番外編/Gradioインターフェイス)

パート1(基礎編)パート2(会話履歴管理編)パート3(function calling編)パート4 (code interpreterぽい編)ときて、パート5では番外編としてインターフェイスをGradioにすげ換えてみたいと思います。Slackを使っていない方も多いと思いますが、そんな皆さんもGradioなら手軽に試すことができます。ただひとつ、実は悲しいお知らせがありまして、パート4 (code interpreterぽい編)でPythonコードの実行に使ったIPython.core.interactiveshell.InteractiveShellはGradioと衝突するようで、併用すると奇怪なエラーが発生してしまいます。なので今回はパート3(function calling編)をベースにインターフェイスをGradioに換装したいと思います。

データ

データについてはパート3(function calling編)パート4 (code interpreterぽい編)と同じです。

Gradioのインストール

pip install gradio

でインストールすることができます。

ソースコード

chatbot.pyをGradio用に書き換えました。utils.pyパート3(function calling編)と同じです。

chatbot.py
import gradio as gr
from utils import ChatEngine

model = "gpt-4-0613"
def quotify(s: str) -> str:
    """Adds quotes to a string.
    Args:
        s (str): The string to add quotes to.
    Returns:
        (str) The string with quotes added.
    """
    return "```" + s + "```"

ChatEngine.setup(model, quotify_fn=quotify)
chat_engine = ChatEngine()

with gr.Blocks() as demo:
    chatbot = gr.Chatbot()
    msg = gr.Textbox()
    with gr.Row():
        verbose = gr.Checkbox(label="Verbose Mode", value=chat_engine.verbose)
        style = gr.Button(value="Set Style")
        clear = gr.ClearButton([msg, chatbot])

    def respond(message, chat_history):
        global chat_engine
        reply_combined = "\n".join(reply for reply in chat_engine.reply_message(message))
        chat_history.append((message, reply_combined))
        return "", chat_history

    def set_verbose_mode(value):
        global chat_engine
        chat_engine.verbose = value
    
    def set_style(message):
        global chat_engine
        message = message.strip()
        if message:
            print(f"Style: {message}")
            chat_engine = ChatEngine(style=message)

        return "", chat_engine.verbose
    
    def clear_chat_engine():
        global chat_engine
        chat_engine = ChatEngine()
        return chat_engine.verbose
        
    msg.submit(respond, [msg, chatbot], [msg, chatbot])
    verbose.change(set_verbose_mode, verbose)
    style.click(set_style, [msg], [msg, verbose])
    clear.click(clear_chat_engine, [], [verbose])

demo.launch()

Gradioでは> ...で引用化するのがうまくいかないのでquotify()関数を書き換えました。それからGradioでユーザーを識別する方法がわからなかったので、ChatEngineは1つしかインスタンス化していません。つまり単一のユーザーが使うことしか想定していないということです。このあたり、うまいやり方をご存じの方がいらっしゃいましたら教えてください。

動作例

gradio chatbot.py 

で起動すると、次のような出力があるはずです。

Launching in reload mode on: http://127.0.0.1:7860 (Press CTRL+C to quit)

Watching: <略>

Running on local URL: http://127.0.0.1:7860

To create a public link, set share=True in launch().

この状態でソースを編集すると自動でリロードしてくれます。便利ですね。

ブラウザでlocalhost:7860を開くと次のような感じでチャットすることができます。
Alt text

パート5は以上です。コードはtf-koichi/slack-chatbot at part5に置いてあります。
このシリーズは一旦完結とします。何かお気づきの点がありましたらフィードバックよろしくお願いします。

Discussion