auto-analyst-backend-2 / src /utils /simple_retriever.py
Arslan1997's picture
Remove unused LFS banner image
e3475e1
Raw
History Blame Contribute Delete
2.19 kB
"""
Lightweight TF-IDF based retriever to replace llama-index VectorStoreIndex.
Uses scikit-learn (already a dependency) — no heavyweight RAG framework needed.
"""
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
class TextNode:
"""Minimal node wrapper matching the llama-index retrieval result interface."""
def __init__(self, text: str):
self.text = text
class Document:
"""Minimal document wrapper matching the llama-index Document interface."""
def __init__(self, text: str):
self.text = text
class SimpleRetriever:
"""
TF-IDF cosine-similarity retriever that mirrors the subset of the
llama-index VectorStoreIndex / BaseRetriever interface actually used:
index = SimpleRetriever.from_documents([Document(text=x) for x in docs])
ret = index.as_retriever(similarity_top_k=1)
nodes = ret.retrieve(query) # -> list[TextNode]
text = nodes[0].text
"""
def __init__(self, texts: list[str]):
self._docs = texts
self._top_k = 1
self._vectorizer = TfidfVectorizer()
if texts:
self._matrix = self._vectorizer.fit_transform(texts)
else:
self._matrix = None
@classmethod
def from_documents(cls, documents) -> "SimpleRetriever":
"""Build a retriever from a list of Document objects."""
texts = [doc.text for doc in documents]
return cls(texts)
def as_retriever(self, similarity_top_k: int = 1) -> "SimpleRetriever":
"""Configure top-k and return self (mirrors llama-index fluent API)."""
self._top_k = similarity_top_k
return self
def retrieve(self, query: str) -> list[TextNode]:
"""Return the top-k most similar nodes for a query."""
if not self._docs or self._matrix is None:
return [TextNode("")]
query_vec = self._vectorizer.transform([query])
scores = cosine_similarity(query_vec, self._matrix)[0]
top_indices = np.argsort(scores)[::-1][: self._top_k]
return [TextNode(self._docs[i]) for i in top_indices]