Aidahaouas commited on
Commit
68c9fc6
·
1 Parent(s): a1b635b

Architecture B Updated

Browse files
.env ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ MISTRAL_API_KEY ="EZ71WTJ4KzfANWluyosmRvIvmhjOjTDt"
2
+
3
+ LANGSMITH_TRACING=true
4
+ LANGSMITH_ENDPOINT="https://api.smith.langchain.com"
5
+ LANGSMITH_API_KEY="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"
6
+ LANGSMITH_PROJECT="rag_architecture"
7
+ #OPENAI_API_KEY="<your-openai-api-key>"
8
+
9
+ PINECONE_API_KEY="pcsk_4cofG5_Uk93QCMSKiPvf7btHrPtuhvK71HmcSwfp5g3hHMZTWfapyjs8tvDCYcQteB51Z"
__pycache__/config.cpython-310.pyc ADDED
Binary file (2.01 kB). View file
 
__pycache__/graph_agentA.cpython-310.pyc ADDED
Binary file (2.08 kB). View file
 
__pycache__/graph_agentB.cpython-310.pyc ADDED
Binary file (2.43 kB). View file
 
__pycache__/initIndex.cpython-310.pyc ADDED
Binary file (1.07 kB). View file
 
__pycache__/pdf_processing.cpython-310.pyc ADDED
Binary file (1.14 kB). View file
 
__pycache__/pinecone_utilsA.cpython-310.pyc ADDED
Binary file (2.65 kB). View file
 
__pycache__/pinecone_utilsB.cpython-310.pyc ADDED
Binary file (5.61 kB). View file
 
app.py CHANGED
@@ -103,9 +103,9 @@ def main():
103
  use_architecture_B = st.checkbox("Utiliser l'architecture B (avancée)")
104
 
105
  # Indexer le PDF (à exécuter une seule fois ou lorsque le PDF change)
106
- pdf_path = get_existing_pdf()
107
- if pdf_path:
108
- index_pdf(pdf_path, use_architecture_B=use_architecture_B)
109
 
110
  display_sidebar()
111
  display_chat_history()
 
103
  use_architecture_B = st.checkbox("Utiliser l'architecture B (avancée)")
104
 
105
  # Indexer le PDF (à exécuter une seule fois ou lorsque le PDF change)
106
+ #pdf_path = get_existing_pdf()
107
+ #if pdf_path:
108
+ #index_pdf(pdf_path, use_architecture_B=use_architecture_B)
109
 
110
  display_sidebar()
111
  display_chat_history()
initIndex.py CHANGED
@@ -8,7 +8,7 @@ from pinecone_utilsB import *
8
 
9
 
10
  search_engine = HybridSearchEngine()
11
-
12
 
13
  def index_pdf(pdf_path, use_architecture_B=False):
14
  """Indexe un PDF dans Pinecone."""
 
8
 
9
 
10
  search_engine = HybridSearchEngine()
11
+ #pdf_path = get_existing_pdf()
12
 
13
  def index_pdf(pdf_path, use_architecture_B=False):
14
  """Indexe un PDF dans Pinecone."""
pinecone_utilsB.py CHANGED
@@ -11,35 +11,28 @@ import nltk
11
  import zlib
12
  import base64
13
  import json
 
14
  nltk.download('punkt_tab')
15
 
16
-
17
-
18
- if "bm25_corpus" not in st.session_state:
19
- st.session_state.bm25_corpus = []
20
- if "indexing_done" not in st.session_state:
21
- st.session_state.indexing_done = False
22
-
23
- CONFIG_FILE = "indexing_state.json"
24
-
25
- def load_indexing_state():
26
- """Charge l'état d'indexation depuis un fichier."""
27
- if os.path.exists(CONFIG_FILE):
28
- with open(CONFIG_FILE, "r") as f:
29
- return json.load(f)
30
- return {"indexed_files": []}
31
-
32
- def save_indexing_state(state):
33
- """Sauvegarde l'état d'indexation dans un fichier."""
34
- with open(CONFIG_FILE, "w") as f:
35
- json.dump(state, f)
36
-
37
  class HybridSearchEngine:
38
  def __init__(self):
 
39
  self.model = SentenceTransformer("intfloat/multilingual-e5-large")
40
- self.sparse_encoder = BM25Encoder().default()
 
 
41
  self.embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
 
 
 
 
 
 
 
 
42
  self.vectorstore = PineconeVectorStore(index=indexB, embedding=self.embeddings)
 
 
43
  self.retriever = PineconeHybridSearchRetriever(
44
  embeddings=self.embeddings,
45
  sparse_encoder=self.sparse_encoder,
@@ -47,73 +40,110 @@ class HybridSearchEngine:
47
  )
48
 
49
  def is_initialized(self):
50
- """Vérifie si l'index BM25 est bien prêt à être utilisé."""
51
- return bool(st.session_state.bm25_corpus) and st.session_state.indexing_done
52
 
53
- def index_pdf_B(self, texts, pdf_path):
54
- """Indexe les textes en évitant les doublons."""
55
- if not texts:
56
- st.error("La liste des textes ne peut pas être vide.")
57
- return
 
58
 
59
- if st.session_state.indexing_done:
60
- st.write("L'indexation est déjà terminée, pas besoin de la refaire.")
61
- return
 
 
 
 
62
 
63
- indexing_state = load_indexing_state()
64
- if pdf_path in indexing_state["indexed_files"]:
65
- st.write("Ce fichier PDF a déjà été indexé.")
 
 
 
 
 
 
 
66
  return
67
 
 
68
  st.write("Indexation en cours, veuillez patienter...")
69
 
 
70
  existing_texts = self.get_existing_vectors()
71
 
72
- # Entraîner BM25 uniquement si ce n'est pas déjà fait
73
  st.session_state.bm25_corpus = texts
74
  self.sparse_encoder.fit(texts)
75
 
76
  documents = []
77
- for text in texts:
78
  chunks = self.split_text_into_chunks(text, max_chunk_size=1024)
79
- for chunk in chunks:
80
  compressed_chunk = self.compress_text(chunk)
 
 
81
  if compressed_chunk in existing_texts:
82
- continue
83
 
 
84
  doc_id = f"doc_{zlib.crc32(chunk.encode('utf-8'))}"
 
85
  metadata = {"compressed_text": compressed_chunk}
86
- if self.get_metadata_size(metadata) <= 40960:
87
- documents.append(Document(page_content=chunk, metadata=metadata))
88
 
 
 
 
 
 
 
 
 
89
  if documents:
90
- self.vectorstore.add_documents(documents)
91
 
92
- # ✅ Marquer l'indexation comme terminée de manière permanente
93
- indexing_state["indexed_files"].append(pdf_path)
94
- save_indexing_state(indexing_state)
95
  st.session_state.indexing_done = True
96
-
97
  st.success("Indexation terminée sans duplication de contenu.")
98
 
99
  def hybrid_search(self, query):
100
- """Effectue une recherche hybride combinant BM25 et Pinecone."""
101
  if not self.is_initialized():
102
  st.warning("L'index BM25 n'est pas encore prêt. Veuillez patienter pendant l'indexation...")
103
  return []
104
 
105
  try:
 
106
  results = self.retriever.get_relevant_documents(query)
 
 
107
  relevant_docs = []
108
  for result in results:
109
- metadata = result.metadata or {}
 
 
 
 
 
 
 
 
 
110
  compressed_text = metadata.get("compressed_text")
111
  if compressed_text:
112
  relevant_docs.append(self.decompress_text(compressed_text))
 
113
  return relevant_docs
 
 
114
  except Exception as e:
115
  st.error(f"Erreur lors de la recherche hybride : {e}")
116
  return []
 
117
 
118
  def compress_text(self, text):
119
  """Compresse un texte en base64."""
 
11
  import zlib
12
  import base64
13
  import json
14
+ import os
15
  nltk.download('punkt_tab')
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  class HybridSearchEngine:
18
  def __init__(self):
19
+ # Initialisation des modèles et encodeurs
20
  self.model = SentenceTransformer("intfloat/multilingual-e5-large")
21
+ self.sparse_encoder = BM25Encoder().default() # Initialisation de BM25Encoder avec des valeurs par défaut
22
+
23
+ # Créer une instance de HuggingFaceEmbeddings
24
  self.embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")
25
+
26
+ # Utiliser st.session_state pour stocker l'état de l'indexation
27
+ if "bm25_corpus" not in st.session_state:
28
+ st.session_state.bm25_corpus = []
29
+ if "indexing_done" not in st.session_state:
30
+ st.session_state.indexing_done = False # Ajout d'un indicateur d'indexation
31
+
32
+ # Initialisation du PineconeVectorStore
33
  self.vectorstore = PineconeVectorStore(index=indexB, embedding=self.embeddings)
34
+
35
+ # Initialisation du retriever hybride
36
  self.retriever = PineconeHybridSearchRetriever(
37
  embeddings=self.embeddings,
38
  sparse_encoder=self.sparse_encoder,
 
40
  )
