Production_Rag / context_manager.py
TharaKavin's picture
Upload 17 files
6f94597 verified
Raw
History Blame Contribute Delete
2.35 kB
from typing import List, Dict, Any, Optional
def _estimate_tokens(text: str) -> int:
return len(text) // 4 + 1
class ContextManager:
def __init__(self, max_tokens: int = 8192):
self.max_tokens = max_tokens
def assemble_prompt(
self,
query: str,
documents: List[Dict[str, Any]],
system_prompt: Optional[str] = None,
) -> str:
if system_prompt is None:
system_prompt = (
"You are a helpful AI assistant. Answer the user's question "
"based solely on the provided context. Keep your answer concise "
"and directly address the question. If the context lacks "
"sufficient information, state that clearly."
)
system_tokens = _estimate_tokens(system_prompt)
query_text = f"Question: {query}\n\nAnswer:"
query_tokens = _estimate_tokens(query_text)
budget = self.max_tokens - system_tokens - query_tokens - 50
if budget < 100:
budget = 100
context_parts = []
chars_used = 0
budget_chars = budget * 4
for i, doc in enumerate(documents):
raw_path = doc.get("metadata", {}).get("hierarchy_path", "")
path_parts = [p.strip() for p in raw_path.split("|") if p.strip()] if raw_path else []
path_str = " > ".join(path_parts) if path_parts else ""
header = f"[Document {i + 1}]" + (f" — {path_str}" if path_str else "")
header_chars = len(header) + 1
text = doc.get("text", "")
text_chars = len(text)
total_needed = header_chars + text_chars
if chars_used + total_needed > budget_chars:
remaining = budget_chars - chars_used - header_chars
if remaining > 80 and len(context_parts) > 0:
truncated = text[:remaining]
context_parts.append(f"{header}\n{truncated}")
chars_used += header_chars + remaining
break
context_parts.append(f"{header}\n{text}")
chars_used += total_needed
context = "\n\n".join(context_parts)
return f"{system_prompt}\n\nContext:\n{context}\n\n{query_text}"
def count_tokens(self, text: str) -> int:
return _estimate_tokens(text)