こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!
- LangChain Memory(メモリー)の概要・使い方が知りたい
- ChatGPTのような言語モデルに対して「過去の会話履歴に基づき返答できる機能」を実装したい
LangChainとは?
LangChainとは、ChatGPTを代表とするような大規模言語モデル(LLM)の機能を拡張し、サービスとして展開する際に役立つライブラリです。
LangChainの主要機能
LangChainの主要な機能として以下があります。
主要機能 | 概要 |
---|---|
Models | 様々な大規模言語モデルを同じインターフェース上で取り扱えるようにする機能 |
Prompts | プロンプトの管理、最適化、シリアル化ができる機能 |
Memory | 言語モデルを用いてユーザーと対話した履歴を記憶する機能 |
Data connection | 言語モデルに外部データを投入し、外部データに基づく回答を生成する機能 |
Chains | チェーンを複数繋げて、一連の処理を連続実行する機能 |
Agents | ユーザーからの要望をどんな手段・順序で応えるか決定・実行する機能 |
LangChainの各種機能の詳細を知りたい方は、こちらの記事をご覧下さい。
【参考】LangChainを用いたプログラミング実装におすすめの学習教材
LangChainライブラリを用いてプログラミングし、アプリケーションを実装したい方向けに、おすすめの学習教材をご紹介します。
LangChain|Memory(メモリー)
LangChain Memory(メモリー)とは、LLMを用いてユーザーと対話した履歴を記憶する機能です。
チャット上のやり取りはデフォルトでステートレスであるため、対話履歴が保持されず、各クエリが独立したものとしてみなされてしまいます。一方、メモリーを用いることで過去の対話を履歴として残し、それに基づき新たな回答を生成することができるようになります。
LangChain Memoryの種類
Langchain Memoryには2種類の代表モジュールがあります。
- ConversationBufferMemory
- ConversationSummaryMemory
- ConversationBufferWindowMemory
- ChatMessageHistory
ConversationBufferMemory
ConversationBufferMemoryとは、チャット履歴を記録するための機能です。
ユーザー(人間)・AIのメッセージをそれぞれ記録し、その記録内容をLLMが容易に参照できる機能を有しています。
ConversationSummaryMemory
ConversationSummaryMemoryとは、チャット内容を要約して記録するための機能です。
前述のConversationBufferMemory を用いて、大量のトークン履歴を保持する場合、ストレージの容量制限を受ける可能性があります。容量対策において、ConversationSummaryMemoryは有効です。
ConversationBufferWindowMemory
ConversationBufferWindowMemoryとは、ConversationBufferMemory同様、チャット履歴を記録するための機能ですが、メモリにウィンドウ機能が付属しています。
Windowとは、ユーザーとAIとの対話を最新のいくつまで記録するかを指定できる機能です。例えば、100と指定すると最新の対話100個まで記録されます。
ChatMessageHistory
ChatMessageHistoryとは、チャット履歴を記録するための機能です。LLMを用いて会話したチャット履歴をローカル環境などの外部に保存したい場合に使い勝手の良い機能です。
【LangChain事前準備】Python環境構築・OpenAIのChatGPT API取得
PythonとLangChainによるLangChain Memory機能構築に際して必要な事前準備を行います。
Pythonライブラリのインストール
プログラム実装に際して、以下に示すライブラリが必要となります。ターミナル(MacOS)またはコマンドプロンプト(Windows)を通じて事前にインストールしておきましょう。
OpenAI
ChatGPTを代表とするOpenAI社のAPI利用に際して必要となるライブラリです。
pip install openai
LangChain
LangChainの利用に際して必要となるライブラリです。
pip install langchain
【ChatGPT】OpenAI社のAPI発行
LangChain機能構築に際して、OpenAI社が提供するGPTモデルをAPI経由で呼び出す必要があります。
OpenAI社の公式サイトから「API シークレットキー」を事前に発行しておきましょう。なお、シークレットキーの発行方法はこちらの記事で詳しく解説しています。
【Python】LangChain Memoryの基本操作
はじめに、LangChain Memoryの基本操作について解説します。
Pythonライブラリのインストール
Pythonプログラムの先頭にライブラリとAPI認証情報を記述します。
前述したOpenAI社のサイトから取得したシークレットキー
を入力しましょう。
import openai
import os
# APIシークレットキーを記述
SECRET_KEY = "............."
# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY
LangChain Memoryの作成
LangChain Memoryには、「ConversationBufferMemory」「ConversationSummaryMemory」「ConversationBufferWindowMemory」という3つの代表機能があります。以下、いづれかのコードを実行してみましょう。
【コード例】ConversationBufferMemory
from langchain.memory import ConversationBufferMemory
# =========================================================================
# メモリ作成
# =========================================================================
# メモリオブジェクト
memory = ConversationBufferMemory(
input_key = None, # 入力キー該当の項目名
output_key = None, # 出力キー該当の項目名
memory_key = 'history', # メモリキー該当の項目名
return_messages = True, # メッセージ履歴をリスト形式での取得有無
human_prefix = 'Human', # ユーザーメッセージの接頭辞
ai_prefix = 'AI', # AIメッセージの接頭辞
)
【コード例】ConversationSummaryMemory
from langchain.memory import ConversationSummaryMemory
from langchain.llms import OpenAI
# =========================================================================
# メモリ作成
# =========================================================================
# メモリオブジェクト
memory = ConversationSummaryMemory(
llm = OpenAI(), # 文章要約に用いるLLM
)
【コード例】ConversationBufferWindowMemory
from langchain.memory import ConversationBufferWindowMemory
# =========================================================================
# メモリ作成
# =========================================================================
# メモリオブジェクト
memory = ConversationBufferWindowMemory(
k = 2, # いくつの対話を記録するか
)
メモリーに対話履歴を保持
前述で記述したLangChain Memoryオブジェクトに対して、ユーザー(人間)・AIのメッセージを追加する場合、次のような2通りの方法があります。
【コード例】chat_memory.add_ai_message()
# =========================================================================
# メッセージ追加
# =========================================================================
# ユーザーメッセージ追加
user_message = "こんにちは!"
memory.chat_memory.add_user_message(user_message)
# AIメッセージ追加
ai_message = "初めまして、どうなされましたか?"
memory.chat_memory.add_ai_message(ai_message)
【コード例】save_context()
# =========================================================================
# メッセージ追加
# =========================================================================
# メッセージ追加
memory.save_context(inputs = {"Human": "こんにちは!"}, # 入力
outputs = {"AI": "初めまして、どうなされましたか?"}, # 出力
)
メモリに記録したメッセージを確認
LangChain Memoryオブジェクトに記録したメッセージは、load_memory_variables()
メソッドを用いて確認できます。
コード
# =========================================================================
# メッセージ確認
# =========================================================================
# メモリロード
loaded_memory = memory.load_memory_variables({})
出力イメージ
# 出力
print(loaded_memory)
# 出力イメージ
# {'history':
# [HumanMessage(content='こんにちは!', additional_kwargs={}, example=False),
# AIMessage(content='初めまして、どうなされましたか?', additional_kwargs={}, example=False)]}
【Python×Memory】過去の会話履歴に基づきチャットする言語モデル実装
「LangChain Memoryを用いて、過去の会話履歴に基づきチャットを返すLLMを構築」という実践的な内容を解説します。
- Pythonライブラリのインストール
- プロンプトテンプレートの作成
- モデル作成(LLM)
- LangChain Memoryの作成
- 会話・LLMチェーンの作成
- モデル実行
Pythonライブラリのインストール
Pythonプログラムの先頭にライブラリとAPI認証情報を記述します。
前述したOpenAI社のサイトから取得したシークレットキー
を入力しましょう。
import openai
import os
# APIシークレットキーを記述
SECRET_KEY = "............."
# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY
プロンプトテンプレートの作成
後述で作成するLLMに渡すプロンプトテンプレートを作成します。以下コードを実行しましょう。
コード
from langchain import LLMChain, PromptTemplate
# ====================================================================================
# Prompt Template作成
# ====================================================================================
template = \
"""
あなたは人間と会話するAIです。
過去の会話履歴はこちらを参照: {history}
Human: {input}
AI:
"""
# プロンプトテンプレート
prompt_template = PromptTemplate(
input_variables = ["history", "input"], # 入力変数
template = template, # テンプレート
validate_template = True, # 入力変数とテンプレートの検証有無
)
LangChain Prompts
プロンプトテンプレートは、LangChain Promptsという機能を用いて実装します。具体的な内容について詳しく知りたい方はこちらの記事をご覧ください。
モデル作成(LLM)
ユーザーと会話するための大規模言語モデル(LLM)を作成します。LLMはOpenAI社が提供するChatGPTモデルを呼び出す形式で次のようなコードを用いて実装します。
コード
from langchain.llms import OpenAI
# ====================================================================================
# LLM作成
# ====================================================================================
LLM = OpenAI(
model_name = "text-davinci-003", # OpenAIモデル名
temperature = 0, # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
n = 1, # いくつの返答を生成するか
)
LLM
今回LLMはLangChain Modelsの機能を用いて実装しています。具体的な内容について知りたい方はこちらの記事をご覧ください。
LangChain Memoryの作成
今回のメイン機能「LangChain Memory」について、以下例ではConversationBufferMemory
を用いた実装方法について言及します。
from langchain.memory import ConversationBufferMemory
# =========================================================================
# メモリ作成
# =========================================================================
# メモリオブジェクト
memory = ConversationBufferMemory(
input_key = None, # 入力キー該当の項目名
output_key = None, # 出力キー該当の項目名
memory_key = 'history', # メモリキー該当の項目名
return_messages = True, # メッセージ履歴をリスト形式での取得有無
human_prefix = 'Human', # ユーザーメッセージの接頭辞
ai_prefix = 'AI', # AIメッセージの接頭辞
)
会話・LLMチェーンの作成
ここまでで言語モデルを実際に稼働させるために必要なコンポーネントである「プロンプトテンプレート」「LLM」「メモリー」の作成が完了しました。最後にこれらを連結して言語モデルを稼働させる「チェーン」機能を実装します。
今回例としてConversation Chain
およびLLM Chain
という2通りの実装方法を紹介します。いづれかのコードを実行しましょう。
【コード例】Conversation Chain
from langchain.chains import ConversationChain
# ====================================================================================
# Conversation Chain
# ====================================================================================
# 対話チェーン
chain = ConversationChain(
llm = LLM, # LLMモデル
prompt = prompt_template, # プロンプトテンプレート
verbose = True, # プロンプトを表示するか否か
memory = memory, # メモリ
)
【コード例】LLMChain
from langchain import LLMChain
# ====================================================================================
# LLM Chain作成
# ====================================================================================
# LLM Chain
chain = LLMChain(
llm = LLM, # LLMモデル
prompt = prompt_template, # プロンプトテンプレート
verbose = True, # プロンプトを表示するか否か
memory = memory, # メモリ
)
LangChain Chains
LangChain Chainsの概要・実装方法について詳しく知りたい方はこちらの記事をご覧ください。
モデル実行
実際に言語モデルを実行し、過去の会話履歴に基づき回答を生成できるモデルが作成できたかどうか確認します。
1回目モデル実行
言語モデルは、前述で作成したチェーンchain
に対してpredict(入力メッセージ)
を適用することで実行できます。例えば以下コードを実行すると、次のような出力結果が得られます。
# ====================================================================================
# モデル実行
# ====================================================================================
# 入力メッセージ
message = "Pythonとは何ですか?"
# Chain実行
result = chain.predict(input=message)
# ====================================================================================
# 出力イメージ
# ====================================================================================
# 出力
print(result)
# 出力イメージ
# > Entering new ConversationChain chain...
# Prompt after formatting:
# あなたは人間と会話するAIです。
# 過去の会話履歴はこちらを参照: []
# Human: Pythonとは何ですか?
# AI:
# > Finished chain.
# Pythonは、オープンソースのプログラミング言語です。
# Pythonは、Web開発、ソフトウェア開発、データ分析など、さまざまな分野で使用されています。
# Pythonは、高い可読性と効率的なプログラミングを可能にするため、プログラマーにとって非常に人気のある言語です。
2回目モデル実行
言語モデルを再実行し、1回目モデル実行結果を考慮した回答が生成されるか検証します。以下のコードを実行してみましょう。
# ====================================================================================
# モデル実行
# ====================================================================================
# 入力メッセージ
message = "それを学んでメリットを得られるのはどのような人か?"
# Chain実行
result = chain.predict(input=message)
# ====================================================================================
# 出力イメージ
# ====================================================================================
# 出力
print(result)
# 出力イメージ
# > Entering new ConversationChain chain...
# Prompt after formatting:
# あなたは人間と会話するAIです。
# 過去の会話履歴はこちらを参照: [HumanMessage(content='Pythonとは何ですか?', additional_kwargs={}, example=False), AIMessage(content='\nPythonは、オープンソースのプログラミング言語です。Pythonは、Web開発、ソフトウェア開発、データ分析など、さまざまな分野で使用されています。Pythonは、高い可読性と効率的なプログラミングを可能にするため、プログラマーにとって非常に人気のある言語です。', additional_kwargs={}, example=False)]
# Human: それを学んでメリットを得られるのはどのような人か?
# AI:
# > Finished chain.
# Pythonを学ぶことで、プログラマー、Web開発者、ソフトウェア開発者、データサイエンティストなど、さまざまな分野で活躍できる人がメリットを得られます。
# Pythonを学ぶことで、プログラミングスキルを向上させることができ、さまざまなプロジェクトを実行できるようになります。
LangChain Memoryを用いた言語モデル実装コードまとめ
ここまで紹介したコードをまとめて紹介します。
import openai
import os
from langchain.llms import OpenAI
from langchain import LLMChain, PromptTemplate
from langchain.chains import ConversationChain
# ====================================================================================
# API認証情報
# ====================================================================================
# APIシークレットキーを記述
SECRET_KEY = "............."
# API認証情報設定
os.environ["OPENAI_API_KEY"] = SECRET_KEY
# ====================================================================================
# Prompt Template作成
# ====================================================================================
template = \
"""
あなたは人間と会話するAIです。
過去の会話履歴はこちらを参照: {history}
Human: {input}
AI:
"""
# プロンプトテンプレート
prompt_template = PromptTemplate(
input_variables = ["history", "input"], # 入力変数
template = template, # テンプレート
validate_template = True, # 入力変数とテンプレートの検証有無
)
# ====================================================================================
# LLM作成
# ====================================================================================
LLM = OpenAI(
model_name = "text-davinci-003", # OpenAIモデル名
temperature = 0, # 出力する単語のランダム性(0から2の範囲) 0であれば毎回返答内容固定
n = 1, # いくつの返答を生成するか
)
# ====================================================================================
# メモリ作成
# ====================================================================================
# メモリオブジェクト
memory = ConversationBufferMemory(
input_key = None, # 入力キー該当の項目名
output_key = None, # 出力キー該当の項目名
memory_key = 'history', # メモリキー該当の項目名
return_messages = True, # メッセージ履歴をリスト形式での取得有無
human_prefix = 'Human', # ユーザーメッセージの接頭辞
ai_prefix = 'AI', # AIメッセージの接頭辞
)
# ====================================================================================
# LLM Chain作成
# ====================================================================================
# LLM Chain
chain = LLMChain(
llm = LLM, # LLMモデル
prompt = prompt_template, # プロンプトテンプレート
verbose = True, # プロンプトを表示するか否か
memory = memory, # メモリ
)
# ====================================================================================
# モデル実行
# ====================================================================================
# 入力メッセージ
message = "Pythonとは何ですか?"
# LLM Chain実行
result = chain.predict(input=message)
# ====================================================================================
# 出力イメージ
# ====================================================================================
# 出力
print(result)
# 出力イメージ
# Pythonは、オープンソースのプログラミング言語です。
# Pythonは、Web開発、ソフトウェア開発、データ分析など、さまざまな分野で使用されています。
# Pythonは、高い可読性と効率的なプログラミングを可能にするため、プログラマーにとって非常に人気のある言語です。
【Python×ChatMessageHistory】ローカル環境にチャット履歴を保存
LLMを用いてユーザーと対話した履歴をローカル環境などの外部に保存したい場面があるかもしれません。そのような場面にLangChain MemoryのChatMessageHistory
機能が役立ちます。以下、この機能の使い方について解説します。
LangChain Memory|ChatMessageHistory機能の作成
ChatMessageHistory
機能の作成には、次のコードを実行しましょう。また、ユーザーメッセージとAIメッセージをこの機能に記録した例も併せて示します。
コード
import json
from langchain.memory import ChatMessageHistory
from langchain.schema import messages_from_dict, messages_to_dict
# =========================================================================
# ChatMessageHistory
# =========================================================================
# オブジェクト作成
history = ChatMessageHistory()
# ユーザーメッセージ追加
user_message = "こんにちは!"
history.add_user_message(user_message)
# AIメッセージ追加
ai_message = "初めまして、どうなされましたか?"
history.add_ai_message(ai_message)
出力イメージ
ChatMessageHistory
のインスタンスを開くと、前述で追加したメッセージが確認できます。
# 出力
print(history)
# 出力イメージ
# messages=[HumanMessage(content='こんにちは!', additional_kwargs={}, example=False),
# AIMessage(content='初めまして、どうなされましたか?', additional_kwargs={}, example=False)]
対話履歴をローカル環境に保存
ChatMessageHistory
に蓄積したチャット履歴をローカル環境に保存する場合、以下のコードを実行します。
①メッセージを辞書形式に変換し、②JSON形式のファイルとして保存する手順が一般的です。
# =========================================================================
# メッセージ履歴をJSON形式でローカルに保存
# =========================================================================
# メッセージを辞書形式に変換
history_dicts = messages_to_dict(history.messages)
# 保存場所指定
filepath = "memory.json"
# JSON形式でメッセージファイル保存
with open(filepath, 'w') as f:
json.dump(history_dicts, f)
ローカル環境に保存した対話履歴をPython環境にロード
前述でローカル環境に保存した対話履歴を再びPython環境でロードする場合、次のコードを実行します。
コード
# =========================================================================
# JSON形式のメッセージ履歴をローカルから読込
# =========================================================================
# 保存場所指定
filepath = "memory.json"
# JSON形式のメッセージ履歴をロード
with open(filepath) as f:
history_dicts = json.load(f)
# 辞書型からメッセージ型に変換
memory = messages_from_dict(history_dicts)
出力イメージ
# 出力
print(history)
# 出力イメージ
# messages=[HumanMessage(content='こんにちは!', additional_kwargs={}, example=False),
# AIMessage(content='初めまして、どうなされましたか?', additional_kwargs={}, example=False)]
【参考】PythonによるLLM実装|ChatGPT・LangChain
本記事では、PythonでLLMを構築し、様々なタスクをこなす機能の実装方法を多数解説しています。
Python × ChatGPT関連記事
Python × LangChain関連記事
自然言語処理の学習におすすめの書籍
自然言語処理の概要について詳しく学びたい方向けに、厳選したおすすめの学習教材を紹介しています。
最後に
お問い合わせフォーム
上記課題に向けてご気軽にご相談下さい。
お問い合わせはこちら