LCEL (대화내용 기억하기): 메모리 추가

대화 메모리

대화 컨텍스트를 관리하는 다양한 메모리 시스템을 다룬다.

AI
RAG
LangChain
저자

Kwangmin Kim

공개

2024년 12월 31일

임의의 체인에 메모리를 추가하는 방법을 보여줍니다. 현재 메모리 클래스를 사용할 수 있지만 수동으로 연결해야 합니다

from dotenv import load_dotenv

load_dotenv()
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


# ChatOpenAI 모델을 초기화합니다.
model = ChatOpenAI()

# 대화형 프롬프트를 생성합니다. 이 프롬프트는 시스템 메시지, 이전 대화 내역, 그리고 사용자 입력을 포함합니다.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful chatbot"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

대화내용을 저장할 메모리인 ConversationBufferMemory 생성하고 return_messages 매개변수를 True로 설정하여, 생성된 인스턴스가 메시지를 반환하도록 합니다.

# 대화 버퍼 메모리를 생성하고, 메시지 반환 기능을 활성화합니다.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")

저장된 대화기록을 확인합니다. 아직 저장하지 않았으므로, 대화기록은 비어 있습니다.

memory.load_memory_variables({})  # 메모리 변수를 빈 딕셔너리로 초기화합니다.

RunnablePassthrough.assign을 사용하여 chat_history 변수에 memory.load_memory_variables 함수의 결과를 할당하고, 이 결과에서 chat_history 키에 해당하는 값을 추출합니다.

runnable = RunnablePassthrough.assign(
    chat_history=RunnableLambda(memory.load_memory_variables)
    | itemgetter("chat_history")  # memory_key 와 동일하게 입력합니다.
)
runnable.invoke({"input": "hi"})
runnable.invoke({"input": "hi"})
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful chatbot"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

runnable 에 첫 번째 대화를 시작합니다.

runnable.invoke({"input": "hi!"})
chain = runnable | prompt | model

첫 번째 대화를 진행합니다.

# chain 객체의 invoke 메서드를 사용하여 입력에 대한 응답을 생성합니다.
response = chain.invoke({"input": "만나서 반갑습니다. 제 이름은 테디입니다."})
print(response.content)  # 생성된 응답을 출력합니다.
memory.load_memory_variables({})

memory.save_context 함수는 입력 데이터(inputs)와 응답 내용(response.content)을 메모리에 저장하는 역할을 합니다. 이는 AI 모델의 학습 과정에서 현재 상태를 기록하거나, 사용자의 요청과 시스템의 응답을 추적하는 데 사용될 수 있습니다.

# 입력된 데이터와 응답 내용을 메모리에 저장합니다.
memory.save_context(
    {"human": "만나서 반갑습니다. 제 이름은 테디입니다."}, {"ai": response.content}
)

# 저장된 대화기록을 출력합니다.
memory.load_memory_variables({})

이름을 기억하고 있는지 추가 질의합니다.

# 이름을 기억하고 있는지 추가 질의합니다.
response = chain.invoke({"input": "제 이름이 무엇이었는지 기억하세요?"})
# 답변을 출력합니다.
print(response.content)

1 커스텀 ConversationChain 구현 예시

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

# ChatOpenAI 모델을 초기화합니다.
llm = ChatOpenAI(model_name="gpt-4.1-mini", temperature=0)

# 대화형 프롬프트를 생성합니다. 이 프롬프트는 시스템 메시지, 이전 대화 내역, 그리고 사용자 입력을 포함합니다.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful chatbot"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

# 대화 버퍼 메모리를 생성하고, 메시지 반환 기능을 활성화합니다.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")
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)  # 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
# ChatOpenAI 모델을 초기화합니다.
llm = ChatOpenAI(model_name="gpt-4.1-mini", temperature=0)

# 대화형 프롬프트를 생성합니다. 이 프롬프트는 시스템 메시지, 이전 대화 내역, 그리고 사용자 입력을 포함합니다.
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful chatbot"),
        MessagesPlaceholder(variable_name="chat_history"),
        ("human", "{input}"),
    ]
)

# 대화 버퍼 메모리를 생성하고, 메시지 반환 기능을 활성화합니다.
memory = ConversationBufferMemory(return_messages=True, memory_key="chat_history")

# 요약 메모리로 교체할 경우
# memory = ConversationSummaryMemory(
#     llm=llm, return_messages=True, memory_key="chat_history"
# )

conversation_chain = MyConversationChain(llm, prompt, memory)
conversation_chain.invoke("안녕하세요? 만나서 반갑습니다. 제 이름은 테디 입니다.")
conversation_chain.invoke("제 이름이 뭐라고요?")
conversation_chain.invoke("앞으로는 영어로만 답변해주세요 알겠어요?")
conversation_chain.invoke("제 이름을 다시 한 번 말해주세요")
conversation_chain.memory.load_memory_variables({})["chat_history"]

Subscribe

Enjoy this blog? Get notified of new posts by email: