LangChainでChatGPTのストリーミング機能を試す

今回はLangChainを使って、ChatGPTの回答をリアルタイムに出力するストリーミング機能について見ていきます。

langchainとそのOpenAI拡張のlangchain-openaiをインストールします。

pip install langchain langchain-openai
  • 今回使用するバージョンは以下のとおりです。

    $ pip list|grep langchain
    langchain                0.2.12
    langchain-core           0.2.29
    langchain-openai         0.1.21
    langchain-text-splitters 0.2.2
    

作業用ディレクトリに.openaiファイルを作成して、その中にAPIキーを保存します。
そして、以下コードで環境変数OPENAI_API_KEYを設定します。

import os

with open('.openai') as f:
    os.environ['OPENAI_API_KEY'] = f.read().strip()

Google Colabを使用する場合はファイルに保存せず「シークレット」機能を使用するのが便利です。

次にLLMを初期化します。今回はGPT-4o mini(gpt-4o-mini-2024-07-18)を使用します。
(2024年8月現在、GPT-3.5 Turboよりも安価で使用できます。)

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model='gpt-4o-mini-2024-07-18', temperature=0)

LLMの回答をリアルタイムで出力するには streamメソッドを使用します。
以下のようにするとChatGPTの回答がリアルタイムに画面に表示されます。

for chunk in llm.stream("LangChainについてわかりやすく解説してください。"):
    print(chunk.content, end="", flush=True)
  • 実行結果 (以下の内容が順にリアルタイムで出力されます)

    LangChainは、自然言語処理(NLP)や生成モデルを活用して、アプリケーションやサービスを構築するためのフレームワークです。特に、言語モデル(例えば、GPT-3やGPT-4など)を利用して、さまざまなタスクを実行するためのツールや機能を提供します。
    
    ### LangChainの主な特徴
    
    1. **モジュール性**:
       LangChainは、異なるコンポーネントを組み合わせて使うことができるため、開発者は自分のニーズに合わせてカスタマイズしたアプリケーションを作成できます。
    
    2. **チェーンの構築**:
       LangChainでは、複数の処理を「チェーン」として連結することができます。例えば、ユーザーの入力を受け取り、それに基づいて情報を検索し、最終的に生成された応答を返すという一連の流れを簡単に構築できます。
    
    3. **データソースとの統合**:
       LangChainは、外部のデータソース(データベースやAPIなど)と連携する機能を持っており、リアルタイムで情報を取得したり、特定のデータに基づいて応答を生成したりすることが可能です。
    
    4. **エージェント機能**:
       LangChainは、エージェントを作成するための機能も提供しています。エージェントは、ユーザーの要求に応じて適切なアクションを選択し、実行することができます。
    
    5. **多様なアプリケーション**:
       LangChainは、チャットボット、質問応答システム、コンテンツ生成、データ分析など、さまざまなアプリケーションに利用できます。
    
    ### 使い方の例
    
    例えば、カスタマーサポート用のチャットボットを作成する場合、LangChainを使って以下のような流れを構築できます。
    
    1. ユーザーからの質問を受け取る。
    2. 質問の内容に基づいて、関連する情報をデータベースから検索する。
    3. 検索結果をもとに、言語モデルを使って自然な応答を生成する。
    4. 生成された応答をユーザーに返す。
    
    ### まとめ
    
    LangChainは、言語モデルを活用したアプリケーションを簡単に構築できる強力なフレームワークです。モジュール性やデータソースとの統合、エージェント機能などを活用することで、さまざまなニーズに応じた柔軟なシステムを開発することができます。
    

Jupyter NotebookやGoogle Colabで使用する場合、IPython.displayMarkdownを使用すると
マークダウン形式の回答を見やすく表示することができます。

from IPython.display import Markdown, display, update_display

contents = ""
display_id = None
for chunk in llm.stream("LangChainについてわかりやすく解説してください。"):
    contents += chunk.content
    markdown = Markdown(contents)
    if not display_id:
        display_id = display(markdown, display_id=True).display_id
    else:
        # 画面更新時の点滅防止のためupdate_displayを使用する
        update_display(markdown, display_id=display_id)
  • 実行結果 (回答がリアルタイムに表示されます)

    実行結果

Streamlitを使用すると以下のようにして簡易的なアプリケーションが作成できます。
(本格的に運用する際は st.secrets を使用してAPIキーを管理してください。)

import os

import streamlit as st
from langchain_openai import ChatOpenAI

# LLM初期化
if "llm" not in st.session_state:
    with open(".openai") as f:
        os.environ["OPENAI_API_KEY"] = f.read().strip()

    st.session_state.llm = ChatOpenAI(model="gpt-4o-mini-2024-07-18", temperature=0)

# タイトル設定
st.title("ChatGPT Streaming Test")


# テキストボックスに文字列が入力された際に呼ばれる関数
def stream_response():
    user_input = st.session_state.user_input
    if user_input:
        response_text = ""
        for chunk in st.session_state.llm.stream(user_input):
            response_text += chunk.content
            st.session_state.response_text = response_text
            response_area.markdown(response_text)


# 初回の実行時にセッション状態を初期化
if "response_text" not in st.session_state:
    st.session_state.response_text = ""

# テキストボックスを作成し、Enterが押されたらstream_responseを実行
st.text_input("Ask a question to ChatGPT:", key="user_input", on_change=stream_response)

# 空のプレースホルダーを作成し、セッション状態から前回の応答を取得して表示
response_area = st.empty()
if st.session_state.response_text:
    response_area.markdown(st.session_state.response_text)
  • 実行結果 (回答がリアルタイムに表示されます)

    実行結果

関連記事