From 8b74c6e54a414c625877d10f42abed535297aac7 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 14:32:43 -0700 Subject: [PATCH 1/7] Add similarity_search_with_normalized_similarities Add a method that exposes a sim ilarity search with corresponding normalized similarity scores. --- langchain/vectorstores/base.py | 37 ++++++++++++- langchain/vectorstores/faiss.py | 53 +++++++++++++++++-- .../vectorstores/test_faiss.py | 35 ++++++++++++ 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/langchain/vectorstores/base.py b/langchain/vectorstores/base.py index f995d3dda31..5f618dce0f0 100644 --- a/langchain/vectorstores/base.py +++ b/langchain/vectorstores/base.py @@ -4,7 +4,7 @@ from __future__ import annotations import asyncio from abc import ABC, abstractmethod from functools import partial -from typing import Any, Dict, Iterable, List, Optional, Type, TypeVar +from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, TypeVar from pydantic import BaseModel, Field, root_validator @@ -81,6 +81,41 @@ class VectorStore(ABC): ) -> List[Document]: """Return docs most similar to query.""" + def similarity_search_with_normalized_similarities( + self, + query: str, + k: int = 4, + **kwargs: Any, + ) -> List[Tuple[Document, float]]: + """Return docs and similarity scores, normalized on a scale from 0 to 1. + + 0 is dissimilar, 1 is most similar. + """ + docs_and_similarities = self._similarity_search_with_normalized_similarities( + query, k=k, **kwargs + ) + if any( + similarity < 0.0 or similarity > 1.0 + for _, similarity in docs_and_similarities + ): + raise ValueError( + "Normalized similarity scores must be between" + f" 0 and 1, got {docs_and_similarities}" + ) + return docs_and_similarities + + def _similarity_search_with_normalized_similarities( + self, + query: str, + k: int = 4, + **kwargs: Any, + ) -> List[Tuple[Document, float]]: + """Return docs and similarity scores, normalized on a scale from 0 to 1. + + 0 is dissimilar, 1 is most similar. + """ + raise NotImplementedError + async def asimilarity_search( self, query: str, k: int = 4, **kwargs: Any ) -> List[Document]: diff --git a/langchain/vectorstores/faiss.py b/langchain/vectorstores/faiss.py index 9b139807a51..371274d6ff5 100644 --- a/langchain/vectorstores/faiss.py +++ b/langchain/vectorstores/faiss.py @@ -48,12 +48,14 @@ class FAISS(VectorStore): index: Any, docstore: Docstore, index_to_docstore_id: Dict[int, str], + normalize_score_fn: Optional[Callable[[float], float]] = None, ): """Initialize with necessary components.""" self.embedding_function = embedding_function self.index = index self.docstore = docstore self.index_to_docstore_id = index_to_docstore_id + self.normalize_score_fn = normalize_score_fn def __add( self, @@ -301,6 +303,7 @@ class FAISS(VectorStore): embeddings: List[List[float]], embedding: Embeddings, metadatas: Optional[List[dict]] = None, + normalize_score_fn: Optional[Callable[[float], float]] = None, **kwargs: Any, ) -> FAISS: faiss = dependable_faiss_import() @@ -314,7 +317,13 @@ class FAISS(VectorStore): docstore = InMemoryDocstore( {index_to_id[i]: doc for i, doc in enumerate(documents)} ) - return cls(embedding.embed_query, index, docstore, index_to_id) + return cls( + embedding.embed_query, + index, + docstore, + index_to_id, + normalize_score_fn=normalize_score_fn, + ) @classmethod def from_texts( @@ -322,6 +331,7 @@ class FAISS(VectorStore): texts: List[str], embedding: Embeddings, metadatas: Optional[List[dict]] = None, + normalize_score_fn: Optional[Callable] = None, **kwargs: Any, ) -> FAISS: """Construct FAISS wrapper from raw documents. @@ -342,7 +352,14 @@ class FAISS(VectorStore): faiss = FAISS.from_texts(texts, embeddings) """ embeddings = embedding.embed_documents(texts) - return cls.__from(texts, embeddings, embedding, metadatas, **kwargs) + return cls.__from( + texts, + embeddings, + embedding, + metadatas, + normalize_score_fn=normalize_score_fn, + **kwargs, + ) @classmethod def from_embeddings( @@ -350,6 +367,7 @@ class FAISS(VectorStore): text_embeddings: List[Tuple[str, List[float]]], embedding: Embeddings, metadatas: Optional[List[dict]] = None, + normalize_score_fn: Optional[Callable[[float], float]] = None, **kwargs: Any, ) -> FAISS: """Construct FAISS wrapper from raw documents. @@ -371,12 +389,19 @@ class FAISS(VectorStore): """ texts = [t[0] for t in text_embeddings] embeddings = [t[1] for t in text_embeddings] - return cls.__from(texts, embeddings, embedding, metadatas, **kwargs) + return cls.__from( + texts, + embeddings, + embedding, + metadatas, + normalize_score_fn=normalize_score_fn, + **kwargs, + ) def save_local(self, folder_path: str) -> None: """Save FAISS index, docstore, and index_to_docstore_id to disk. - Args: + Args:s folder_path: folder path to save index, docstore, and index_to_docstore_id to. """ @@ -409,3 +434,23 @@ class FAISS(VectorStore): with open(path / "index.pkl", "rb") as f: docstore, index_to_docstore_id = pickle.load(f) return cls(embeddings.embed_query, index, docstore, index_to_docstore_id) + + def _get_similarity_score(self, score: float) -> float: + if self.normalize_score_fn is None: + raise ValueError( + "normalize_score_fn must be provided to" + " FAISS constructor to normalize scores" + ) + return self.normalize_score_fn(score) + + def _similarity_search_with_normalized_similarities( + self, + query: str, + k: int = 4, + **kwargs: Any, + ) -> List[Tuple[Document, float]]: + """Return docs and their similarity scores on a scale from 0 to 1.""" + docs_and_scores = self.similarity_search_with_score(query, k=k) + return [ + (doc, self._get_similarity_score(score)) for doc, score in docs_and_scores + ] diff --git a/tests/integration_tests/vectorstores/test_faiss.py b/tests/integration_tests/vectorstores/test_faiss.py index d1fc9c5e886..e5b27532e44 100644 --- a/tests/integration_tests/vectorstores/test_faiss.py +++ b/tests/integration_tests/vectorstores/test_faiss.py @@ -1,4 +1,5 @@ """Test FAISS functionality.""" +import math import tempfile import pytest @@ -109,3 +110,37 @@ def test_faiss_local_save_load() -> None: docsearch.save_local(temp_file.name) new_docsearch = FAISS.load_local(temp_file.name, FakeEmbeddings()) assert new_docsearch.index is not None + + +def test_faiss_similarity_search_with_normalized_similarities() -> None: + """Test the similarity search with normalized similarities.""" + texts = ["foo", "bar", "baz"] + docsearch = FAISS.from_texts( + texts, + FakeEmbeddings(), + normalize_score_fn=lambda score: 1.0 - score / math.sqrt(2), + ) + outputs = docsearch.similarity_search_with_normalized_similarities("foo", k=1) + output, score = outputs[0] + assert output == Document(page_content="foo") + assert score == 1.0 + + +def test_faiss_invalid_normalize_fn() -> None: + """Test the similarity search with normalized similarities.""" + texts = ["foo", "bar", "baz"] + docsearch = FAISS.from_texts( + texts, FakeEmbeddings(), normalize_score_fn=lambda _: 2.0 + ) + with pytest.raises( + ValueError, match="Normalized similarity scores must be between 0 and 1" + ): + docsearch.similarity_search_with_normalized_similarities("foo", k=1) + + +def test_missing_normalize_score_fn() -> None: + """Test doesn't perform similarity search without a normalize score function.""" + with pytest.raises(ValueError): + texts = ["foo", "bar", "baz"] + faiss_instance = FAISS.from_texts(texts, FakeEmbeddings()) + faiss_instance.similarity_search_with_normalized_similarities("foo", k=2) From 8bd2434862a00b908a58b3a182727f4ed8fba508 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:24:21 -0700 Subject: [PATCH 2/7] Update --- docs/use_cases/agents/characters.ipynb | 260 ++++++++++-------- .../retrievers/time_weighted_retriever.py | 33 +-- 2 files changed, 156 insertions(+), 137 deletions(-) diff --git a/docs/use_cases/agents/characters.ipynb b/docs/use_cases/agents/characters.ipynb index 7f74b696bc8..5203e0300cb 100644 --- a/docs/use_cases/agents/characters.ipynb +++ b/docs/use_cases/agents/characters.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "id": "53f81c37-db45-4fdc-843c-aa8fd2a9e99d", "metadata": {}, "outputs": [], @@ -25,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "id": "8851c370-b395-4b80-a79d-486a38ffc244", "metadata": { "tags": [] @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "id": "81824e76", "metadata": {}, "outputs": [], @@ -84,7 +84,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "id": "043e5203-6a41-431c-9efa-3e1743d7d25a", "metadata": { "tags": [] @@ -406,24 +406,32 @@ "source": [ "## Create a Generative Character\n", "\n", + "\n", + "\n", "Now that we've walked through the definition, we will create two characters named \"Tommie\" and \"Eve\"." ] }, { "cell_type": "code", - "execution_count": 5, - "id": "608c0272", + "execution_count": 7, + "id": "ee9c1a1d-c311-4f1c-8131-75fccd9025b1", "metadata": { "tags": [] }, "outputs": [], "source": [ + "import math\n", "import faiss\n", "\n", - "def interview_agent(agent: GenerativeAgent, message: str) -> str:\n", - " \"\"\"Help the notebook user interact with the agent.\"\"\"\n", - " new_message = f\"{USER_NAME} says {message}\"\n", - " return agent.generate_dialogue_response(new_message)[1]\n", + "def normalize_score_fn(score: float) -> float:\n", + " \"\"\"Return a similarity score on a scale [0, 1].\"\"\"\n", + " # This will differ depending on a few things:\n", + " # - the distance / similarity metric used by the VectorStore\n", + " # - the scale of your embeddings (OpenAI's are unit norm. Many others are not!)\n", + " # This function converts the euclidean norm of normalized embeddings\n", + " # (0 is most similar, sqrt(2) most dissimilar)\n", + " # to a similarity function (0 to 1)\n", + " return 1.0 - score / math.sqrt(2)\n", "\n", "def create_new_memory_retriever():\n", " \"\"\"Create a new vector store retriever unique to the agent.\"\"\"\n", @@ -432,13 +440,13 @@ " # Initialize the vectorstore as empty\n", " embedding_size = 1536\n", " index = faiss.IndexFlatL2(embedding_size)\n", - " vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})\n", - " return TimeWeightedVectorStoreRetriever(vectorstore=vectorstore, other_score_keys=[\"importance\"]) " + " vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}, normalize_score_fn=normalize_score_fn)\n", + " return TimeWeightedVectorStoreRetriever(vectorstore=vectorstore, other_score_keys=[\"importance\"], k=15) " ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "id": "7884f9dd-c597-4c27-8c77-1402c71bc2f8", "metadata": { "tags": [] @@ -460,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "id": "c524d529", "metadata": { "tags": [] @@ -472,7 +480,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Unfortunately, there are no statements provided to summarize Tommie's core characteristics.\n" + "Sorry, there are no statements provided to summarize Tommie's core characteristics. Please provide more information.\n" ] } ], @@ -484,7 +492,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "id": "4be60979-d56e-4abf-a636-b34ffa8b7fba", "metadata": { "tags": [] @@ -507,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "id": "6992b48b-697f-4973-9560-142ef85357d7", "metadata": { "tags": [] @@ -519,7 +527,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a person who is currently on a road trip and experiencing various sensory stimuli such as noise from the road at night, memories of his childhood dog, observing a new home and neighbors with a cat. He is also experiencing physical sensations such as fatigue from driving and hunger. Tommie attempts to rest to alleviate his tiredness and hunger.\n" + "Tommie is a person who sees a new home, remembers his childhood dog, tries to rest, feels tired from driving, and is hungry. He is also bothered by the noise of the road at night and aware that his new neighbors have a cat.\n" ] } ], @@ -542,7 +550,22 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, + "id": "eaf125d8-f54c-4c5f-b6af-32789b1f7d3a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def interview_agent(agent: GenerativeAgent, message: str) -> str:\n", + " \"\"\"Help the notebook user interact with the agent.\"\"\"\n", + " new_message = f\"{USER_NAME} says {message}\"\n", + " return agent.generate_dialogue_response(new_message)[1]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, "id": "54024d41-6e83-4914-91e5-73140e2dd9c8", "metadata": { "tags": [] @@ -551,10 +574,10 @@ { "data": { "text/plain": [ - "'\"I really enjoy design. I find it calming and a way to express my creativity. But right now, I\\'m mostly focused on finding a job to support myself. How about you, Person A? What do you like to do?\"'" + "'\"I really enjoy design. I like creating something beautiful and functional. It helps me take my mind off things.\"'" ] }, - "execution_count": 10, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -565,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "id": "71e2e8cc-921e-4816-82f1-66962b2c1055", "metadata": { "tags": [] @@ -574,10 +597,10 @@ { "data": { "text/plain": [ - "'\"Well, since it\\'s already late at night, I\\'m mostly looking forward to getting some rest and starting fresh in the morning. How about you, Person A? What are you looking forward to doing tomorrow?\"'" + "'\"Well, right now I\\'m actually in the process of looking for a job. So, I\\'m hoping to make some progress on that front today. How about you?\"'" ] }, - "execution_count": 11, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -588,7 +611,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "id": "a2521ffc-7050-4ac3-9a18-4cccfc798c31", "metadata": { "tags": [] @@ -597,10 +620,10 @@ { "data": { "text/plain": [ - "'\"Honestly, I\\'ve been feeling pretty anxious lately about finding a job and making ends meet. But I\\'m trying to stay positive and keep pushing forward. How about you, Person A? What worries you?\"'" + "'\"Honestly, my biggest worry right now is finding a job. It\\'s been tough out there, but I\\'m trying to stay positive and keep searching. How about you, what are you most worried about today?\"'" ] }, - "execution_count": 12, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -619,7 +642,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "id": "154dee3d-bfe0-4828-b963-ed7e885799b3", "metadata": { "tags": [] @@ -669,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "id": "238be49c-edb3-4e26-a2b6-98777ba8de86", "metadata": { "tags": [] @@ -679,49 +702,49 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie covers his head with a pillow to block out the noise.\n", - "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie starts brewing his coffee and enjoys the smell.\n", - "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie sighs in frustration and continues to search for the filters.\n", - "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie takes a sip of his coffee and feels relieved.\n", - "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie grimaces at the bitter taste of the coffee and makes a mental note to buy a better brand next time.\n", - "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie feels disappointed and anxious.\n", - "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie feels determined to continue job searching and improving his resume and cover letter.\n", - "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie feels excited to explore the city and hopeful about finding job openings.\n", - "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m \"That job fair looks promising. I'll definitely check it out.\"\n", - "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie feels impatient and frustrated by the long wait in line.\n", - "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie feels disappointed but determined to keep looking for job opportunities.\n", - "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie feels discouraged but still determined to keep searching for job opportunities.\n", - "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m \"Hi, can I get a menu please?\"\n", - "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie sighs in frustration and looks around for something to occupy his time while he waits.\n", - "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m \"Excuse me, I couldn't help but overhear about the job opening. Could you tell me more about it?\"\n", - "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m \"Thank you for the information. Do you happen to have any contact information for the company or know where I can apply?\"\n", + "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie covers his head with a pillow to try to block out the noise.\n", + "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie grabs a mug and starts brewing coffee.\n", + "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie sighs in frustration and continues to search through the boxes.\n", + "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie takes a sip of his coffee and feels a sense of relief.\n", + "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie grimaces at the bitter taste and makes a mental note to buy a better brand of coffee next time.\n", + "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie sighs in disappointment and feels more anxious about finding a job.\n", + "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie feels a sense of accomplishment and relief after updating his resume and cover letter.\n", + "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie nods to themselves and heads out with a sense of purpose.\n", + "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m \"That job fair could be a great opportunity for me to find a job.\"\n", + "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie sighs and checks their phone to pass the time.\n", + "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie feels disappointed and frustrated after not receiving any job offers at the fair.\n", + "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie feels disappointed and frustrated after not receiving any job offers at the fair.\n", + "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m Tommie's stomach grumbles in anticipation of lunch.\n", + "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie sighs in frustration and checks his phone to pass the time while waiting for his food.\n", + "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m \"Excuse me, I couldn't help but overhear your conversation about the job opening. Do you have any more information about it?\"\n", "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", - "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m \"Thank you for the information. Do you happen to have any contact information for the company or know where I can apply?\"\n", - "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie feels hopeful but also anxious about the possibility of not hearing back from any of the businesses.\n", - "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie feels a sense of calm and relaxation as he takes a break from his job search to enjoy nature.\n", - "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie feels a brief moment of happiness and connection with the dog before continuing on with his day.\n", + "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m \"Thank you for the information. I'll definitely look into that company.\"\n", + "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m Tommie feels a sense of hope and relief after applying for the job.\n", + "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie feels a sense of accomplishment and determination after dropping off his resume at several local businesses.\n", + "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie takes a deep breath and enjoys the peaceful surroundings of the park.\n", + "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie smiles and enjoys the moment with the dog before continuing his walk.\n", "****************************************\n", "\u001b[34mAfter 20 observations, Tommie's summary is:\n", "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a determined and persistent job seeker who experiences a range of emotions, including disappointment, anxiety, determination, and excitement. He is proactive in his search and seeks out opportunities to explore the city and meet potential employers. Despite facing setbacks and challenges, he remains hopeful and continues to update his resume and cover letter.\u001b[0m\n", + "Tommie is currently unemployed and actively searching for a job, which is a significant source of stress for him impacting his overall well-being. His job search is emotionally challenging, causing him to experience a range of feelings such as anxiety, frustration, disappointment, and relief. However, despite facing challenges and setbacks, Tommie remains determined and resilient in his job search. He takes proactive steps to find employment, such as attending job fairs and updating his resume. Tommie is interested in design and finds it helpful in taking his mind off things, providing him with a sense of purpose and motivation during his job search. He feels a sense of accomplishment and determination after dropping off his resume at several local businesses and feels hopeful and relieved after applying for a job.\u001b[0m\n", "****************************************\n", - "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m \"Hi, can I play with you guys?\"\n", - "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie winces in pain and holds his nose, but continues to play through the discomfort.\n", - "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie sighs and takes a deep breath, feeling tired from the day's events.\n", - "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie cleans up the garbage and secures the trash bag to prevent future incidents.\n", - "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie takes a deep breath and reminds himself to stay positive and persistent in his job search.\n", - "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m \"Hey, thanks for listening. It feels good to talk about it and get some support.\"\n", - "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m \"Thanks for the encouragement, I really appreciate it.\"\n", - "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m Tommie nods and smiles, feeling grateful for his friend's support.\n", - "\u001b[32mTommie decides to go for a jog to clear his mind.\u001b[0m Tommie puts on his running shoes and heads out the door.\n", - "\u001b[32mTommie jogs through the city and sees some interesting sights.\u001b[0m Tommie feels a sense of wonder and appreciation for the beauty of the city.\n", - "\u001b[32mTommie stops to take a picture of a street mural.\u001b[0m Tommie feels inspired and appreciative of the creativity and beauty of the street mural.\n", - "\u001b[32mTommie runs into an old friend from college who now lives in the city.\u001b[0m \"Hey! It's great to see you! What have you been up to?\"\n", + "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m There is no mention of Tommie seeing a group of people playing frisbee in the given context, so no reaction is necessary.\n", + "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie winces in pain and touches his nose to check for any damage.\n", + "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie takes a deep breath and rests for a bit.\n", + "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie cleans up the garbage and disposes of it properly.\n", + "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie sighs and takes a moment to collect himself before continuing his job search.\n", + "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m \"Hey, can we talk? I'm feeling really frustrated with my job search and could use someone to vent to.\"\n", + "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m \"Thanks for the encouragement, it means a lot.\"\n", + "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m \"Thanks for being there for me, it really helps to talk to someone about my job search.\"\n", + "\u001b[32mTommie decides to go for a jog to clear his mind.\u001b[0m Tommie takes a deep breath and starts jogging to clear his mind.\n", + "\u001b[32mTommie jogs through the city and sees some interesting sights.\u001b[0m Tommie enjoys the sights while jogging through the city.\n", + "\u001b[32mTommie stops to take a picture of a street mural.\u001b[0m Tommie smiles and admires the street mural before continuing his jog.\n", + "\u001b[32mTommie runs into an old friend from college who now lives in the city.\u001b[0m \"Hey, it's great to see you! How have you been?\"\n", "\u001b[32mThey catch up for a few minutes, but Tommie's friend has to leave to attend a meeting.\u001b[0m \"It was great seeing you, let's catch up again soon!\"\n", - "\u001b[32mTommie thanks his friend and feels hopeful again.\u001b[0m Tommie nods and smiles, feeling grateful for his friend's support.\n", - "\u001b[32mTommie heads back to his apartment to rest and prepare for his upcoming interviews.\u001b[0m Tommie takes a deep breath and feels a sense of relief knowing that he has upcoming interviews.\n", - "\u001b[32mTommie spends the evening rehearsing his interview pitch.\u001b[0m Tommie feels focused and determined to do well in his upcoming interviews.\n" + "\u001b[32mTommie thanks his friend and feels hopeful again.\u001b[0m \"Thanks for catching up with me, it was great seeing you again!\"\n", + "\u001b[32mTommie heads back to his apartment to rest and prepare for his upcoming interviews.\u001b[0m \"I should review my notes and prepare for my upcoming interviews.\"\n", + "\u001b[32mTommie spends the evening rehearsing his interview pitch.\u001b[0m Tommie feels focused and determined while rehearsing his interview pitch.\n" ] } ], @@ -746,7 +769,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "id": "6336ab5d-3074-4831-951f-c9e2cba5dfb5", "metadata": { "tags": [] @@ -755,10 +778,10 @@ { "data": { "text/plain": [ - "'\"Well, it\\'s been a bit of a rollercoaster, to be honest. I\\'ve been job searching all day and it\\'s been a mix of excitement, disappointment, and anxiety. But I\\'m trying to stay positive and keep pushing forward.\"'" + "'\"Well, it\\'s been a bit of a rollercoaster, to be honest. I\\'m still looking for a job, which is pretty stressful, but I\\'ve been trying to stay positive and keep myself busy. I took a walk in the park earlier and even played some frisbee with a group of people. It was fun, but I did get hit in the face with the frisbee and hurt my nose a bit. Overall, though, I\\'m feeling more hopeful now that I\\'ve been rehearsing my interview pitch for upcoming interviews.\"'" ] }, - "execution_count": 15, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -769,7 +792,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "id": "809ac906-69b7-4326-99ec-af638d32bb20", "metadata": { "tags": [] @@ -778,10 +801,10 @@ { "data": { "text/plain": [ - "'\"I actually really like coffee, it helps me stay focused during my job search. How about you?\"'" + "'\"I don\\'t really have strong feelings about coffee, to be honest. I prefer tea myself. How about you?\"'" ] }, - "execution_count": 16, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -792,25 +815,32 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 21, "id": "f733a431-19ea-421a-9101-ae2593a8c626", "metadata": { "tags": [] }, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n" + ] + }, { "data": { "text/plain": [ - "'Tommie would say: \"I actually really like coffee, it helps me stay focused during my job search. How about you?\" '" + "'\"Oh, I actually had a dog when I was a kid named Bruno. He was a big golden retriever and always made me feel better when I was feeling down. But unfortunately, he passed away a few years ago. Thanks for asking though.\"'" ] }, - "execution_count": 17, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "interview_agent(tommie, \"What are your thoughts on coffee\")" + "interview_agent(tommie, \"Tell me about your childhood dog!\")" ] }, { @@ -825,7 +855,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 22, "id": "ec8bbe18-a021-419c-bf1f-23d34732cd99", "metadata": { "tags": [] @@ -847,7 +877,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 23, "id": "1e2745f5-e0da-4abd-98b4-830802ce6698", "metadata": { "tags": [] @@ -870,7 +900,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 24, "id": "de4726e3-4bb1-47da-8fd9-f317a036fe0f", "metadata": { "tags": [] @@ -882,7 +912,7 @@ "text": [ "Name: Eve (age: 34)\n", "Innate traits: curious, helpful\n", - "Eve is attentive to her colleagues, enjoys physical activity, helpful to coworkers, responsible in waking up to her alarm, and eats breakfast.\n" + "Eve is helpful, social, observant, and has a typical daily routine.\n" ] } ], @@ -903,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 25, "id": "6cda916d-800c-47bc-a7f9-6a2f19187472", "metadata": { "tags": [] @@ -912,10 +942,10 @@ { "data": { "text/plain": [ - "'\"I\\'m feeling curious about what we have planned for today. How about you?\"'" + "'\"I\\'m feeling pretty good, thanks for asking. How about you?\"'" ] }, - "execution_count": 21, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -926,7 +956,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 26, "id": "448ae644-0a66-4eb2-a03a-319f36948b37", "metadata": { "tags": [] @@ -935,10 +965,10 @@ { "data": { "text/plain": [ - "'\"I overheard someone mention that Tommie is hard to work with, but I don\\'t know much else about them. Why do you ask?\"'" + "'\"I actually overheard someone say that Tommie is hard to work with earlier, but I don\\'t know much else about him. Have you worked with him before?\"'" ] }, - "execution_count": 22, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -949,7 +979,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 27, "id": "493fc5b8-8730-4ef8-9820-0f1769ce1691", "metadata": { "tags": [] @@ -958,10 +988,10 @@ { "data": { "text/plain": [ - "'\"That\\'s interesting, I didn\\'t know Tommie was looking for a job. What kind of job is he looking for? Maybe I can keep an eye out for any openings that might be a good fit for him.\"'" + "'\"That\\'s great to hear! What kind of job is Tommie looking for? Maybe I can help in some way.\"'" ] }, - "execution_count": 23, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -972,7 +1002,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 28, "id": "4b46452a-6c54-4db2-9d87-18597f70fec8", "metadata": { "tags": [] @@ -981,10 +1011,10 @@ { "data": { "text/plain": [ - "'\"Sure, I\\'d be happy to talk to him and see if I can help in any way. Do you have any specific questions you\\'d like me to ask him?\"'" + "'\"Sure, I\\'d be happy to help Tommie out. Can you give me his contact information so I can reach out to him?\"'" ] }, - "execution_count": 24, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1005,7 +1035,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 29, "id": "042ea271-4bf1-4247-9082-239a6fea43b8", "metadata": { "tags": [] @@ -1032,7 +1062,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 30, "id": "d5462b14-218e-4d85-b035-df57ea8e0f80", "metadata": { "tags": [] @@ -1042,14 +1072,15 @@ "name": "stdout", "output_type": "stream", "text": [ - "Eve: \"Sure, I'd love to share my story with you and offer any advice I can. Where would you like me to start?\"\n", - "Tommie: \"I've had some ups and downs, but overall I'm feeling hopeful about my job search. I've been updating my resume and cover letter, and I have a few upcoming interviews that I'm excited about. How about you, how has your day been going?\"\n", - "Eve: \"That's great to hear, Tommie. I'm glad you're feeling hopeful and have some upcoming interviews. Is there anything specific you're looking for in a job? Maybe I can keep an eye out for any opportunities that might be a good fit for you.\"\n", - "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", - "Tommie: \"Thank you so much, Eve! I really appreciate your offer to keep an eye out for job opportunities. Right now, I'm looking for a job in the design field, preferably in a creative agency or startup. But I'm open to exploring different options as well.\"\n", - "Eve: \"That's great to know, Tommie. I'll definitely keep an eye out for any opportunities in the design field, whether it's in a creative agency or startup. And if I come across anything that might be a good fit, I'll let you know right away. Good luck with your upcoming interviews and let me know if there's anything else I can do to help!\"\n", - "Tommie: \"Thank you so much, Eve! I really appreciate your willingness to help me find job opportunities. Have a great day!\"\n", - "Eve: \"You're welcome, Tommie. It was great talking with you and I wish you the best of luck in your job search. Have a great day!\"\n" + "Eve: \"Sure, I'd be happy to share my story and offer any advice I can.\"\n", + "Tommie: \"Thank you so much, I really appreciate it. It's been tough trying to navigate the job market, but I'm trying to stay positive and keep pushing forward. Do you have any tips for staying motivated during a job search?\"\n", + "Eve: \"Of course, Tommie. It can definitely be tough, but I'm glad I can offer some help. One tip I have is to make sure you take breaks and take care of yourself during the job search process. It can be easy to get burnt out or discouraged, but remember to prioritize your mental health as well. Do you have any specific industries or job types you're interested in?\"\n", + "Tommie: \"Thank you, Eve. That's really good advice. I'm actually interested in design and have been looking for opportunities in that field. Do you have any suggestions for finding job openings in that industry?\"\n", + "Eve: \"Absolutely, Tommie! I have some connections in the design industry and can definitely keep an eye out for any job openings that may be a good fit for you. Have you tried networking through LinkedIn or attending any design events in the area? Those can be great ways to meet people in the industry and potentially find job opportunities. And if you ever need any help with your resume or portfolio, I'd be happy to take a look and give you some feedback.\"\n", + "Tommie: \"Thank you so much, Eve! I really appreciate your willingness to help and your suggestions. I haven't tried networking through LinkedIn or attending any design events yet, but I will definitely look into those options. And I would love any feedback you can provide on my resume or portfolio. Thank you again for your support and advice!\"\n", + "Eve: \"No problem, Tommie! I'm happy to help in any way I can. Just let me know if you need anything else or if you come across any job openings that you're interested in. Best of luck with your job search!\"\n", + "Tommie: \"Thank you so much, Eve. I really appreciate your help and support. I will definitely keep you updated on my job search and let you know if I come across any job openings that interest me. Thanks again and have a great day!\"\n", + "Eve: \"You're welcome, Tommie! I look forward to hearing about your progress and any updates on your job search. Have a great day!\"\n" ] } ], @@ -1072,7 +1103,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 31, "id": "c4d252f3-fcc1-474c-846e-a7605a6b4ce7", "metadata": { "tags": [] @@ -1084,7 +1115,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a determined and persistent individual who seeks support from friends during his job search. He finds inspiration in the creativity and beauty around him, and experiences a range of emotions including disappointment, anxiety, determination, and excitement. He copes with setbacks by remaining hopeful and proactive in his search, exploring the city and seeking out potential employers. He values the support and understanding of his friends throughout the process.\n" + "Tommie is currently unemployed and actively searching for a job, which is causing him significant stress and impacting his overall well-being. He experiences a range of emotions throughout the day, such as anxiety, frustration, disappointment, and relief. However, he remains determined and resilient in his search, taking actions such as attending job fairs and updating his resume. Tommie seeks support from his friends and finds ways to take his mind off things. His interests in design provide him with a potential career path and a sense of purpose and motivation during his job search.\n" ] } ], @@ -1095,7 +1126,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 32, "id": "c04db9a4", "metadata": {}, "outputs": [ @@ -1105,19 +1136,18 @@ "text": [ "Name: Eve (age: 34)\n", "Innate traits: curious, helpful\n", - "Eve is a helpful and attentive person who is willing to offer assistance and keep an eye out for job opportunities. She is curious and interested in others' experiences and is a team player, willing to assist her colleagues with their tasks. She is also a tennis player and enjoys a bowl of porridge for breakfast. However, she is not immune to workplace gossip and occasionally overhears negative comments about others.\n" + "Eve is a helpful and supportive coworker who offers advice and assistance to others. She is knowledgeable about the job market and offers tips for staying motivated during a job search. She is also proactive in helping others find job opportunities and is willing to network on their behalf. She is attentive to her colleagues' needs and is willing to offer support and conversation. In her personal life, she enjoys playing tennis and eating porridge for breakfast.\n" ] } ], "source": [ - "\n", "# We can see a current \"Summary\" of a character based on their own perception of self\n", "print(eve.get_summary(force_refresh=True))" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 33, "id": "71762558-8fb6-44d7-8483-f5b47fb2a862", "metadata": { "tags": [] @@ -1126,10 +1156,10 @@ { "data": { "text/plain": [ - "'\"It was really helpful actually. Eve offered to keep an eye out for any job opportunities in the design field, which is exactly what I\\'m looking for. It\\'s great to have supportive friends like her.\"'" + "'\"It was really helpful, actually. She had some great advice for staying motivated during a job search and even offered to keep an eye out for any job openings in the design industry. I\\'m feeling more optimistic now. Thanks for asking!\"'" ] }, - "execution_count": 29, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1140,7 +1170,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 35, "id": "085af3d8-ac21-41ea-8f8b-055c56976a67", "metadata": { "tags": [] @@ -1149,10 +1179,10 @@ { "data": { "text/plain": [ - "'\"It was really nice! Tommie seems like a great person and I\\'m happy to help them with their job search. Is there anything else you wanted to know about our conversation?\"'" + "'\"It was great! Tommie is really motivated and has a lot of great experience in the design industry. I offered to keep an eye out for any job openings that may be a good fit for him, and I also suggested networking through LinkedIn and attending design events. I\\'m excited to see where his job search takes him!\"'" ] }, - "execution_count": 30, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1163,7 +1193,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 36, "id": "5b439f3c-7849-4432-a697-2bcc85b89dae", "metadata": { "tags": [] @@ -1172,10 +1202,10 @@ { "data": { "text/plain": [ - "'\"I think our conversation went well, but if there was one thing I wish I had said to Tommie, it would be to ask if they have any specific companies or agencies in mind that they would love to work for. That way, I can keep an even closer eye out for any job opportunities that might be a perfect fit for them. But overall, I think we covered a lot of ground and I\\'m excited to help Tommie in any way I can.\"'" + "'\"I feel like we covered a lot of ground during our conversation, but if there was one thing I could have emphasized more, it would be to stay positive and persistent. Job searching can be tough, but it\\'s important to remember that the right opportunity is out there and to keep pushing forward. Is there anything else you\\'d like to know or discuss, Person A?\"'" ] }, - "execution_count": 31, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } diff --git a/langchain/retrievers/time_weighted_retriever.py b/langchain/retrievers/time_weighted_retriever.py index da232de1d81..2e7975aa481 100644 --- a/langchain/retrievers/time_weighted_retriever.py +++ b/langchain/retrievers/time_weighted_retriever.py @@ -1,9 +1,9 @@ """Retriever that combines embedding similarity with recency in retrieving values.""" from copy import deepcopy from datetime import datetime -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, Field from langchain.schema import BaseRetriever, Document from langchain.vectorstores.base import VectorStore @@ -30,7 +30,7 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): decay_factor: float = Field(default=0.99) """The exponential decay factor used as decay_factor ** (hrs_passed).""" - k: int = 15 + k: int = 4 """The maximum number of documents to retrieve in a given call.""" other_score_keys: List[str] = [] @@ -47,16 +47,6 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): arbitrary_types_allowed = True - @validator("vectorstore") - def validate_vectorstore(cls, vectorstore: VectorStore) -> VectorStore: - """Validate the vectorstore has the required methods implemented.""" - if not hasattr(vectorstore, "similarity_search_with_score"): - raise ValueError( - f"Required method 'similarity_search_with_score not implemented" - f" for vectorstore of type {type(vectorstore)}" - ) - return vectorstore - def _get_combined_score( self, document: Document, @@ -76,18 +66,13 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): score += vector_salience return score - @property - def _similarity_search_with_score( - self, - ) -> Callable[[str], List[Tuple[Document, float]]]: - """Search the vector store for related docs and their similarities.""" - return self.vectorstore.similarity_search_with_score # type: ignore - def get_salient_docs(self, query: str) -> Dict[int, Tuple[Document, float]]: """Return documents that are salient to the query.""" docs_and_scores: List[Tuple[Document, float]] - docs_and_scores = self._similarity_search_with_score( - query, **self.search_kwargs + docs_and_scores = ( + self.vectorstore.similarity_search_with_normalized_similarities( + query, **self.search_kwargs + ) ) results = {} for fetched_doc, salience in docs_and_scores: @@ -98,6 +83,10 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): def get_relevant_documents(self, query: str) -> List[Document]: """Return documents that are relevant to the query.""" + if query.startswith("FOOBAR"): + import pdb + + pdb.set_trace() current_time = datetime.now() docs_and_scores = { doc.metadata["buffer_idx"]: (doc, self.default_salience) From 42ea0a0b3376dd5e83626dcdcd42566dea6cfb21 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:25:14 -0700 Subject: [PATCH 3/7] Rm method --- langchain/vectorstores/faiss.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/langchain/vectorstores/faiss.py b/langchain/vectorstores/faiss.py index 371274d6ff5..8fd4674d115 100644 --- a/langchain/vectorstores/faiss.py +++ b/langchain/vectorstores/faiss.py @@ -435,14 +435,6 @@ class FAISS(VectorStore): docstore, index_to_docstore_id = pickle.load(f) return cls(embeddings.embed_query, index, docstore, index_to_docstore_id) - def _get_similarity_score(self, score: float) -> float: - if self.normalize_score_fn is None: - raise ValueError( - "normalize_score_fn must be provided to" - " FAISS constructor to normalize scores" - ) - return self.normalize_score_fn(score) - def _similarity_search_with_normalized_similarities( self, query: str, @@ -450,7 +442,10 @@ class FAISS(VectorStore): **kwargs: Any, ) -> List[Tuple[Document, float]]: """Return docs and their similarity scores on a scale from 0 to 1.""" + if self.normalize_score_fn is None: + raise ValueError( + "normalize_score_fn must be provided to" + " FAISS constructor to normalize scores" + ) docs_and_scores = self.similarity_search_with_score(query, k=k) - return [ - (doc, self._get_similarity_score(score)) for doc, score in docs_and_scores - ] + return [(doc, self.normalize_score_fn(score)) for doc, score in docs_and_scores] From 285bd56d11936d631fb959aa292dad3a91c6ff16 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:26:08 -0700 Subject: [PATCH 4/7] Update nits --- langchain/vectorstores/faiss.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/langchain/vectorstores/faiss.py b/langchain/vectorstores/faiss.py index 8fd4674d115..61d7f8ce109 100644 --- a/langchain/vectorstores/faiss.py +++ b/langchain/vectorstores/faiss.py @@ -303,7 +303,6 @@ class FAISS(VectorStore): embeddings: List[List[float]], embedding: Embeddings, metadatas: Optional[List[dict]] = None, - normalize_score_fn: Optional[Callable[[float], float]] = None, **kwargs: Any, ) -> FAISS: faiss = dependable_faiss_import() @@ -322,7 +321,6 @@ class FAISS(VectorStore): index, docstore, index_to_id, - normalize_score_fn=normalize_score_fn, ) @classmethod @@ -331,7 +329,6 @@ class FAISS(VectorStore): texts: List[str], embedding: Embeddings, metadatas: Optional[List[dict]] = None, - normalize_score_fn: Optional[Callable] = None, **kwargs: Any, ) -> FAISS: """Construct FAISS wrapper from raw documents. @@ -357,7 +354,6 @@ class FAISS(VectorStore): embeddings, embedding, metadatas, - normalize_score_fn=normalize_score_fn, **kwargs, ) @@ -367,7 +363,6 @@ class FAISS(VectorStore): text_embeddings: List[Tuple[str, List[float]]], embedding: Embeddings, metadatas: Optional[List[dict]] = None, - normalize_score_fn: Optional[Callable[[float], float]] = None, **kwargs: Any, ) -> FAISS: """Construct FAISS wrapper from raw documents. @@ -394,14 +389,13 @@ class FAISS(VectorStore): embeddings, embedding, metadatas, - normalize_score_fn=normalize_score_fn, **kwargs, ) def save_local(self, folder_path: str) -> None: """Save FAISS index, docstore, and index_to_docstore_id to disk. - Args:s + Args: folder_path: folder path to save index, docstore, and index_to_docstore_id to. """ From 265fb5f829e615da519e5ae7b05bc039bf035880 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:50:57 -0700 Subject: [PATCH 5/7] Add tests --- docs/use_cases/agents/characters.ipynb | 281 +++++++++--------- .../retrievers/time_weighted_retriever.py | 4 - .../test_time_weighted_retriever.py | 111 ++++++- 3 files changed, 235 insertions(+), 161 deletions(-) diff --git a/docs/use_cases/agents/characters.ipynb b/docs/use_cases/agents/characters.ipynb index 5203e0300cb..d1392dafe69 100644 --- a/docs/use_cases/agents/characters.ipynb +++ b/docs/use_cases/agents/characters.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "id": "53f81c37-db45-4fdc-843c-aa8fd2a9e99d", "metadata": {}, "outputs": [], @@ -25,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "8851c370-b395-4b80-a79d-486a38ffc244", "metadata": { "tags": [] @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "81824e76", "metadata": {}, "outputs": [], @@ -84,7 +84,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "043e5203-6a41-431c-9efa-3e1743d7d25a", "metadata": { "tags": [] @@ -188,8 +188,10 @@ " new_insights.extend(insights)\n", " return new_insights\n", " \n", - " def _score_memory_importance(self, memory_content: str) -> float:\n", + " def _score_memory_importance(self, memory_content: str, weight: float = 0.15) -> float:\n", " \"\"\"Score the absolute importance of the given memory.\"\"\"\n", + " # A weight of 0.25 makes this less important than it\n", + " # would be otherwise, relative to salience and time\n", " prompt = PromptTemplate.from_template(\n", " \"On the scale of 1 to 10, where 1 is purely mundane\"\n", " +\" (e.g., brushing teeth, making bed) and 10 is\"\n", @@ -203,7 +205,7 @@ " score = chain.run(memory_content=memory_content).strip()\n", " match = re.search(r\"^\\D*(\\d+)\", score)\n", " if match:\n", - " return float(score[0]) / 10\n", + " return (float(score[0]) / 10) * weight\n", " else:\n", " return 0.0\n", "\n", @@ -353,9 +355,10 @@ " self.add_memory(f\"{self.name} observed {observation} and reacted by {result}\")\n", " if \"REACT:\" in result:\n", " reaction = result.split(\"REACT:\")[-1].strip()\n", - " return False, reaction\n", + " return False, f\"{self.name} {reaction}\"\n", " if \"SAY:\" in result:\n", - " return True, result.split(\"SAY:\")[-1].strip()\n", + " said_value = result.split(\"SAY:\")[-1].strip()\n", + " return True, f\"{self.name} said {said_value}\"\n", " else:\n", " return False, result\n", "\n", @@ -369,11 +372,11 @@ " if \"GOODBYE:\" in result:\n", " farewell = result.split(\"GOODBYE:\")[-1].strip()\n", " self.add_memory(f\"{self.name} observed {observation} and said {farewell}\")\n", - " return False, farewell\n", + " return False, f\"{self.name} said {farewell}\"\n", " if \"SAY:\" in result:\n", " response_text = result.split(\"SAY:\")[-1].strip()\n", " self.add_memory(f\"{self.name} observed {observation} and said {response_text}\")\n", - " return True, response_text\n", + " return True, f\"{self.name} said {response_text}\"\n", " else:\n", " return False, result" ] @@ -381,7 +384,10 @@ { "cell_type": "markdown", "id": "361bd49e", - "metadata": {}, + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, "source": [ "## Memory Lifecycle\n", "\n", @@ -413,7 +419,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "ee9c1a1d-c311-4f1c-8131-75fccd9025b1", "metadata": { "tags": [] @@ -446,7 +452,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "7884f9dd-c597-4c27-8c77-1402c71bc2f8", "metadata": { "tags": [] @@ -468,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "c524d529", "metadata": { "tags": [] @@ -480,7 +486,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Sorry, there are no statements provided to summarize Tommie's core characteristics. Please provide more information.\n" + "No statements or information about Tommie have been provided. Therefore, it is not possible to summarize Tommie's core characteristics.\n" ] } ], @@ -492,7 +498,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "4be60979-d56e-4abf-a636-b34ffa8b7fba", "metadata": { "tags": [] @@ -515,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "6992b48b-697f-4973-9560-142ef85357d7", "metadata": { "tags": [] @@ -527,7 +533,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is a person who sees a new home, remembers his childhood dog, tries to rest, feels tired from driving, and is hungry. He is also bothered by the noise of the road at night and aware that his new neighbors have a cat.\n" + "Tommie is observant, has a sentimental side, gets hungry and tired like any person, and is affected by his surroundings such as the noise level.\n" ] } ], @@ -550,7 +556,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "eaf125d8-f54c-4c5f-b6af-32789b1f7d3a", "metadata": { "tags": [] @@ -565,7 +571,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "id": "54024d41-6e83-4914-91e5-73140e2dd9c8", "metadata": { "tags": [] @@ -574,10 +580,10 @@ { "data": { "text/plain": [ - "'\"I really enjoy design. I like creating something beautiful and functional. It helps me take my mind off things.\"'" + "'Tommie said \"I really enjoy design, specifically graphic design. I find it fulfilling to create something visually appealing while also communicating a message. How about you?\"'" ] }, - "execution_count": 13, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -588,7 +594,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "71e2e8cc-921e-4816-82f1-66962b2c1055", "metadata": { "tags": [] @@ -597,10 +603,10 @@ { "data": { "text/plain": [ - "'\"Well, right now I\\'m actually in the process of looking for a job. So, I\\'m hoping to make some progress on that front today. How about you?\"'" + "'Tommie said \"I\\'m actually on the job hunt right now, so I\\'m hoping to find some promising leads today. How about you?\"'" ] }, - "execution_count": 14, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -611,7 +617,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "a2521ffc-7050-4ac3-9a18-4cccfc798c31", "metadata": { "tags": [] @@ -620,10 +626,10 @@ { "data": { "text/plain": [ - "'\"Honestly, my biggest worry right now is finding a job. It\\'s been tough out there, but I\\'m trying to stay positive and keep searching. How about you, what are you most worried about today?\"'" + "'Tommie said \"Honestly, I\\'m feeling anxious about finding a job. It\\'s been a bit of a struggle lately. But I\\'m trying to stay positive and keep working at it. How about you, what are you most worried about today?\"'" ] }, - "execution_count": 15, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -642,7 +648,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "154dee3d-bfe0-4828-b963-ed7e885799b3", "metadata": { "tags": [] @@ -679,20 +685,12 @@ " \"Tommie calls his best friend to vent about his struggles.\",\n", " \"Tommie's friend offers some words of encouragement and tells him to keep trying.\",\n", " \"Tommie feels slightly better after talking to his friend.\",\n", - " \"Tommie decides to go for a jog to clear his mind.\",\n", - " \"Tommie jogs through the city and sees some interesting sights.\",\n", - " \"Tommie stops to take a picture of a street mural.\",\n", - " \"Tommie runs into an old friend from college who now lives in the city.\",\n", - " \"They catch up for a few minutes, but Tommie's friend has to leave to attend a meeting.\",\n", - " \"Tommie thanks his friend and feels hopeful again.\",\n", - " \"Tommie heads back to his apartment to rest and prepare for his upcoming interviews.\",\n", - " \"Tommie spends the evening rehearsing his interview pitch.\"\n", "]\n" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "id": "238be49c-edb3-4e26-a2b6-98777ba8de86", "metadata": { "tags": [] @@ -702,49 +700,40 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie covers his head with a pillow to try to block out the noise.\n", - "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie grabs a mug and starts brewing coffee.\n", - "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie sighs in frustration and continues to search through the boxes.\n", - "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie takes a sip of his coffee and feels a sense of relief.\n", - "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie grimaces at the bitter taste and makes a mental note to buy a better brand of coffee next time.\n", - "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie sighs in disappointment and feels more anxious about finding a job.\n", - "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie feels a sense of accomplishment and relief after updating his resume and cover letter.\n", - "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie nods to themselves and heads out with a sense of purpose.\n", - "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m \"That job fair could be a great opportunity for me to find a job.\"\n", - "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie sighs and checks their phone to pass the time.\n", - "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie feels disappointed and frustrated after not receiving any job offers at the fair.\n", - "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie feels disappointed and frustrated after not receiving any job offers at the fair.\n", - "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m Tommie's stomach grumbles in anticipation of lunch.\n", - "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie sighs in frustration and checks his phone to pass the time while waiting for his food.\n", - "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m \"Excuse me, I couldn't help but overhear your conversation about the job opening. Do you have any more information about it?\"\n", - "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n", - "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m \"Thank you for the information. I'll definitely look into that company.\"\n", - "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m Tommie feels a sense of hope and relief after applying for the job.\n", - "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie feels a sense of accomplishment and determination after dropping off his resume at several local businesses.\n", - "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie takes a deep breath and enjoys the peaceful surroundings of the park.\n", - "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie smiles and enjoys the moment with the dog before continuing his walk.\n", + "\u001b[32mTommie wakes up to the sound of a noisy construction site outside his window.\u001b[0m Tommie Tommie covers his head with a pillow to try to block out the noise.\n", + "\u001b[32mTommie gets out of bed and heads to the kitchen to make himself some coffee.\u001b[0m Tommie Tommie makes himself a cup of coffee.\n", + "\u001b[32mTommie realizes he forgot to buy coffee filters and starts rummaging through his moving boxes to find some.\u001b[0m Tommie Tommie sighs and continues to search through the boxes for coffee filters.\n", + "\u001b[32mTommie finally finds the filters and makes himself a cup of coffee.\u001b[0m Tommie Tommie takes a sip of his coffee and feels a sense of relief.\n", + "\u001b[32mThe coffee tastes bitter, and Tommie regrets not buying a better brand.\u001b[0m Tommie Tommie grimaces and adds sugar to his coffee to try and improve the taste.\n", + "\u001b[32mTommie checks his email and sees that he has no job offers yet.\u001b[0m Tommie Tommie sighs and feels discouraged.\n", + "\u001b[32mTommie spends some time updating his resume and cover letter.\u001b[0m Tommie Tommie nods and feels productive.\n", + "\u001b[32mTommie heads out to explore the city and look for job openings.\u001b[0m Tommie Tommie feels excited to explore the city and find job openings.\n", + "\u001b[32mTommie sees a sign for a job fair and decides to attend.\u001b[0m Tommie Tommie's eyes light up with hope and he feels a surge of optimism.\n", + "\u001b[32mThe line to get in is long, and Tommie has to wait for an hour.\u001b[0m Tommie Tommie taps his foot impatiently while waiting in line.\n", + "\u001b[32mTommie meets several potential employers at the job fair but doesn't receive any offers.\u001b[0m Tommie Tommie feels disappointed but tries to stay positive and continues to search for job openings.\n", + "\u001b[32mTommie leaves the job fair feeling disappointed.\u001b[0m Tommie Tommie feels discouraged but tries to stay optimistic and continues to search for job openings.\n", + "\u001b[32mTommie stops by a local diner to grab some lunch.\u001b[0m Tommie Tommie feels relieved to take a break and enjoy some food.\n", + "\u001b[32mThe service is slow, and Tommie has to wait for 30 minutes to get his food.\u001b[0m Tommie Tommie taps his foot impatiently while waiting for his food.\n", + "\u001b[32mTommie overhears a conversation at the next table about a job opening.\u001b[0m Tommie said \"Excuse me, I couldn't help but overhear about the job opening. Can you tell me more about it?\"\n", + "\u001b[32mTommie asks the diners about the job opening and gets some information about the company.\u001b[0m Tommie said \"Can you tell me more about it?\"\n", + "\u001b[32mTommie decides to apply for the job and sends his resume and cover letter.\u001b[0m Tommie said \"Thank you for the information. I will definitely apply for the job.\"\n", + "\u001b[32mTommie continues his search for job openings and drops off his resume at several local businesses.\u001b[0m Tommie Tommie feels hopeful about the job search and continues to actively search for opportunities.\n", + "\u001b[32mTommie takes a break from his job search to go for a walk in a nearby park.\u001b[0m Tommie Tommie takes a deep breath and enjoys the fresh air.\n", + "\u001b[32mA dog approaches and licks Tommie's feet, and he pets it for a few minutes.\u001b[0m Tommie Tommie smiles and pets the dog for a few minutes before continuing his walk.\n", "****************************************\n", "\u001b[34mAfter 20 observations, Tommie's summary is:\n", "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is currently unemployed and actively searching for a job, which is a significant source of stress for him impacting his overall well-being. His job search is emotionally challenging, causing him to experience a range of feelings such as anxiety, frustration, disappointment, and relief. However, despite facing challenges and setbacks, Tommie remains determined and resilient in his job search. He takes proactive steps to find employment, such as attending job fairs and updating his resume. Tommie is interested in design and finds it helpful in taking his mind off things, providing him with a sense of purpose and motivation during his job search. He feels a sense of accomplishment and determination after dropping off his resume at several local businesses and feels hopeful and relieved after applying for a job.\u001b[0m\n", + "Tommie is a determined and optimistic individual who is actively searching for job opportunities in the city. He feels excited and hopeful when he finds potential job openings, but also experiences disappointment and discouragement when his efforts do not yield immediate results. He tries to stay positive and continues to actively search for opportunities, while also taking breaks and enjoying simple pleasures like walking in the park and interacting with dogs. Tommie is interested in graphic design and values productive activities that contribute to his job search.\u001b[0m\n", "****************************************\n", - "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m There is no mention of Tommie seeing a group of people playing frisbee in the given context, so no reaction is necessary.\n", - "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie winces in pain and touches his nose to check for any damage.\n", - "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie takes a deep breath and rests for a bit.\n", - "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie cleans up the garbage and disposes of it properly.\n", - "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie sighs and takes a moment to collect himself before continuing his job search.\n", - "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m \"Hey, can we talk? I'm feeling really frustrated with my job search and could use someone to vent to.\"\n", - "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m \"Thanks for the encouragement, it means a lot.\"\n", - "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m \"Thanks for being there for me, it really helps to talk to someone about my job search.\"\n", - "\u001b[32mTommie decides to go for a jog to clear his mind.\u001b[0m Tommie takes a deep breath and starts jogging to clear his mind.\n", - "\u001b[32mTommie jogs through the city and sees some interesting sights.\u001b[0m Tommie enjoys the sights while jogging through the city.\n", - "\u001b[32mTommie stops to take a picture of a street mural.\u001b[0m Tommie smiles and admires the street mural before continuing his jog.\n", - "\u001b[32mTommie runs into an old friend from college who now lives in the city.\u001b[0m \"Hey, it's great to see you! How have you been?\"\n", - "\u001b[32mThey catch up for a few minutes, but Tommie's friend has to leave to attend a meeting.\u001b[0m \"It was great seeing you, let's catch up again soon!\"\n", - "\u001b[32mTommie thanks his friend and feels hopeful again.\u001b[0m \"Thanks for catching up with me, it was great seeing you again!\"\n", - "\u001b[32mTommie heads back to his apartment to rest and prepare for his upcoming interviews.\u001b[0m \"I should review my notes and prepare for my upcoming interviews.\"\n", - "\u001b[32mTommie spends the evening rehearsing his interview pitch.\u001b[0m Tommie feels focused and determined while rehearsing his interview pitch.\n" + "\u001b[32mTommie sees a group of people playing frisbee and decides to join in.\u001b[0m Tommie Tommie watches the group play for a few minutes but decides not to join in and continues his walk.\n", + "\u001b[32mTommie has fun playing frisbee but gets hit in the face with the frisbee and hurts his nose.\u001b[0m Tommie Tommie touches his nose and winces in pain.\n", + "\u001b[32mTommie goes back to his apartment to rest for a bit.\u001b[0m Tommie Tommie sits down on his couch and takes a deep breath to rest his sore nose.\n", + "\u001b[32mA raccoon tore open the trash bag outside his apartment, and the garbage is all over the floor.\u001b[0m Tommie Tommie sighs and grabs some gloves and a trash bag to clean up the mess.\n", + "\u001b[32mTommie starts to feel frustrated with his job search.\u001b[0m Tommie Tommie takes a deep breath and tries to stay positive, reminding himself that the right opportunity will come along eventually.\n", + "\u001b[32mTommie calls his best friend to vent about his struggles.\u001b[0m Tommie said \"Hey, can we talk? I'm feeling frustrated with my job search and could use someone to vent to.\"\n", + "\u001b[32mTommie's friend offers some words of encouragement and tells him to keep trying.\u001b[0m Tommie said \"Thanks for the encouragement, it means a lot to me.\"\n", + "\u001b[32mTommie feels slightly better after talking to his friend.\u001b[0m Tommie said \"Thank you for being there for me, it really helps to have your support.\"\n" ] } ], @@ -769,7 +758,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "id": "6336ab5d-3074-4831-951f-c9e2cba5dfb5", "metadata": { "tags": [] @@ -778,10 +767,10 @@ { "data": { "text/plain": [ - "'\"Well, it\\'s been a bit of a rollercoaster, to be honest. I\\'m still looking for a job, which is pretty stressful, but I\\'ve been trying to stay positive and keep myself busy. I took a walk in the park earlier and even played some frisbee with a group of people. It was fun, but I did get hit in the face with the frisbee and hurt my nose a bit. Overall, though, I\\'m feeling more hopeful now that I\\'ve been rehearsing my interview pitch for upcoming interviews.\"'" + "'Tommie said \"It\\'s been a bit of a mixed day. I went to a job fair and met some potential employers, but didn\\'t receive any offers. I also applied for a job that I heard about at a diner, so I\\'m hoping that turns into something. But overall, it\\'s been a bit frustrating. How about you?\"'" ] }, - "execution_count": 18, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -792,7 +781,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "809ac906-69b7-4326-99ec-af638d32bb20", "metadata": { "tags": [] @@ -801,10 +790,10 @@ { "data": { "text/plain": [ - "'\"I don\\'t really have strong feelings about coffee, to be honest. I prefer tea myself. How about you?\"'" + "'Tommie said \"I enjoy drinking coffee, but I recently bought a bitter brand and regretted it. I\\'ve been trying to improve the taste by adding sugar, but I also need to remember to buy coffee filters.\"'" ] }, - "execution_count": 19, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -815,26 +804,19 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 18, "id": "f733a431-19ea-421a-9101-ae2593a8c626", "metadata": { "tags": [] }, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[34mCharacter Tommie is reflecting\u001b[0m\n" - ] - }, { "data": { "text/plain": [ - "'\"Oh, I actually had a dog when I was a kid named Bruno. He was a big golden retriever and always made me feel better when I was feeling down. But unfortunately, he passed away a few years ago. Thanks for asking though.\"'" + "'Tommie said \"Oh, I had a dog named Bruno when I was a kid. He was a loyal and loving companion. I haven\\'t had a pet since then, but I hope to adopt one in the future.\"'" ] }, - "execution_count": 21, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -855,7 +837,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 19, "id": "ec8bbe18-a021-419c-bf1f-23d34732cd99", "metadata": { "tags": [] @@ -877,7 +859,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 20, "id": "1e2745f5-e0da-4abd-98b4-830802ce6698", "metadata": { "tags": [] @@ -900,7 +882,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 21, "id": "de4726e3-4bb1-47da-8fd9-f317a036fe0f", "metadata": { "tags": [] @@ -912,7 +894,7 @@ "text": [ "Name: Eve (age: 34)\n", "Innate traits: curious, helpful\n", - "Eve is helpful, social, observant, and has a typical daily routine.\n" + "Eve is helpful towards her coworkers, enjoys playing tennis with friends, eats breakfast, is attentive to conversations around her, and is punctual in waking up for work.\n" ] } ], @@ -933,7 +915,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 22, "id": "6cda916d-800c-47bc-a7f9-6a2f19187472", "metadata": { "tags": [] @@ -942,10 +924,10 @@ { "data": { "text/plain": [ - "'\"I\\'m feeling pretty good, thanks for asking. How about you?\"'" + "'Eve said \"I\\'m feeling pretty good, thanks for asking! How about you?\"'" ] }, - "execution_count": 25, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -956,7 +938,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 23, "id": "448ae644-0a66-4eb2-a03a-319f36948b37", "metadata": { "tags": [] @@ -965,10 +947,10 @@ { "data": { "text/plain": [ - "'\"I actually overheard someone say that Tommie is hard to work with earlier, but I don\\'t know much else about him. Have you worked with him before?\"'" + "'Eve said \"I overheard someone say that Tommie is hard to work with, but I don\\'t really know much beyond that. Have you worked with Tommie before?\"'" ] }, - "execution_count": 26, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -979,7 +961,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 24, "id": "493fc5b8-8730-4ef8-9820-0f1769ce1691", "metadata": { "tags": [] @@ -988,10 +970,10 @@ { "data": { "text/plain": [ - "'\"That\\'s great to hear! What kind of job is Tommie looking for? Maybe I can help in some way.\"'" + "'Eve said \"That\\'s interesting, what kind of job is Tommie looking for?\"'" ] }, - "execution_count": 27, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1002,7 +984,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 25, "id": "4b46452a-6c54-4db2-9d87-18597f70fec8", "metadata": { "tags": [] @@ -1011,10 +993,10 @@ { "data": { "text/plain": [ - "'\"Sure, I\\'d be happy to help Tommie out. Can you give me his contact information so I can reach out to him?\"'" + "'Eve said \"Sure thing, I\\'ll do my best to make him feel comfortable and ask him some questions about his job search. Thanks for the heads up.\"'" ] }, - "execution_count": 28, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1035,7 +1017,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 26, "id": "042ea271-4bf1-4247-9082-239a6fea43b8", "metadata": { "tags": [] @@ -1045,14 +1027,14 @@ "def run_conversation(agents: List[GenerativeAgent], initial_observation: str, max_turns:int = 25) -> None:\n", " \"\"\"Runs a conversation between agents.\"\"\"\n", " _, observation = agents[1].generate_reaction(initial_observation)\n", - " print(f\"{agents[1].name}: {observation}\")\n", + " print(observation)\n", " turns = 0\n", " while True:\n", " break_dialogue = False\n", " for agent in agents:\n", - " stay_in_dialogue, reaction = agent.generate_dialogue_response(observation)\n", - " print(f\"{agent.name}: {reaction}\")\n", - " observation = f\"{agent.name} said {reaction}\"\n", + " stay_in_dialogue, observation = agent.generate_dialogue_response(observation)\n", + " print(observation)\n", + " # observation = f\"{agent.name} said {reaction}\"\n", " if not stay_in_dialogue:\n", " break_dialogue = True \n", " if break_dialogue:\n", @@ -1062,7 +1044,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 27, "id": "d5462b14-218e-4d85-b035-df57ea8e0f80", "metadata": { "tags": [] @@ -1072,21 +1054,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "Eve: \"Sure, I'd be happy to share my story and offer any advice I can.\"\n", - "Tommie: \"Thank you so much, I really appreciate it. It's been tough trying to navigate the job market, but I'm trying to stay positive and keep pushing forward. Do you have any tips for staying motivated during a job search?\"\n", - "Eve: \"Of course, Tommie. It can definitely be tough, but I'm glad I can offer some help. One tip I have is to make sure you take breaks and take care of yourself during the job search process. It can be easy to get burnt out or discouraged, but remember to prioritize your mental health as well. Do you have any specific industries or job types you're interested in?\"\n", - "Tommie: \"Thank you, Eve. That's really good advice. I'm actually interested in design and have been looking for opportunities in that field. Do you have any suggestions for finding job openings in that industry?\"\n", - "Eve: \"Absolutely, Tommie! I have some connections in the design industry and can definitely keep an eye out for any job openings that may be a good fit for you. Have you tried networking through LinkedIn or attending any design events in the area? Those can be great ways to meet people in the industry and potentially find job opportunities. And if you ever need any help with your resume or portfolio, I'd be happy to take a look and give you some feedback.\"\n", - "Tommie: \"Thank you so much, Eve! I really appreciate your willingness to help and your suggestions. I haven't tried networking through LinkedIn or attending any design events yet, but I will definitely look into those options. And I would love any feedback you can provide on my resume or portfolio. Thank you again for your support and advice!\"\n", - "Eve: \"No problem, Tommie! I'm happy to help in any way I can. Just let me know if you need anything else or if you come across any job openings that you're interested in. Best of luck with your job search!\"\n", - "Tommie: \"Thank you so much, Eve. I really appreciate your help and support. I will definitely keep you updated on my job search and let you know if I come across any job openings that interest me. Thanks again and have a great day!\"\n", - "Eve: \"You're welcome, Tommie! I look forward to hearing about your progress and any updates on your job search. Have a great day!\"\n" + "Eve said \"Of course, I'd be happy to share my experience with you. I started in the industry after completing my degree in business management. How about you, what inspired you to pursue this field?\"\n", + "Tommie said \"I've always been interested in design and the creative process. It's something that I've enjoyed doing since I was a kid, so I decided to pursue it in college. I'm still trying to find my footing in the industry, but it's been a challenging and rewarding experience so far.\"\n", + "Eve said \"That's great to hear that you've been pursuing your passion. It can definitely be challenging, but it sounds like you're on the right track. Have you had any particular projects or experiences that have stood out to you so far?\"\n", + "Tommie said \"Thank you, Eve. I've had some interesting projects, like designing a logo for a local business and creating graphics for a social media campaign. It's been a great learning experience so far.\"\n", + "Eve said \"Those sound like great experiences, Tommie. Have you been able to apply any of those skills to your current work? I'd love to hear more about what you're currently working on.\"\n", + "Tommie said \"Yes, I've been updating my resume and cover letter to showcase my design skills. Right now, I'm actively searching for job opportunities in the design industry. It's been a bit challenging, but I'm hopeful that something will come along soon.\"\n", + "Eve said \"That's great to hear that you're actively searching for job opportunities, Tommie. Have you considered any specific companies or positions that you're interested in? I might be able to offer some advice or suggestions.\"\n", + "Tommie said \"Thank you for your offer, Eve. I've been exploring different companies and positions in the design industry, but I'm open to any suggestions or advice you may have.\"\n", + "Eve said \"Well, it was great chatting with you, Tommie. Best of luck with your job search and feel free to reach out if you ever need any advice or support.\"\n" ] } ], "source": [ "agents = [tommie, eve]\n", - "run_conversation(agents, \"Hi, Eve. Thanks for agreeing to share your story with me and give me advice. Maybe we can start with how you got into the industry.\")" + "run_conversation(agents, \"Tommie said: Hi, Eve. Thanks for agreeing to share your story with me and give me advice. Maybe we can start with how you got into the industry.\")" ] }, { @@ -1103,7 +1085,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 28, "id": "c4d252f3-fcc1-474c-846e-a7605a6b4ce7", "metadata": { "tags": [] @@ -1115,7 +1097,7 @@ "text": [ "Name: Tommie (age: 25)\n", "Innate traits: anxious, likes design\n", - "Tommie is currently unemployed and actively searching for a job, which is causing him significant stress and impacting his overall well-being. He experiences a range of emotions throughout the day, such as anxiety, frustration, disappointment, and relief. However, he remains determined and resilient in his search, taking actions such as attending job fairs and updating his resume. Tommie seeks support from his friends and finds ways to take his mind off things. His interests in design provide him with a potential career path and a sense of purpose and motivation during his job search.\n" + "Tommie is a determined and optimistic individual who is actively searching for job opportunities. He feels excited about exploring new places and meeting potential employers but also experiences disappointment and frustration when things don't go as planned. He seeks support from his friends and tries to stay positive even in challenging situations. Tommie has a passion for graphic design and finds fulfillment in creating visually appealing designs that convey a message.\n" ] } ], @@ -1126,7 +1108,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 29, "id": "c04db9a4", "metadata": {}, "outputs": [ @@ -1136,7 +1118,7 @@ "text": [ "Name: Eve (age: 34)\n", "Innate traits: curious, helpful\n", - "Eve is a helpful and supportive coworker who offers advice and assistance to others. She is knowledgeable about the job market and offers tips for staying motivated during a job search. She is also proactive in helping others find job opportunities and is willing to network on their behalf. She is attentive to her colleagues' needs and is willing to offer support and conversation. In her personal life, she enjoys playing tennis and eating porridge for breakfast.\n" + "Eve is a helpful and friendly coworker who is attentive to her colleagues' needs and interests. She enjoys playing tennis and eating breakfast before work, and is always willing to engage in conversation and provide support to those around her. She is also curious and interested in learning about others' experiences and providing advice and suggestions when possible.\n" ] } ], @@ -1147,7 +1129,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 30, "id": "71762558-8fb6-44d7-8483-f5b47fb2a862", "metadata": { "tags": [] @@ -1156,10 +1138,10 @@ { "data": { "text/plain": [ - "'\"It was really helpful, actually. She had some great advice for staying motivated during a job search and even offered to keep an eye out for any job openings in the design industry. I\\'m feeling more optimistic now. Thanks for asking!\"'" + "'Tommie said \"It was really helpful actually. Eve offered some great advice and suggestions for my job search. I\\'m feeling more optimistic about finding the right opportunity now.\"'" ] }, - "execution_count": 33, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1170,7 +1152,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 31, "id": "085af3d8-ac21-41ea-8f8b-055c56976a67", "metadata": { "tags": [] @@ -1179,10 +1161,10 @@ { "data": { "text/plain": [ - "'\"It was great! Tommie is really motivated and has a lot of great experience in the design industry. I offered to keep an eye out for any job openings that may be a good fit for him, and I also suggested networking through LinkedIn and attending design events. I\\'m excited to see where his job search takes him!\"'" + "'Eve said \"It was really nice chatting with Tommie. He\\'s a talented designer and seems really passionate about his work. I offered some advice and suggestions for his job search, so hopefully that helps him out. How about you, Person A? How\\'s your day going?\"'" ] }, - "execution_count": 35, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1193,7 +1175,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 32, "id": "5b439f3c-7849-4432-a697-2bcc85b89dae", "metadata": { "tags": [] @@ -1202,10 +1184,10 @@ { "data": { "text/plain": [ - "'\"I feel like we covered a lot of ground during our conversation, but if there was one thing I could have emphasized more, it would be to stay positive and persistent. Job searching can be tough, but it\\'s important to remember that the right opportunity is out there and to keep pushing forward. Is there anything else you\\'d like to know or discuss, Person A?\"'" + "'Eve said \"It sounds like you have a good grasp on what you\\'re looking for, Tommie. Keep up the great work and don\\'t hesitate to reach out if you need any more advice or support. Have a great day!\"'" ] }, - "execution_count": 36, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1216,11 +1198,26 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "52eb7532-e38f-4278-8dc4-5b95df6c8a17", - "metadata": {}, - "outputs": [], - "source": [] + "execution_count": 40, + "id": "526e8863-8b32-4216-8e61-2dfe82e3fb47", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Tommie said \"Oh, I bought a bitter brand and regretted it. I need to remember to buy filters next time. But overall, it\\'s been okay. How about you?\"'" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interview_agent(tommie, \"What happened with your coffee this morning?\")" + ] } ], "metadata": { diff --git a/langchain/retrievers/time_weighted_retriever.py b/langchain/retrievers/time_weighted_retriever.py index 2e7975aa481..be49d48bbdc 100644 --- a/langchain/retrievers/time_weighted_retriever.py +++ b/langchain/retrievers/time_weighted_retriever.py @@ -83,10 +83,6 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): def get_relevant_documents(self, query: str) -> List[Document]: """Return documents that are relevant to the query.""" - if query.startswith("FOOBAR"): - import pdb - - pdb.set_trace() current_time = datetime.now() docs_and_scores = { doc.metadata["buffer_idx"]: (doc, self.default_salience) diff --git a/tests/unit_tests/retrievers/test_time_weighted_retriever.py b/tests/unit_tests/retrievers/test_time_weighted_retriever.py index f7b397a7fe4..840528c2ffc 100644 --- a/tests/unit_tests/retrievers/test_time_weighted_retriever.py +++ b/tests/unit_tests/retrievers/test_time_weighted_retriever.py @@ -1,19 +1,33 @@ """Tests for the time-weighted retriever class.""" -from typing import Any, Iterable, List, Optional, Type +from datetime import datetime +from typing import Any, Iterable, List, Optional, Tuple, Type import pytest -from pydantic import ValidationError from langchain.embeddings.base import Embeddings from langchain.retrievers.time_weighted_retriever import ( TimeWeightedVectorStoreRetriever, + _get_hours_passed, ) from langchain.schema import Document from langchain.vectorstores.base import VectorStore -class MockInvalidVectorStore(VectorStore): +def _get_example_memories(k: int = 4) -> List[Document]: + return [ + Document( + page_content="foo", + metadata={ + "buffer_idx": i, + "last_accessed_at": datetime(2023, 4, 14, 12, 0), + }, + ) + for i in range(k) + ] + + +class MockVectorStore(VectorStore): """Mock invalid vector store.""" def add_texts( @@ -32,7 +46,7 @@ class MockInvalidVectorStore(VectorStore): Returns: List of ids from adding the texts into the vectorstore. """ - return [] + return list(texts) async def aadd_texts( self, @@ -51,11 +65,11 @@ class MockInvalidVectorStore(VectorStore): @classmethod def from_documents( - cls: Type["MockInvalidVectorStore"], + cls: Type["MockVectorStore"], documents: List[Document], embedding: Embeddings, **kwargs: Any, - ) -> "MockInvalidVectorStore": + ) -> "MockVectorStore": """Return VectorStore initialized from documents and embeddings.""" texts = [d.page_content for d in documents] metadatas = [d.metadata for d in documents] @@ -63,20 +77,87 @@ class MockInvalidVectorStore(VectorStore): @classmethod def from_texts( - cls: Type["MockInvalidVectorStore"], + cls: Type["MockVectorStore"], texts: List[str], embedding: Embeddings, metadatas: Optional[List[dict]] = None, **kwargs: Any, - ) -> "MockInvalidVectorStore": + ) -> "MockVectorStore": """Return VectorStore initialized from texts and embeddings.""" return cls() + def _similarity_search_with_normalized_similarities( + self, + query: str, + k: int = 4, + **kwargs: Any, + ) -> List[Tuple[Document, float]]: + """Return docs and similarity scores, normalized on a scale from 0 to 1. -def test_time_weighted_retriever_on_invalid_vector_store() -> None: - vectorstore = MockInvalidVectorStore() - with pytest.raises( - ValidationError, - match="Required method 'similarity_search_with_score not implemented", - ): - TimeWeightedVectorStoreRetriever(vectorstore=vectorstore) + 0 is dissimilar, 1 is most similar. + """ + return [(doc, 0.5) for doc in _get_example_memories()] + + +@pytest.fixture +def time_weighted_retriever() -> TimeWeightedVectorStoreRetriever: + vectorstore = MockVectorStore() + return TimeWeightedVectorStoreRetriever( + vectorstore=vectorstore, memory_stream=_get_example_memories() + ) + + +def test__get_hours_passed() -> None: + time1 = datetime(2023, 4, 14, 14, 30) + time2 = datetime(2023, 4, 14, 12, 0) + expected_hours_passed = 150 + hours_passed = _get_hours_passed(time1, time2) + assert hours_passed == expected_hours_passed + + +def test_get_combined_score( + time_weighted_retriever: TimeWeightedVectorStoreRetriever, +) -> None: + document = Document( + page_content="Test document", + metadata={"last_accessed_at": datetime(2023, 4, 14, 12, 0)}, + ) + vector_salience = 0.7 + expected_hours_passed = 150 + current_time = datetime(2023, 4, 14, 14, 30) + combined_score = time_weighted_retriever._get_combined_score( + document, vector_salience, current_time + ) + expected_score = ( + time_weighted_retriever.decay_factor**expected_hours_passed + vector_salience + ) + assert combined_score == pytest.approx(expected_score) + + +def test_get_salient_docs( + time_weighted_retriever: TimeWeightedVectorStoreRetriever, +) -> None: + query = "Test query" + docs_and_scores = time_weighted_retriever.get_salient_docs(query) + assert isinstance(docs_and_scores, dict) + + +def test_get_relevant_documents( + time_weighted_retriever: TimeWeightedVectorStoreRetriever, +) -> None: + query = "Test query" + relevant_documents = time_weighted_retriever.get_relevant_documents(query) + assert isinstance(relevant_documents, list) + + +def test_add_documents( + time_weighted_retriever: TimeWeightedVectorStoreRetriever, +) -> None: + documents = [Document(page_content="test_add_documents document")] + added_documents = time_weighted_retriever.add_documents(documents) + assert isinstance(added_documents, list) + assert len(added_documents) == 1 + assert ( + time_weighted_retriever.memory_stream[-1].page_content + == documents[0].page_content + ) From a742c2ca3dd008635de18de22a0af47b1b86b49f Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Fri, 14 Apr 2023 16:42:20 -0700 Subject: [PATCH 6/7] Update the twr implementation --- langchain/retrievers/time_weighted_retriever.py | 8 +++++--- .../unit_tests/retrievers/test_time_weighted_retriever.py | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/langchain/retrievers/time_weighted_retriever.py b/langchain/retrievers/time_weighted_retriever.py index be49d48bbdc..32923bef105 100644 --- a/langchain/retrievers/time_weighted_retriever.py +++ b/langchain/retrievers/time_weighted_retriever.py @@ -11,7 +11,7 @@ from langchain.vectorstores.base import VectorStore def _get_hours_passed(time: datetime, ref_time: datetime) -> float: """Get the hours passed between two datetime objects.""" - return (time - ref_time).total_seconds() / 60 + return (time - ref_time).total_seconds() / 3600 class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): @@ -99,8 +99,10 @@ class TimeWeightedVectorStoreRetriever(BaseRetriever, BaseModel): # Ensure frequently accessed memories aren't forgotten current_time = datetime.now() for doc, _ in rescored_docs[: self.k]: - doc.metadata["last_accessed_at"] = current_time - result.append(doc) + # TODO: Update vector store doc once `update` method is exposed. + buffered_doc = self.memory_stream[doc.metadata["buffer_idx"]] + buffered_doc.metadata["last_accessed_at"] = current_time + result.append(buffered_doc) return result async def aget_relevant_documents(self, query: str) -> List[Document]: diff --git a/tests/unit_tests/retrievers/test_time_weighted_retriever.py b/tests/unit_tests/retrievers/test_time_weighted_retriever.py index 840528c2ffc..a99ab9e17fd 100644 --- a/tests/unit_tests/retrievers/test_time_weighted_retriever.py +++ b/tests/unit_tests/retrievers/test_time_weighted_retriever.py @@ -110,7 +110,7 @@ def time_weighted_retriever() -> TimeWeightedVectorStoreRetriever: def test__get_hours_passed() -> None: time1 = datetime(2023, 4, 14, 14, 30) time2 = datetime(2023, 4, 14, 12, 0) - expected_hours_passed = 150 + expected_hours_passed = 2.5 hours_passed = _get_hours_passed(time1, time2) assert hours_passed == expected_hours_passed @@ -123,7 +123,7 @@ def test_get_combined_score( metadata={"last_accessed_at": datetime(2023, 4, 14, 12, 0)}, ) vector_salience = 0.7 - expected_hours_passed = 150 + expected_hours_passed = 2.5 current_time = datetime(2023, 4, 14, 14, 30) combined_score = time_weighted_retriever._get_combined_score( document, vector_salience, current_time From d31d92acdd719cf62bd162cc7fe8435d30ffa7f1 Mon Sep 17 00:00:00 2001 From: vowelparrot <130414180+vowelparrot@users.noreply.github.com> Date: Sat, 15 Apr 2023 08:13:49 -0700 Subject: [PATCH 7/7] Update __from --- langchain/vectorstores/faiss.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/langchain/vectorstores/faiss.py b/langchain/vectorstores/faiss.py index 61d7f8ce109..3d76b377cb6 100644 --- a/langchain/vectorstores/faiss.py +++ b/langchain/vectorstores/faiss.py @@ -316,12 +316,7 @@ class FAISS(VectorStore): docstore = InMemoryDocstore( {index_to_id[i]: doc for i, doc in enumerate(documents)} ) - return cls( - embedding.embed_query, - index, - docstore, - index_to_id, - ) + return cls(embedding.embed_query, index, docstore, index_to_id, **kwargs) @classmethod def from_texts(