跳到主要內容
Open In ColabOpen on GitHub

如何使用時間加權向量儲存檢索器

檢索器結合了語義相似度和時間衰減。

它們的評分演算法是

semantic_similarity + (1.0 - decay_rate) ^ hours_passed

值得注意的是,hours_passed 指的是自檢索器中的物件上次被訪問以來經過的小時數,而不是自其創建以來。這意味著經常訪問的物件保持「新鮮」。

from datetime import datetime, timedelta

import faiss
from langchain.retrievers import TimeWeightedVectorStoreRetriever
from langchain_community.docstore import InMemoryDocstore
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings

低衰減率

decay rate(在此,為了極端,我們將其設定為接近 0)意味著記憶將被「記住」更長時間。 decay rate 為 0 意味著記憶永遠不會被遺忘,使此檢索器等同於向量查找。

# Define your embedding model
embeddings_model = OpenAIEmbeddings()
# Initialize the vectorstore as empty
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model, index, InMemoryDocstore({}), {})
retriever = TimeWeightedVectorStoreRetriever(
vectorstore=vectorstore, decay_rate=0.0000000000000000000000001, k=1
)
yesterday = datetime.now() - timedelta(days=1)
retriever.add_documents(
[Document(page_content="hello world", metadata={"last_accessed_at": yesterday})]
)
retriever.add_documents([Document(page_content="hello foo")])
['73679bc9-d425-49c2-9d74-de6356c73489']
# "Hello World" is returned first because it is most salient, and the decay rate is close to 0., meaning it's still recent enough
retriever.invoke("hello world")
[Document(metadata={'last_accessed_at': datetime.datetime(2024, 10, 22, 16, 37, 40, 818583), 'created_at': datetime.datetime(2024, 10, 22, 16, 37, 37, 975074), 'buffer_idx': 0}, page_content='hello world')]

高衰減率

使用高 decay rate(例如,幾個 9),recency score 很快變為 0! 如果您將其一直設定為 1,則所有物件的 recency 均為 0,再次使此檢索器等同於向量查找。

# Define your embedding model
embeddings_model = OpenAIEmbeddings()
# Initialize the vectorstore as empty
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model, index, InMemoryDocstore({}), {})
retriever = TimeWeightedVectorStoreRetriever(
vectorstore=vectorstore, decay_rate=0.999, k=1
)
yesterday = datetime.now() - timedelta(days=1)
retriever.add_documents(
[Document(page_content="hello world", metadata={"last_accessed_at": yesterday})]
)
retriever.add_documents([Document(page_content="hello foo")])
['379631f0-42c2-4773-8cc2-d36201e1e610']
# "Hello Foo" is returned first because "hello world" is mostly forgotten
retriever.invoke("hello world")
[Document(metadata={'last_accessed_at': datetime.datetime(2024, 10, 22, 16, 37, 46, 553633), 'created_at': datetime.datetime(2024, 10, 22, 16, 37, 43, 927429), 'buffer_idx': 1}, page_content='hello foo')]

虛擬時間

使用 LangChain 中的一些實用程式,您可以模擬時間組件。

from langchain_core.utils import mock_now
API 參考:mock_now
# Notice the last access time is that date time

tomorrow = datetime.now() + timedelta(days=1)

with mock_now(tomorrow):
print(retriever.invoke("hello world"))
[Document(metadata={'last_accessed_at': MockDateTime(2024, 10, 23, 16, 38, 19, 66711), 'created_at': datetime.datetime(2024, 10, 22, 16, 37, 43, 599877), 'buffer_idx': 0}, page_content='hello world')]

此頁面是否對您有幫助?