# 파일 다운로드 또는 WikipediaRetriever를 이용한 퀴즈 생성
import streamlit as st
from langchain.document_loaders import UnstructuredFileLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.retrievers import WikipediaRetriever
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.callbacks import StreamingStdOutCallbackHandler
# 파피콘 과 페이지 타이틀 설정
st.set_page_config(
page_title="QuizGPT",
page_icon="❓",
)
st.title("QuizGPT")
llm = ChatOpenAI(
temperature=0.1,
model="gpt-3.5-turbo-1106",
streaming=True,
callbacks=[
StreamingStdOutCallbackHandler(),
],
)
#Streamlit에서 앱에서 상호작용이 발생할 때마다 전체 스크립트가 처음부터 다시 실행하기 때문에 캐시 사용
@st.cache_data(show_spinner="Loading file...")
def split_file(file):
file_content = file.read()
file_path = f"./.cache/quiz_files/{file.name}"
with open(file_path, "wb") as f:
f.write(file_content)
splitter = CharacterTextSplitter.from_tiktoken_encoder(
separator="\n",
chunk_size=600,
chunk_overlap=100,
)
# UnstructuredFileLoader를 사용하여 파일을 로드하고 분할
loader = UnstructuredFileLoader(file_path)
docs = loader.load_and_split(text_splitter=splitter)
return docs
# 추출한 문서를 저장하는 함수
def format_docs(docs):
return "\n\n".join(document.page_content for document in docs)
# 사이드 바에 select 박스 형태로 file 또는 wikipedia를 선택할 수 있게 함
with st.sidebar:
docs = None
choice = st.selectbox(
"Choose what you want to use.",
(
'File',
'Wikipedia Article',
),
)
# 만일 File을 선택할 경우
if choice == 'File':
file = st.file_uploader(
"Upload a .docx , .txt or .pdf file",
type=["pdf", "txt", "docx"],
)
if file:
# 파일을 읽어서 docs에 저장
docs = split_file(file)
st.write(docs)
else:
#WikipediaRetriever 사용
topic = st.text_input("Search Wikipedia...")
if topic:
retriever = WikipediaRetriever(top_k_results=5)
with st.status("Searching Wikipedia..."):
docs = retriever.get_relevant_documents(topic)
# 문서가 없을경우 기본 메세지 출력
if not docs:
st.markdown(
"""
Welcome to QuizGPT.
I will make a quiz from Wikipedia articles or files you upload to test your knowledge and help you study.
Get started by uploading a file or searching on Wikipedia in the sidebar.
"""
)
else:
# 문서가 있을경우 프롬프트 생성
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""
You are a helpful assistant that is role playing as a teacher.
Based ONLY on the following context make 10 questions to test the user's knowledge about the text.
Each question should have 4 answers, three of them must be incorrect and one should be correct.
Use (o) to signal the correct answer.
Question examples:
Question: What is the color of the ocean?
Answers: Red|Yellow|Green|Blue(o)
Question: What is the capital or Georgia?
Answers: Baku|Tbilisi(o)|Manila|Beirut
Question: When was Avatar released?
Answers: 2007|2001|2009(o)|1998
Question: Who was Julius Caesar?
Answers: A Roman Emperor(o)|Painter|Actor|Model
Your turn!
Context: {context}
""",
)
]
)
chain = {"context": format_docs} | prompt | llm
start = st.button("Generate Quiz")
if start:
chain.invoke(docs)