import os import json import numpy as np class InMemoryVectorEngine: def __init__(self, catalog_path="catalog.json", embeddings_path="embeddings.npy"): self.catalog_path = catalog_path self.embeddings_path = embeddings_path self.products = [] self.embeddings = np.empty((0, 512), dtype=np.float32) self.load() def load(self): if os.path.exists(self.catalog_path): with open(self.catalog_path, "r") as f: self.products = json.load(f) if os.path.exists(self.embeddings_path): self.embeddings = np.load(self.embeddings_path).astype(np.float32) def save(self): with open(self.catalog_path, "w") as f: json.dump(self.products, f, indent=2) np.save(self.embeddings_path, self.embeddings) def add(self, product, embedding): self.products.append(product) embedding = embedding / np.linalg.norm(embedding) if self.embeddings.size == 0: self.embeddings = np.array([embedding], dtype=np.float32) else: self.embeddings = np.vstack([self.embeddings, embedding.astype(np.float32)]) self.save() def search(self, query_vector, top_k=6): if self.embeddings.size == 0: return [] query_vector = query_vector / np.linalg.norm(query_vector) similarities = np.dot(self.embeddings, query_vector) indices = np.argsort(similarities)[::-1] results = [] for idx in indices[:top_k]: results.append({ "product": self.products[idx], "score": float(similarities[idx]) }) return results def get_by_id(self, product_id): for idx, prod in enumerate(self.products): if prod["id"] == product_id: return prod, self.embeddings[idx] return None, None class QdrantVectorEngine: def __init__(self): pass def load(self): pass def save(self): pass def add(self, product, embedding): pass def search(self, query_vector, top_k=6): return [] def get_by_id(self, product_id): return None, None class VectorStore: def __init__(self): self.engine = InMemoryVectorEngine() def add_product(self, product, embedding): self.engine.add(product, embedding) def search_by_vector(self, query_vector, top_k=6): return self.engine.search(query_vector, top_k) def search_similar(self, product_id, top_k=6): prod, embedding = self.engine.get_by_id(product_id) if embedding is None: return [] results = self.engine.search(embedding, top_k + 1) return [res for res in results if res["product"]["id"] != product_id][:top_k] def get_all_products(self): return self.engine.products