Eric Marchand commited on
Commit
3afd61a
·
1 Parent(s): 590d088

Refactoring

Browse files
.gitignore CHANGED
@@ -1,6 +1,2 @@
1
- db/rag_app/
2
- venv/
3
- __pycache__/
4
- .vscode/
5
- .gradio/
6
- .env
 
1
+ git-commit-push.bat
2
+
 
 
 
 
README.md CHANGED
@@ -9,6 +9,7 @@ app_file: app.py
9
  pinned: false
10
  license: cc0-1.0
11
  short_description: RAG app with minimal depencies
 
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
9
  pinned: false
10
  license: cc0-1.0
11
  short_description: RAG app with minimal depencies
12
+ python_version: 3.11
13
  ---
14
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,72 +1,133 @@
1
  from pathlib import Path
2
  import gradio as gr
3
  from src.rag import Rag
4
- from src.amodel import ModelType
 
 
 
5
 
6
  STORE_DIR = "./db/rag_app" # Le répertoire de la base
7
  # STORE_DIR = None # Store éphémère
8
  MAX_DOCS = 6 # Le nombre max de documents dans la base
9
 
10
- def main():
11
- # UI
12
- with gr.Blocks() as demo:
13
- def upload_file(file_path):
14
- name:str = Path(file_path).name
15
- names = rag.emb_store.get_collection_names()
16
- count = len(names)
17
- if name in names:
18
- rag.delete_collection(name)
19
- if count >= MAX_DOCS:
20
- rag.delete_collection(names[0])
21
- rag.add_pdf_to_store(file_name=file_path, collection_name=name)
22
- return name
23
 
24
- def ask_rag(question:str, col_name:str):
25
- if col_name == "Aucun fichier":
26
- return "Aucun pdf actif, veuillez en uploader un !"
27
- if question.strip() == "":
28
- return "Veuillez poser une question."
29
- names = rag.emb_store.get_collection_names()
30
- if not col_name in names:
31
- return "'{name}' n'est plus sur le serveur, veuillez le recharger".format(name=col_name)
32
- prompt, resp, sources, ids = rag.ask_rag(question, col_name)
33
- return resp
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- def on_temperature_change(temp):
36
- rag.set_temperature(temp)
37
-
38
- # global State https://www.gradio.app/guides/state-in-blocks
39
- rag:Rag = Rag(ModelType.MTHUGGINGFACE, store_dir=STORE_DIR) # Création du rag
40
- # rag.reset_store() # Reset de la base à chaque démarrage du serveur
41
- with gr.Tab("RAG"):
42
- gr.Image("./files/drane.jpg", height=100, show_download_button=False,
43
- show_fullscreen_button=False, show_label=False, show_share_button=False,
44
- interactive=False, container=False)
45
- # Le label qui affiche le nom du pdf courant
46
- pdf_name = gr.Markdown("Aucun fichier")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  # Le button qui permet d'uploader un pdf
48
- upload_button = gr.UploadButton("Clique pour ajouter un pdf", file_types=[".pdf"], file_count="single")
49
- # La zone on pose une question au RAG
50
- ask_input = gr.Text(label="Pose une question à ton pdf")
51
- # La réponse du RAG (Markdown pour afficher les formules .tex)
52
- rag_output = gr.Markdown(label="Réponse")
53
- with gr.Tab("Réglages"):
54
- gr.Markdown("## Modèles:")
55
- gr.Markdown("- " + rag.get_llm_name())
56
- gr.Markdown("- " + rag.get_feature_name())
57
- temperature_slider = gr.Slider(minimum=0,
58
- maximum=1.0,
59
- value=0.0,
60
- step=0.1,
61
- label="Température")
62
 
63
- # Réponses aux évènements
64
- upload_button.upload(fn=upload_file, inputs=upload_button, outputs=[pdf_name], show_progress="full")
65
- ask_input.submit(fn=ask_rag, inputs=[ask_input, pdf_name], outputs=rag_output, show_progress="full")
66
- temperature_slider.change(fn=on_temperature_change, inputs=temperature_slider)
67
-
68
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
 
71
  if __name__ == "__main__":
72
- main()
 
1
  from pathlib import Path
2
  import gradio as gr
3
  from src.rag import Rag
4
+ from src.model_huggingface import HuggingFaceModel
5
+
6
+ from src.amodel import AModel
7
+ AModel.load_env_variables()
8
 
9
  STORE_DIR = "./db/rag_app" # Le répertoire de la base
10
  # STORE_DIR = None # Store éphémère
11
  MAX_DOCS = 6 # Le nombre max de documents dans la base
12
 
13
+ # global State https://www.gradio.app/guides/state-in-blocks
14
+ rag:Rag = Rag(
15
+ HuggingFaceModel("meta-llama/Meta-Llama-3-8B-Instruct", None, 0),
16
+ HuggingFaceModel(None, "sentence-transformers/all-MiniLM-l6-v2", 0),
17
+ STORE_DIR
18
+ )
19
+ rag.reset_store() # Reset de la base à chaque démarrage du serveur
20
+ print("rag created, store reseted")
 
 
 
 
 
21
 
22
+ # UI
23
+ with gr.Blocks(title="RAGnar",
24
+ # theme="Yntec/HaleyCH_Theme_Orange_Green",
25
+ fill_height=True,
26
+ analytics_enabled=False,
27
+ css="footer {visibility: hidden}",
28
+ ) as demo:
29
+ def upload_file(file_path):
30
+ name:str = Path(file_path).name
31
+ names = rag.emb_store.get_collection_names()
32
+ count = len(names)
33
+ if name in names:
34
+ rag.delete_collection(name)
35
+ print("collection", name, "deleted because already exists")
36
+ names = rag.emb_store.get_collection_names()
37
+ if count >= MAX_DOCS:
38
+ print("collection", names[0], "deleted because too many collections")
39
+ rag.delete_collection(names[0])
40
+ rag.add_pdf_to_store(file_name=file_path, collection_name=name)
41
+ return gr.Dropdown(
42
+ choices=rag.emb_store.get_collection_names(),
43
+ value=rag.emb_store.collections[-1].name,
44
+ show_label=False,
45
+ container=False,
46
+ interactive=True
47
+ )
48
 
49
+ def ask_rag(question:str, col_name:str):
50
+ if col_name == "Aucun fichier":
51
+ return "Aucun pdf actif, veuillez en uploader un !"
52
+ if question.strip() == "":
53
+ return "Veuillez poser une question."
54
+ names = rag.emb_store.get_collection_names()
55
+ if not col_name in names:
56
+ return "'{name}' n'est plus sur le serveur, veuillez le recharger".format(name=col_name)
57
+ prompt, resp, sources, ids = rag.ask_rag(question, col_name)
58
+ return resp
59
+
60
+ def on_temperature_change(temp):
61
+ rag.set_temperature(temp)
62
+
63
+ def on_refresh():
64
+ print("on_refresh")
65
+ choices=rag.emb_store.get_collection_names() if len(rag.emb_store.collections) > 0 else ["Aucun fichier"]
66
+ value = rag.emb_store.collections[-1].name if len(rag.emb_store.collections) > 0 else "Aucun fichier"
67
+ return gr.Dropdown(
68
+ choices=choices,
69
+ value=value,
70
+ show_label=False,
71
+ container=False,
72
+ interactive=True
73
+ )
74
+
75
+
76
+ with gr.Row():
77
+ gr.Image("./files/drane.png", show_download_button=False,
78
+ show_fullscreen_button=False, show_label=False, show_share_button=False,
79
+ interactive=False, container=False)
80
+ # https://www.svgrepo.com/svg/483648/viking-face
81
+ gr.Image("./files/viking.png", show_download_button=False,
82
+ show_fullscreen_button=False, show_label=False, show_share_button=False,
83
+ interactive=False, container=False)
84
+ with gr.Tab("RAG naïf"):
85
+ with gr.Row():
86
+ # Le button qui permet d'updater le combo des collections
87
+ refresh = gr.Button("Refresh", scale=1)
88
+ # Le combo qui affiche toutes les collections du store
89
+ choices=rag.emb_store.get_collection_names() if len(rag.emb_store.collections) > 0 else ["Aucun fichier"]
90
+ value = rag.emb_store.collections[-1].name if len(rag.emb_store.collections) > 0 else "Aucun fichier"
91
+ cols = gr.Dropdown(
92
+ choices=choices,
93
+ value=value,
94
+ show_label=False,
95
+ container=False,
96
+ interactive=True,
97
+ scale=10
98
+ )
99
  # Le button qui permet d'uploader un pdf
100
+ upload_button = gr.UploadButton(
101
+ "Clique pour ajouter un pdf",
102
+ file_types=[".pdf"],
103
+ file_count="single",
104
+ scale=10)
 
 
 
 
 
 
 
 
 
