| import re |
| import numpy as np |
| from sklearn.feature_extraction.text import TfidfVectorizer |
| from sklearn.metrics.pairwise import cosine_similarity |
|
|
| class ResumeRAGStore: |
| def __init__(self, chunk_size: int = 250, overlap: int = 50): |
| self.chunk_size = chunk_size |
| self.overlap = overlap |
| self.chunks = [] |
| self.vectorizer = None |
| self.tfidf_matrix = None |
|
|
| def index_resume_text(self, text: str): |
| """ |
| Chunks raw resume text and indexes it using TF-IDF for RAG retrieval. |
| """ |
| if not text or not text.strip(): |
| self.chunks = ["No resume content indexed."] |
| return |
|
|
| |
| lines = [line.strip() for line in text.splitlines() if line.strip()] |
| self.chunks = [] |
|
|
| current_chunk = [] |
| current_len = 0 |
|
|
| for line in lines: |
| current_chunk.append(line) |
| current_len += len(line) |
| if current_len >= self.chunk_size: |
| self.chunks.append(" ".join(current_chunk)) |
| current_chunk = current_chunk[-1:] |
| current_len = len(current_chunk[0]) if current_chunk else 0 |
|
|
| if current_chunk: |
| self.chunks.append(" ".join(current_chunk)) |
|
|
| if not self.chunks: |
| self.chunks = [text] |
|
|
| |
| self.vectorizer = TfidfVectorizer(stop_words="english") |
| try: |
| self.tfidf_matrix = self.vectorizer.fit_transform(self.chunks) |
| except Exception as e: |
| print(f"[RAGStore] TFIDF indexing warning: {e}") |
| self.tfidf_matrix = None |
|
|
| def retrieve_context(self, query: str, top_k: int = 3) -> str: |
| """ |
| Retrieves top_k most relevant resume passages matching the query. |
| """ |
| if not self.chunks or self.vectorizer is None or self.tfidf_matrix is None: |
| return "\n".join(self.chunks[:top_k]) |
|
|
| try: |
| query_vec = self.vectorizer.transform([query]) |
| scores = cosine_similarity(query_vec, self.tfidf_matrix).flatten() |
| top_indices = np.argsort(scores)[::-1][:top_k] |
| |
| relevant_chunks = [self.chunks[i] for i in top_indices if scores[i] > 0.05] |
| if not relevant_chunks: |
| relevant_chunks = self.chunks[:top_k] |
|
|
| return "\n\n---\n\n".join(relevant_chunks) |
| except Exception as e: |
| print(f"[RAGStore] Context retrieval error: {e}") |
| return "\n".join(self.chunks[:top_k]) |
|
|