RAG & LANCHAIN (3)- Langchain 개념 & 문법 정리 ch.05 메모리

이영락·2024년 8월 28일
0

인공지능 공부

목록 보기
10/33

목차

  1. ConversationBufferMemory 개요
  2. 문자열로 메시지 추출하기
  3. 대화 기록 저장 및 확인
  4. return_messages=True 옵션 사용
  5. 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) 메서드를 사용하여 대화 기록을 저장할 수 있습니다.
  • 이 메서드는 inputsoutputs 두 개의 인자를 받습니다.
    • 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 옵션을 사용하면 HumanMessageAIMessage 객체를 반환합니다.
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)

목차

  1. ConversationBufferWindowMemory 개요
  2. 최근 K개의 상호작용만 저장
  3. 대화 기록 예제

🏖️ 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='네, 계좌 개설이 완료되었습니다. 고객님의 계좌 번호와 관련 정보는 등록하신 이메일로 발송되었습니다. 추가적인 도움이 필요하시면 언제든지 문의해 주세요. 감사합니다!')]

목차

  1. ConversationTokenBufferMemory 개요
  2. 최대 토큰 길이 설정
  3. 대화 기록 예제

🏖️ 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

# API KEY 정보로드
load_dotenv()

# LLM 모델 생성
llm = ChatOpenAI()

# 메모리 설정
memory = ConversationTokenBufferMemory(
    llm=llm, max_token_limit=150, return_messages=True  # 최대 토큰 길이를 150개로 제한
)

🏖️ 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='언제든지 도와드릴 준비가 되어 있습니다. 추가적인 질문이나 지원이 필요하시면 언제든지 문의해 주세요. 좋은 하루 되세요!')]

목차

  1. ConversationEntityMemory 개요
  2. ENTITY_MEMORY_CONVERSATION_TEMPLATE 사용
  3. 대화 예제 및 엔티티 저장 확인

🏖️ 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

# Entity Memory를 사용하는 프롬프트 내용을 출력합니다.
print(ENTITY_MEMORY_CONVERSATION_TEMPLATE.template)
  • 프롬프트는 대화 중에 엔티티를 식별하고 그 정보를 축적하도록 설계되어 있습니다.

🏖️ 3. 대화 예제 및 엔티티 저장 확인

  • ConversationEntityMemory는 입력된 대화에서 주요 엔티티 정보를 추출하여 별도로 저장합니다.
# LLM을 생성합니다.
llm = ChatOpenAI(temperature=0)

# ConversationChain을 생성합니다.
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)
  • 출력된 엔티티 메모리에는 테디와 셜리에 대한 정보가 저장되어 있으며, 이후 대화에서도 이 정보를 활용할 수 있습니다.
{'테디': '테디는 개발자이고, 셜리와 함께 자신들의 회사를 차릴 계획을 세우고 있습니다.', 
 '셜리': '셜리는 한 회사에서 디자이너로 일하고 있으며, 테디와 함께 자신들의 회사를 차릴 계획을 세우고 있다.'}

목차

  1. ConversationKGMemory 개요
  2. 지식 그래프 메모리의 활용
  3. 대화 예제 및 지식 그래프 메모리 확인

🏖️ 1. ConversationKGMemory 개요

  • ConversationKGMemory는 대화 중에 얻은 정보를 지식 그래프 형태로 저장하고 불러옵니다.
  • 이를 통해 서로 다른 개체 간의 관계를 이해하고, 복잡한 연결망과 역사적 맥락을 바탕으로 대화를 더욱 풍부하게 할 수 있습니다.

🏖️ 2. 지식 그래프 메모리의 활용

  • ConversationKGMemory를 사용하면 대화 중 얻은 정보를 저장하고, 그 정보를 바탕으로 대화의 맥락을 더욱 잘 이해할 수 있습니다.
  • 예를 들어, 특정 인물이나 장소에 대한 정보를 지식 그래프에 저장하고, 이후 대화에서 해당 정보를 활용할 수 있습니다.
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationKGMemory
from dotenv import load_dotenv

# API KEY 정보로드
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에 메모리 활용하기

  • ConversationChainConversationKGMemory를 메모리로 지정하여 대화를 나눌 수 있습니다.
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)

# ConversationKGMemory를 사용하는 ConversationChain을 생성합니다.
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라는 인물에 대해 질문하면, 메모리에 저장된 정보를 바탕으로 답변할 수 있습니다.
# 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.'}

profile
AI Engineer / 의료인공지능

0개의 댓글

관련 채용 정보