105
 
106
+ # La zone où on pose une question au RAG
107
+ ask_input = gr.Text(placeholder="Pose une question à ton pdf", show_label=False, container=False)
108
+ # La réponse du RAG (Markdown pour afficher les formules .tex)
109
+ rag_output = gr.Textbox("", show_copy_button=False,
110
+ show_label=False,
111
+ container=False,
112
+ max_lines=15)
113
+
114
+ with gr.Tab("Réglages"):
115
+ gr.Markdown("## Modèles:")
116
+ gr.Markdown("- " + rag.get_llm_name())
117
+ gr.Markdown("- " + rag.get_feature_name())
118
+ temperature_slider = gr.Slider(minimum=0,
119
+ maximum=1.0,
120
+ value=0.0,
121
+ step=0.1,
122
+ label="Température")
123
+
124
+ # Réponses aux évènements
125
+ refresh.click(fn=on_refresh, inputs=[], outputs=[cols])
126
+ upload_button.upload(fn=upload_file, inputs=upload_button, outputs=[cols], show_progress=True)
127
+ ask_input.submit(fn=ask_rag, inputs=[ask_input, cols], outputs=rag_output, show_progress=True)
128
+ temperature_slider.change(fn=on_temperature_change, inputs=temperature_slider)
129
+ demo.load(fn=on_refresh, inputs=[], outputs=[cols])
130
 
131
 
132
  if __name__ == "__main__":
133
+ demo.queue().launch()
db/readme.txt DELETED
@@ -1 +0,0 @@
1
- Chaque collection dans un répertoire
 
 
files/drane.jpg DELETED
Binary file (41.6 kB)
 
files/drane.png ADDED
files/viking.png ADDED
git-commit-push.bat CHANGED
@@ -2,3 +2,4 @@ git add .
2
  git commit -a
3
  git push
4
  PAUSE
 
 
2
  git commit -a
3
  git push
4
  PAUSE
5
+
requirements.txt CHANGED
@@ -1,2 +1,4 @@
 
 
1
  pypdf
2
- huggingface-hub
 
1
+ gradio
2
+ numpy
3
  pypdf
4
+ huggingface_hub
src/amodel.py CHANGED
@@ -1,21 +1,5 @@
1
  from abc import ABC, abstractmethod
2
- from enum import Enum
3
-
4
- class ModelType(Enum):
5
- ''' Les différentes technos de models '''
6
- MTOPENAI = 1
7
- MTOLLAMA = 2
8
- MTHUGGINGFACE = 3
9
- MTMISTRAL = 4
10
-
11
- @classmethod
12
- def to_str(self, mt:int)->str:
13
- match mt:
14
- case 1: return "MTOPENAI"
15
- case 2: return "MTOLLAMA"
16
- case 3: return "MTHUGGINGFACE"
17
- case 4: return "MTMISTRAL"
18
- case _: return "UNKNOWN"
19
 
20
  class AModel(ABC):
21
  '''
@@ -27,6 +11,21 @@ class AModel(ABC):
27
  ...
28
  '''
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  @abstractmethod
31
  def ask_llm(self, question:str)->str:
32
  pass
 
1
  from abc import ABC, abstractmethod
2
+ import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  class AModel(ABC):
5
  '''
 
11
  ...
12
  '''
13
 
14
+ @classmethod
15
+ def load_env_variables(cls):
16
+ '''
17
+ Gestion des tokens par variables d'environnement
18
+ On utilise dotenv, sauf si la platforme est un space HuggingFace
19
+ Dans ce cas les variables d'env sont déjà chargées
20
+ '''
21
+ # HF_ACTIVE est une variable d'environnement créée dans les spaces HuggingFace
22
+ # Elle sert à savoir que l'appli tourne dans un space
23
+ if not os.getenv("HF_ACTIVE"): # Utilisation ailleurs que dans un space
24
+ # load_dotenv ne passe pas dans un space HuggingFace
25
+ from dotenv import load_dotenv
26
+ load_dotenv()
27
+
28
+
29
  @abstractmethod
30
  def ask_llm(self, question:str)->str:
31
  pass