41
 
42
  def is_initialized(self):
43
+ """Vérifie si l'index BM25 est initialisé."""
44
+ return bool(st.session_state.bm25_corpus)
45
 
46
+ def tokenize(self, text):
47
+ """Tokenise un texte avec NLTK."""
48
+ return nltk.word_tokenize(text.lower())
49
+ def get_existing_vectors(self):
50
+ """Récupère les textes compressés déjà indexés dans Pinecone."""
51
+ existing_texts = set()
52
 
53
+ try:
54
+ # Effectuer une recherche avec un mot-clé fictif pour récupérer des documents
55
+ results = self.vectorstore.similarity_search("random_query", k=10000) # Ajuster k selon l'index
56
+
57
+ for doc in results:
58
+ if "compressed_text" in doc.metadata:
59
+ existing_texts.add(doc.metadata["compressed_text"]) # Stocker les textes existants
60
 
61
+ except Exception as e:
62
+ st.error(f"Erreur lors de la récupération des vecteurs existants : {e}")
63
+
64
+ return existing_texts
65
+
66
+
67
+ def index_pdf_B(self, texts):
68
+ """Indexe les textes en évitant les doublons (même contenu)."""
69
+ if not texts:
70
+ st.error("La liste des textes ne peut pas être vide.")
71
  return
72
 
73
+ st.session_state.indexing_done = False
74
  st.write("Indexation en cours, veuillez patienter...")
75
 
76
+ # Récupérer les textes déjà indexés dans Pinecone
77
  existing_texts = self.get_existing_vectors()
78
 
79
+ # Initialiser BM25
80
  st.session_state.bm25_corpus = texts
81
  self.sparse_encoder.fit(texts)
82
 
83
  documents = []
84
+ for i, text in enumerate(texts):
85
  chunks = self.split_text_into_chunks(text, max_chunk_size=1024)
86
+ for j, chunk in enumerate(chunks):
87
  compressed_chunk = self.compress_text(chunk)
88
+
89
+ # Vérifier si ce texte est déjà dans l'index Pinecone
90
  if compressed_chunk in existing_texts:
91
+ continue # Ignorer ce document car il est déjà indexé
92
 
93
+ # Générer un ID unique pour ce chunk
94
  doc_id = f"doc_{zlib.crc32(chunk.encode('utf-8'))}"
95
+
96
  metadata = {"compressed_text": compressed_chunk}
97
+ metadata_size = self.get_metadata_size(metadata)
 
98
 
99
+ if metadata_size <= 40960: # 40 KB
100
+ document = Document(
101
+ page_content=chunk,
102
+ metadata=metadata
103
+ )
104
+ documents.append((doc_id, document))
105
+
106
+ # Ajouter uniquement les nouveaux documents
107
  if documents:
108
+ self.vectorstore.add_documents([doc for _, doc in documents]) # Remplacer upsert() par add_documents()
109
 
 
 
 
110
  st.session_state.indexing_done = True
 
111
  st.success("Indexation terminée sans duplication de contenu.")
112
 
113
  def hybrid_search(self, query):
114
+ """Récupère les documents pertinents en combinant les résultats de Pinecone et BM25."""
115
  if not self.is_initialized():
116
  st.warning("L'index BM25 n'est pas encore prêt. Veuillez patienter pendant l'indexation...")
117
  return []
118
 
119
  try:
120
+ # Recherche hybride avec PineconeHybridSearchRetriever
121
  results = self.retriever.get_relevant_documents(query)
122
+
123
+ # Récupérer les documents pertinents
124
  relevant_docs = []
125
  for result in results:
126
+ # Vérifier si le résultat est un objet Document
127
+ if hasattr(result, "metadata"):
128
+ metadata = result.metadata or {} # Assurez-vous que metadata n'est jamais None
129
+ else:
130
+ metadata = {}
131
+
132
+ # Vérifier si 'context' existe avant d'y accéder
133
+ if "context" in metadata:
134
+ _ = metadata.pop("context", None) # Sécuriser l'accès à 'context'
135
+
136
  compressed_text = metadata.get("compressed_text")
137
  if compressed_text:
138
  relevant_docs.append(self.decompress_text(compressed_text))
139
+
140
  return relevant_docs
141
+
142
+
143
  except Exception as e:
144
  st.error(f"Erreur lors de la recherche hybride : {e}")
145
  return []
146
+ print(relevant_docs)
147
 
148
  def compress_text(self, text):
149
  """Compresse un texte en base64."""