fastAPI 심화
- Chart.js - pdf, csv 파일 업로드 후 데이터 정제하여 llm으로 처리 후 결과 도출 - sqlite로 데이터 저장 - ORM - SQLAlchemy
This commit is contained in:
@@ -1,6 +1,90 @@
|
||||
# pdf 업로드 => 분할 => 인덱스 생성
|
||||
def upload_document(file):
|
||||
pass
|
||||
import os
|
||||
|
||||
from langchain_community.document_loaders import PyPDFLoader
|
||||
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_core.runnables import RunnablePassthrough
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
|
||||
from backend.ai.embedding import watson_embedding
|
||||
from backend.ai.llm import watson_llm
|
||||
|
||||
UPLOAD_PATH = "uploads"
|
||||
|
||||
def upload_document(file):
|
||||
# file 저장
|
||||
file_path = os.path.join(UPLOAD_PATH, file.filename)
|
||||
|
||||
with open(file_path, "wb") as f:
|
||||
f.write(file.file.read())
|
||||
|
||||
# pdf 업로드 => 분할 => 인덱스 생성
|
||||
# pdf 로드
|
||||
loader = PyPDFLoader(file_path)
|
||||
docs = loader.load()
|
||||
|
||||
splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30)
|
||||
chunks = splitter.split_documents(docs)
|
||||
|
||||
faiss_store = FAISS.from_documents(documents=chunks, embedding=watson_embedding)
|
||||
faiss_store.save_local("./db/vectorstore")
|
||||
|
||||
return {"message": "업로드 성공"}
|
||||
|
||||
# 질문 => 유사도 검색 => 문서 => llm 답변 생성
|
||||
def rag_chat(question: str):
|
||||
|
||||
faiss_store = FAISS.load_local("./db/vectorstore", watson_embedding, allow_dangerous_deserialization=True)
|
||||
|
||||
retriever = faiss_store.as_retriever(search_kwargs={"k": 3})
|
||||
|
||||
### LLM
|
||||
# 1. prompt
|
||||
message = """\
|
||||
당신은 PDF 기반 RAG AI 입니다.
|
||||
다음 문서를 참고해서 질문에 답변하세요.
|
||||
|
||||
문서:
|
||||
{context}
|
||||
|
||||
질문:
|
||||
{question}
|
||||
"""
|
||||
|
||||
rag_prompt = ChatPromptTemplate.from_template(message)
|
||||
# 2. chain
|
||||
chain = {"context": retriever, "question": RunnablePassthrough()} | rag_prompt | watson_llm | StrOutputParser()
|
||||
|
||||
# 3. answer
|
||||
answer = chain.invoke(question)
|
||||
return answer
|
||||
|
||||
async def rag_chat_stream(question: str):
|
||||
|
||||
faiss_store = FAISS.load_local("./db/vectorstore", watson_embedding, allow_dangerous_deserialization=True)
|
||||
|
||||
retriever = faiss_store.as_retriever(search_kwargs={"k": 3})
|
||||
|
||||
### LLM
|
||||
# 1. prompt
|
||||
message = """\
|
||||
당신은 PDF 기반 RAG AI 입니다.
|
||||
다음 문서를 참고해서 질문에 답변하세요.
|
||||
|
||||
문서:
|
||||
{context}
|
||||
|
||||
질문:
|
||||
{question}
|
||||
"""
|
||||
|
||||
rag_prompt = ChatPromptTemplate.from_template(message)
|
||||
# 2. chain
|
||||
chain = {"context": retriever, "question": RunnablePassthrough()} | rag_prompt | watson_llm | StrOutputParser()
|
||||
|
||||
# 3. answer
|
||||
# chain.stream() : 동기방식(요청 => 응답을 할 떄까지 기다리는 방식)
|
||||
# chain.astream() : 비동기방식(다른 일 처리 가능)
|
||||
async for chunk in chain.astream(question):
|
||||
yield chunk
|
||||
Reference in New Issue
Block a user