メインコンテンツへスキップ
見出し画像

LangChain の チャットモデル (ChatGPTの新しい抽象化) を試す

    「LangChain」の「チャットモデル」(ChatGPTの新しい抽象化) を試したので、まとめました。

    ・LangChain v0.0.102

    1. チャットモデル

    「LangChain」の「チャットモデル」は、「言語モデル」のバリエーションです。「チャットモデル」は内部で「言語モデル」を使用しますが、インターフェイスは少し異なります。

    ◎ 言語モデル (GPT-3など)
    ・入力 : テキスト
    ・出力 : テキスト

    ◎ チャットモデル (ChatGPTなど)
    ・入力 : チャットメッセージリスト
    ・出力 : チャットメッセージ

    「チャットモデル」のAPIはかなり新しいため、正しい抽象化をまだ検討中になります。

    2. チャットモデルの呼び出し

    Google Colabでの実行手順は、次のとおりです。

    (1) パッケージのインストール。

    # パッケージのインストール
    !pip install langchain
    !pip install openai

    (2) 環境変数の準備。
    以下のコードの <OpenAI_APIのトークン> にはOpenAI APIのトークンを指定します。(有料)

    import os
    os.environ["OPENAI_API_KEY"] = "<OpenAI_APIのトークン>"

    (3) チャットモデルの準備
    言語モデルでは「OpenAI」を使いましたが、チャットモデルでは「ChatOpenAI」を使います。

    from langchain.chat_models import ChatOpenAI
    
    # チャットモデルの準備
    chat = ChatOpenAI(temperature=0)

    (4) 1メッセージによるチャットモデルの呼び出し。
    1メッセージを入力した例になります。

    from langchain.schema import (
        AIMessage,
        HumanMessage,
        SystemMessage
    )
    
    # 1メッセージによるチャットモデルの呼び出し
    chat([HumanMessage(content="「私はプログラミングが大好きです。」を日本語から英語に翻訳してください。")])
    AIMessage(content='"I love programming."', additional_kwargs={})

    1つ以上のメッセージをチャットモデルに渡すことで、応答のメッセージを取得できます。

    現在サポートされているメッセージのタイプは、次のとおりです。

    ・AIMessage
    ・HumanMessage
    ・SystemMessage
    ・ChatMessage

    ChatMessage は任意の役割 (roll) を指定できます。多くの場合、「HumanMessage」「AIMessage」「SystemMessage」のみ使用します。

    (5) 複数メッセージによるチャットモデルの呼び出し。
    複数メッセージを入力した例になります。

    # 複数メッセージによるチャットモデルの呼び出し
    messages = [
        SystemMessage(content="あなたは日本語を英語に翻訳するアシスタントです。"),
        HumanMessage(content="「私はプログラミングが大好きです。」を日本語から英語に翻訳してください。")
    ]
    chat(messages)
    AIMessage(content='"I love programming."', additional_kwargs={})

    (5) 複数メッセージセットによるチャットモデルの呼び出し。
    generate()を使用して、複数メッセージ セットでチャットモデルを呼び出します。戻り値は「LLMResult」になります。

    # 複数メッセージセットによるチャットモデルの呼び出し
    batch_messages = [
        [
            SystemMessage(content="あなたは日本語を英語に翻訳するアシスタントです。"),
            HumanMessage(content="「私はプログラミングが大好きです。」を日本語から英語に翻訳してください。")
        ],
        [
            SystemMessage(content="あなたは日本語を英語に翻訳するアシスタントです。"),
            HumanMessage(content="「私は人工知能が大好きです。」を日本語から英語に翻訳してください。")
        ],
    ]
    chat.generate(batch_messages)
    LLMResult(generations=[
        [ChatGeneration(text='"I love programming."', generation_info=None, message=AIMessage(content='"I love programming."', additional_kwargs={}))], 
        [ChatGeneration(text='"I love artificial intelligence."', generation_info=None, message=AIMessage(content='"I love artificial intelligence."', additional_kwargs={}))]
    ], llm_output=None)

    3. プロンプトテンプレート

    チャットモデルのテンプレートには、チャットモデルの呼び出し用の「ChatPromptTemplate」と、メッセージ用の「MessagePromptTemplates」があります。1つ以上の「MessagePromptTemplates」で「ChatPromptTemplate」を構築できます。

    ・SystemMessagePromptTemplate
    ・AIMessagePromptTemplate
    ・HumanMessagePromptTemplate

    (1) チャットモデルのプロンプトテンプレートの準備。

    from langchain.prompts.chat import (
        ChatPromptTemplate,
        SystemMessagePromptTemplate,
        AIMessagePromptTemplate,
        HumanMessagePromptTemplate,
    )
    
    # systemメッセージプロンプトテンプレートの準備
    template="あなたは {input_language} を {output_language} に翻訳するアシスタントです。"
    system_message_prompt = SystemMessagePromptTemplate.from_template(template)
    
    # humanメッセージプロンプトテンプレートの準備
    human_template="{text}"
    human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
    
    # chatプロンプトテンプレートの準備
    chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])

    (2) プロンプトテンプレートによるチャットモデルの呼び出し。
    「ChatPromptTemplate」のformat_prompt()に入力値を与えることで、「PromptValue」を生成できます。「PromptValue」は、言語モデル用の文字列とチャットモデル用のチャットメッセージリストに変換できます。

    # プロンプトテンプレートによるチャットモデルの呼び出し
    chat(chat_prompt.format_prompt(
        input_language="日本語", 
        output_language="英語", 
        text="私はプログラミングが大好きです。"
    ).to_messages())
    AIMessage(content='I love programming.', additional_kwargs={})


    「MessagePromptTemplate」をより直接的に構築したい場合は、外部で 「PromptTemplate」を作成してから渡すこともできます。

    from langchain import PromptTemplate
    
    # PromptTemplateからのsystemメッセージプロンプトテンプレートの作成
    prompt=PromptTemplate(
        template="あなたは {input_language} を {output_language} に翻訳するアシスタントです。",
        input_variables=["input_language", "output_language"],
    )
    system_message_prompt = SystemMessagePromptTemplate(prompt=prompt)

    4. LLMChain

    これまでと非常によく似た方法で「LLMChain」を使用できます。

    from langchain import LLMChain
    
    # LLMチェーンの準備
    chain = LLMChain(
        llm=chat, 
        prompt=chat_prompt
    )
    
    # LLMチェーンの実行
    chain.run(
        input_language="日本語", 
        output_language="英語", 
        text="私はプログラミングが大好きです。"
    )
    I love programming.

    5. メモリ

    チャットモデルでメモリを利用するには、「MessagesPlaceholder」と「return_messages=True」を使用します。

    (1) chatプロンプトテンプレートの準備
    chatプロンプトテンプレートに「MessagesPlaceholder」を追加することで、メモリのプロンプトに含めることができます。

    from langchain.prompts import (
        ChatPromptTemplate, 
        MessagesPlaceholder, 
        SystemMessagePromptTemplate, 
        HumanMessagePromptTemplate
    )
    
    # テンプレートの準備
    template = """あなたは人間と友好的に会話するAIです。
    AIはおしゃべりで、その文脈から多くの具体的な詳細を提供します。
    AIが質問に対する答えを知らない場合、正直に「知らない」と言います。"""
    
    # chatプロンプトテンプレートの準備
    prompt = ChatPromptTemplate.from_messages([
        SystemMessagePromptTemplate.from_template(template),
        MessagesPlaceholder(variable_name="history"),
        HumanMessagePromptTemplate.from_template("{input}")
    ])

    (2) チャットモデル、メモリ、会話チェーンの準備
    メモリに「return_messages=True」を指定することで、文字列でなくList[ChatMessage]を返すように指示します。

    from langchain.chains import ConversationChain
    from langchain.chat_models import ChatOpenAI
    from langchain.memory import ConversationBufferMemory
    
    # チャットモデルの準備
    llm = ChatOpenAI(temperature=0)
    
    # メモリの準備
    memory = ConversationBufferMemory(return_messages=True)
    
    # 会話チェーンの準備
    conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)

    (3) 質問応答。

    conversation.predict(input="スーパーマリオを発売しているゲームメーカーは?")
    スーパーマリオを発売しているゲームメーカーは任天堂です。

    (4) 質問応答。
    過去の会話履歴を理解していることを確認できました。

    conversation.predict(input="そのゲームメーカーの本社はどこにある?")
    任天堂の本社は日本にあります。具体的には、京都府京都市南区に本社があります

    6. ストリーミング

    「ChatOpenAI」には、コールバック処理を通じたストリーミングがサポートされています。

    (1) ストリーミングを有効にしたチャットモデルの準備。
    「streaming=True」と「callback_manager」を設定します。今回は標準出力 (StreamingStdOutCallbackHandler) を指定しています。

    from langchain.callbacks.base import CallbackManager
    from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
    
    # チャットモデルの準備
    chat = ChatOpenAI(
        streaming=True, 
        callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]), 
        verbose=True, 
        temperature=0
    )

    (2) チャットモデルの呼び出し。
    応答が少しずつ標準出力されることを確認します。

    # チャットモデルの呼び出し
    resp = chat([HumanMessage(content="人工知能が作る明るい未来の歌詞を書いてください。")])
    Verse 1:
    未来は明るくて、希望に満ちている
    人工知能が私たちを導いてくれる
    自動運転車が道路を走り、
    環境に優しいエネルギーが私たちを支える
    
    Chorus:
    明るい未来が待っている
    人工知能が私たちを導いてくれる
    夢を追いかけて、前進しよう
    未来は私たちの手の中にある
    
    Verse 2:
    医療技術が進化し、病気を治す
    ロボットが家事を手伝ってくれる
    人々は平和に暮らし、
    文化や言語の壁を越えて交流する
    
    Chorus:
    明るい未来が待っている
    人工知能が私たちを導いてくれる
    夢を

    関連



     
     

    npaka

     
     
    プログラマー。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガジェット。年2冊ペースで技術書を執筆。アニソン / カラオケ / ギター / 猫 twitter : @npaka123

    あなたへのおすすめ