안녕하세요. 오늘은 문서를 기반으로 응답할 수 있는 챗봇을 만들어 보도록 하겠습니다.
CromaDB,langchain,ChatGPT (gpt-3.5-turbo)을 사용하여 QA ChatBot을 만들어보도록 하겠습니다.
domain specific한 챗봇을 만들기 원하시는 분들이 참고하면 좋을 것 같습니다.
우선 필요한 패키지들을 설치해줍니다.
!pip install langchain==0.0.142
!pip install openai==0.27.4
!pip install chromadb==0.3.21
!pip install tiktoken==0.3.3
그리고 여러 문서들을 이용할 수 있는데, 이 실습에서는 TechCrunch article 21개를 사용합니다.
!wget -q https://github.com/kairess/toy-datasets/raw/master/techcrunch-articles.zip
!unzip -q techcrunch-articles.zip -d articles
개인 api_key를 입력해주고, 필요한 라이브러리들을 import해주세요.
import os
os.environ["OPENAI_API_KEY"] = " 개인 api key 입력 "
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.document_loaders import DirectoryLoader
데이터를 로드해주고 1000 chunk씩 나누어 줍니다. 이때 chunk_overlap은 누락되는 부분을 방지해서 200개씩은 겹쳐주는 방식이라고 하네요.
loader = DirectoryLoader('./articles', glob="*.txt", loader_cls=TextLoader)
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
texts = text_splitter.split_documents(documents)
여기까지 만들어주면 len(texts)는 233이라는 결과가 나와야합니다.
persist_directory = 'db'
embedding = OpenAIEmbeddings()
vectordb = Chroma.from_documents(
documents=texts,
embedding=embedding,
persist_directory=persist_directory)
vectordb.persist()
vectordb = None
vectordb = Chroma(
persist_directory=persist_directory,
embedding_function=embedding)
WARNING:chromadb:Using embedded DuckDB with persistence: data will be stored in: db 이라는 경고문이 뜨긴하는데 뒤에서 잘돌아가서 일단은 냅두기로 합니다.
retriever = vectordb.as_retriever(search_kwargs={"k": 3})
docs = retriever.get_relevant_documents("What is Generative AI?")
for doc in docs:
print(doc.metadata["source"])
이때 k는 상위 k개의 결과를 반환할 수 있도록 하는 변수를 의미합니다.
결과값을 보시면 이렇게 세가지의 문서가 뽑히게 되는 것을 확인 할 수 있습니다.
# 결과값
articles/05-04-slack-updates-aim-to-put-ai-at-the-center-of-the-user-experience.txt
articles/05-04-microsoft-doubles-down-on-ai-with-new-bing-features.txt
articles/05-03-spawning-lays-out-its-plans-for-letting-creators-opt-out-of-generative-ai-training.txt
이제 langchain을 통해 연결하면 마무리되게 됩니다.
qa_chain = RetrievalQA.from_chain_type(
llm=OpenAI(),
chain_type="stuff",
retriever=retriever,
return_source_documents=True)
def process_llm_response(llm_response):
print(llm_response['result'])
print('\n\nSources:')
for source in llm_response["source_documents"]:
print(source.metadata['source'])
이제 chain이 완성되었고, 문서에서 궁금한 query를 하게되면 출처 문서와 함께 응답을 하게됩니다.
query = "How much money did Pando raise?"
llm_response = qa_chain(query)
process_llm_response(llm_response)
# 결과값
Pando raised $30 million in a Series B round, bringing its total raised to $45 million.
Sources:
articles/05-03-ai-powered-supply-chain-startup-pando-lands-30m-investment.txt
articles/05-03-ai-powered-supply-chain-startup-pando-lands-30m-investment.txt
articles/05-03-ai-powered-supply-chain-startup-pando-lands-30m-investment.txt
간단하고 재밌는 실습이었습니다.😃
앞으로 text 말고도 다른 형태의 문서도 활용해 볼 예정입니다.
빵형의 개발도상국 : https://www.youtube.com/watch?v=ftXLn9DE7YY
외국 유튜브 : https://www.youtube.com/watch?v=3yPBVii7Ct0
도움이 됐습니다. 유익합니다. 감사합니다.