import gradio as gr from huggingface_hub import hf_hub_download import faiss import numpy as np from dotenv import load_dotenv import os from litellm import completion from langchain_community.embeddings import HuggingFaceEmbeddings from huggingface_hub import login import pickle token=os.getenv("HF_TOKEN") login(token) model_name = "bge-small-en-v1.5" model_kwargs = {'device': 'cpu'} encode_kwargs = {'normalize_embeddings': False} embeddings = HuggingFaceEmbeddings( # model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs ) # Charger les variables d'environnement depuis un fichier .env (recommandé pour les clés API) load_dotenv() GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") title = "NGAP'ot" description = """ 🔎 Chatbot utilisant le modèle Gemini via LiteLLM et une base de connaissances indexée avec FAISS. """ # --- Fonctions et variables nécessaires --- # Supposons que vous ayez une fonction pour obtenir les embeddings de texte def get_text_embedding(text): return embeddings.embed_query(text) # Charger l'index FAISS doc_path = hf_hub_download(repo_id="xavierbarbier/rag_ngap", filename="resource/embeddings_ngap.faiss", repo_type="space") index = faiss.read_index(doc_path) if not index: print("Problème index") # Télécharger le fichier depuis le Hub doc_path = hf_hub_download(repo_id="xavierbarbier/rag_ngap", filename="resource/fichier_chunks.pkl", repo_type="space") # Charger les chunks depuis le fichier pickle with open(doc_path, "rb") as f: chunks = pickle.load(f) if not chunks: print("Problème chunks") if len(chunks): print("Problème len chunks") def qa(question): """Fonction principale pour répondre à la question en utilisant RAG avec jusqu'à 5 chunks.""" global index # Indique que nous utilisons la variable globale index if not GEMINI_API_KEY: return "Erreur : La clé API Gemini n'est pas configurée.", "" question_embeddings = np.array([get_text_embedding(question)]) k = 10 # Nombre de voisins à récupérer D, I = index.search(question_embeddings, k=k) # distances et indices retrieved_chunks = [chunks[i] for i in I.tolist()[0]] if I.size > 0 else "Aucune information pertinente trouvée." if not retrieved_chunks: context = "Aucune information pertinente trouvée." else: context = "\n---------------------\n".join(retrieved_chunks) prompt = f""" Vous êtes un chatbot spécialisé dans l'assurance maladie en France, avec une expertise particulière sur la Nomenclature Générale des Actes Professionnels (NGAP). Votre mission est de fournir des informations précises, claires et à jour sur les différents aspects de l'assurance maladie et des actes médicaux codifiés par la NGAP. Vous devez répondre en français à toutes les questions, en utilisant un langage accessible et compréhensible pour les utilisateurs. Instructions : 1. Répondez aux questions concernant les droits des assurés, les remboursements, les démarches administratives, et les services proposés par l'assurance maladie en France. 2. Fournissez des explications détaillées sur les différentes couvertures (maladie, maternité, invalidité, décès) et les conditions d'éligibilité. 3. Expliquez ce qu'est la NGAP et son rôle dans le système de santé français. 4. Répondez aux questions sur les codes NGAP, leur signification, et les tarifs associés. 5. Aidez les utilisateurs à comprendre comment les actes médicaux sont facturés et remboursés selon la NGAP. 6. Utilisez un langage clair et précis, en évitant le jargon technique autant que possible. 7. Soyez empathique et rassurant, surtout lorsque les utilisateurs posent des questions sensibles ou complexes. 8. Fournissez des liens vers des ressources officielles ou des documents utiles lorsque cela est pertinent. 9. Respectez la confidentialité des informations personnelles des utilisateurs. 10. Ne demandez jamais d'informations sensibles comme les numéros de sécurité sociale ou les données médicales personnelles. Contexte : --------------------- {context} --------------------- En vous basant sur le contexte fourni et sans utiliser de connaissances préalables, répondez à la question suivante : Question : {question} Réponse : """ try: response = completion(model="gemini/gemini-2.0-flash-lite", messages=[{"role": "user", "content": prompt}]) answer = response.choices[0].message.content return answer, prompt except Exception as e: return f"Erreur lors de la communication avec le modèle Gemini : {e}", prompt with gr.Blocks() as demo: gr.Markdown(f"# {title}") gr.Markdown(description) with gr.Row(): question_input = gr.Textbox(label="Question") with gr.Row(): qa_button = gr.Button("Poser la question") with gr.Column(): answer_output = gr.Textbox(label="Réponse") prompt_output = gr.Textbox(label="Prompt envoyé au modèle", visible=True) # Optionnel : afficher le prompt pour le débogage qa_button.click( fn=qa, inputs=question_input, outputs=[answer_output, prompt_output] ) if __name__ == "__main__": demo.queue(max_size=3).launch() # creating a pdf reader object