mirror of
https://github.com/Ladebeze66/llm_ticket3.git
synced 2025-12-13 17:37:05 +01:00
267 lines
9.6 KiB
Python
267 lines
9.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Script simple pour tester directement l'API Mistral Large.
|
|
Ce script permet de diagnostiquer si le problème vient de l'API ou de notre application.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import logging
|
|
import requests
|
|
from datetime import datetime
|
|
|
|
# Configuration du logging
|
|
logging.basicConfig(
|
|
level=logging.DEBUG,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.StreamHandler(sys.stdout)
|
|
]
|
|
)
|
|
|
|
logger = logging.getLogger("test_mistral_api")
|
|
|
|
# Clés API à tester
|
|
API_KEYS = [
|
|
"2iGzTzE9csRQ9IoASoUjplHwEjA200Vh", # Clé actuelle dans MistralLarge
|
|
"sk-d359d9236ca84a5986f889631832d1e6" # Clé utilisée dans list_mistral_models.py
|
|
]
|
|
|
|
def test_api_key(api_key):
|
|
"""Test si la clé API est valide en listant les modèles disponibles."""
|
|
url = "https://api.mistral.ai/v1/models"
|
|
headers = {
|
|
"Authorization": f"Bearer {api_key}"
|
|
}
|
|
|
|
try:
|
|
logger.info(f"Test de la clé API: {api_key[:5]}...{api_key[-5:]}")
|
|
response = requests.get(url, headers=headers)
|
|
|
|
logger.info(f"Code de statut: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
logger.info("La clé API est valide!")
|
|
try:
|
|
models = response.json().get('data', [])
|
|
logger.info(f"Modèles disponibles: {[model.get('id') for model in models]}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du parsing de la réponse: {e}")
|
|
logger.error(f"Réponse brute: {response.text}")
|
|
return False
|
|
else:
|
|
logger.error(f"Erreur API: {response.status_code}")
|
|
logger.error(f"Réponse d'erreur: {response.text}")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Exception lors du test de la clé API: {e}")
|
|
return False
|
|
|
|
def test_direct_chat_completion(api_key):
|
|
"""Test directement l'endpoint chat/completions."""
|
|
url = "https://api.mistral.ai/v1/chat/completions"
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {api_key}"
|
|
}
|
|
|
|
data = {
|
|
"model": "mistral-large-latest",
|
|
"messages": [
|
|
{"role": "system", "content": "Tu es un assistant utile."},
|
|
{"role": "user", "content": "Dis simplement 'API FONCTIONNE' sans rien ajouter."}
|
|
],
|
|
"temperature": 0.1,
|
|
"max_tokens": 100
|
|
}
|
|
|
|
try:
|
|
logger.info(f"Test d'appel direct à chat/completions avec la clé: {api_key[:5]}...{api_key[-5:]}")
|
|
response = requests.post(url, headers=headers, json=data)
|
|
|
|
logger.info(f"Code de statut: {response.status_code}")
|
|
|
|
if response.status_code in [200, 201]:
|
|
try:
|
|
result = response.json()
|
|
message = result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
|
logger.info(f"Réponse: {message}")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du parsing de la réponse: {e}")
|
|
logger.error(f"Réponse brute: {response.text}")
|
|
return False
|
|
else:
|
|
logger.error(f"Erreur API: {response.status_code}")
|
|
logger.error(f"Réponse d'erreur: {response.text}")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Exception lors de l'appel direct: {e}")
|
|
return False
|
|
|
|
# Essayer d'importer la classe MistralLarge
|
|
try:
|
|
from llm_classes.mistral_large import MistralLarge
|
|
logger.info("Module MistralLarge importé avec succès")
|
|
except ImportError as e:
|
|
logger.error(f"Impossible d'importer MistralLarge: {e}")
|
|
sys.exit(1)
|
|
|
|
def test_simple_prompt():
|
|
"""Test avec un prompt simple pour vérifier que l'API répond."""
|
|
try:
|
|
logger.info("Initialisation du modèle Mistral Large...")
|
|
model = MistralLarge()
|
|
logger.info("Modèle initialisé avec succès")
|
|
|
|
# Afficher la clé API utilisée
|
|
api_key = model.cleAPI()
|
|
logger.info(f"Clé API utilisée: {api_key[:5]}...{api_key[-5:]}")
|
|
|
|
# Prompt simple pour tester la connexion
|
|
prompt = "Réponds uniquement avec le texte 'API MISTRAL FONCTIONNE' sans rien ajouter d'autre."
|
|
|
|
logger.info(f"Envoi du prompt simple: {prompt}")
|
|
start_time = datetime.now()
|
|
response = model.interroger(prompt)
|
|
end_time = datetime.now()
|
|
|
|
duration = (end_time - start_time).total_seconds()
|
|
logger.info(f"Réponse reçue en {duration} secondes")
|
|
|
|
if response:
|
|
logger.info(f"Réponse complète: {response}")
|
|
# Vérifier si la réponse contient une erreur API
|
|
if "erreur" in response.lower() or "error" in response.lower():
|
|
logger.error("La réponse contient une erreur")
|
|
logger.error(f"Détails de l'erreur: {response}")
|
|
return False
|
|
return True
|
|
else:
|
|
logger.error("Réponse vide reçue")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du test avec prompt simple: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
return False
|
|
|
|
def test_json_prompt():
|
|
"""Test avec un prompt demandant un JSON pour vérifier si c'est le format qui pose problème."""
|
|
try:
|
|
logger.info("Initialisation du modèle Mistral Large...")
|
|
model = MistralLarge()
|
|
logger.info("Modèle initialisé avec succès")
|
|
|
|
# Prompt demandant un JSON simple
|
|
prompt = """
|
|
Réponds uniquement avec un JSON valide au format suivant, sans aucun texte avant ou après:
|
|
|
|
{
|
|
"test": "réussi",
|
|
"timestamp": "heure actuelle",
|
|
"message": "API Mistral fonctionne correctement"
|
|
}
|
|
"""
|
|
|
|
logger.info(f"Envoi du prompt JSON: {prompt}")
|
|
start_time = datetime.now()
|
|
response = model.interroger(prompt)
|
|
end_time = datetime.now()
|
|
|
|
duration = (end_time - start_time).total_seconds()
|
|
logger.info(f"Réponse reçue en {duration} secondes")
|
|
|
|
if response:
|
|
logger.info(f"Réponse complète: {response}")
|
|
|
|
# Vérifier si la réponse contient une erreur API
|
|
if "erreur" in response.lower() or "error" in response.lower():
|
|
logger.error("La réponse contient une erreur")
|
|
logger.error(f"Détails de l'erreur: {response}")
|
|
return False
|
|
|
|
# Essayer de parser le JSON
|
|
try:
|
|
# Chercher un bloc de code JSON
|
|
import re
|
|
match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", response)
|
|
if match:
|
|
response_cleaned = match.group(1).strip()
|
|
logger.info(f"JSON trouvé dans un bloc de code Markdown")
|
|
else:
|
|
response_cleaned = response
|
|
|
|
json_response = json.loads(response_cleaned)
|
|
logger.info(f"JSON valide reçu: {json.dumps(json_response, indent=2)}")
|
|
return True
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"Réponse reçue mais JSON invalide: {e}")
|
|
return False
|
|
else:
|
|
logger.error("Réponse vide reçue")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du test avec prompt JSON: {e}")
|
|
import traceback
|
|
logger.error(traceback.format_exc())
|
|
return False
|
|
|
|
def dump_model_info():
|
|
"""Affiche les informations sur le modèle et sa configuration."""
|
|
try:
|
|
model = MistralLarge()
|
|
logger.info("Informations sur le modèle:")
|
|
|
|
# Récupérer et afficher les attributs du modèle
|
|
for attr_name in dir(model):
|
|
if not attr_name.startswith('_'): # Ignorer les attributs privés
|
|
try:
|
|
attr_value = getattr(model, attr_name)
|
|
# N'afficher que les attributs simples, pas les méthodes
|
|
if not callable(attr_value):
|
|
logger.info(f" {attr_name}: {attr_value}")
|
|
except Exception as e:
|
|
logger.warning(f" Impossible d'accéder à {attr_name}: {e}")
|
|
|
|
# Afficher les méthodes disponibles
|
|
methods = [m for m in dir(model) if not m.startswith('_') and callable(getattr(model, m))]
|
|
logger.info(f"Méthodes disponibles: {', '.join(methods)}")
|
|
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors de la récupération des informations du modèle: {e}")
|
|
return False
|
|
|
|
def main():
|
|
"""Fonction principale exécutant les tests."""
|
|
logger.info("=== DÉBUT DES TESTS API MISTRAL ===")
|
|
|
|
logger.info("=== TEST DES CLÉS API ===")
|
|
for api_key in API_KEYS:
|
|
test_api_key(api_key)
|
|
test_direct_chat_completion(api_key)
|
|
|
|
logger.info("\n=== INFORMATIONS SUR LE MODÈLE ===")
|
|
dump_model_info()
|
|
|
|
logger.info("\n=== TEST AVEC PROMPT SIMPLE ===")
|
|
test_simple = test_simple_prompt()
|
|
|
|
logger.info("\n=== TEST AVEC PROMPT JSON ===")
|
|
test_json = test_json_prompt()
|
|
|
|
logger.info("\n=== RÉSULTATS DES TESTS ===")
|
|
logger.info(f"Test simple: {'RÉUSSI' if test_simple else 'ÉCHEC'}")
|
|
logger.info(f"Test JSON: {'RÉUSSI' if test_json else 'ÉCHEC'}")
|
|
|
|
logger.info("=== FIN DES TESTS ===")
|
|
|
|
return 0 if test_simple and test_json else 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |