1515
1616
1717class RAGSystem :
18+ # Cache file paths
19+ DOC_EMBEDDINGS_PATH = "./data/doc_embeddings.npy"
20+ DOC_ABOUT_EMBEDDINGS_PATH = "./data/doc_about_embeddings.npy"
21+
1822 def __init__ (self , knowledge_base_path = "./data/knowledge_base.json" ):
1923 self .knowledge_base_path = knowledge_base_path
2024
@@ -24,13 +28,22 @@ def __init__(self, knowledge_base_path="./data/knowledge_base.json"):
2428 # load existing embeddings if available
2529 logging .info ("Embedding knowledge base..." )
2630
27- if os .path .exists ("./data/doc_about_embeddings.npy" ) and os .path .exists (
28- "./data/doc_embeddings.npy"
31+ if os .path .exists (self . DOC_ABOUT_EMBEDDINGS_PATH ) and os .path .exists (
32+ self . DOC_EMBEDDINGS_PATH
2933 ):
30- self .doc_about_embeddings = np .load ("./data/doc_about_embeddings.npy" )
34+ self .doc_about_embeddings = np .load (self . DOC_ABOUT_EMBEDDINGS_PATH )
3135 logging .info ("Loaded existing about document about embeddings from disk." )
32- self .doc_embeddings = np .load ("./data/doc_embeddings.npy" )
36+ self .doc_embeddings = np .load (self . DOC_EMBEDDINGS_PATH )
3337 logging .info ("Loaded existing document embeddings from disk." )
38+
39+ # Save file timestamps when loading cache
40+ self .doc_embeddings_timestamp = os .path .getmtime (self .DOC_EMBEDDINGS_PATH )
41+ self .doc_about_embeddings_timestamp = os .path .getmtime (
42+ self .DOC_ABOUT_EMBEDDINGS_PATH
43+ )
44+ logging .info (
45+ f"Cache loaded - doc_embeddings timestamp: { self .doc_embeddings_timestamp } , doc_about_embeddings timestamp: { self .doc_about_embeddings_timestamp } "
46+ )
3447 else :
3548 self .rebuild_embeddings ()
3649
@@ -49,16 +62,22 @@ def rebuild_embeddings(self):
4962
5063 # Atomic saves with guaranteed order
5164 self ._atomic_save_numpy (
52- "./data/doc_embeddings.npy" , new_doc_embeddings .cpu ().numpy ()
65+ self . DOC_EMBEDDINGS_PATH , new_doc_embeddings .cpu ().numpy ()
5366 )
5467 self ._atomic_save_numpy (
55- "./data/doc_about_embeddings.npy" , new_about_embeddings .cpu ().numpy ()
68+ self . DOC_ABOUT_EMBEDDINGS_PATH , new_about_embeddings .cpu ().numpy ()
5669 )
5770
5871 # Update in-memory embeddings only after successful saves
5972 self .doc_embeddings = new_doc_embeddings
6073 self .doc_about_embeddings = new_about_embeddings
6174
75+ # Update file timestamps after successful saves
76+ self .doc_embeddings_timestamp = os .path .getmtime (self .DOC_EMBEDDINGS_PATH )
77+ self .doc_about_embeddings_timestamp = os .path .getmtime (
78+ self .DOC_ABOUT_EMBEDDINGS_PATH
79+ )
80+
6281 logging .info ("Embeddings rebuilt successfully." )
6382
6483 def load_knowledge_base (self ):
@@ -117,6 +136,43 @@ def compute_document_scores(
117136
118137 return result
119138
139+ def cache_check (func ):
140+ """Decorator to automatically check cache consistency"""
141+
142+ def wrapper (self , * args , ** kwargs ):
143+ try :
144+ current_times = [
145+ os .path .getmtime (self .DOC_EMBEDDINGS_PATH ),
146+ os .path .getmtime (self .DOC_ABOUT_EMBEDDINGS_PATH ),
147+ ]
148+ stored_times = [
149+ self .doc_embeddings_timestamp ,
150+ self .doc_about_embeddings_timestamp ,
151+ ]
152+
153+ # update cache if timestamps are different from out last load
154+ if current_times != stored_times :
155+ self ._reload_cache ()
156+
157+ except (OSError , FileNotFoundError , PermissionError ):
158+ logging .warning ("Cache files inaccessible, rebuilding..." )
159+ self .rebuild_embeddings ()
160+
161+ return func (self , * args , ** kwargs )
162+
163+ return wrapper
164+
165+ def _reload_cache (self ):
166+ self .doc_embeddings = np .load (self .DOC_EMBEDDINGS_PATH )
167+ self .doc_about_embeddings = np .load (self .DOC_ABOUT_EMBEDDINGS_PATH )
168+
169+ # update our timestamps of the cached files
170+ self .doc_embeddings_timestamp = os .path .getmtime (self .DOC_EMBEDDINGS_PATH )
171+ self .doc_about_embeddings_timestamp = os .path .getmtime (
172+ self .DOC_ABOUT_EMBEDDINGS_PATH
173+ )
174+
175+ @cache_check
120176 def retrieve (
121177 self , query , similarity_threshold = 0.4 , high_match_threshold = 0.8 , max_docs = 5
122178 ):
0 commit comments