안녕하세요! 이번 강의에서는 LangChain 라이브러리를 사용하여 대화형 인공지능 애플리케이션을 구축하는 방법을 자세히 살펴보겠습니다. 특히, 대화 버퍼 메모리(Conversation Buffer Memory)를 사용하여 사용자와 AI 사이의 이전 대화 내용을 어떻게 추적하고 활용하는지 알아볼 것입니다.
이 강의의 목표는 다음과 같습니다:
ConversationChain
과 ConversationBufferMemory
를 사용하는 방법 이해먼저, 필요한 라이브러리를 설치해야 합니다. 이 예제에서는 langchain
과 openai
라이브러리를 사용합니다.
pip install langchain openai python-dotenv
또한, OpenAI API 키를 사용해야 하므로, 프로젝트 디렉토리에 .env
파일을 생성하고 다음과 같이 입력합니다:
OPENAI_API_KEY=your_openai_api_key_here
your_openai_api_key_here
부분을 실제 API 키로 대체하세요.
Python 코드에서 필요한 라이브러리를 임포트하고, .env
파일에서 API 키를 로드합니다.
import os
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from dotenv import load_dotenv
# .env 파일에서 API 키 로드
load_dotenv()
ChatOpenAI
모델과 ConversationBufferMemory
메모리를 초기화합니다.
# OpenAI의 챗봇 모델 초기화 (온도 설정은 0.0으로 하여 일관된 응답 제공)
llm = ChatOpenAI(temperature=0.0)
# 대화 버퍼 메모리 초기화
memory = ConversationBufferMemory()
ConversationChain
을 사용하여 대화 체인을 생성하고, 여기에 모델과 메모리를 연결합니다.
# 대화 체인 생성 (verbose=True로 상세 정보 출력)
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
이제 대화를 시작해보겠습니다. conversation.predict
메서드를 사용하여 입력을 전달하고, AI의 응답을 받을 수 있습니다.
# 첫 번째 인사말 입력
response1 = conversation.predict(input="안녕하세요, 만나서 반가워요!")
print(response1)
# 두 번째 질문 입력
response2 = conversation.predict(input="아인슈타인-실라르드 서한에 대해 알려주세요.")
print(response2)
이렇게 하면 AI와의 대화를 진행하면서 메모리에 대화 내용이 저장됩니다.
현재까지의 대화 내용을 메모리에서 확인할 수 있습니다.
# 메모리 버퍼 내용 출력
print("현재까지의 대화 내용:")
print(memory.buffer)
메모리 변수는 대화의 역사(history)를 포함하는 딕셔너리 형태로 불러올 수 있습니다.
# 메모리 변수 로드
memory_variables = memory.load_memory_variables({})
print("메모리 변수:", memory_variables)
또한, 새로운 대화 내용을 메모리에 추가할 수 있습니다.
# 새로운 대화 내용 저장
memory.save_context({"input": "매우 흥미롭네요."},
{"output": "네, AI로서 답변해드려 기쁩니다."})
# 업데이트된 메모리 변수 확인
updated_memory_variables = memory.load_memory_variables({})
print("업데이트된 메모리 변수:", updated_memory_variables)
대화 메모리를 저장하여 나중에 다시 불러올 수 있습니다. 여기서는 pickle
모듈을 사용하여 메모리를 파일로 저장하고 불러옵니다.
import pickle
# 메모리 객체를 피클로 직렬화하여 저장
with open('memory.pkl', 'wb') as f:
pickle.dump(conversation.memory, f)
# 메모리 객체를 파일에서 불러오기
with open('memory.pkl', 'rb') as f:
loaded_memory = pickle.load(f)
불러온 메모리를 새로운 대화 체인에 연결할 수 있습니다.
# 새로운 대화 체인에 불러온 메모리 사용
new_conversation = ConversationChain(
llm=llm,
memory=loaded_memory,
verbose=True
)
# 이어서 대화 진행
response3 = new_conversation.predict(input="우주에 관한 재미있는 사실을 알려주세요.")
print(response3)
아래는 위에서 설명한 모든 내용을 포함한 전체 코드입니다.
import os
import pickle
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
# 1. .env 파일에서 OpenAI API 키 로드
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# 2. OpenAI 챗봇 모델 초기화
llm = ChatOpenAI(temperature=0.0, openai_api_key=OPENAI_API_KEY)
# 3. 대화 버퍼 메모리 초기화
memory = ConversationBufferMemory()
# 4. 대화 체인 생성
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 5. 대화 시작
response1 = conversation.predict(input="안녕하세요, 만나서 반가워요!")
print("AI:", response1)
# 6. 대화 진행
response2 = conversation.predict(input="아인슈타인-실라르드 서한에 대해 알려주세요.")
print("AI:", response2)
# 7. 메모리 내용 확인
print("\n현재까지의 대화 내용:")
print(memory.buffer)
# 8. 메모리 변수 로드
memory_variables = memory.load_memory_variables({})
print("\n메모리 변수:", memory_variables)
# 9. 새로운 대화 내용 추가
memory.save_context({"input": "매우 흥미롭네요."},
{"output": "네, AI로서 답변해드려 기쁩니다."})
# 10. 업데이트된 메모리 변수 확인
updated_memory_variables = memory.load_memory_variables({})
print("\n업데이트된 메모리 변수:", updated_memory_variables)
# 11. 메모리 저장
with open('memory.pkl', 'wb') as f:
pickle.dump(conversation.memory, f)
# 12. 메모리 불러오기
with open('memory.pkl', 'rb') as f:
loaded_memory = pickle.load(f)
# 13. 새로운 대화 체인에 불러온 메모리 사용
new_conversation = ConversationChain(
llm=llm,
memory=loaded_memory,
verbose=True
)
# 14. 이어서 대화 진행
response3 = new_conversation.predict(input="우주에 관한 재미있는 사실을 알려주세요.")
print("AI:", response3)
# 15. 불러온 메모리의 내용 확인
print("\n불러온 메모리의 대화 내용:")
print(new_conversation.memory.buffer)
위의 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다:
AI: 안녕하세요! 만나 뵙게 되어 반갑습니다. 어떻게 도와드릴까요?
AI: 아인슈타인-실라르드 서한은 1939년 알베르트 아인슈타인과 레오 실라르드가 미국 대통령 프랭클린 D. 루스벨트에게 보낸 편지로, 핵분열을 이용한 강력한 무기의 개발 가능성을 경고하고 미국이 이에 대한 연구를 시작할 필요성을 강조하였습니다. 이 서한은 맨해튼 프로젝트의 계기가 되었습니다.
현재까지의 대화 내용:
Human: 안녕하세요, 만나서 반가워요!
AI: 안녕하세요! 만나 뵙게 되어 반갑습니다. 어떻게 도와드릴까요?
Human: 아인슈타인-실라르드 서한에 대해 알려주세요.
AI: 아인슈타인-실라르드 서한은 1939년 알베르트 아인슈타인과 레오 실라르드가 미국 대통령 프랭클린 D. 루스벨트에게 보낸 편지로, 핵분열을 이용한 강력한 무기의 개발 가능성을 경고하고 미국이 이에 대한 연구를 시작할 필요성을 강조하였습니다. 이 서한은 맨해튼 프로젝트의 계기가 되었습니다.
메모리 변수: {'history': 'Human: 안녕하세요, 만나서 반가워요!\nAI: 안녕하세요! 만나 뵙게 되어 반갑습니다. 어떻게 도와드릴까요?\nHuman: 아인슈타인-실라르드 서한에 대해 알려주세요.\nAI: 아인슈타인-실라르드 서한은 1939년 알베르트 아인슈타인과 레오 실라르드가 미국 대통령 프랭클린 D. 루스벨트에게 보낸 편지로, 핵분열을 이용한 강력한 무기의 개발 가능성을 경고하고 미국이 이에 대한 연구를 시작할 필요성을 강조하였습니다. 이 서한은 맨해튼 프로젝트의 계기가 되었습니다.'}
업데이트된 메모리 변수: {'history': 'Human: 안녕하세요, 만나서 반가워요!\nAI: 안녕하세요! 만나 뵙게 되어 반갑습니다. 어떻게 도와드릴까요?\nHuman: 아인슈타인-실라르드 서한에 대해 알려주세요.\nAI: 아인슈타인-실라르드 서한은 1939년 알베르트 아인슈타인과 레오 실라르드가 미국 대통령 프랭클린 D. 루스벨트에게 보낸 편지로, 핵분열을 이용한 강력한 무기의 개발 가능성을 경고하고 미국이 이에 대한 연구를 시작할 필요성을 강조하였습니다. 이 서한은 맨해튼 프로젝트의 계기가 되었습니다.\nHuman: 매우 흥미롭네요.\nAI: 네, AI로서 답변해드려 기쁩니다.'}
AI: 우주에는 우리가 관측할 수 있는 별보다 더 많은 수의 은하가 있습니다. 실제로, 추정에 따르면 약 2조 개의 은하가 존재하며, 각 은하에는 수십억에서 수천억 개의 별이 있습니다.
불러온 메모리의 대화 내용:
Human: 안녕하세요, 만나서 반가워요!
AI: 안녕하세요! 만나 뵙게 되어 반갑습니다. 어떻게 도와드릴까요?
Human: 아인슈타인-실라르드 서한에 대해 알려주세요.
AI: 아인슈타인-실라르드 서한은 1939년 알베르트 아인슈타인과 레오 실라르드가 미국 대통령 프랭클린 D. 루스벨트에게 보낸 편지로, 핵분열을 이용한 강력한 무기의 개발 가능성을 경고하고 미국이 이에 대한 연구를 시작할 필요성을 강조하였습니다. 이 서한은 맨해튼 프로젝트의 계기가 되었습니다.
Human: 매우 흥미롭네요.
AI: 네, AI로서 답변해드려 기쁩니다.
이번 강의에서는 LangChain을 사용하여 대화형 AI 애플리케이션을 구축하고, 대화 내용을 메모리에 저장하고 불러오는 방법을 학습했습니다. ConversationBufferMemory
를 사용하면 사용자와 AI 사이의 이전 대화 내용을 추적하고, 이를 활용하여 보다 일관된 대화를 진행할 수 있습니다.
메모리를 파일로 저장하고 다시 불러오는 기능은 장기간의 대화를 관리하거나, 애플리케이션을 재시작한 후에도 이전 대화를 이어나가고자 할 때 유용합니다.
이제 제공된 코드를 직접 실행해보면서 대화형 AI와의 상호작용을 경험해보세요!