반응형
1. 먼저 질의 에 대한 퀴즈를 생성한다.
2. 이를 기반으로 원하는 형태로 formatting 을 한다.
# 파일 다운로드 또는 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(),
],
)
# 추출한 문서를 저장하는 함수
def format_docs(docs):
return "\n\n".join(document.page_content for document in docs)
# 문서가 있을경우 문제를 생성하는 프롬프트 생성
question_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}
""",
)
]
)
questions_chain = {"context": format_docs} | question_prompt | llm
# 만들어진 질문을 이용하여 원하는 형태로 생성 [JSON 형태로 변환]
formatting_prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""
You are a powerful formatting algorithm.
You format exam questions into JSON format.
Answers with (o) are the correct ones.
Example Input:
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
Example Output:
```json
{{ "questions": [
{{
"question": "What is the color of the ocean?",
"answers": [
{{
"answer": "Red",
"correct": false
}},
{{
"answer": "Yellow",
"correct": false
}},
{{
"answer": "Green",
"correct": false
}},
{{
"answer": "Blue",
"correct": true
}},
]
}},
{{
"question": "What is the capital or Georgia?",
"answers": [
{{
"answer": "Baku",
"correct": false
}},
{{
"answer": "Tbilisi",
"correct": true
}},
{{
"answer": "Manila",
"correct": false
}},
{{
"answer": "Beirut",
"correct": false
}},
]
}},
{{
"question": "When was Avatar released?",
"answers": [
{{
"answer": "2007",
"correct": false
}},
{{
"answer": "2001",
"correct": false
}},
{{
"answer": "2009",
"correct": true
}},
{{
"answer": "1998",
"correct": false
}},
]
}},
{{
"question": "Who was Julius Caesar?",
"answers": [
{{
"answer": "A Roman Emperor",
"correct": true
}},
{{
"answer": "Painter",
"correct": false
}},
{{
"answer": "Actor",
"correct": false
}},
{{
"answer": "Model",
"correct": false
}},
]
}}
]
}}
```
Your turn!
Questions: {context}
""",
)
]
)
formatting_chain = formatting_prompt | llm
#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,
)
loader = UnstructuredFileLoader(file_path)
docs = loader.load_and_split(text_splitter=splitter)
return docs
# 사이드 바에 select 박스 형태로 file 또는 wikipedia를 선택할 수 있게 함
with st.sidebar:
docs = None
choice = st.selectbox(
"Choose what you want to use.",
(
"File",
"Wikipedia Article",
),
)
if choice == "File":
file = st.file_uploader(
"Upload a .docx , .txt or .pdf file",
type=["pdf", "txt", "docx"],
)
if file:
docs = split_file(file)
else:
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:
start = st.button("Generate Quiz")
if start:
questions_response = questions_chain.invoke(docs)
st.write(questions_response.content)
formatting_response = formatting_chain.invoke(
{"context": questions_response.content}
)
st.write(formatting_response.content)
'python' 카테고리의 다른 글
[GPT][SITEGPT] AsyncChromiumLoader (0) | 2024.05.02 |
---|---|
[GPT][QUIZGPT]Output Parser 를 이용한 데이터 형태 제어 (1) | 2024.04.18 |
[GPT][QUIZGPT]Questions Prompt (0) | 2024.04.18 |
[GPT][QUIZGPT]WikipediaRetriever (0) | 2024.04.18 |
[GPT][PRIVATEGPT] Ollama (0) | 2024.04.16 |