Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
import bs4 | |
from langchain_community.document_loaders import WebBaseLoader | |
from langchain.text_splitter import CharacterTextSplitter | |
from langchain_community.embeddings import HuggingFaceEmbeddings | |
from langchain.vectorstores import FAISS | |
from langchain.chains import RetrievalQA | |
from langchain_groq import ChatGroq | |
from langchain_community.document_loaders import UnstructuredExcelLoader | |
# ํ๊ฒฝ ๋ณ์๋ก๋ถํฐ Groq API Key ๋ถ๋ฌ์ค๊ธฐ | |
groq_api_key = os.environ.get("GROQ_API_KEY", "") | |
# ๊ตญ๊ฐ๊ธฐ๋ก์ ์น ๋ฌธ์ ๋ชฉ๋ก | |
urls = [ | |
"https://archives.go.kr/next/newsearch/listSubjectContent.do?subjectFieldId=000011", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003140&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003288&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003290&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003292&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008757&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003293&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003294&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003295&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003289&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010816&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010817&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=009154&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003260&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003278&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003281&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003283&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003284&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003280&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003282&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003287&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003286&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003285&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003279&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003141&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003143&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003144&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003142&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008653&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010827&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008582&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008663&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008581&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010828&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010830&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010831&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003145&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=009425&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003146&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=010821&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003151&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003149&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003148&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008655&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=008654&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newsearch/listSubjectDescription.do?id=003150&pageFlag=A&sitePage=1-2-1", | |
"https://archives.go.kr/next/newmanager/recodeRegister.do", | |
"https://archives.go.kr/next/newtour/tourCourse.do", | |
"https://archives.go.kr/next/newrecordsMngPro/recordsDonateInfo.do", | |
"https://archives.go.kr/next/newdata/pepoleRecodPresentIntro.do", | |
"https://archives.go.kr/next/newsearch/searchGuideList.do", | |
"https://archives.go.kr/next/newsearch/searchGuideList.do?page=2", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=441", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=381", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=341", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=261", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=227", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=59", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=30", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=64", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=321", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=124", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=267", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=141", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=149", | |
"https://archives.go.kr/next/newsearch/searchGuideDetail.do?guideSeq=22" | |
] | |
# ์น๋ฌธ์ ๋ก๋ฉ | |
loader = WebBaseLoader(web_paths=urls, bs_kwargs=dict(parse_only=bs4.SoupStrainer())) | |
docs = loader.load() | |
# ๊ธฐ๋ก๋ฌผ ๋ชฉ๋ก ์์ ํ์ผ | |
excel_files = [ | |
"๊ต์ก ์ ๋ฐ ๊ด๋ จ ๊ธฐ๋ก๋ฌผ ๋ชฉ๋ก1.xls", | |
"๊ต์ก ์ ๋ฐ ๊ด๋ จ ๊ธฐ๋ก๋ฌผ ๋ชฉ๋ก2.xls", | |
"๊ต์ก ์ ๋ฐ ๊ด๋ จ ๊ธฐ๋ก๋ฌผ ๋ชฉ๋ก3.xls" | |
] | |
# ์์ ๋ฌธ์ ๋ก๋ฉ | |
excel_docs = [] | |
for file in excel_files: | |
loader = UnstructuredExcelLoader(file) | |
excel_docs.extend(loader.load()) | |
# ์น๋ฌธ์ + ์์ ๋ฌธ์ ๊ฒฐํฉ | |
docs.extend(excel_docs) | |
# ๋ฌธ์ ๋ถํ | |
splitter = CharacterTextSplitter(separator="\n", chunk_size=500, chunk_overlap=50) | |
split_docs = splitter.split_documents(docs) | |
# ์๋ฒ ๋ฉ ๋ฐ ๋ฒกํฐ ์ ์ฅ ๋ฐ ๋ฆฌํธ๋ฆฌ๋ฒ ์ค์ | |
embedding_model = HuggingFaceEmbeddings(model_name="snunlp/KR-SBERT-V40K-klueNLI-augSTS") | |
vectorstore = FAISS.from_documents(split_docs, embedding_model) | |
retriever = vectorstore.as_retriever() | |
# LLM + QA ์ฒด์ธ | |
llm = ChatGroq(groq_api_key=groq_api_key, model_name="llama3-70b-8192") | |
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever, chain_type="stuff") | |
# ์์ ์ง๋ฌธ | |
example_questions = [ | |
"๊ธฐ๋ก๋ฌผ ์ด๋ ๋ฐฉ๋ฒ์ ์ด๋ป๊ฒ ๋๋์?", | |
"๊ฒฌํ์ ์ฒญ์ ๋ํด ์ ์ ์๋์?", | |
"๊ธฐ๋ก๋ฌผ ๊ธฐ์ฆ ์ ์ฐจ๋ ์ด๋ป๊ฒ ๋๋์?", | |
"๊ธฐ๋ก๋ฌผ ๊ฒ์ ๊ธธ์ก์ด๊ฐ ๋ฌด์์ธ๊ฐ์?", | |
"๋ฏผ์ค๊ต์ก์ง ์ฌ๊ฑด์ ์ฃผ์ ์ ํ์ ๋ฌด์์ธ๊ฐ์?", | |
"๊ต์ก๊ฐํ์๋ฏผ์ด๋์ฐ๋์ ๋ฐฐ๊ฒฝ์ ๋ฌด์์ธ๊ฐ์?", | |
"์ฐธ๊ต์ก ์ด๋์ ์ญ์ฌ์ ์์๋ ๋ฌด์์ธ๊ฐ์?", | |
"ํ๋ํธ๊ตญ๋จ์ ๊ธฐ๋ก๋ฌผ๋ค์ ๊ณต๊ฐ๊ตฌ๋ถ์ด ์ด๋ป๊ฒ ๋๋์?", | |
"AI ๋์งํธ ๊ต๊ณผ์์ ๊ธฐ๋ก๋ฌผ ์ค์ ์ ๋ถ๊ฐํ๋ฌผ์ ๋ช๊ฑด์ธ๊ฐ์?", | |
"๊ต์ก๊ฐํ์ฌ์ํ์ ๊ธฐ๋ก๋ฌผ์ ๋ช๊ฑด์ธ๊ฐ์?", | |
"๊ตญ๋ฏผ๊ต์กํ์ฅ์ ๊ธฐ๋ก๋ฌผ๋ค์ด ์ด๋ค ์ ๋ชฉ์ธ์ง ์ ์ ์๋์?", | |
"์ธ๊ณ๋ฐ๋ํ(EXPO) ๊ธฐ๋ก๋ฌผ์ ๊ฐ์๋ ๋ฌด์์ธ๊ฐ์?", | |
"๋ํ์ํ๋ฅ๋ ฅ์ํ ๊ด๋ จ ๊ธฐ๋ก๋ฌผ์ ๊ธฐ๋ก๋ฌผ ์์ฐ์ ๋ณด๋ฅผ ์ ์ ์๋์?", | |
"ํ๋ฏธ๋๋งน ๊ธฐ๋ก๋ฌผ์ ๊ฒ์ํ๊ณ ์ถ์๋ฐ, ํค์๋๋ฅผ ์ ์ ์๋์?", | |
"๋ํ๋๋ฏผํ๋ช ์ ๊ธฐ๋ก๋ฌผ ์์ง ํํฉ์ด ์ด๋ป๊ฒ ๋๋์?" | |
] | |
# ํค์๋ ๊ณ์ธต ๊ตฌ์กฐ | |
keyword_tree = { | |
"๊ต์ก ์ ๋ฐ": { | |
"๊ต์ก ๋ฏผ์ฃผํ์ด๋": { | |
"๊ต์์ด๋": { | |
"๊ต์ก ๋ฏผ์ฃผํ์ ์ธ": {}, | |
"๋ฏผ์ค๊ต์ก์ง ์ฌ๊ฑด": {}, | |
"์ฐธ๊ต์ก ์ด๋": {} | |
}, | |
"ํ๋ถ๋ชจ ์ด๋": { | |
"๊ต์ก๊ฐํ์๋ฏผ์ด๋์ฐ๋": {} | |
}, | |
"ํ์์ด๋": {} | |
}, | |
"๊ต์ก ์ ๋ณดํ ์ ์ฑ ": { | |
"AI ๋์งํธ ๊ต๊ณผ์": {}, | |
"e๋ฌ๋ํ์ฑํ": {}, | |
"๊ต์กํ์ ์ ๋ณด์์คํ (NEIS)": {} | |
}, | |
"๊ต์ก๊ฐํ": { | |
"๊ต์ก๊ฐํ์ฌ์ํ": {}, | |
"๊ต์ก๊ฐํ์์ํ": { | |
"5ยท31 ๊ต์ก๊ฐํ": {} | |
}, | |
"๊ต์ก์ ์ฑ ์ฌ์ํ": {}, | |
"๊ต์ก์ ์ฑ ์๋ฌธํ์": {}, | |
"๊ต์กํ์ ์์ํ": {}, | |
"์๊ต์ก๊ณต๋์ฒด์์ํ": {}, | |
"์ธ๋ ฅ์์๊ฐ๋ฐํ์": {}, | |
"์ฅ๊ธฐ์ข ํฉ๊ณํ์ฌ์ํ": {} | |
}, | |
"๊ต์ก์ด๋ ": { | |
"๊ตญ๋ฏผ๊ต์กํ์ฅ": { | |
"ํ๋ํธ๊ตญ๋จ": {} | |
}, | |
"ํ์ต์ธ๊ฐ ๊ต์ก์ด๋ ": { | |
"์ผ๋ฏผ์ฃผ์": {} | |
} | |
}, | |
"๊ต์ก์ ์ฑ ๊ด๋ จ ๊ธฐ๊ด": { | |
"ํ๊ตญ๊ต์ก๊ฐ๋ฐ์": {}, | |
"ํ๊ตญ๊ต์ก๊ณผ์ ํ๊ฐ์": {}, | |
"ํ๊ตญ๊ต์ก๋ฐฉ์ก๊ณต์ฌ": {} | |
}, | |
"ํ์ ์งํฅ ์ ์ฑ ": { | |
"KERIS": {}, | |
"๋ํ๋ฏผ๊ตญํ์ ์": {} | |
}, | |
"ํ์ ": { | |
"ํ๋ น์ธ๊ตฌ ๊ฐ์": {}, | |
"ํ์ ํ์ ": {} | |
}, | |
"ํ๋ฒ์ ๊ต์ก์กฐํญ๊ณผ ๋ณ์ฒ": { | |
"๊ณ ๋ฑ๊ต์ก๋ฒ": {}, | |
"๊ต์ก๊ธฐ๋ณธ๋ฒ": {}, | |
"๊ต์ก๋ฒ ์ ์ ": {}, | |
"๊ต์ก์ ๊ดํ ์์ํน๋ก๋ฒ": {}, | |
"์ฌ๋ฆฝํ๊ต๋ฒ": {}, | |
"์ดยท์ค๋ฑ๊ต์ก๋ฒ": {} | |
} | |
}, | |
"๊ธฐ๋ก๋ฌผ ๊ฒ์ ๊ธธ์ก์ด": { | |
"๋ํ๋๋ฏผํ๋ช ": {}, | |
"์ฐํธํ์ ": {}, | |
"๋ํ์ํ๋ฅ๋ ฅ์ํ": {}, | |
"๋์์ฒ ๋": { | |
"๋์์ฒ ๋ 1ํธ์ ": {} | |
}, | |
"์ฌ์ธ๋ํฌ": { | |
"์ฌ์ธ๋ํฌ์ฌ๋จ": {}, | |
"๋จ๋ฏธ ํ์ธ": {}, | |
"์ค๊ตญ ํ์ธ": {}, | |
"๊ณ ๋ ค์ธ": {}, | |
"์ฌ์ธ๋ํฌ": {}, | |
"ํ๋ฏธ๋๋งน": {}, | |
"๋ฏธ๊ตญ ํ์ธ": {}, | |
"ํ๋ ๊ด๋ถ ๋ฐ ๊ฐํธ์ฌ": {}, | |
"์กฐ์ ๊ธฐ์ ์": {} | |
}, | |
"ํ๋ฏธ๋๋งน": {}, | |
"๊ณต๊ธฐ์ ": { | |
"ํ๊ตญ์ ๋ ฅ๊ณต์ฌ": {} | |
}, | |
"๋ฐ๋ํ": { | |
"์ธ๊ณ๋ฐ๋ํ(EXPO)": {} | |
} | |
}, | |
"๊ฒ์ ๋ฐฉํฅ": { | |
"๊ต์ก ์ ๋ฐ ๊ด๋ จ": { | |
"๊ธฐ๋ก๋ฌผ ๋ชฉ๋ก": { | |
"๊ด๋ฆฌ๋ฒํธ": {}, | |
"๊ธฐ๋ก๋ฌผ ์ฒ ์ ๋ชฉ": {}, | |
"๊ธฐ๋ก๋ฌผ ๊ฑด ์ ๋ชฉ": {}, | |
"์์ฐ๊ธฐ๊ด๋ช ": {}, | |
"์์ฐ๋ ๋": {}, | |
"๊ธฐ๋ก๋ฌผํํ": { | |
"์ผ๋ฐ๋ฌธ์๋ฅ": {}, | |
"์ ๋ถ๊ฐํ๋ฌผ๋ฅ": {}, | |
"์ฌ์ง,ํ๋ฆ๋ฅ": {}, | |
"๋ น์,๋์์๋ฅ": {} | |
}, | |
"๊ณต๊ฐ๊ตฌ๋ถ": {} | |
}, | |
"์ฃผ์ ์ค๋ช ": { | |
"์ฃผ์ ์ ํ": {}, | |
"๊ทผ๊ฑฐ": {}, | |
"๋ฐฐ๊ฒฝ(๋ฐ์๋ฐฐ๊ฒฝ)": {}, | |
"๊ฒฝ๊ณผ": {}, | |
"๋ด์ฉ": {}, | |
"์ญ์ฌ์ ์์": {}, | |
"์ฐธ๊ณ ์๋ฃ": {}, | |
"์งํ์": {} | |
} | |
}, | |
"๊ธฐ๋ก๋ฌผ ๊ฒ์ ๊ธธ์ก์ด ๊ด๋ จ": { | |
"๊ฐ์": {}, | |
"์์ฐ์ ๋ณด": {}, | |
"์ด๊ด ํํฉ": {}, | |
"์์ฅ ํํฉ": {}, | |
"์ ๋ฆฌ ํํฉ": {} | |
} | |
} | |
} | |
# ๊ฒฝ๋ก์์ ํ์ ํค์๋ ๋ฐํ | |
def get_keywords(path): | |
node = keyword_tree | |
for key in path: | |
node = node.get(key, {}) | |
return list(node.keys()) | |
def format_path(path): | |
return " > ".join(path) if path else "๊ต์ก ์ ๋ฐ" | |
def on_keyword_select(selected, path): | |
new_path = path + [selected] | |
next_keywords = get_keywords(new_path) | |
formatted = format_path(new_path) | |
return formatted, new_path, gr.update(choices=next_keywords) | |
# Gradio ์ฑํ ํจ์ | |
def chat_with_history(user_input, history): | |
if history is None: | |
history = [] | |
query = user_input.strip() + " ํ๊ตญ์ด๋ก ๋ตํด์ฃผ์ธ์." | |
result = qa_chain({"query": query}) | |
answer = result.get("result", "๋ต๋ณ์ ์ฐพ์ ์ ์์ต๋๋ค.") | |
# ๋ฉ์์ง ํฌ๋งท ๋ง์ถ๊ธฐ (๋์ ๋๋ฆฌ ํํ) | |
history.append({"role": "user", "content": user_input}) | |
history.append({"role": "assistant", "content": answer}) | |
return "", history, history | |
# Gradio ์ธํฐํ์ด์ค ๊ตฌ์ฑ | |
with gr.Blocks() as demo: | |
gr.Markdown("## ๐ ๊ตญ๊ฐ๊ธฐ๋ก์ ์ฑ๋ด") | |
gr.Markdown( | |
"""### **๊ตญ๊ฐ๊ธฐ๋ก์ ์ ๋ณด ์ฑ๋ด์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค!** | |
์ด ์ฑ๋ด์ ๊ตญ๊ฐ๊ธฐ๋ก์์ ๋ณด๊ด๋ ๋ค์ํ ๊ธฐ๋ก๋ฌผ์ ๋ฐํ์ผ๋ก ์ฌ๋ฌ๋ถ์ ๊ถ๊ธ์ฆ์ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ํด๊ฒฐํด ๋๋ฆฝ๋๋ค. | |
๊ตญ๊ฐ๊ธฐ๋ก์์ ์ญํ , ๊ธฐ๋ก๋ฌผ ์ด๋ ๋ฐฉ๋ฒ, ๊ฒฌํ ์ ์ฒญ, ๊ธฐ์ฆ ์ ์ฐจ ๋ฑ์ ๊ณต์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ผ๋ฉฐ, ๊ต์ก ์ ๋ฐ ๋ถ์ผ์ ๊ดํ ์ ๋ณด๋ฅผ ์๋ดํด ๋๋ฆฝ๋๋ค. | |
์๋ ์ ๋ ฅ์ฐฝ์ ๊ถ๊ธํ ๋ด์ฉ์ ์์ ๋กญ๊ฒ ์ ๋ ฅํด ๋ณด์ธ์. | |
๐ก ์ง๋ฌธ์ ์ด๋ป๊ฒ ์์ํ ์ง ๊ณ ๋ฏผ ์ค์ด์ ๊ฐ์? | |
- **์์ ์ง๋ฌธ ๋ณด๊ธฐ**์์ ์ง๋ฌธ์ ์ ํํด ๋ณด์ธ์. ๊ธฐ๋ก๋ฌผ ์ ๋ณด ํ์์ด ์ฒ์์ด๋ผ๋ ์ฝ๊ฒ ์์ํ ์ ์์ต๋๋ค. | |
- **๊ฒ์ ํค์๋ ํ์** ๊ธฐ๋ฅ์ ์ด์ฉํด ๋ณด์ธ์. ํค์๋๋ฅผ ์ฐธ๊ณ ํ์ฌ ๋๋ง์ ๊ฒ์ ๋ฐฉํฅ์ ์ ํด๋ณด์ธ์! | |
""" | |
) | |
chatbot = gr.Chatbot(label="๊ธฐ๋ก์ ์ฑ๋ด", type="messages") | |
with gr.Row(): | |
dropdown = gr.Dropdown(choices=example_questions, label="๐ ์์ ์ง๋ฌธ ๋ณด๊ธฐ") | |
msg = gr.Textbox(placeholder="์ง๋ฌธ์ ์ ๋ ฅํ์ธ์", label="๐ฌ ์ง๋ฌธ ์ ๋ ฅ", lines=1) | |
state = gr.State([]) # ์ฑํ ๊ธฐ๋ก | |
path_state = gr.State([]) # ํค์๋ ๊ฒฝ๋ก ์ํ | |
dropdown.change(lambda q: q, inputs=dropdown, outputs=msg) | |
msg.submit(chat_with_history, inputs=[msg, state], outputs=[msg, chatbot, state]) | |
with gr.Column(): | |
gr.Markdown("### ๐ ๊ฒ์ ํค์๋ ํ์") | |
gr.Markdown( | |
""" **๊ฒ์ ํค์๋ ํ์ ์๋ด** | |
๊ตญ๊ฐ๊ธฐ๋ก์์ ๋ค์ํ ๊ธฐ๋ก๋ฌผ์ ์ฃผ์ ๋ณ๋ก ๋ถ๋ฅํ ํค์๋๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ, ๊ด์ฌ ์๋ ๋ถ์ผ์ ๊ธฐ๋ก์ **๊ณ์ธต์ ์ผ๋ก ์ฝ๊ฒ ํ์**ํ ์ ์์ต๋๋ค. | |
""" | |
) | |
keyword_path_display = gr.Textbox(label="ํ์ฌ ํค์๋ ๊ฒฝ๋ก", interactive=False) | |
keyword_selector = gr.Radio(choices=get_keywords([]), label="ํค์๋ ์ ํ", value=None) | |
keyword_selector.change( | |
fn=on_keyword_select, | |
inputs=[keyword_selector, path_state], | |
outputs=[keyword_path_display, path_state, keyword_selector] | |
) | |
# ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ ์ถ๊ฐ | |
def on_back_click(path): | |
if path: | |
path = path[:-1] | |
next_keywords = get_keywords(path) | |
formatted = format_path(path) | |
return formatted, path, gr.update(choices=next_keywords) | |
back_btn = gr.Button("๐ ํ ๋จ๊ณ ๋ค๋ก๊ฐ๊ธฐ") | |
back_btn.click( | |
fn=on_back_click, | |
inputs=[path_state], | |
outputs=[keyword_path_display, path_state, keyword_selector] | |
) | |
demo.launch() |