見出し画像

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:
明るい未来が待っている
人工知能が私たちを導いてくれる
夢を

関連



この記事が気に入ったらサポートをしてみませんか?