LoginSignup
0
1

Jupyterでipywidgetsを使ってGPTと会話する

Last updated at Posted at 2024-01-15

はじめに

LangChainを使ってGPT関連の開発していると、Jupyter中でGPTと会話しながら調整したいことがある。
そこで、Jupyter中でipywidgetsを使ってインタラクティブにchainを使ってGPTと会話できるようにした。

本記事の完成品

gpt.gif

準備 環境の設定, apiキー, chainの設定

使用した環境のrequirements.txt

langchain==0.0.343
openai==0.28.1
jupyterlab==4.0.10

JupyterLabでipywidgetを動かすために、以下を実行して再起動した。

jupyter labextension install @jupyter-widgets/jupyterlab-manager

まずapiキーを環境変数に入れておく

import os

#APIキーをセット
os.environ["OPENAI_API_KEY"] = #############

GPTとの会話で使いたいchainを作っておく。記法はLangChain Expression Language (LCEL)を使用した。(関連記事: LangChainのLCELで | (パイプ文字)を使って処理できる理由)

from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder, HumanMessagePromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from operator import itemgetter

# memoryを作成。これによって、会話の履歴を保存し、gptに毎回履歴を渡せるようになる。
memory = ConversationBufferMemory(return_messages=True)

# promptを作成
template = """Answer the question in Japanese:
Question: {question}
"""
prompt = ChatPromptTemplate.from_messages([
    MessagesPlaceholder(variable_name="chat_history"),
    HumanMessagePromptTemplate.from_template(template)
])
# modelを作成
model = ChatOpenAI(model_name="gpt-3.5-turbo-16k",verbose=True)
# parserを作成
output_parser = StrOutputParser()

# chainへの入力に、chat_histryという変数名で、memoryが持っている会話履歴が加わるようにする。
setup = RunnablePassthrough.assign(
    chat_history = RunnableLambda(memory.load_memory_variables)| itemgetter("history")
)

chain = setup | prompt | model | output_parser

ipyywidgetsで会話

from IPython.display import display, HTML, Markdown
import ipywidgets as widgets

# テキストボックスとボタンの作成
text_box = widgets.Text(placeholder='テキストを入力してください')
submit_button = widgets.Button(description='実行')
# 出力用のウィジェット
output = widgets.Output()
display(output)

# 実行ボタンを押したときの関数
def run_function(_):
    # gptの返事を待っている間は、実行ボタンを選択不可にする。
    submit_button.description = "実行中"
    submit_button.disabled = True
    # 入力された値を取得、取得後はクリア
    text = text_box.value
    text_box.value = ""
    with output:
        # 入力されたテキストをアウトプットウィンドウに出力
        input_section_format = """<div>
            <p>入力> {text}</p>
        </div>"""
        input_section = HTML(input_section_format.format(text=text))
        display(input_section)
    
        # gptのchainの実行
        # 入力されたテキストを渡し、chainを実行
        input = {"question":text}
        gpt_output = chain.invoke(input)
        # 入力とgptからの出力をmemoryに保存しておく。
        memory.save_context({"input":template.format(**input)},{"output": gpt_output})
    
        # gptの出力内容をアウトプットウィンドウに出力
        # 出力内容を折り畳めるように、detailsタグを使用する。
        gpt_section = Markdown(f"""<div>
                    <details><summary>GPT</summary><pre>{gpt_output}</pre></details>
                </div>""")
        display(gpt_section)
    
        # 実行ボタンの選択不可を解除。
        submit_button.description = "実行"
        submit_button.disabled = False

submit_button.on_click(run_function)

# テキストボックスと実行ボタンを表示
display(text_box, submit_button)

完成。chainの部分を色々変えて試行錯誤しながら使えそう。

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1