src/astore.py DELETED
@@ -1,39 +0,0 @@
1
- from abc import ABC, abstractmethod
2
-
3
-
4
- class AStore(ABC):
5
- '''
6
- Classe abstraite de base pour tous les stores :
7
- Chroma
8
- Perso
9
- ...
10
- '''
11
-
12
- @abstractmethod
13
- def reset(self)->None:
14
- pass
15
-
16
- @abstractmethod
17
- def print_infos(self)->None:
18
- pass
19
-
20
- @abstractmethod
21
- def add_to_collection(self, collection_name:str, source:str, vectors:list[list[float]], chunks:list[str])->None:
22
- pass
23
-
24
- @abstractmethod
25
- def delete_collection(self, name:str)->None:
26
- pass
27
-
28
- @abstractmethod
29
- def get_similar_vector(self, vector:list[float], collection_name:str)->list[float]:
30
- pass
31
-
32
- @abstractmethod
33
- def get_similar_chunk(self, query_vector:list[float], collection_name:str)->tuple[str, str]:
34
- pass
35
-
36
- @abstractmethod
37
- def get_similar_chunks(self, query_vector:list[float], count:int, collection_name:str):
38
- pass
39
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/model_huggingface.py CHANGED
@@ -10,14 +10,7 @@ class HuggingFaceModel(AModel):
10
  self.llm_name:str = llm_name
11
  self.feature_name:str = feature_name
12
  self.temperature = temperature
13
- # La variable HF_ACTIVE a été créée dans les settings de l'app sur HuggingFace
14
- if (os.getenv("HF_ACTIVE")): # Lancement depuis l'app sur HuggingFace
15
- api_token = os.getenv("HF_TOKEN")
16
- else: # Lancement depuis mon ordi
17
- # print("Launch Rag in HuggingFace local")
18
- from dotenv import load_dotenv # Trick: ne passe pas dans une app sur HuggingFace
19
- load_dotenv()
20
- api_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
21
  try:
22
  self.model = InferenceClient(api_key=api_token)
23
  except:
@@ -29,7 +22,7 @@ class HuggingFaceModel(AModel):
29
  resp = self.model.chat.completions.create(
30
  model=self.llm_name,
31
  messages=messages,
32
- max_tokens=500,
33
  temperature=self.temperature,
34
  # stream=True
35
  )
 
10
  self.llm_name:str = llm_name
11
  self.feature_name:str = feature_name
12
  self.temperature = temperature
13
+ api_token = os.getenv("HUGGINGFACEHUB_API_TOKEN")
 
 
 
 
 
 
 
14
  try:
15
  self.model = InferenceClient(api_key=api_token)
16
  except:
 
22
  resp = self.model.chat.completions.create(
23
  model=self.llm_name,
24
  messages=messages,
25
+ max_tokens=2048,
26
  temperature=self.temperature,
27
  # stream=True
28
  )
src/rag.py CHANGED
@@ -1,14 +1,14 @@
1
- import sys
2
-
3
  from pypdf import PdfReader
4
  from .chunker import Chunker
5
- from .amodel import ModelType
6
- from .model_huggingface import HuggingFaceModel
7
  from .store import Store
8
 
 
 
9
 
10
  class Rag:
11
  '''
 
12
  Classe qui s'occupe de toute la chaine du RAG.
13
  Elle permet :
14
  d'interroger un llm directement (sans RAG) avec ask_llm()
@@ -29,39 +29,36 @@ class Rag:
29
  Question : {question}
30
  """
31
 
32
- def __init__(self, model_type:ModelType, store_dir:str) -> None:
33
- '''
34
  Constructeur du Rag
35
  Args:
36
- model_type: la techno utilisée
37
- store_dir: le répertoire de persistance de la base de données ou None
 
38
  Exception:
39
- Si le model ne peut pas être créé
40
- Si le type de model est inconnu
41
  '''
42
- self.model_type = model_type
 
 
43
  try:
44
- match model_type:
45
- case ModelType.MTHUGGINGFACE:
46
- self.model = HuggingFaceModel("meta-llama/Meta-Llama-3-8B-Instruct", "sentence-transformers/all-MiniLM-l6-v2", 0)
47
- case _:
48
- raise Exception("Rag.__init__: Unknown model type: {mt} : {v}".format(mt=ModelType.to_str(model_type), v=model_type))
49
  self.emb_store = Store(store_dir) # persistant
50
  # self.emb_store = Store(None) # éphémère
51
- except Exception as e:
52
  raise
53
 
54
  def get_llm_name(self):
55
- return self.model.get_llm_name()
56
 
57
  def get_feature_name(self):
58
- return self.model.get_feature_name()
59
 
60
  def get_temperature(self):
61
- return self.model.get_temperature()
62
 
63
  def set_temperature(self, temperature:float):
64
- self.model.set_temperature(temperature)
65
 
66
  def reset_store(self):
67
  self.emb_store.reset()
@@ -71,7 +68,7 @@ class Rag:
71
 
72
  def create_vectors(self, chunks:list[str])->list[list[float]]:
73
  '''
