AzureからGPTを使ってみる|memoryを使って会話履歴に沿って会話する。その2
LangchainのRunnableWithMessageHistoryを使って会話履歴に沿った会話を実現する
Langchainで会話履歴に沿った会話を実装するには、ConversationBufferMemoryや、ConversationBufferWindowMemoryを使うことで実現できるが、今回は、RunnableWithMessageHistoryの使い方をまとめました。
RunnableWithMessageHistoryを使う利点として、IDごとに会話セッションをわけることができます。
実際の利用方法は後述しますが、
output = with_message_history.invoke(
input={"question":"こんにちは。私の名前はPON吉です。"},
config={"configurable": {"session_id": "123"}},
)
のように、session_idを利用して、セッションを分けることができます。
RunnableWithMessageHistoryの実装
#langchain-openai=0.1.15
#langchain=0.2.7
#langchain-community=0.2.7
#langchain-core=0.2.12
from langchain_openai import AzureChatOpenAI
from langchain.chains import LLMChain
from langchain_core.messages import SystemMessage
from langchain_core.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
MessagesPlaceholder,
)
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from dotenv import load_dotenv
import os
# OpenAI APIキーの設定
dotenv_path = ".env"
load_dotenv(dotenv_path)
OPENAI_API_BASE = os.getenv('OPENAI_API_BASE')
OPENAI_API_VERSION = os.getenv('OPENAI_API_VERSION')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
os.environ["AZURE_OPENAI_API_KEY"] = OPENAI_API_KEY
os.environ["AZURE_OPENAI_ENDPOINT"] = OPENAI_API_BASE
#prompt_templateを設定
template_messages = [
SystemMessage(content="You are a helpful assistant."),
MessagesPlaceholder(variable_name="chat_history"),
HumanMessagePromptTemplate.from_template("{question}"),
]
prompt_template = ChatPromptTemplate.from_messages(template_messages)
#LLMを定義
llm = AzureChatOpenAI(
api_version=OPENAI_API_VERSION,
azure_deployment="gpt4o" # azure_deployment = "deployment_name"
)
#chainをLCELで記述
chain = prompt_template|llm
#会話履歴はstoreに貯められていく
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:
if session_id not in store:
store[session_id] = ChatMessageHistory()
return store[session_id]
with_message_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="question",
history_messages_key="chat_history",
#output_messages_key="output",
)
・1回目の会話
output = with_message_history.invoke(
input={"question":"こんにちは。私の名前はPON吉です。"},
config={"configurable": {"session_id": "123"}},
)
print(output.content)
こんにちは、PON吉さん!お会いできて嬉しいです。今日はどんなお手伝いをしましょうか?
・2回目の会話
output = with_message_history.invoke(
input={"question":"私の名前を呼んでください。"},
config={"configurable": {"session_id": "123"}},
)
print(output.content)
もちろんです、PON吉さん。今日はどんなことをお話ししましょうか?
・3回目の会話 (session_idを変えてみます。)
output = with_message_history.invoke(
input={"question":"私の名前を呼んでください。"},
config={"configurable": {"session_id": "456"}},
)
print(output.content)
申し訳ありませんが、あなたの名前はまだ教えていただいていないのでわかりません。お名前を教えていただけますか?
というように、idごとの会話が可能になります。
idごとの会話履歴を確認することもできます。
#idごとに会話履歴を表示する
history = get_session_history("123")
print(history)
Human: こんにちは。私の名前はPON吉です。
AI: こんにちは、PON吉さん!お会いできて嬉しいです。今日はどんなお手伝いをしましょうか?
Human: 私の名前を呼んでください。
AI: もちろんです、PON吉さん。今日はどんなことをお話ししましょうか?
clear()で、履歴をクリアします。
#会話をクリア
history = get_session_history("123").clear()
print(history)
None
おまけ
prompt_templateは、↓の形などでも取ることが、できます。
from langchain_core.prompts import PromptTemplate
template = """You are a helpful assistant.
chat history:
{chat_history}
user input:{question}
AI:
"""
prompt_template = PromptTemplate(
template=template,
input_variables=["chat_history", "question"]
)
chatアプリにmemoryを組み込むなら、セッションをわけることができるので、RunnableWithMessageHistoryの方が使いやすそうですが、履歴がstoreの中にどんどんたまってしまうので、注意が必要です。
一定数の会話をしたら、古い順に履歴を削除するロジックが必要になりますが、それは、こちらが参考になります。
この記事が気に入ったらサポートをしてみませんか?