AzureからGPTを使ってみる|memoryを使って会話履歴に沿って会話する。その1

LangchainのConversationBufferMemory、ConversationBufferWindowMemoryを使って会話履歴に沿った会話を実現する

過去の会話履歴を保持するための方法はいくつかあるが、今回は、ConversationBufferMemory、ConversationBufferWindowMemoryを使ってみる。
Langchainは、0.2.xを使用する。


ConversationBufferMemory

基本の形として以下のようにmemoryを設定して、historyを確認できる。

 #langchain =0.2.7
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory()
memory.save_context({"input": "こんにちわ"}, {"ouput": "どうかしましたか"})
memory.load_memory_variables({})
{'history': 'Human: こんにちわ\nAI: どうかしましたか'}

履歴をクリアする場合は、clear()を使う。

memory.clear()
memory.load_memory_variables({})
{'history': ''}

return_messagesをTrueにすると、履歴がリスト型になる。

memory = ConversationBufferMemory(return_messages=True)
memory.save_context({"input": "こんにちわ"}, {"ouput": "どうかしましたか"})
memory.load_memory_variables({})
{'history': [HumanMessage(content='こんにちわ'), AIMessage(content='どうかしましたか')]}

ConversationBufferWindowMemory

使い方は、ConversationBufferMemoryとほぼ同じ、違う点は、kで何回分の会話履歴を保持するかを指定できる。例えば"k=1"にすると最新の会話ターンのみ保持されるようになる。

memory = ConversationBufferWindowMemory(k=1)
memory.save_context({"input": "こんにちわ"}, {"ouput": "どうかしましたか"})
memory.save_context({"input": "ありがとうございます。"}, {"ouput": "どういたしまして"})
memory.load_memory_variables({})
{'history': 'Human: ありがとうございます。\nAI: どういたしまして'}

LLMでConversationBufferMemoryを使う

#langchain=0.2.7
#langchain_core=0.2.12
#langchain-openai=0.1.14

from langchain_openai import AzureChatOpenAI

from langchain.memory import ConversationBufferMemory

from langchain.chains import LLMChain
from langchain_core.messages import SystemMessage
from langchain_core.prompts.chat import (
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
    MessagesPlaceholder,
)

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

template_messages = [
    SystemMessage(content="You are a helpful assistant."),
    MessagesPlaceholder(variable_name="chat_history"),
    HumanMessagePromptTemplate.from_template("{text}"),
]
prompt_template = ChatPromptTemplate.from_messages(template_messages)

llm = AzureChatOpenAI(
    api_version=OPENAI_API_VERSION, 
    azure_deployment="gpt4o" # azure_deployment = "deployment_name"
    )

#memoryインスタンスを作成
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
    )

chain = LLMChain(
    llm=llm, 
    prompt=prompt_template,
    verbose=True, 
    memory=memory
)

chain.run(text = "こんにちは、私の名前はPON吉です。")

出力(verbose=TrueにするとLangchainの動きを確認できます。)

> Entering new LLMChain chain...
Prompt after formatting:
System: You are a helpful assistant.
Human: こんにちは、私の名前はPON吉です。

> Finished chain.
'こんにちは、PON吉さん!お会いできて嬉しいです。今日はどのようなお手伝いが必要ですか?'

さらに会話を続けてみる。

chain.run(text = "私の名前を呼んでください。")
> Entering new LLMChain chain...
Prompt after formatting:
System: You are a helpful assistant.
Human: こんにちは、私の名前はPON吉です。
AI: こんにちは、PON吉さん!お会いできて嬉しいです。今日はどのようなお手伝いが必要ですか?
Human: 私の名前を呼んでください。

> Finished chain.
'もちろんです、PON吉さん。どのようにお呼びすればよいですか?例えば、「PON吉さん」や「PON吉くん」、それとも他の呼び方がよろしいですか?'

成功!ちゃんと名前を憶えています。

LLMでConversationBufferWindowMemoryを使う

ほぼ同じ"k"を指定するくらい。
会話履歴に沿って会話するためのpromptは以下の形でも設定可能。while文を使って連続で会話をできるようにしてみる。

from langchain_openai import AzureChatOpenAI

from langchain.memory import ConversationBufferWindowMemory

from langchain_core.prompts import PromptTemplate
from langchain.chains import LLMChain


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



template = """You are a helpful assistant.

chat history:
{chat_history}

user input:{text}

AI:
"""

prompt_template = PromptTemplate(
		template=template,
    input_variables=["chat_history", "text"]
)
"""
template_messages = [
    SystemMessage(content="You are a helpful assistant."),
    MessagesPlaceholder(variable_name="chat_history"),
    HumanMessagePromptTemplate.from_template("{text}"),
]
prompt_template = ChatPromptTemplate.from_messages(template_messages)
"""
print(prompt_template)

llm = AzureChatOpenAI(
    api_version=OPENAI_API_VERSION, 
    azure_deployment="gpt4o" # azure_deployment = "deployment_name"
    )

#memoryインスタンスを作成
memory = ConversationBufferWindowMemory(
    k=1,#kで指定した数のみ、最新の会話履歴を保存
    memory_key="chat_history",
    return_messages=True
    )

chain = LLMChain(
    llm=llm, 
    prompt=prompt_template,
    verbose=True, 
    memory=memory
)

# 会話を開始
user_input=input("You: ")

while True: 
  response = chain.run(text=user_input)
  print(f"AI: {response}")
  user_input = input("You: ")
  if user_input == "exit":
    break

2ターンほど会話してみる。

> Entering new LLMChain chain...
Prompt after formatting:
You are a helpful assistant.

chat history:
[]

user input:こんにちは、私の名前はPON吉です。

AI:


> Finished chain.
AI: こんにちは、PON吉さん!お会いできて嬉しいです。今日はどのようなお手伝いをしましょうか?


> Entering new LLMChain chain...
Prompt after formatting:
You are a helpful assistant.

chat history:
[HumanMessage(content='こんにちは、私の名前はPON吉です。'), AIMessage(content='こんにちは、PON吉さん!お会いできて嬉しいです。今日はどのようなお手伝いをしましょうか?')]
...


> Finished chain.
AI: もちろんです、PON吉さん。何か他にお手伝いできることがあれば教えてくださいね。


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