74
- Renvoie les vecteurs correspondant à 'chunks', calculés par 'emb_model'
75
  Args:
76
  chunks: les extraits de texte à calculer
77
  Return:
@@ -80,7 +77,7 @@ class Rag:
80
  vectors:list = []
81
  tokens:int = 0
82
  try:
83
- vectors:list[list[float]] = self.model.create_vectors(chunks) # batch si le model le permet
84
  return vectors
85
  except:
86
  raise
@@ -101,17 +98,8 @@ class Rag:
101
  Return:
102
  La liste des chunks
103
  '''
104
- # splitter = RecursiveCharacterTextSplitter(
105
- # # separator="\n",
106
- # chunk_size=1000,
107
- # chunk_overlap=200,
108
- # length_function=len,
109
- # is_separator_regex=False
110
- # )
111
- # chunks = splitter.split_text(text)
112
- # print("get_chunks: " + str(len(chunks)))
113
  chunker = Chunker()
114
- chunks = chunker.split_basic(text=text, char_count=1000, overlap=200)
115
  return chunks
116
 
117
  def add_pdf_to_store(self, file_name:str, collection_name:str)->None:
@@ -157,14 +145,14 @@ class Rag:
157
 
158
  def ask_llm(self, question:str)->str:
159
  '''
160
- Pose une question au llm_model, attend sa réponse et la renvoie.
161
  Args:
162
  question: La question qu'on veut lui poser
163
  Returns:
164
- La réponse du llm_model
165
  '''
166
  try:
167
- return self.model.ask_llm(question=question)
168
  except:
169
  return "Error while comminicating with model !"
170
 
@@ -175,8 +163,8 @@ class Rag:
175
  question: La question qu'on veut lui poser
176
  collection_name: le nom de la collection que l'on veut interroger
177
  Returns:
178
- Le prompt effectivement donné au llm_model
179
- La réponse du llm_model
180
  Les sources du RAG utilisées
181
  Les ids des documents du RAG
182
  '''
@@ -188,7 +176,7 @@ class Rag:
188
  return "", "Error: {name} is no more in the database !".format(name=collection_name), [], []
189
  try:
190
  # Transformer la 'question' en vecteur avec emb_model
191
- query_vector:list[float] = self.model.create_vector(question)
192
  # Récupérer les chunks du store similaires à la question
