241106
LangChain 사용
In [ ]:
!pip install -r requirements.txt
In [ ]:
!pip install openai
In [ ]:
!pip install langchain
In [ ]:
!pip install -U langchain-community
In [ ]:
!pip install wikipedia
In [ ]:
import pandas as pd
import numpy as np
import os
import openai
from langchain.document_loaders import PyMuPDFLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA #← RetrievalQA를 가져오기
from langchain.chat_models import ChatOpenAI
from langchain.retrievers import WikipediaRetriever
from langchain.schema import HumanMessage, SystemMessage, AIMessage
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
In [ ]:
def load_api_key(filepath):
with open(filepath, 'r') as file:
return file.readline().strip()
path = ''
# API 키 로드 및 환경변수 설정: API는 환경변수에 들어 있음
openai.api_key = load_api_key(path + 'api_key.txt')
os.environ['OPENAI_API_KEY'] = openai.api_key
In [ ]:
# 위키피디아 준비
wiki_retriever = WikipediaRetriever(lang = "ko")
In [ ]:
# 모델
chat = ChatOpenAI(model = "gpt-3.5-turbo")
In [ ]:
wiki_chat = RetrievalQA.from_llm(llm = chat, retriever = wiki_retriever,
return_source_documents=True) # 정보를 가져온 원본 문서를 반환
In [ ]:
result = wiki_chat("세종대왕의 맥북던짐사건에 대해 설명해줘")
print(result["result"])
제가 알기로는 '세종대왕의 맥북던짐사건'이라는 사건에 대한 구체적인 내용이나 역사적 배경을 알고는 없습니다. 이에 대해 자세한 정보를 제공해 드리지 못해서 죄송합니다. 다른 궁금한 사항이 있으시면 도와드리겠습니다.
Langchain 사용2
In [ ]:
# langeuage_models
from langchain.chat_models import ChatOpenAI
chat = ChatOpenAI(model = "gpt-3.5-turbo")
In [ ]:
result = chat([HumanMessage(content="안녕하세요!")])
print(result.content)
안녕하세요! 무엇을 도와드릴까요? :)
In [ ]:
sys_role = '당신은 애국심을 가지고 있는 건전한 대한민국 국민입니다.'
question = "독도는 어느나라 땅이야?"
result = chat([HumanMessage(content = question), SystemMessage(content = sys_role)])
print(result.content)
독도는 대한민국의 영토이며, 일본이 주장하는 일본의 땅이 아닙니다. 독도는 우리 대한민국의 땅이라는 사실을 자부할 수 있습니다. 함께 대한민국의 영토를 지키고 보호하는 데 최선을 다해야 합니다.
In [ ]:
In [ ]:
from langchain.output_parsers import CommaSeparatedListOutputParser
# 출력파서 선언
output_parser = CommaSeparatedListOutputParser()
# 사용
result = chat([HumanMessage(content = "트랜스포머 기반 언어모델 3개 알려줘."),
HumanMessage(content = output_parser.get_format_instructions())])
# 결과 출력1
print(result.content)
# 결과 출력2
output = output_parser.parse(result.content)
print(output)
GPT-3, BERT, XLNet
['GPT-3', 'BERT', 'XLNet']
In [ ]:
from langchain import PromptTemplate
# 입력 탬플릿
prompt = PromptTemplate(template = "{loc}에 있는 대표 관광지 5개는?", input_variables = ["loc"])
# 출력파서 선언
output_parser = CommaSeparatedListOutputParser()
# 사용
result = chat([HumanMessage(content=prompt.format(loc= "대구")),
HumanMessage(content = output_parser.get_format_instructions())])
# 결과 출력
output = output_parser.parse(result.content)
print(output)
['Buddha Statue at Donghwasa Temple', 'Daegu Yangnyeongsi Museum of Oriental Medicine', 'Apsan Park', 'Kim Gwangseok-gil Street', 'Palgongsan Mountain']
In [ ]:
RAG
In [ ]:
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
database = Chroma(persist_directory = path + "db", # 경로 지정(구글 드라이브에서 db 폴더 생성)
embedding_function = embeddings) # 임베딩 벡터로 만들 모델 지정
In [ ]:
input_list = ['test 데이터 입력1', 'test 데이터 입력2']
# 입력시 인덱스 저장(조회시 사용)
ind = database.add_texts(input_list)
ind
Out[ ]:
['bb94bf7f-2492-4f83-8bd4-e0c9d33242d5',
'5a344d07-c521-4efb-b042-87cd0052ffbf']
In [ ]:
database.get(ind)
Out[ ]:
{'ids': ['5a344d07-c521-4efb-b042-87cd0052ffbf',
'bb94bf7f-2492-4f83-8bd4-e0c9d33242d5'],
'embeddings': None,
'metadatas': [None, None],
'documents': ['test 데이터 입력2', 'test 데이터 입력1'],
'uris': None,
'data': None}
In [ ]:
input_list2 = ['오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.', '어제 주가는 큰 폭으로 상승했습니다.']
metadata = [{'category':'test'}, {'category':'test'}]
doc2 = [Document(page_content = input_list2[i], metadata = metadata[i]) for i in range(2)]
doc2
Out[ ]:
[Document(page_content='오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.', metadata={'category': 'test'}),
Document(page_content='어제 주가는 큰 폭으로 상승했습니다.', metadata={'category': 'test'})]
In [ ]:
ind2 = database.add_documents(doc2)
In [ ]:
database.get(ind2)
Out[ ]:
{'ids': ['5df72772-6e08-457f-b07e-7d751ab8c1aa',
'b1ab78ed-5229-40f7-b5e8-befc586e6dcf'],
'embeddings': None,
'metadatas': [{'category': 'test'}, {'category': 'test'}],
'documents': ['오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.', '어제 주가는 큰 폭으로 상승했습니다.'],
'uris': None,
'data': None}
In [ ]:
database.get()
Out[ ]:
{'ids': ['5a344d07-c521-4efb-b042-87cd0052ffbf',
'5df72772-6e08-457f-b07e-7d751ab8c1aa',
'b1ab78ed-5229-40f7-b5e8-befc586e6dcf',
'bb94bf7f-2492-4f83-8bd4-e0c9d33242d5'],
'embeddings': None,
'metadatas': [None, {'category': 'test'}, {'category': 'test'}, None],
'documents': ['test 데이터 입력2',
'오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.',
'어제 주가는 큰 폭으로 상승했습니다.',
'test 데이터 입력1'],
'uris': None,
'data': None}
In [ ]:
# 문서 조회1
query = "오늘 낮 기온은?" # 질문할 문장
k = 3 # 유사도 상위 k 개 문서 가져오기.
result = database.similarity_search(query, k = k) #← 데이터베이스에서 유사도가 높은 문서를 가져옴
print(result)
print('-'*50)
for doc in result:
print(f"문서 내용: {doc.page_content}") # 문서 내용 표시
[Document(page_content='오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.', metadata={'category': 'test'}), Document(page_content='어제 주가는 큰 폭으로 상승했습니다.', metadata={'category': 'test'}), Document(page_content='test 데이터 입력1')]
--------------------------------------------------
문서 내용: 오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.
문서 내용: 어제 주가는 큰 폭으로 상승했습니다.
문서 내용: test 데이터 입력1
In [ ]:
# 문서 조회2 : 유사도 점수도 함께 조회
query = "오늘 낮 기온은?" # 질문할 문장
k = 3 # 유사도 상위 k 개 문서 가져오기.
result = database.similarity_search_with_score(query, k = k) #← 데이터베이스에서 유사도가 높은 문서를 가져옴
print(result)
print('-'*50)
for doc in result:
print(f"유사도 점수 : {round(doc[1], 5)}, 문서 내용: {doc[0].page_content}") # 문서 내용 표시
[(Document(page_content='오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.', metadata={'category': 'test'}), 0.22618641133398137), (Document(page_content='어제 주가는 큰 폭으로 상승했습니다.', metadata={'category': 'test'}), 0.38118057585848064), (Document(page_content='test 데이터 입력1'), 0.49542535750587824)]
--------------------------------------------------
유사도 점수 : 0.22619, 문서 내용: 오늘 날씨는 매우 맑음. 낮 기온은 30도 입니다.
유사도 점수 : 0.38118, 문서 내용: 어제 주가는 큰 폭으로 상승했습니다.
유사도 점수 : 0.49543, 문서 내용: test 데이터 입력1
Memory & Chain
In [ ]:
from langchain.memory import ConversationBufferMemory
In [ ]:
# 메모리 선언하기(초기화)
memory = ConversationBufferMemory(return_messages=True)
# 저장
memory.save_context({"input": "안녕하세요!"},
{"output": "안녕하세요! 어떻게 도와드릴까요?"})
memory.save_context({"input": "메일을 써야하는데 도와줘"},
{"output": "누구에게 보내는 어떤 메일인가요?"})
# 현재 담겨 있는 메모리 내용 전체 확인
memory.load_memory_variables({})
Out[ ]:
{'history': [HumanMessage(content='안녕하세요!'),
AIMessage(content='안녕하세요! 어떻게 도와드릴까요?'),
HumanMessage(content='메일을 써야하는데 도와줘'),
AIMessage(content='누구에게 보내는 어떤 메일인가요?')]}
In [ ]:
k = 3
# Chroma 데이터베이스 인스턴스
embeddings = OpenAIEmbeddings(model = "text-embedding-ada-002")
database = Chroma(persist_directory = path + "db2", embedding_function = embeddings)
# retriever 선언
retriever = database.as_retriever(search_kwargs={"k": k})
# ChatOpenAI 선언
chat = ChatOpenAI(model="gpt-3.5-turbo")
# RetrievalQA 선언
qa = RetrievalQA.from_llm(llm=chat, retriever=retriever, return_source_documents=True)
In [ ]:
# 질문 답변1
query = "생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?"
result = qa(query)
memory = ConversationBufferMemory(return_messages=True)
memory.save_context({"input": query},
{"output": result['result']})
memory.load_memory_variables({})
Out[ ]:
{'history': [HumanMessage(content='생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?'),
AIMessage(content='생성형 AI를 도입할 때 예상되는 보안 위협은 다양합니다. 예를 들어, 생성형 AI가 악의적인 목적으로 사용될 수 있거나 개인정보 침해가 발생할 수 있습니다. 또한, 생성된 콘텐츠가 사람들을 혼란시키거나 오도할 수도 있습니다. 이러한 위협을 방지하기 위해 보안 전문가들은 생성형 AI 시스템을 설계하고 모니터링하는 데 노력하고 있습니다.')]}
In [ ]:
# 질문 답변2
query = "훈련 데이터나 가중치를 오염시키는게 무슨 의미야?"
result = qa(query)
result['result']
memory.save_context({"input": query},
{"output": result['result']})
memory.load_memory_variables({})
Out[ ]:
{'history': [HumanMessage(content='생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?'),
AIMessage(content='생성형 AI를 도입할 때 예상되는 보안 위협은 다양합니다. 예를 들어, 생성형 AI가 악의적인 목적으로 사용될 수 있거나 개인정보 침해가 발생할 수 있습니다. 또한, 생성된 콘텐츠가 사람들을 혼란시키거나 오도할 수도 있습니다. 이러한 위협을 방지하기 위해 보안 전문가들은 생성형 AI 시스템을 설계하고 모니터링하는 데 노력하고 있습니다.'),
HumanMessage(content='훈련 데이터나 가중치를 오염시키는게 무슨 의미야?'),
AIMessage(content='훈련 데이터나 가중치를 오염시키는 것은 모델의 성능을 저하시키거나 잘못된 예측을 유발할 수 있는 방법이다. 이는 모델의 학습 능력을 손상시키거나 잘못된 결론에 이르게 할 수 있어 모델의 정확도와 일반화 능력을 해칠 수 있다.')]}
In [ ]:
# 질문 답변3
query = "이를 방지하기 위해 어떻게 해야 해?"
result = qa(query)
result['result']
memory.save_context({"input": query},
{"output": result['result']})
memory.load_memory_variables({})
Out[ ]:
{'history': [HumanMessage(content='생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?'),
AIMessage(content='생성형 AI를 도입할 때 예상되는 보안 위협은 다양합니다. 예를 들어, 생성형 AI가 악의적인 목적으로 사용될 수 있거나 개인정보 침해가 발생할 수 있습니다. 또한, 생성된 콘텐츠가 사람들을 혼란시키거나 오도할 수도 있습니다. 이러한 위협을 방지하기 위해 보안 전문가들은 생성형 AI 시스템을 설계하고 모니터링하는 데 노력하고 있습니다.'),
HumanMessage(content='훈련 데이터나 가중치를 오염시키는게 무슨 의미야?'),
AIMessage(content='훈련 데이터나 가중치를 오염시키는 것은 모델의 성능을 저하시키거나 잘못된 예측을 유발할 수 있는 방법이다. 이는 모델의 학습 능력을 손상시키거나 잘못된 결론에 이르게 할 수 있어 모델의 정확도와 일반화 능력을 해칠 수 있다.'),
HumanMessage(content='이를 방지하기 위해 어떻게 해야 해?'),
AIMessage(content='어떤 이유나 상황에 대해 더 많은 정보를 제공해주시면 도와드릴 수 있을 것 같아요. 현재 어떤 문제를 방지하려고 하는지 더 자세히 설명해주시겠어요?')]}
In [ ]:
embeddings = OpenAIEmbeddings(model = "text-embedding-ada-002")
database = Chroma(persist_directory = "./db2", embedding_function = embeddings)
chat = ChatOpenAI(model="gpt-3.5-turbo")
k=3
retriever = database.as_retriever(search_kwargs={"k": k})
# 대화 메모리 생성
memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", output_key="answer",
return_messages=True)
# ConversationalRetrievalQA 체인 생성
qa = ConversationalRetrievalChain.from_llm(llm=chat, retriever=retriever, memory=memory,
return_source_documents=True, output_key="answer")
In [ ]:
# 첫번째 질문
query1 = "생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?"
result = qa(query1)
result['answer']
Out[ ]:
'생성형 AI의 도입으로 예상되는 보안 위협은 다양합니다. 일부 위험 요소로는 데이터 유출, 악의적인 사용, 개인정보 침해, 위조된 콘텐츠 생성 등이 있을 수 있습니다. 또한 생성형 AI가 잘못된 정보를 생성하거나 악의적인 목적으로 사용될 수도 있습니다. 추가적인 세부적인 위험을 평가하기 위해서는 구체적인 사용 사례 및 시나리오에 대한 분석이 필요합니다.'
In [ ]:
# 메모리 확인
memory.load_memory_variables({})
Out[ ]:
{'chat_history': [HumanMessage(content='생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?'),
AIMessage(content='생성형 AI의 도입으로 예상되는 보안 위협은 다양합니다. 일부 위험 요소로는 데이터 유출, 악의적인 사용, 개인정보 침해, 위조된 콘텐츠 생성 등이 있을 수 있습니다. 또한 생성형 AI가 잘못된 정보를 생성하거나 악의적인 목적으로 사용될 수도 있습니다. 추가적인 세부적인 위험을 평가하기 위해서는 구체적인 사용 사례 및 시나리오에 대한 분석이 필요합니다.')]}
In [ ]:
# 두번째 질문
query2 = "모델을 재학습시키면 어떤 문제가 발생되는거야?"
result = qa(query2)
result['answer']
Out[ ]:
'모델을 재학습시키면 과적합(overfitting)이 발생할 수 있습니다. 과적합은 모델이 학습 데이터에 너무 맞춰져서 새로운 데이터에 대해 일반화가 어려운 상태를 말합니다. 또한, 모델을 재학습시키면 이전에 학습했던 지식이 손실될 수 있으며, 시간과 자원이 소모될 수도 있습니다.'
In [ ]:
# 메모리 확인
memory.load_memory_variables({})
Out[ ]:
{'chat_history': [HumanMessage(content='생성형 AI 도입시 예상되는 보안 위협은 어떤 것들이 있어?'),
AIMessage(content='생성형 AI의 도입으로 예상되는 보안 위협은 다양합니다. 일부 위험 요소로는 데이터 유출, 악의적인 사용, 개인정보 침해, 위조된 콘텐츠 생성 등이 있을 수 있습니다. 또한 생성형 AI가 잘못된 정보를 생성하거나 악의적인 목적으로 사용될 수도 있습니다. 추가적인 세부적인 위험을 평가하기 위해서는 구체적인 사용 사례 및 시나리오에 대한 분석이 필요합니다.'),
HumanMessage(content='모델을 재학습시키면 어떤 문제가 발생되는거야?'),
AIMessage(content='모델을 재학습시키면 과적합(overfitting)이 발생할 수 있습니다. 과적합은 모델이 학습 데이터에 너무 맞춰져서 새로운 데이터에 대해 일반화가 어려운 상태를 말합니다. 또한, 모델을 재학습시키면 이전에 학습했던 지식이 손실될 수 있으며, 시간과 자원이 소모될 수도 있습니다.')]}
In [ ]:
# memory = ConversationBufferMemory(memory_key="chat_history", input_key="question", output_key="answer",
# return_messages=True)
# 딴 질문하기
In [ ]:
while True:
query = input('질문 > ')
query = query.strip()
print(f'질문 : {query}')
print('-' * 20)
if len(query) == 0:
break
result = qa({"question": query})
print(f'답변 : {result["answer"]}')
print('=' * 50)
질문 : 너는 어떤 정보를 갖고있니?
--------------------
답변 : 네, 저는 다양한 주제에 관한 정보를 가지고 있습니다. 무엇에 대해 물어보시겠어요?
==================================================
질문 : 한국 여행지 추천해줘
--------------------
답변 : 한국 여행지를 추천할 때 고려해야 할 요소는 다음과 같습니다:
1. 여행 목적: 문화 여행, 자연 풍경 감상, 쇼핑, 음식 체험 등 여행 목적에 맞는 여행지를 선택해야 합니다.
2. 시기: 계절에 따라 여행지의 매력이 달라질 수 있으므로 여행 계획을 세울 때 시기를 고려해야 합니다.
3. 관심사: 역사, 문화, 음식, 자연 등 여행자의 관심사를 고려하여 적합한 여행지를 선택해야 합니다.
4. 예산: 여행 경비에 맞는 여행지를 선택하여 예산을 효율적으로 활용할 수 있습니다.
여행자의 취향과 상황에 맞게 이러한 요소들을 고려하여 여행지를 추천해 드릴 수 있습니다.
==================================================
In [ ]: