arabic-rag-chatbot / llm_handler.py
Ashabk's picture
Upload 6 files
03291e0 verified
Raw
History Blame Contribute Delete
4.56 kB
import os
from dotenv import load_dotenv
from langchain_groq import ChatGroq
load_dotenv()
llm = ChatGroq(
model_name="llama-3.3-70b-versatile",
groq_api_key=os.getenv("GROQ_API_KEY"),
temperature=0.3
)
def generate_answer(question, retrieved_chunks, language="arabic",
recent_history=None, conversation_summary=None):
"""
Generates the final answer using Groq, grounded in retrieved
document chunks and aware of conversation context.
recent_history: list of the last 1-2 (question, answer) tuples,
kept in full detail
conversation_summary: short summary of everything OLDER than
the recent history, kept compact
"""
context = "\n\n".join(retrieved_chunks)
history_text = ""
if conversation_summary:
history_text += f"Summary of earlier conversation:\n{conversation_summary}\n\n"
if recent_history:
history_text += "Most recent exchange(s):\n"
for past_question, past_answer in recent_history:
history_text += f"Q: {past_question}\nA: {past_answer}\n\n"
if language == "arabic":
prompt = f"""أنت مساعد ذكي متخصص في الإجابة على الأسئلة بناءً على النص المعطى فقط.
{history_text if history_text else ""}
السياق المتاح من الوثيقة:
{context}
السؤال الحالي:
{question}
التعليمات:
- أجب باللغة العربية فقط
- إذا كان السؤال يشير إلى محادثة سابقة (مثل "ذلك" أو "هذا")، استخدم ملخص المحادثة أو آخر تبادل لفهم المرجع
- استخدم فقط المعلومات الموجودة في السياق أعلاه
- لا تضف أي معلومات غير موجودة في الوثيقة، حتى لو كانت معلومات عامة صحيحة
- إذا لم تجد الإجابة، قل بوضوح أنك لا تملك معلومات كافية
الإجابة:"""
else:
prompt = f"""You are a helpful assistant that answers questions based on the provided document context.
{history_text if history_text else ""}
Document context (in Arabic):
{context}
Current question:
{question}
Instructions:
- Answer ONLY in English
- If the question refers to earlier conversation (like "that" or "it"), use the summary or recent exchange to understand the reference
- Use the information found in the context above
- If the answer is not in the context, clearly say you don't have enough information
- Don't give information which is not in the PDF if something is not there in the PDF simply say you don't have enough information
Answer:"""
response = llm.invoke(prompt)
return response.content
def translate_to_arabic(english_text):
"""
Translates an English question into Arabic using Groq,
so we can search our all-Arabic vector store accurately.
This fixes cross-lingual retrieval failures on larger,
more complex documents.
"""
prompt = f"""Translate the following English question into Modern Standard Arabic.
Only output the Arabic translation, nothing else - no explanation, no quotes.
English: {english_text}
Arabic translation:"""
response = llm.invoke(prompt)
return response.content.strip()
def summarize_conversation(existing_summary, old_question, old_answer):
"""
Takes the current running summary plus one older exchange
that's about to fall out of the "recent" window, and asks
Groq to fold it into an updated, still-short summary.
This keeps conversation memory compact regardless of how
long the chat gets, instead of sending the full raw history
every time.
"""
prompt = f"""You are maintaining a brief running summary of a conversation between a user and an assistant about a document.
Existing summary so far:
{existing_summary if existing_summary else "(no summary yet - this is the first exchange to summarize)"}
New exchange to fold in:
User asked: {old_question}
Assistant answered: {old_answer}
Update the summary to include this new exchange, staying concise.
Keep it to 2-4 sentences maximum. Focus on WHAT TOPICS were discussed
and any specific facts/numbers that might be referenced later, not
the exact wording. Output ONLY the updated summary, nothing else.
Updated summary:"""
response = llm.invoke(prompt)
return response.content.strip()