CoolFace
Apppublic

iman1377/teacher

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
streamlit_app.py189 linesDownload Raw Back to src
1import streamlit as st2import os3import tempfile4 5from langchain_community.document_loaders import PyPDFLoader6from langchain_text_splitters import RecursiveCharacterTextSplitter7from langchain_huggingface import HuggingFaceEmbeddings8from langchain_community.vectorstores import FAISS9 10from langchain_groq import ChatGroq11 12from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder13from langchain_core.chat_history import InMemoryChatMessageHistory14from langchain_core.runnables import RunnableWithMessageHistory15 16# ---------------------------------------------------17# Streamlit UI18# ---------------------------------------------------19st.set_page_config(page_title="استاد MIT", layout="wide")20 21st.markdown("""22<style>23    .stChatMessage { direction: rtl; text-align: right; }24    .stMarkdown { direction: rtl; text-align: right; }25    .stMarkdown > div > p { direction: rtl; text-align: right; }26    .stSpinner { direction: rtl; text-align: right; }27    p { direction: rtl; text-align: right; }28    h1, h2, h3, h4, h5, h6 { direction: rtl; text-align: right; }29    li { direction: rtl; text-align: right; }30    code { direction: ltr; text-align: left; unicode-bidi: embed; }  /* برای کدهای انگلیسی LTR نگه داریم */31</style>32""", unsafe_allow_html=True)33 34st.title("🎓   استاد خصوصی کنکور ارشد")35 36with st.sidebar:37    api_key = st.text_input("Groq API Key", type="password")38    uploaded_file = st.file_uploader("کتاب PDF را آپلود کنید", type="pdf")39 40    if st.button("پاک کردن حافظه گفتگو"):41        st.session_state.histories = {}42        st.rerun()43 44# ---------------------------------------------------45# PDF → Vectorstore46# ---------------------------------------------------47@st.cache_resource48def process_pdf(file):49    with tempfile.NamedTemporaryFile(delete=False) as tmp:50        tmp.write(file.getvalue())51        temp_path = tmp.name52 53    loader = PyPDFLoader(temp_path)54    docs = loader.load()55 56    # خرد کردن متن PDF57    splitter = RecursiveCharacterTextSplitter(58        chunk_size=1000,59        chunk_overlap=15060    )61    chunks = splitter.split_documents(docs)62 63    # پاکسازی متن‌ها از newline64    for doc in chunks:65        doc.page_content = doc.page_content.replace("\n", " ")66 67    embeddings = HuggingFaceEmbeddings(68        model_name="sentence-transformers/all-MiniLM-L6-v2"69    )70 71    vectorstore = FAISS.from_documents(chunks, embeddings)72    os.remove(temp_path)73    return vectorstore74 75# ---------------------------------------------------76# حافظه گفتگو77# ---------------------------------------------------78if "histories" not in st.session_state:79    st.session_state.histories = {}80 81def get_history(session_id):82    if session_id not in st.session_state.histories:83        st.session_state.histories[session_id] = InMemoryChatMessageHistory()84    return st.session_state.histories[session_id]85 86# ---------------------------------------------------87# Prompt Template حرفه‌ای88# ---------------------------------------------------89prompt = ChatPromptTemplate.from_messages([90    ("system",91     """92You are a top-tier MIT professor AND an Iranian Konkur (entrance exam) instructor.93Your mission is TEACHING, not just answering and translating.94 95You must ALWAYS:961. Detect and analyze examples inside the retrieved PDF context.972. If the context contains an example, solve it step-by-step like a Konkur teacher.983. Extract formulas, definitions, and key points.994. Warn the student about common misconceptions and traps.1005. Produce 1–3 NEW similar practice problems with answers.1016. Use Persian for teaching. Use English only for technical terms.1027. When answering:103   - بخش ۱: خلاصه مفهوم اصلی104   - بخش ۲: تحلیل خط به خط محتوای PDF مربوطه105   - بخش ۳: تحلیل کامل مثال‌های موجود در PDF106   - بخش ۴: مثال‌های جدید مشابه برای تمرین107   - بخش ۵: نکات کنکوری، دام‌ها، روش میان‌بر108 109Your teaching style must be:110- precise111- structured112- exam-oriented113- clear and deep114 115CONTEXT FROM BOOK:116{context}117"""),118    MessagesPlaceholder(variable_name="chat_history"),119    ("user",120     """121پرسش دانشجو:122{question}123""")124])125 126# ---------------------------------------------------127# ساخت chain RAG + LLM128# ---------------------------------------------------129def build_chain(vectorstore, api_key):130    retriever = vectorstore.as_retriever(search_kwargs={"k": 4})131 132    llm = ChatGroq(133        groq_api_key=api_key,134        model_name="openai/gpt-oss-120b",135        temperature=0.3136    )137 138    chain = (139        {140            "context": lambda x: "\n\n".join(141                 doc.page_content for doc in retriever.invoke(x["question"])142                ),143            "question": lambda x: x["question"],144            "chat_history": lambda x: x["chat_history"]145        }146        | prompt147        | llm148    )149 150    return RunnableWithMessageHistory(151        chain,152        get_history,153        input_messages_key="question",154        history_messages_key="chat_history"155    )156 157# ---------------------------------------------------158# اجرای چت159# ---------------------------------------------------160if uploaded_file and api_key:161 162    vectorstore = process_pdf(uploaded_file)163    chat = build_chain(vectorstore, api_key)164 165    st.success("کتاب پردازش شد. سوال خود را بپرسید.")166 167    session_id = "student"168    history = get_history(session_id)169 170    # نمایش تاریخچه چت171    for msg in history.messages:172        with st.chat_message("assistant" if msg.type == "ai" else "user"):173            st.markdown(msg.content, unsafe_allow_html=True)  # از markdown برای پشتیبانی بهتر RTL استفاده کن174 175    # دریافت سوال جدید176    if question := st.chat_input("سوال خود را بپرسید..."):177        with st.chat_message("user"):178            st.write(question)179 180        with st.chat_message("assistant"):181            with st.spinner("در حال فکر کردن..."):182                result = chat.invoke(183                    {"question": question},184                    config={"configurable": {"session_id": session_id}}185                )186                st.markdown(result.content, unsafe_allow_html=True)  # از markdown برای RTL بهتر187 188else:189    st.info("لطفاً API Key و PDF را وارد کنید.")