193
  chunks, sources, ids = self.emb_store.get_similar_chunks(
194
  query_vector=query_vector,
@@ -207,42 +195,7 @@ class Rag:
207
  except:
208
  return "", "Error with communicating with model !", [], []
209
 
210
- def test_cours_TSTL()->None:
211
- # Test placé ici pendant la mise au point
212
- STORE_DIR = "./db/chroma_vectors"
213
- # rag = Rag(ModelType.MTOPENAI, store_dir=STORE_DIR)
214
- rag = Rag(ModelType.MTHUGGINGFACE, store_dir=STORE_DIR)
215
- # rag = Rag(llm_type=ModelType.MTHUGGINGFACE, emb_type=ModelType.MTHUGGINGFACE, store_dir=STORE_DIR)
216
-
217
- rag.reset_store()
218
- rag.add_pdf_to_store("chap-1-Statique.pdf", "T_SPCL")
219
- # rag.add_pdf_to_store("chap-2-Regulation.pdf", "T_SPCL")
220
- # rag.add_pdf_to_store("chap-3-Dynamique.pdf", "T_SPCL")
221
- # rag.add_pdf_to_store("chap-4-Echangeurs.pdf", "T_SPCL")
222
-
223
- rag.emb_store.print_infos()
224
-
225
- prompt, resp, sources, ids = rag.ask_rag(
226
- question="Quelle est la différence entre une pression relative et une pression absolue?",
227
- # question="Qu'est-ce qu'un échangeur à contre-courant?",
228
- # question="Quelle est la formule de la résistance thermique? Réponds brièvement",
229
- # question="Quelle est l'équation de Bernouilli avec les termes de pompe et pertes de charges? Réponds brièvement",
230
- # question="Que signifie le terme de vitesse dans l'équation de Bernouilli ?",
231
- # question="Transforme 1 bar en mètre de colonne d'eau",
232
- # question="A quoi correspond HMT d'une pompe?",
233
- collection_name="T_SPCL"
234
- )
235
- print(prompt)
236
- print("---------------------------")
237
- print(resp)
238
- print("---------------------------")
239
- print("sources:", sources)
240
- print("ids=", ids)
241
-
242
- # print(rag.ask_llm("Quelle est l'équation de Bernouilli avec les termes de pompe et pertes de charges? Réponds brièvement"))
243
-
244
- if __name__ == "__main__":
245
- test_cours_TSTL()
246
 
247
 
248
 
 
 
 
1
  from pypdf import PdfReader
2
  from .chunker import Chunker
3
+ from .amodel import AModel
 
4
  from .store import Store
5
 
6
+ CHUNK_CHAR_COUNT = 1000
7
+ CHUNK_OVERLAP = 200
8
 
9
  class Rag:
10
  '''
11
+ RAG naïf
12
  Classe qui s'occupe de toute la chaine du RAG.
13
  Elle permet :
14
  d'interroger un llm directement (sans RAG) avec ask_llm()
 
29
  Question : {question}
30
  """
31
 
32
+ def __init__(self, llm:AModel, emb:AModel, store_dir:str)->None:
33
+ '''
34
  Constructeur du Rag
35
  Args:
36
+ llm: le model de langage
37
+ emb: le model d'embeddings
38
+ store_dir: le répertoire de persistance de la base de données ou None pour éphémère
39
  Exception:
40
+ Si le store ne peut pas se créer (répertoire inaccessible par ex.)
 
41
  '''
42
+ self.llm:AModel = llm
43
+ self.emb:AModel = emb
44
+ self.store_dir:str = store_dir
45
  try:
 
 
 
 
 
46
  self.emb_store = Store(store_dir) # persistant
47
  # self.emb_store = Store(None) # éphémère
48
+ except:
49
  raise
50
 
51
  def get_llm_name(self):
52
+ return self.llm.get_llm_name()
53
 
54
  def get_feature_name(self):
55
+ return self.emb.get_feature_name()
56
 
57
  def get_temperature(self):
58
+ return self.llm.get_temperature()
59
 
60
  def set_temperature(self, temperature:float):
61
+ self.llm.set_temperature(temperature)
62
 
63
  def reset_store(self):
64
  self.emb_store.reset()
 
68
 
69
  def create_vectors(self, chunks:list[str])->list[list[float]]:
70
  '''
71
+ Renvoie les vecteurs correspondant à 'chunks', calculés par 'emb'
72
  Args:
73
  chunks: les extraits de texte à calculer
74
  Return:
 
77
  vectors:list = []
78
  tokens:int = 0
79
  try:
80
+ vectors:list[list[float]] = self.emb.create_vectors(chunks) # batch si le model le permet
81
  return vectors
82
  except:
83
  raise
 
98
  Return:
99
  La liste des chunks
100
  '''
 
 
 
 
 
 
 
 
 
101
  chunker = Chunker()
102
+ chunks = chunker.split_basic(text=text, char_count=CHUNK_CHAR_COUNT, overlap=CHUNK_OVERLAP)
103
  return chunks
104
 
105
  def add_pdf_to_store(self, file_name:str, collection_name:str)->None:
 
145
 
146
  def ask_llm(self, question:str)->str:
147
  '''
148
+ Pose une question au llm, attend sa réponse et la renvoie.
149
  Args:
150
  question: La question qu'on veut lui poser
151
  Returns:
152
+ La réponse du llm
153
  '''
154
  try:
155
+ return self.llm.ask_llm(question=question)
156
  except:
157
  return "Error while comminicating with model !"
158
 
 
163
  question: La question qu'on veut lui poser
164
  collection_name: le nom de la collection que l'on veut interroger
165
  Returns:
166
+ Le prompt effectivement donné au llm
167
+ La réponse du llm
168
  Les sources du RAG utilisées
169
  Les ids des documents du RAG
170
  '''
 
176
  return "", "Error: {name} is no more in the database !".format(name=collection_name), [], []
177
  try:
178
  # Transformer la 'question' en vecteur avec emb_model
179
+ query_vector:list[float] = self.emb.create_vector(question)
180
  # Récupérer les chunks du store similaires à la question
181
  chunks, sources, ids = self.emb_store.get_similar_chunks(
182
  query_vector=query_vector,
 
195
  except:
196
  return "", "Error with communicating with model !", [], []
197
 
198
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
 
201