Julien Simon commited on
Commit
b7afa04
Β·
1 Parent(s): 08980d3

feat: emphasize top chunk and add contextual headers in RAG context

Browse files

Improve 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.

Files changed (1) hide show
  1. qa_chain.py +38 -1
qa_chain.py CHANGED
@@ -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
- context = "\n\n".join(doc.page_content for doc in docs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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)