# requires: pip install sentence-transformers import numpy as np from sentence_transformers import SentenceTransformer encoder = SentenceTransformer("all-MiniLM-L6-v2") class SemanticCache: def __init__(self, threshold=0.95): self.threshold = threshold self.vectors = np.empty((0, encoder.get_sentence_embedding_dimension())) self.prompts, self.responses = [], [] def _embed(self, text): return encoder.encode([text], normalize_embeddings=True)[0] def lookup(self, prompt): vec = self._embed(prompt) if len(self.prompts) == 0: return None, 0.0, vec scores = self.vectors @ vec # cosine sim, vectors are unit length best = int(np.argmax(scores)) if scores[best] >= self.threshold: return self.responses[best], float(scores[best]), vec return None, float(scores[best]), vec def store(self, prompt, response, vec): self.vectors = np.vstack([self.vectors, vec]) self.prompts.append(prompt) self.responses.append(response) cache = SemanticCache(threshold=0.95) def answer(prompt, call_model): hit, score, vec = cache.lookup(prompt) if hit is not None: return hit, f"HIT (score {score:.3f})" response = call_model(prompt) # the expensive path cache.store(prompt, response, vec) return response, f"MISS (best {score:.3f})" # Stand in for the model so this runs without an API key. fake_model = lambda p: f"" for q in ["How do I reset my password?", "How can I reset my password?", "Is the API rate limited?"]: _, status = answer(q, fake_model) print(f"{status} {q}") # Output: "MISS (best 0.000) How do I reset my password?" "HIT (score 0.961) How can I reset my password?" "MISS (best 0.112) Is the API rate limited?"