langchain_openai_faiss_chatbot_test
langchain, opeanai, faiss를 활용한 챗봇 개념증명으로, 제 json 데이터를 llm 활용해 시멘틱 검색할 수 있습니다.
아래 코드는 openai api를 사용하는데, 언어모델을 바꿔서 완전히 로컬에서 동작할 수도 있습니다
(임베딩할때 사용량이 많았는지 4.7달러 과금, 지금은 질문응답하면 2건당 0.01정도 과금)
응답 예시
질의문/프롬프트
책은 컨텍스트로 제공된 것 중에서만 골라줘
응답은 200자 이내로 간략히 요약해서 작성해줘
books.txt
: 검색대상, json 형태로 추출한 책 데이터입니다.
embed.py
: 텍스트파일을 로컬 faiss 벡터 데이터베이스로 임베딩합니다.
임베딩: 자연어를 ai가 이해할 수 있는 행렬 형태로 표현하는 것
벡터 데이터베이스 : 그런 임베딩 결과를 저장하기 위해 고안된 데이터베이스 종류
청크 크기를 1000(최대 토큰수 제한) > 200(문맥을 잃어버림) > 500 > 700으로 조정함
from langchain .embeddings import OpenAIEmbeddings
from langchain .embeddings import ChatOpenAIEmbeddings
from langchain .text_splitter import RecursiveCharacterTextSplitter
from langchain .vectorstores import FAISS
from langchain .document_loaders import TextLoader
embeddings = OpenAIEmbeddings (openai_api_key = "" )
from langchain .document_loaders import TextLoader
loader = TextLoader ('./books.txt' )
documents = loader .load ()
text_splitter = RecursiveCharacterTextSplitter (
chunk_size = 700 ,
chunk_overlap = 50 ,
length_function = len )
docs = text_splitter .split_documents (documents )
db = FAISS .from_documents (docs , embeddings )
db .save_local ("faiss_index" )
query = "Who is Whitfield Diffie?"
docs = db .similarity_search (query )
for doc in docs :
print (doc .page_content )
search.py
: 사용자 질의문을 임베딩하고, 벡터 데이터베이스에서 관련 데이터를 찾습니다. 찾은 데이터를 질의문 컨텍스트로 포함시켜 llm에 전달합니다.
질의문 임베딩, 벡터 데이터베이스 쿼리, 컨텍스트 제공 등은 langchain을 사용해서 체이닝합니다.
오픈소스 llm대신 한국어를 잘 이해하고, 질문/응답에 최적화된 chatopenai를 사용, openai는 응답이 자연스럽지 않고 최대 토큰수가 작음
from langchain .vectorstores import FAISS
from langchain .chat_models import ChatOpenAI
from langchain .prompts .chat import (
ChatPromptTemplate ,
SystemMessagePromptTemplate ,
HumanMessagePromptTemplate ,
)
from langchain .embeddings import OpenAIEmbeddings
from langchain .callbacks .manager import CallbackManager
from langchain .callbacks .streaming_stdout import StreamingStdOutCallbackHandler
from langchain .chains import RetrievalQA
embeddings = OpenAIEmbeddings (openai_api_key = "" )
new_db = FAISS .load_local ("faiss_index" , embeddings )
callback_manager = CallbackManager ([StreamingStdOutCallbackHandler ()])
llm = ChatOpenAI (
openai_api_key = "" ,
temperature = 0.7 ,
callback_manager = callback_manager ,
verbose = True
)
retriever = new_db .as_retriever ()
qa = RetrievalQA .from_chain_type (
llm = llm
,chain_type = "stuff"
,retriever = retriever
)
while True :
query = input ("You: " )
if query .lower () == "exit" :
break
response = qa .run (query )
print (f"AI: { response } " )
print ("==============================================" )
데이터 도메인에 적절한, 문맥을 잃지 않으면서 llm 최대토큰 이내로 들어올 수 있는 임베딩 청크크기 찾기
데이터 도메인에 적절한, 한국어를 잘 이해하는 언어모델 적용해보기(hugging face에서?)
레퍼런스 (아래 글들을 보고 따라한 수준입니다)