Spaces:
Runtime error
feat: emphasize top chunk and add contextual headers in RAG context
Browse filesImprove RAG context formatting to follow best practices by explicitly
highlighting the most relevant chunk and adding contextual metadata.
Changes:
- Identify top chunk based on similarity/distance scores
- Wrap top chunk with [MOST RELEVANT CONTEXT] tags to guide model focus
- Add document name and page number headers to each chunk for better
traceability and context understanding
- Use clear delimiters (---) between chunks for improved readability
This follows RAG best practices by:
- Explicitly emphasizing the most relevant information for the model
- Providing contextual headers that help the model understand source
information
- Maintaining clear structure that improves model comprehension
The model now receives structured context with clear emphasis on the
top-ranked chunk while still considering supporting context from other
chunks.
- qa_chain.py +38 -1
|
@@ -1,5 +1,7 @@
|
|
| 1 |
"""Question-answering chain with RAG capabilities."""
|
| 2 |
|
|
|
|
|
|
|
| 3 |
from langchain_core.prompts import ChatPromptTemplate
|
| 4 |
from sentence_transformers import CrossEncoder
|
| 5 |
|
|
@@ -291,7 +293,42 @@ Rewritten query (keywords and key phrases only, be concise):"""
|
|
| 291 |
docs = docs[:RETRIEVER_K]
|
| 292 |
docs_with_scores = docs_with_scores[:RETRIEVER_K]
|
| 293 |
|
| 294 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
|
| 296 |
# Format chat history
|
| 297 |
history_str = format_chat_history(chat_history)
|
|
|
|
| 1 |
"""Question-answering chain with RAG capabilities."""
|
| 2 |
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
from langchain_core.prompts import ChatPromptTemplate
|
| 6 |
from sentence_transformers import CrossEncoder
|
| 7 |
|
|
|
|
| 293 |
docs = docs[:RETRIEVER_K]
|
| 294 |
docs_with_scores = docs_with_scores[:RETRIEVER_K]
|
| 295 |
|
| 296 |
+
# Identify top chunk for emphasis
|
| 297 |
+
top_chunk_idx = 0
|
| 298 |
+
if docs_with_scores and len(docs_with_scores) > 0:
|
| 299 |
+
best_score = float("-inf")
|
| 300 |
+
for i, (doc, score) in enumerate(docs_with_scores):
|
| 301 |
+
if score is not None:
|
| 302 |
+
# Handle both similarity scores (higher is better, <= 1.0)
|
| 303 |
+
# and distance scores (lower is better, > 1.0)
|
| 304 |
+
if score <= 1.0:
|
| 305 |
+
if score > best_score:
|
| 306 |
+
best_score = score
|
| 307 |
+
top_chunk_idx = i
|
| 308 |
+
else:
|
| 309 |
+
# For distance scores, lower is better
|
| 310 |
+
if -score > best_score:
|
| 311 |
+
best_score = -score
|
| 312 |
+
top_chunk_idx = i
|
| 313 |
+
|
| 314 |
+
# Format context with emphasis on top chunk and contextual headers
|
| 315 |
+
context_parts = []
|
| 316 |
+
for i, doc in enumerate(docs):
|
| 317 |
+
# Add contextual header with source and page info
|
| 318 |
+
source = doc.metadata.get("source", "Unknown")
|
| 319 |
+
source_name = os.path.basename(source) if source != "Unknown" else "Unknown"
|
| 320 |
+
page = doc.metadata.get("page", "unknown")
|
| 321 |
+
header = f"[Document: {source_name}, Page: {page}]"
|
| 322 |
+
|
| 323 |
+
# Emphasize top chunk explicitly
|
| 324 |
+
if i == top_chunk_idx:
|
| 325 |
+
content = f"{header}\n\n[MOST RELEVANT CONTEXT]\n{doc.page_content}\n[/MOST RELEVANT CONTEXT]"
|
| 326 |
+
else:
|
| 327 |
+
content = f"{header}\n\n{doc.page_content}"
|
| 328 |
+
|
| 329 |
+
context_parts.append(content)
|
| 330 |
+
|
| 331 |
+
context = "\n\n---\n\n".join(context_parts)
|
| 332 |
|
| 333 |
# Format chat history
|
| 334 |
history_str = format_chat_history(chat_history)
|