Ahmed-Alghamdi commited on
Commit
27bc8f0
·
verified ·
1 Parent(s): 5017c51

Update response_generator.py

Browse files
Files changed (1) hide show
  1. response_generator.py +93 -8
response_generator.py CHANGED
@@ -18,12 +18,8 @@ class ResponseGenerator:
18
  if len(relevant_docs) == 0:
19
  return "عذرًا، لم أجد أي معلومات ذات صلة في المستندات."
20
 
21
- # Get the most relevant document (first one)
22
- context = self._prepare_context(relevant_docs)
23
-
24
- # For BERT-based models, we do extractive QA instead of generation
25
- # Return the most relevant context as the answer
26
- response = self._create_extractive_answer(query, context, relevant_docs)
27
  return response
28
 
29
  except Exception as e:
@@ -39,6 +35,46 @@ class ResponseGenerator:
39
  max_context_length = 300
40
  return combined_content[:max_context_length]
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  def _create_extractive_answer(self, query, context, relevant_docs):
43
  """
44
  Create an answer by extracting relevant information from documents
@@ -57,13 +93,19 @@ class ResponseGenerator:
57
  else:
58
  most_relevant = truncated + "..."
59
 
 
 
 
 
 
 
60
  # Format the response
61
  response = f"""بناءً على المستندات المتاحة:
62
 
63
  {most_relevant}
64
 
65
  ---
66
- المصدر: {relevant_docs.iloc[0]['path']}"""
67
 
68
  return response
69
 
@@ -81,4 +123,47 @@ class ResponseGenerator:
81
  self.tokenizer = AutoTokenizer.from_pretrained(new_model_name)
82
  logger.info(f"Model updated to {new_model_name}")
83
  except Exception as e:
84
- logger.error(f"Error updating model: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  if len(relevant_docs) == 0:
19
  return "عذرًا، لم أجد أي معلومات ذات صلة في المستندات."
20
 
21
+ # NEW: Use multi-chunk synthesis for better answers
22
+ response = self._create_multi_chunk_answer(query, relevant_docs)
 
 
 
 
23
  return response
24
 
25
  except Exception as e:
 
35
  max_context_length = 300
36
  return combined_content[:max_context_length]
37
 
38
+ # NEW: Multi-chunk answer synthesis
39
+ def _create_multi_chunk_answer(self, query, relevant_docs):
40
+ """
41
+ Create a comprehensive answer by combining top relevant chunks
42
+ """
43
+ # Get top 3 chunks
44
+ top_chunks = relevant_docs.head(3)
45
+
46
+ # Build answer
47
+ answer_parts = []
48
+ answer_parts.append("**بناءً على المستندات المتاحة:**\n")
49
+
50
+ for idx, (_, row) in enumerate(top_chunks.iterrows(), 1):
51
+ content = row['content'].strip()
52
+ similarity = row.get('similarity_score', 0)
53
+
54
+ # Add chunk with similarity indicator
55
+ if len(top_chunks) > 1:
56
+ # NEW: Show similarity score for transparency
57
+ answer_parts.append(f"\n**[{idx}] مطابقة: {similarity:.0%}**")
58
+
59
+ answer_parts.append(content)
60
+
61
+ # NEW: Add metadata footer
62
+ answer_parts.append("\n\n---")
63
+
64
+ # NEW: Show number of sources
65
+ unique_files = top_chunks['path'].nunique()
66
+ answer_parts.append(f"**عدد المصادر:** {unique_files}")
67
+
68
+ # NEW: Show score range for quality indicator
69
+ if 'similarity_score' in top_chunks.columns:
70
+ scores = top_chunks['similarity_score'].values
71
+ if len(scores) == 1:
72
+ answer_parts.append(f" | **المطابقة:** {scores[0]:.0%}")
73
+ else:
74
+ answer_parts.append(f" | **المطابقة:** {scores[-1]:.0%} - {scores[0]:.0%}")
75
+
76
+ return "\n".join(answer_parts)
77
+
78
  def _create_extractive_answer(self, query, context, relevant_docs):
79
  """
80
  Create an answer by extracting relevant information from documents
 
93
  else:
94
  most_relevant = truncated + "..."
95
 
96
+ # NEW: Include similarity score if available
97
+ similarity_info = ""
98
+ if 'similarity_score' in relevant_docs.columns:
99
+ score = relevant_docs.iloc[0]['similarity_score']
100
+ similarity_info = f"\n**المطابقة:** {score:.0%}"
101
+
102
  # Format the response
103
  response = f"""بناءً على المستندات المتاحة:
104
 
105
  {most_relevant}
106
 
107
  ---
108
+ المصدر: {relevant_docs.iloc[0]['path']}{similarity_info}"""
109
 
110
  return response
111
 
 
123
  self.tokenizer = AutoTokenizer.from_pretrained(new_model_name)
124
  logger.info(f"Model updated to {new_model_name}")
125
  except Exception as e:
126
+ logger.error(f"Error updating model: {e}")
127
+ ```
128
+
129
+ ---
130
+
131
+ ## What Was Added (All marked with "# NEW"):
132
+
133
+ 1. ✅ **`_create_multi_chunk_answer()`** - New function that combines multiple chunks
134
+ 2. ✅ **Top 3 chunks** - Uses top 3 instead of just 1 for complete context
135
+ 3. ✅ **Similarity scores** - Shows match percentage for each chunk (e.g., "مطابقة: 85%")
136
+ 4. ✅ **Metadata footer** - Shows number of sources used
137
+ 5. ✅ **Score range** - Shows overall quality (e.g., "المطابقة: 72% - 85%")
138
+ 6. ✅ **Updated main method** - Now calls `_create_multi_chunk_answer()` instead of old method
139
+ 7. ✅ **Similarity in single answer** - Even single-chunk answers show score
140
+
141
+ ---
142
+
143
+ ## Before vs After Examples:
144
+
145
+ **Before (Single chunk only):**
146
+ ```
147
+ بناءً على المستندات المتاحة:
148
+
149
+ نسبة الحضور المطلوبة هي 75%
150
+
151
+ ---
152
+ المصدر: RAG DATA.txt
153
+ ```
154
+
155
+ **After (Multi-chunk with scores):**
156
+ ```
157
+ بناءً على المستندات المتاحة:
158
+
159
+ [1] مطابقة: 85%
160
+ نسبة الحضور المطلوبة هي 75%
161
+
162
+ [2] مطابقة: 72%
163
+ الغياب أكثر من 25% يؤدي للحرمان من دخول الامتحان
164
+
165
+ [3] مطابقة: 68%
166
+ يمكن تقديم عذر طبي للغياب
167
+
168
+ ---
169
+ عدد المصادر: 1 | المطابقة: 68% - 85%