LangChainのConversation Knowledge Graph Memoryを検証してみた

## はじめに
LangChainの会話履歴を保存するMemory機能の1つであるConversation Knowledge Graph Memoryを検証してみました。LangChainのConversation Knowledge Graph Memoryの挙動を確認したい方におすすめです。

## 開発環境
- Windows 11
- Python 3.11.5
- dotenv
- LangChain
- Azure OpenAI

## 実装
### 必要なパッケージのインストール
以下のコマンドで必要なパッケージをインストールします。

```
pip install langchain
pip install openai
pip install python-dotenv
```

### 環境変数の設定と依存関係の読み込み
.envファイルを作成し、Azure Open AIの環境変数の設定をします。
ご自身の環境に合わせて設定してください。

```.env
# APIキー
OPENAI_API_KEY = "XXXXX"

# エンドポイント
AZURE_OPENAI_ENDPOINT = "XXXXX"

# 使用するOpenAI APIのバージョン
OPENAI_API_VERSION = "XXXXX"
```
　　
必要なライブラリをインポートします。
```test.py
# 環境変数を.envファイルから読み込む
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import AzureChatOpenAI
from langchain.chains import ConversationChain # 会話専用のChain
from langchain.memory import ConversationKGMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE # ConversationEntityMemory専用のテンプレート
```
　　
### 使用するモデルの準備
Azure Chat OpenAIを定義します。

```test.py
llm = AzureChatOpenAI(
    temperature=0,
    azure_deployment="gpt-35-turbo-16k",
)
```
　　
### プロンプトの定義
使用するプロンプトを定義します。プロンプトは、[こちら](https://python.langchain.com/docs/modules/memory/types/kg#using-in-a-chain)のプロンプトをそのまま活用しています。

```test.py
template = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. 
If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the "Relevant Information" section and does not hallucinate.

Relevant Information:

{history}

Conversation:
Human: {input}
AI:"""
prompt = PromptTemplate(input_variables=["history", "input"], template=template)
```
　　
### Conversation Knowledge Graph Memoryの定義

以下のようにConversation Knowledge Graph Memoryを定義します。
Conversation Knowledge Graph Memoryは**ナレッジグラフを使って記憶を再現**します。
ナレッジグラフとは、さまざまな知識（ナレッジ）を体系的に連結し、グラフ構造で表した知識のネットワークのことです。

```test.py
memory = ConversationKGMemory(llm=llm)
```
　　
### chainを作成し、実行

最後にchainを作成し、実行します。私自身の自己紹介を3問投げた後、4問目で私について知っていることを回答させました。

```test.py
conversation_with_kg = ConversationChain(
    llm=llm, verbose=True, prompt=prompt, memory=memory
)

result = conversation_with_kg.predict(input="土山竜輝は月に約400km走るエンジニアです。")
print(result)

result = conversation_with_kg.predict(input="土山竜輝は生成AIを活用して仕事をしています。")
print(result)

result = conversation_with_kg.predict(input="土山竜輝は社会人1年目です。")
print(result)

result = conversation_with_kg.predict(input="土山竜輝について知っていることを教えてください。")
print(result)
```

　　
これまでのPythonコードを上から順に記述し終わったら、Pythonファイルを実行します。
実行結果は以下のようになりました。

```terminal
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context.
If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the "Relevant Information" section and does not hallucinate.

Relevant Information:



Conversation:
Human: 土山竜輝は月に約400km走るエンジニアです。
AI:

> Finished chain.
それはすごいですね！土山竜輝さんは月に約400km走るエンジニアなんですね。彼はどのようにしてその距離を走ることができるので しょうか？


> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context.
If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the "Relevant Information" section and does not hallucinate.

Relevant Information:

On 土山竜輝: 土山竜輝 は 月に約400km走るエンジニア.

Conversation:
Human: 土山竜輝は生成AIを活用して仕事をしています。
AI:

> Finished chain.
土山竜輝は月に約400km走るエンジニアです。彼は生成AIを活用して仕事をしているかどうかはわかりません。


> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context.
If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the "Relevant Information" section and does not hallucinate.

Relevant Information:

On 土山竜輝: 土山竜輝 は 月に約400km走るエンジニア. 土山竜輝 は活用している 生成AI. 土山竜輝 している 仕事.

Conversation:
Human: 土山竜輝は社会人1年目です。
AI:

> Finished chain.
土山竜輝はエンジニアであり、月に約400km走ることができる人です。彼は生成AIを活用して仕事をしています。


> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context.
If the AI does not know the answer to a question, it truthfully says it does not know. The AI ONLY uses information contained in the "Relevant Information" section and does not hallucinate.

Relevant Information:

On 土山竜輝: 土山竜輝 は 月に約400km走るエンジニア. 土山竜輝 は活用している 生成AI. 土山竜輝 している 仕事. 土山竜輝 は 社会人1年目.

Conversation:
Human: 土山竜輝について知っていることを教えてください。
AI:

> Finished chain.
土山竜輝は月に約400km走るエンジニアで、生成AIを活用して仕事をしています。彼は社会人1年目です。
```

「Relevant Information」に会話履歴からの情報が生成されています。
その情報を元にして、4問目は回答していることが分かります。


## おわりに
LangChainの会話履歴を保存するMemory機能の1つであるConversation Knowledge Graph Memoryを検証してみました。文脈を考慮した回答を生成したい場合には、おすすめです。ぜひ、試してみてください。

最後までお読みいただき、ありがとうございました！ 
以下のXでも情報を発信しています！

https://twitter.com/t___tatsuki

## 参考文献
https://python.langchain.com/docs/modules/memory/types/kg