Time-Weighted Rerankï
Showcase capabilities of time-weighted node postprocessor
from llama_index import GPTVectorStoreIndex, SimpleDirectoryReader, ServiceContext
from llama_index.indices.postprocessor import (
TimeWeightedPostprocessor,
)
from llama_index.node_parser import SimpleNodeParser
from llama_index.storage.docstore import SimpleDocumentStore
from llama_index.response.notebook_utils import display_response
from datetime import datetime, timedelta
Parse Documents into Nodes, add to Docstoreï
In this example, there are 3 different versions of PGâs essay. They are largely identical except for one specific section, which details the amount of funding they raised for Viaweb.
V1: 50k, V2: 30k, V3: 10K
V1: -1 day, V2: -2 days, V3: -3 days
The idea is to encourage index to fetch the most recent info (which is V3)
# load documents
from llama_index.storage.storage_context import StorageContext
now = datetime.now()
key = "__last_accessed__"
doc1 = SimpleDirectoryReader(
input_files=['../node_postprocessor/test_versioned_data/paul_graham_essay_v1.txt']
).load_data()[0]
doc2 = SimpleDirectoryReader(
input_files=['../node_postprocessor/test_versioned_data/paul_graham_essay_v2.txt']
).load_data()[0]
doc3 = SimpleDirectoryReader(
input_files=['../node_postprocessor/test_versioned_data/paul_graham_essay_v3.txt']
).load_data()[0]
# define service context (wrapper container around current classes)
service_context = ServiceContext.from_defaults(chunk_size_limit=512)
node_parser = service_context.node_parser
# use node parser in service context to parse docs into nodes
nodes1 = node_parser.get_nodes_from_documents([doc1])
nodes2 = node_parser.get_nodes_from_documents([doc2])
nodes3 = node_parser.get_nodes_from_documents([doc3])
# fetch the modified chunk from each document, set node info
nodes1[22].node_info[key] = (now - timedelta(hours=3)).timestamp()
nodes2[22].node_info[key] = (now - timedelta(hours=2)).timestamp()
nodes3[22].node_info[key] = (now - timedelta(hours=1)).timestamp()
# add to docstore
docstore = SimpleDocumentStore()
nodes = [nodes1[22], nodes2[22], nodes3[22]]
docstore.add_documents(nodes)
storage_context = StorageContext.from_defaults(docstore=docstore)
Build Indexï
# build index
index = GPTVectorStoreIndex(nodes, storage_context=storage_context)
INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens
INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 1383 tokens
Define Recency Postprocessorsï
node_postprocessor = TimeWeightedPostprocessor(time_decay=0.5, time_access_refresh=False, top_k=1)
Query Indexï
# naive query
query_engine = index.as_query_engine(
similarity_top_k=3,
)
response = query_engine.query(
"How much did the author raise in seed funding from Idelle's husband (Julian) for Viaweb?",
)
INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 1660 tokens
INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens
display_response(response)
# query using time weighted node postprocessor
query_engine = index.as_query_engine(
similarity_top_k=3,
node_postprocessors=[node_postprocessor]
)
response = query_engine.query(
"How much did the author raise in seed funding from Idelle's husband (Julian) for Viaweb?",
)
INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 516 tokens
INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens
Query Index (Lower-Level Usage)ï
In this example we first get the full set of nodes from a query call, and then send to node postprocessor, and then finally synthesize response through a list index.
from llama_index import GPTListIndex
query_str = "How much did the author raise in seed funding from Idelle's husband (Julian) for Viaweb?"
query_engine = index.as_query_engine(
similarity_top_k=3,
response_mode="no_text"
)
init_response = query_engine.query(
query_str,
)
resp_nodes = [n.node for n in init_response.source_nodes]
INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 0 tokens
INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 22 tokens
new_resp_nodes = node_postprocessor.postprocess_nodes(resp_nodes)
list_index = GPTListIndex(new_resp_nodes)
query_engine = list_index.as_query_engine()
response = query_engine.query(query_str)
INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total LLM token usage: 0 tokens
INFO:llama_index.token_counter.token_counter:> [build_index_from_nodes] Total embedding token usage: 0 tokens
INFO:llama_index.token_counter.token_counter:> [query] Total LLM token usage: 516 tokens
INFO:llama_index.token_counter.token_counter:> [query] Total embedding token usage: 0 tokens