"""Fake Embedding class for testing purposes.""" import math from typing import List from langchain.embeddings.base import Embeddings fake_texts = ["foo", "bar", "baz"] class FakeEmbeddings(Embeddings): """Fake embeddings functionality for testing.""" def embed_documents(self, texts: List[str]) -> List[List[float]]: """Return simple embeddings. Embeddings encode each text as its index.""" return [[float(1.0)] * 9 + [float(i)] for i in range(len(texts))] def embed_query(self, text: str) -> List[float]: """Return constant query embeddings. Embeddings are identical to embed_documents(texts)[0]. Distance to each text will be that text's index, as it was passed to embed_documents.""" return [float(1.0)] * 9 + [float(0.0)] class ConsistentFakeEmbeddings(FakeEmbeddings): """Fake embeddings which remember all the texts seen so far to return consistent vectors for the same texts.""" def __init__(self, dimensionality: int = 10) -> None: self.known_texts: List[str] = [] self.dimensionality = dimensionality def embed_documents(self, texts: List[str]) -> List[List[float]]: """Return consistent embeddings for each text seen so far.""" out_vectors = [] for text in texts: if text not in self.known_texts: self.known_texts.append(text) vector = [float(1.0)] * (self.dimensionality - 1) + [ float(self.known_texts.index(text)) ] out_vectors.append(vector) return out_vectors def embed_query(self, text: str) -> List[float]: """Return consistent embeddings for the text, if seen before, or a constant one if the text is unknown.""" if text not in self.known_texts: return [float(1.0)] * (self.dimensionality - 1) + [float(0.0)] return [float(1.0)] * (self.dimensionality - 1) + [ float(self.known_texts.index(text)) ] class AngularTwoDimensionalEmbeddings(Embeddings): """ From angles (as strings in units of pi) to unit embedding vectors on a circle. """ def embed_documents(self, texts: List[str]) -> List[List[float]]: """ Make a list of texts into a list of embedding vectors. """ return [self.embed_query(text) for text in texts] def embed_query(self, text: str) -> List[float]: """ Convert input text to a 'vector' (list of floats). If the text is a number, use it as the angle for the unit vector in units of pi. Any other input text becomes the singular result [0, 0] ! """ try: angle = float(text) return [math.cos(angle * math.pi), math.sin(angle * math.pi)] except ValueError: # Assume: just test string, no attention is paid to values. return [0.0, 0.0]