p14 / utils /vector_store.py
DidierHernandez's picture
Premiére version avec streamlit testeurs
956d16b
Raw History Blame Contribute Delete
3.04 kB
# utils/vector_store.py — Le Socle Technique Unique
"""
Module central de gestion de la base de données vectorielle FAISS pour l'Assistant de Caisse projet14 objectif1.
Anciennement "coquille vide", ce script centralise désormais la logique de chargement
de l'index et de formatage des documents afin d'alléger 'streamlit_app.py' et 'MistralChat.py',
évitant ainsi toute duplication de logique LangChain (Phase 4 : Optimisation).
"""
import streamlit as st
# Embaucher un conseiller expert (l’IA Mistral) qui sait comprendre et guider sur les procédures de caisse
from langchain_mistralai import MistralAIEmbeddings
# Organiser les fiches de procédures dans des casiers intelligents (FAISS)
from langchain_community.vectorstores import FAISS
# Utilisation de la configuration centralisée
from utils.config import (
MISTRAL_API_KEY,
FAISS_INDEX_DIR,
EMBEDDING_MODEL
)
def load_vector_store():
"""
Charge la base de données vectorielle FAISS existante en utilisant les chemins configurés.
Cette responsabilité a été déportée ici pour respecter la séparation des responsabilités
(logique d’UI vs logique de stockage vectoriel).
"""
if not MISTRAL_API_KEY:
st.error("Clé API Mistral manquante dans la configuration.")
return None
# Etape 2 : Chargement de l'Index Vectoriel
# Didier : d'après IA il est CRUCIAL d'utiliser les mêmes embeddings que lors de l'indexation
embeddings = MistralAIEmbeddings(
mistral_api_key=MISTRAL_API_KEY,
model=EMBEDDING_MODEL
)
if not FAISS_INDEX_DIR.exists():
st.error(f"L'index FAISS est introuvable dans {FAISS_INDEX_DIR}. Veuillez lancer indexer.py.")
return None
try:
# allow_dangerous_deserialization est nécessaire pour charger les fichiers .pkl de l'index local
vector_store = FAISS.load_local(
str(FAISS_INDEX_DIR),
embeddings,
allow_dangerous_deserialization=True
)
return vector_store
except Exception as e:
st.error(f"Erreur lors du chargement de l'index : {e}")
return None
def format_docs(docs):
"""
Etape 6 : Création de la Chaîne de Formatage des Documents.
Didier : Mutation majeure pour le Projet14 objectif1. On extrait les métadonnées sémantiques
de nos blocs de procédures (Processus, Action, Écran de départ) au lieu des anciens tags iCalendar.
"""
formatted = []
for d in docs:
# Reprise dynamique des clés de métadonnées du Front Matter gérées par le md_parser
header = f"--- PROCESSUS : {d.metadata.get('process', 'Général')} | ACTION MÉTIER : {d.metadata.get('action', 'N/A')} ---"
details = f"Écran de départ: {d.metadata.get('ecran_depart', 'N/A')} | Mots-clés: {d.metadata.get('mots_cles', 'N/A')}"
content = f"Instructions de l'interface :\n{d.page_content}"
formatted.append(f"{header}\n{details}\n{content}")
return "\n\n".join(formatted)