Spaces:
Sleeping
Sleeping
File size: 4,559 Bytes
03291e0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 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() |