Update src/qa.py
Browse files
src/qa.py
CHANGED
|
@@ -70,18 +70,14 @@ except Exception as e:
|
|
| 70 |
# 4️⃣ Prompt Templates
|
| 71 |
# ==========================================================
|
| 72 |
STRICT_PROMPT = (
|
| 73 |
-
"
|
| 74 |
-
"
|
| 75 |
-
"If the context doesn’t contain the answer, reply exactly:\n"
|
| 76 |
-
"'I don't know based on the provided document.'\n\n"
|
| 77 |
"Context:\n{context}\n\nQuestion: {query}\nAnswer:"
|
| 78 |
)
|
| 79 |
|
| 80 |
REASONING_PROMPT = (
|
| 81 |
-
"You are
|
| 82 |
-
"
|
| 83 |
-
"If the context doesn’t provide enough detail, you may infer sensibly based on common knowledge, "
|
| 84 |
-
"but make it clear when you are reasoning beyond the text.\n\n"
|
| 85 |
"Context:\n{context}\n\nQuestion: {query}\nAnswer:"
|
| 86 |
)
|
| 87 |
|
|
@@ -116,47 +112,46 @@ def retrieve_chunks(query: str, index, chunks: list, top_k: int = 5):
|
|
| 116 |
# ==========================================================
|
| 117 |
def generate_answer(query: str, retrieved_chunks: list, reasoning_mode: bool = False):
|
| 118 |
"""
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
"""
|
| 123 |
if not retrieved_chunks:
|
| 124 |
return "Sorry, I couldn’t find relevant information in the document."
|
| 125 |
|
| 126 |
-
# Build the prompt with selected mode
|
| 127 |
context = "\n".join(chunk.strip() for chunk in retrieved_chunks)
|
| 128 |
-
prompt = (REASONING_PROMPT if reasoning_mode else STRICT_PROMPT).format(
|
| 129 |
-
context=context,
|
| 130 |
-
query=query
|
| 131 |
-
)
|
| 132 |
|
| 133 |
try:
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
|
|
|
|
|
|
| 155 |
|
| 156 |
except Exception as e:
|
| 157 |
print(f"⚠️ Generation failed: {e}")
|
| 158 |
return "⚠️ Error: Could not generate an answer."
|
| 159 |
|
|
|
|
| 160 |
# ==========================================================
|
| 161 |
# 7️⃣ Local Test
|
| 162 |
# ==========================================================
|
|
|
|
| 70 |
# 4️⃣ Prompt Templates
|
| 71 |
# ==========================================================
|
| 72 |
STRICT_PROMPT = (
|
| 73 |
+
"Answer based ONLY on the context below.\n"
|
| 74 |
+
"If the answer isn’t in the context, say: 'I don't know based on the provided document.'\n\n"
|
|
|
|
|
|
|
| 75 |
"Context:\n{context}\n\nQuestion: {query}\nAnswer:"
|
| 76 |
)
|
| 77 |
|
| 78 |
REASONING_PROMPT = (
|
| 79 |
+
"You are an expert assistant. Use the context and your reasoning ability to form a clear, step-by-step answer.\n"
|
| 80 |
+
"Be concise yet complete. If the context doesn’t contain the answer, say: 'I don't know based on the provided document.'\n\n"
|
|
|
|
|
|
|
| 81 |
"Context:\n{context}\n\nQuestion: {query}\nAnswer:"
|
| 82 |
)
|
| 83 |
|
|
|
|
| 112 |
# ==========================================================
|
| 113 |
def generate_answer(query: str, retrieved_chunks: list, reasoning_mode: bool = False):
|
| 114 |
"""
|
| 115 |
+
Generate answers with or without reasoning.
|
| 116 |
+
reasoning_mode=True → reasoning-rich, slightly slower
|
| 117 |
+
reasoning_mode=False → strict factual, fast
|
| 118 |
"""
|
| 119 |
if not retrieved_chunks:
|
| 120 |
return "Sorry, I couldn’t find relevant information in the document."
|
| 121 |
|
|
|
|
| 122 |
context = "\n".join(chunk.strip() for chunk in retrieved_chunks)
|
| 123 |
+
prompt = (REASONING_PROMPT if reasoning_mode else STRICT_PROMPT).format(context=context, query=query)
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
try:
|
| 126 |
+
if reasoning_mode:
|
| 127 |
+
# 🧠 “Brainy mode” — restores the earlier expressive logic
|
| 128 |
+
result = _answer_model(
|
| 129 |
+
prompt,
|
| 130 |
+
max_new_tokens=180,
|
| 131 |
+
temperature=0.4,
|
| 132 |
+
do_sample=False, # deterministic reasoning chain
|
| 133 |
+
pad_token_id=_tokenizer.eos_token_id,
|
| 134 |
+
)
|
| 135 |
+
else:
|
| 136 |
+
# ⚡ Strict factual fast mode
|
| 137 |
+
result = _answer_model(
|
| 138 |
+
prompt,
|
| 139 |
+
max_new_tokens=120,
|
| 140 |
+
temperature=0.2,
|
| 141 |
+
do_sample=False,
|
| 142 |
+
pad_token_id=_tokenizer.eos_token_id,
|
| 143 |
+
)
|
| 144 |
+
|
| 145 |
+
raw = result[0]["generated_text"]
|
| 146 |
+
if "Answer:" in raw:
|
| 147 |
+
raw = raw.split("Answer:")[-1].strip()
|
| 148 |
+
return raw.strip()
|
| 149 |
|
| 150 |
except Exception as e:
|
| 151 |
print(f"⚠️ Generation failed: {e}")
|
| 152 |
return "⚠️ Error: Could not generate an answer."
|
| 153 |
|
| 154 |
+
|
| 155 |
# ==========================================================
|
| 156 |
# 7️⃣ Local Test
|
| 157 |
# ==========================================================
|