08. Add Memory to Lcel Chain

08. Add memory to LCEL Chain

LCEL (Remember Conversation): Menambahkan memory

Menunjukkan cara menambahkan memori ke chain sembarang. Anda dapat menggunakan kelas memory saat ini, tetapi Anda harus menambahkannya secara manual

Python
from dotenv import load_dotenv
 
load_dotenv()
Python
from operator import itemgetter
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_openai import ChatOpenAI
 
# Menginisialisasi model ChatOpenAI.
model = ChatOpenAI()
 
# Membuat prompt percakapan. Prompt ini mencakup pesan sistem, riwayat percakapan sebelumnya, dan input pengguna.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "Anda adalah chatbot yang membantu"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

Buat ConversationBufferMemory, memori untuk menyimpan dialog, dan setel parameter return_messages ke True, sehingga instance yang dibuat akan mengembalikan pesan.

Atur memory_key: kunci yang nantinya akan ditetapkan ke prompt dalam chain. Anda dapat mengubahnya dan menggunakannya

Python
# Buat conversation buffer memory, dan aktifkan fitur pengembalian pesan.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")

Periksa riwayat obrolan yang disimpan. Karena Anda belum menyimpannya, riwayat obrolan masih kosong.

Python
# Menginisialisasi variabel-variabel memori ke dalam kamus kosong.
memory.load_memory_variables({})
{'chat_history': []}

Gunakan RunnablePasssthrough.assign untuk menetapkan hasil fungsi memory.load_memory_variables ke variabel chat_history, dan mengekstrak nilai yang sesuai dengan kunci chat_history dari hasil ini.

Python
runnable = RunnablePassthrough.assign(
    chat_history = RunnableLambda(memory.load_memory_variables)
    | itemgetter("chat_history") # Masukkan yang sama dengan memory_key.
)
Python
runnable.invoke({"input": "hi"})
{'input': 'hi', 'chat_history': []}
Python
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "Anda adalah chatbot yang membantu"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

runnable untuk memulai dialog pertama

  • input: Dialog masukan pengguna dimasukkan.
  • chat_history: Riwayat obrolan diteruskan.
Python
runnable.invoke({"input": "hi!"})
{'input': 'hi', 'chat_history': []}
Python
chain = runnable | prompt | model

Lakukan percakapan pertama Anda.

Python
# Menggunakan metode invoke dari objek chain untuk menghasilkan respons terhadap input.
response = chain.invoke({"input": "Senang bertemu dengan Anda. Nama saya Teddy."})
print(response.content)  # Mencetak respons yang dihasilkan.
Senang bertemu dengan Anda juga, Teddy! Ada yang bisa saya bantu hari ini?
Python
memory.load_memory_variables({})
{'chat_history': []}

Fungsi memory.save_context bertanggung jawab untuk menyimpan data input (input) dan konten respons (response.content) di dalam memori. Hal ini dapat digunakan untuk merekam kondisi saat ini selama proses pelatihan model AI, atau untuk melacak permintaan pengguna dan respons sistem.

Python
# Menyimpan data input dan konten respons ke dalam memori.
memory.save_context(
    {"human": "Senang bertemu dengan Anda. Nama saya Teddy."}, {"ai": response.content}
)
 
# Mencetak riwayat percakapan yang disimpan.
memory.load_memory_variables({})
{'chat_history': [HumanMessage(content='Senang bertemu dengan Anda. Nama saya Teddy.'), AIMessage(content='Senang bertemu dengan Anda juga, Teddy! Ada yang bisa saya bantu hari ini?')]}

Tanyakan lebih lanjut apakah masih mengingat nama yang diberikan

Python
 # Menanyakan apakah nama masih diingat.
  response = chain.invoke({"input": "Apakah Anda ingat apa nama saya?"})
  # Mencetak jawaban.
  print(response.content)
Ya, tentu saja! Nama Anda adalah Teddy. Apa yang bisa saya bantu untuk Anda hari ini?

Contoh penerapan CoversationChain khusus

Python
from operator import itemgetter
from langchain.memory import ConversationBufferMemory, ConversationSummaryMemory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableLambda, RunnablePassthrough, Runnable
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
 
# Menginisialisasi model ChatOpenAI.
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
 
# Membuat prompt percakapan. Prompt ini mencakup pesan sistem, riwayat percakapan sebelumnya, dan input pengguna.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "Anda adalah chatbot yang membantu"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)
 
# Membuat memori buffer percakapan, dan mengaktifkan fitur pengembalian pesan.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")
Python
class MyConversationChain(Runnable):
 
    def __init__(self, llm, prompt, memory, input_key="input"):
 
        self.prompt = prompt
        self.memory = memory
        self.input_key = input_key
 
        self.chain = (
            RunnablePassthrough.assign(
                chat_history=RunnableLambda(self.memory.load_memory_variables)
                | itemgetter(memory.memory_key)  # Sesuaikan dengan memory_key.
            )
            | prompt
            | llm
            | StrOutputParser()
        )
 
    def invoke(self, query, configs=None, **kwargs):
        answer = self.chain.invoke({self.input_key: query})
        self.memory.save_context(inputs={"human": query}, outputs={"ai": answer})
        return answer
Python
# Menginisialisasi model ChatOpenAI.
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)
 
# Membuat prompt percakapan. Prompt ini mencakup pesan sistem, riwayat percakapan sebelumnya, dan input pengguna.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "Anda adalah chatbot yang membantu"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)
 
# Membuat memori buffer percakapan, dan mengaktifkan fitur pengembalian pesan.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")
 
# Jika ingin mengganti dengan memori ringkasan
# memory = ConversationSummaryMemory(
#     llm=llm, return_messages=True, memory_key="chat_history"
# )
 
conversation_chain = MyConversationChain(llm, prompt, memory)
Python
conversation_chain.invoke("Halo? Senang bertemu dengan Anda. Nama saya Teddy.")
Halo, Teddy! Senang bertemu dengan Anda juga. Ada yang bisa saya bantu hari ini?
Python
conversation_chain.invoke("Apa nama saya tadi?")
Nama Anda Teddy. Ada yang bisa saya bantu, Teddy?
Python
conversation_chain.invoke("Tolong jawab hanya dalam bahasa Inggris mulai sekarang, oke?")
Sure, I can do that. How can I assist you today?
Python
conversation_chain.invoke("Bisakah Anda sebutkan nama saya sekali lagi?")
Your name is Teddy.
Python
conversation_chain.memory.load_memory_variables({})["chat_history"]
[HumanMessage(content='Halo? Senang bertemu dengan Anda. Nama saya Teddy.'), AIMessage(content='Halo, Teddy! Senang bertemu dengan Anda juga. Ada yang bisa saya bantu hari ini?'), HumanMessage(content='Apa nama saya tadi?'), AIMessage(content='Nama Anda Teddy. Ada yang bisa saya bantu, Teddy?'), HumanMessage(content='Tolong jawab hanya dalam bahasa Inggris mulai sekarang, oke?'), AIMessage(content='Sure, I can do that. How can I assist you today?'), HumanMessage(content='Bisakah Anda sebutkan nama saya sekali lagi?'), AIMessage(content='Your name is Teddy.')]