إنتقل إلى المحتوى الرئيسي

الفصل 1: بناء نظام أسئلة وأجوبة على الوثائق

نظرة عامة على المشروع​

ابنِ نظام أسئلة وأجوبة كامل على ملفات PDF يتضمّن:

  • رفع PDF ومعالجته
  • واجهة محادثة مع تاريخ
  • استشهادات بالمصادر

المعمارية​

الخطوة 1: الإعداد​

# requirements.txt
langchain==0.1.0
openai==1.3.0
chromadb==0.4.0
streamlit==1.28.0
pypdf==3.17.0

الخطوة 2: معالجة الوثائق​

# document_processor.py
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma

def process_pdf(pdf_path, collection_name="docs"):
# Load
loader = PyPDFLoader(pdf_path)
documents = loader.load()

# Split
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = splitter.split_documents(documents)

# Embed and store
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
chunks,
embeddings,
collection_name=collection_name,
persist_directory="./chroma_db"
)

return vectorstore

الخطوة 3: سلسلة RAG​

# rag_chain.py
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory

def create_qa_chain(vectorstore):
llm = ChatOpenAI(model="gpt-4", temperature=0)

memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)

chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
memory=memory,
return_source_documents=True
)

return chain

الخطوة 4: واجهة Streamlit​

# app.py
import streamlit as st
from document_processor import process_pdf
from rag_chain import create_qa_chain

st.title("📄 Document Q&A")

# File upload
uploaded_file = st.file_uploader("Upload PDF", type="pdf")

if uploaded_file:
# Process PDF
with st.spinner("Processing..."):
vectorstore = process_pdf(uploaded_file)
chain = create_qa_chain(vectorstore)

# Chat interface
if "messages" not in st.session_state:
st.session_state.messages = []

for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])

if prompt := st.chat_input("Ask about your document"):
st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").write(prompt)

response = chain({"question": prompt})
answer = response["answer"]

st.session_state.messages.append({"role": "assistant", "content": answer})
st.chat_message("assistant").write(answer)

# Show sources
with st.expander("Sources"):
for doc in response["source_documents"]:
st.write(f"Page {doc.metadata.get('page', 'N/A')}")
st.write(doc.page_content[:200] + "...")

تشغيل التطبيق​

streamlit run app.py

تحسينات​

  • إضافة المصادقة
  • دعم عدة ملفات PDF
  • تصدير المحادثات
  • إضافة reranking