목차
- ConversationBufferMemory 개요
- 문자열로 메시지 추출하기
- 대화 기록 저장 및 확인
- return_messages=True 옵션 사용
- ConversationChain에 적용하기
🏖️ 1. ConversationBufferMemory 개요
ConversationBufferMemory
는 메시지를 저장하고, 이후 변수에 메시지를 추출할 수 있게 해주는 메모리입니다.
🏖️ 2. 문자열로 메시지 추출하기
- 이 메모리로 메시지를 문자열로 추출할 수 있습니다.
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context(
inputs={"human": "안녕하세요, 비대면으로 은행 계좌를 개설하고 싶습니다. 어떻게 시작해야 하나요?"},
outputs={"ai": "안녕하세요! 계좌 개설을 원하신다니 기쁩니다. 먼저, 본인 인증을 위해 신분증을 준비해 주시겠어요?"}
)
load_memory_variables({})
함수를 사용하여 history
키에 저장된 대화 기록을 확인할 수 있습니다.
print(memory.load_memory_variables({})["history"])
🏖️ 3. 대화 기록 저장 및 확인
save_context(inputs, outputs)
메서드를 사용하여 대화 기록을 저장할 수 있습니다.
- 이 메서드는
inputs
와 outputs
두 개의 인자를 받습니다.
inputs
: 사용자의 입력
outputs
: AI의 출력
memory.save_context(
inputs={"human": "네, 신분증을 준비했습니다. 이제 무엇을 해야 하나요?"},
outputs={"ai": "감사합니다. 신분증 앞뒤를 명확하게 촬영하여 업로드해 주세요. 이후 본인 인증 절차를 진행하겠습니다."}
)
- 여러 대화를 저장한 후,
load_memory_variables
메서드를 사용하여 대화 기록을 확인할 수 있습니다.
print(memory.load_memory_variables({})["history"])
🏖️ 4. return_messages=True 옵션 사용
return_messages=True
옵션을 사용하면 HumanMessage
와 AIMessage
객체를 반환합니다.
memory = ConversationBufferMemory(return_messages=True)
memory.save_context(
inputs={"human": "안녕하세요, 비대면으로 은행 계좌를 개설하고 싶습니다. 어떻게 시작해야 하나요?"},
outputs={"ai": "안녕하세요! 계좌 개설을 원하신다니 기쁩니다. 먼저, 본인 인증을 위해 신분증을 준비해 주시겠어요?"}
)
history
에 저장된 대화 기록을 객체 형태로 확인할 수 있습니다.
print(memory.load_memory_variables({})["history"])
🏖️ 5. ConversationChain에 적용하기
ConversationChain
을 사용하여 대화를 진행할 수 있습니다.
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
load_dotenv()
llm = ChatOpenAI(temperature=0)
conversation = ConversationChain(
llm=llm,
memory=ConversationBufferMemory(),
)
- 대화를 시작하고, 대화 기록을 바탕으로 이전 답변을 불렛포인트 형식으로 정리할 수 있습니다.
response = conversation.predict(
input="이전 답변을 불렛포인트 형식으로 정리하여 알려주세요."
)
print(response)
목차
- ConversationBufferWindowMemory 개요
- 최근 K개의 상호작용만 저장
- 대화 기록 예제
🏖️ 1. ConversationBufferWindowMemory 개요
ConversationBufferWindowMemory
는 시간이 지남에 따라 대화의 상호작용 목록을 유지합니다.
- 이 메모리는 모든 대화 내용을 저장하지 않고, 최근 K개의 상호작용만 저장합니다.
🏖️ 2. 최근 K개의 상호작용만 저장
ConversationBufferWindowMemory
는 버퍼가 너무 커지지 않도록 최근 대화의 슬라이딩 창을 유지하는 데 유용합니다.
- 예를 들어,
k=2
로 설정하면 가장 최근 두 개의 상호작용만 저장합니다.
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=2, return_messages=True)
save_context
메서드를 사용하여 대화 기록을 저장하고, load_memory_variables
메서드를 통해 최근 K개의 상호작용만 반환받을 수 있습니다.
🏖️ 3. 대화 기록 예제
- 다음은
k=2
로 설정한 후, 여러 대화를 저장하고 최근 대화만 반환하는 예제입니다.
memory.save_context(
inputs={"human": "안녕하세요, 비대면으로 은행 계좌를 개설하고 싶습니다. 어떻게 시작해야 하나요?"},
outputs={"ai": "안녕하세요! 계좌 개설을 원하신다니 기쁩니다. 먼저, 본인 인증을 위해 신분증을 준비해 주시겠어요?"}
)
memory.save_context(
inputs={"human": "네, 신분증을 준비했습니다. 이제 무엇을 해야 하나요?"},
outputs={"ai": "감사합니다. 신분증 앞뒤를 명확하게 촬영하여 업로드해 주세요. 이후 본인 인증 절차를 진행하겠습니다."}
)
memory.save_context(
inputs={"human": "사진을 업로드했습니다. 본인 인증은 어떻게 진행되나요?"},
outputs={"ai": "업로드해 주신 사진을 확인했습니다. 이제 휴대폰을 통한 본인 인증을 진행해 주세요. 문자로 발송된 인증번호를 입력해 주시면 됩니다."}
)
memory.save_context(
inputs={"human": "인증번호를 입력했습니다. 계좌 개설은 이제 어떻게 하나요?"},
outputs={"ai": "본인 인증이 완료되었습니다. 이제 원하시는 계좌 종류를 선택하고 필요한 정보를 입력해 주세요. 예금 종류, 통화 종류 등을 선택할 수 있습니다."}
)
memory.save_context(
inputs={"human": "정보를 모두 입력했습니다. 다음 단계는 무엇인가요?"},
outputs={"ai": "입력해 주신 정보를 확인했습니다. 계좌 개설 절차가 거의 끝났습니다. 마지막으로 이용 약관에 동의해 주시고, 계좌 개설을 최종 확인해 주세요."}
)
memory.save_context(
inputs={"human": "모든 절차를 완료했습니다. 계좌가 개설된 건가요?"},
outputs={"ai": "네, 계좌 개설이 완료되었습니다. 고객님의 계좌 번호와 관련 정보는 등록하신 이메일로 발송되었습니다. 추가적인 도움이 필요하시면 언제든지 문의해 주세요. 감사합니다!"}
)
print(memory.load_memory_variables({})["history"])
- 위 코드를 실행하면 가장 최근 2개의 대화만 반환됩니다.
[HumanMessage(content='정보를 모두 입력했습니다. 다음 단계는 무엇인가요?'),
AIMessage(content='입력해 주신 정보를 확인했습니다. 계좌 개설 절차가 거의 끝났습니다. 마지막으로 이용 약관에 동의해 주시고, 계좌 개설을 최종 확인해 주세요.'),
HumanMessage(content='모든 절차를 완료했습니다. 계좌가 개설된 건가요?'),
AIMessage(content='네, 계좌 개설이 완료되었습니다. 고객님의 계좌 번호와 관련 정보는 등록하신 이메일로 발송되었습니다. 추가적인 도움이 필요하시면 언제든지 문의해 주세요. 감사합니다!')]
목차
- ConversationTokenBufferMemory 개요
- 최대 토큰 길이 설정
- 대화 기록 예제
🏖️ 1. ConversationTokenBufferMemory 개요
ConversationTokenBufferMemory
는 대화 히스토리를 메모리에 보관하면서, 대화의 개수가 아닌 토큰 길이를 기준으로 대화 내용을 관리합니다.
- 특정 토큰 길이 제한에 도달하면, 오래된 대화 내용이 플러시(flush)됩니다.
🏖️ 2. 최대 토큰 길이 설정
max_token_limit
는 대화 내용을 저장할 최대 토큰 길이를 설정하는 옵션입니다.
- 예를 들어,
max_token_limit=150
으로 설정하면, 대화 기록이 150개의 토큰을 초과하지 않도록 관리됩니다.
from langchain.memory import ConversationTokenBufferMemory
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
load_dotenv()
llm = ChatOpenAI()
memory = ConversationTokenBufferMemory(
llm=llm, max_token_limit=150, return_messages=True
)
🏖️ 3. 대화 기록 예제
- 다음은
max_token_limit=150
으로 설정한 후, 여러 대화를 저장하고 최대 토큰 길이에 도달한 후의 동작을 확인하는 예제입니다.
memory.save_context(
inputs={"human": "안녕하세요, 저는 최근에 여러분 회사의 공작 기계를 구매했습니다. 설치 방법을 알려주실 수 있나요?"},
outputs={"ai": "안녕하세요! 구매해 주셔서 감사합니다. 해당 기계 모델 번호를 알려주시겠어요?"}
)
memory.save_context(
inputs={"human": "네, 모델 번호는 XG-200입니다."},
outputs={"ai": "감사합니다. XG-200 모델의 설치 안내를 도와드리겠습니다. 먼저, 설치할 장소의 전원 공급 상태를 확인해주세요. 기계는 220V 전원이 필요합니다."}
)
memory.save_context(
inputs={"human": "전원은 확인했습니다. 다음 단계는 무엇인가요?"},
outputs={"ai": "좋습니다. 다음으로, 기계를 평평하고 안정된 바닥에 배치해 주세요. 이후, 제공된 사용자 매뉴얼에 따라 케이블 연결을 진행해 주시기 바랍니다."}
)
memory.save_context(
inputs={"human": "연결은 어떻게 하나요?"},
outputs={"ai": "매뉴얼의 5페이지를 참조해 주세요. 케이블 연결에 관한 상세한 지침이 있습니다. 이 과정에서 어려움이 있으시면 추가적으로 도와드리겠습니다."}
)
memory.save_context(
inputs={"human": "설치가 완료되면 어떻게 해야 하나요?"},
outputs={"ai": "설치가 완료되면, 전원을 켜고 초기 구동 테스트를 진행해 주시기 바랍니다. 테스트 절차는 매뉴얼의 10페이지에 설명되어 있습니다. 만약 기계에 이상이 있거나 추가적인 지원이 필요하시면 언제든지 연락 주시기 바랍니다."}
)
memory.save_context(
inputs={"human": "감사합니다, 도움이 많이 되었어요!"},
outputs={"ai": "언제든지 도와드릴 준비가 되어 있습니다. 추가적인 질문이나 지원이 필요하시면 언제든지 문의해 주세요. 좋은 하루 되세요!"}
)
- 대화 내용이 150개의 토큰 길이를 초과할 경우, 가장 오래된 대화 내용이 제거되고 최신 대화만 남습니다.
print(memory.load_memory_variables({})["history"])
- 결과적으로, 가장 최근의 대화만 기록에 남게 됩니다.
[HumanMessage(content='감사합니다, 도움이 많이 되었어요!'),
AIMessage(content='언제든지 도와드릴 준비가 되어 있습니다. 추가적인 질문이나 지원이 필요하시면 언제든지 문의해 주세요. 좋은 하루 되세요!')]
목차
- ConversationEntityMemory 개요
- ENTITY_MEMORY_CONVERSATION_TEMPLATE 사용
- 대화 예제 및 엔티티 저장 확인
🏖️ 1. ConversationEntityMemory 개요
ConversationEntityMemory
는 대화 중에 등장하는 특정 엔티티에 대한 정보를 기억하고, 시간이 지남에 따라 그 지식을 축적하는 메모리입니다.
- 엔티티 메모리는 LLM을 사용하여 엔티티에 대한 정보를 추출하고 관리합니다.
🏖️ 2. ENTITY_MEMORY_CONVERSATION_TEMPLATE 사용
ConversationEntityMemory
를 효과적으로 사용하기 위해 제공되는 프롬프트인 ENTITY_MEMORY_CONVERSATION_TEMPLATE
을 사용합니다.
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE
print(ENTITY_MEMORY_CONVERSATION_TEMPLATE.template)
- 프롬프트는 대화 중에 엔티티를 식별하고 그 정보를 축적하도록 설계되어 있습니다.
🏖️ 3. 대화 예제 및 엔티티 저장 확인
ConversationEntityMemory
는 입력된 대화에서 주요 엔티티 정보를 추출하여 별도로 저장합니다.
llm = ChatOpenAI(temperature=0)
conversation = ConversationChain(
llm=llm,
prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
memory=ConversationEntityMemory(llm=llm),
)
response = conversation.predict(
input="테디와 셜리는 한 회사에서 일하는 동료입니다. "
"테디는 개발자이고 셜리는 디자이너입니다. "
"그들은 최근 회사에서 일하는 것을 그만두고 자신들의 회사를 차릴 계획을 세우고 있습니다."
)
print(response)
- 예제를 통해
ConversationEntityMemory
가 대화 중에 엔티티와 그들의 상태를 어떻게 기억하는지 확인할 수 있습니다.
print(conversation.memory.entity_store.store)
- 출력된 엔티티 메모리에는 테디와 셜리에 대한 정보가 저장되어 있으며, 이후 대화에서도 이 정보를 활용할 수 있습니다.
{'테디': '테디는 개발자이고, 셜리와 함께 자신들의 회사를 차릴 계획을 세우고 있습니다.',
'셜리': '셜리는 한 회사에서 디자이너로 일하고 있으며, 테디와 함께 자신들의 회사를 차릴 계획을 세우고 있다.'}
목차
- ConversationKGMemory 개요
- 지식 그래프 메모리의 활용
- 대화 예제 및 지식 그래프 메모리 확인
🏖️ 1. ConversationKGMemory 개요
ConversationKGMemory
는 대화 중에 얻은 정보를 지식 그래프 형태로 저장하고 불러옵니다.
- 이를 통해 서로 다른 개체 간의 관계를 이해하고, 복잡한 연결망과 역사적 맥락을 바탕으로 대화를 더욱 풍부하게 할 수 있습니다.
🏖️ 2. 지식 그래프 메모리의 활용
ConversationKGMemory
를 사용하면 대화 중 얻은 정보를 저장하고, 그 정보를 바탕으로 대화의 맥락을 더욱 잘 이해할 수 있습니다.
- 예를 들어, 특정 인물이나 장소에 대한 정보를 지식 그래프에 저장하고, 이후 대화에서 해당 정보를 활용할 수 있습니다.
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationKGMemory
from dotenv import load_dotenv
load_dotenv()
llm = ChatOpenAI(temperature=0)
memory = ConversationKGMemory(llm=llm, return_messages=True)
memory.save_context(
{"input": "이쪽은 Pangyo에 거주중인 김셜리씨 입니다."},
{"output": "김셜리씨는 누구시죠?"},
)
memory.save_context(
{"input": "김셜리씨는 우리 회사의 신입 디자이너입니다."},
{"output": "만나서 반갑습니다."},
)
- 이처럼 메모리에 저장된 정보는 이후 대화에서 활용될 수 있습니다.
🏖️ 3. 대화 예제 및 지식 그래프 메모리 확인
- 저장된 정보는 지식 그래프 형태로 기록되며, 이를 바탕으로 대화의 맥락을 이해할 수 있습니다.
memory.load_memory_variables({"input": "김셜리씨는 누구입니까?"})
- 출력된 결과는 지식 그래프에 저장된 김셜리씨에 대한 정보를 나타냅니다.
{'history': [SystemMessage(content='On Pangyo: Pangyo has resident 김셜리씨.'),
SystemMessage(content='On 김셜리씨: 김셜리씨 is a 신입 디자이너. 김셜리씨 is in 우리 회사.')]}
Chain에 메모리 활용하기
ConversationChain
에 ConversationKGMemory
를 메모리로 지정하여 대화를 나눌 수 있습니다.
from langchain.prompts.prompt import PromptTemplate
from langchain.chains import ConversationChain
llm = ChatOpenAI(temperature=0)
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_with_kg = ConversationChain(
llm=llm, prompt=prompt, memory=ConversationKGMemory(llm=llm)
)
response = conversation_with_kg.predict(
input="My name is Teddy. Shirley is a coworker of mine, and she's a new designer at our company."
)
print(response)
- 이후 Shirley라는 인물에 대해 질문하면, 메모리에 저장된 정보를 바탕으로 답변할 수 있습니다.
conversation_with_kg.memory.load_memory_variables({"input": "who is Shirley?"})
- 이 명령을 실행하면, Shirley에 대한 저장된 정보가 출력됩니다.
{'history': 'On Shirley: Shirley is a coworker. Shirley is a new designer. Shirley is at company.'}