llm_ticket3/agents/mistral_large/agent_ticket_analyser.py
2025-04-14 14:10:19 +02:00

179 lines
7.7 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import json
import time
import logging
from typing import Dict, Any, Optional
# Importer BaseAgent depuis le répertoire utils
from agents.utils.base_agent import BaseAgent
# Configuration du logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("AgentTicketAnalyser_MistralLarge")
class AgentTicketAnalyser(BaseAgent):
"""
Agent spécialisé pour analyser un ticket et en extraire les informations clés.
Version optimisée pour Mistral Large.
"""
def __init__(self, llm: Any):
"""
Initialise l'agent d'analyse de ticket avec un modèle LLM.
Args:
llm: Instance du modèle de langage à utiliser
"""
super().__init__(llm)
self.temperature = 0.1 # Température très basse pour une analyse très factuelle
self.top_p = 0.9
self.max_tokens = 3000
# System prompt spécifique pour l'analyse de tickets
self.system_prompt = """Tu es un expert en analyse de tickets pour le support informatique.
Ton rôle est d'analyser en profondeur le contenu du ticket pour extraire toutes les informations essentielles et de structurer cette analyse de manière exhaustive.
À partir du ticket fourni, tu dois :
1. Extraire et synthétiser tous les points clés du ticket
2. Identifier les informations techniques importantes et leurs implications
3. Comprendre en détail le problème principal, son contexte, et ses ramifications
4. Déterminer la pertinence des images pour comprendre le problème
5. Anticiper les questions de clarification potentielles
Ta réponse doit suivre un format strictement structuré :
```
1. Résumé du contexte
- Client : [Nom, fonction et contacts du client si mentionnés]
- Sujet du ticket : [Sujet principal du ticket analysé en détail]
- Description technique synthétique : [Synthèse technique approfondie du problème]
2. Informations techniques détectées
- Logiciels/modules mentionnés : [Liste complète des logiciels, applications ou modules mentionnés]
- Paramètres évoqués : [Tous les paramètres, configurations ou variables mentionnés]
- Fonctionnalités impactées : [Description détaillée des fonctionnalités touchées]
- Conditions spécifiques : [Analyse des conditions particulières où le problème se manifeste]
3. Analyse du problème
- Problème principal : [Description approfondie du problème principal]
- Impact pour l'utilisateur : [Évaluation complète de l'impact sur l'utilisateur]
- Contexte d'apparition : [Analyse détaillée des circonstances d'apparition]
- Complexité estimée : [FAIBLE/MOYENNE/ÉLEVÉE] avec justification technique
4. Pertinence des images
- Images mentionnées : [OUI/NON] et leur importance [FAIBLE/MOYENNE/ÉLEVÉE]
- Justification : [Analyse détaillée de la pertinence des images]
- Éléments à rechercher : [Points spécifiques à examiner dans les images]
5. Questions pour clarification (si nécessaire)
- [Questions techniques que le support devrait poser]
- [Informations manquantes à obtenir]
```
Ton analyse doit être exhaustive tout en restant factuelle. Focalise-toi sur l'extraction complète des informations sans proposer de solutions."""
def executer(self, ticket_data: Dict[str, Any]) -> str:
"""
Analyse un ticket à partir des données fournies.
Args:
ticket_data: Dictionnaire contenant les données du ticket
- 'ticket_summary': Résumé du ticket
- 'messages': Liste des messages du ticket
Returns:
str: Analyse structurée du ticket
"""
start_time = time.time()
try:
# Extraire le résumé du ticket
ticket_summary = ticket_data.get('ticket_summary', {})
ticket_code = ticket_summary.get('code', 'INCONNU')
ticket_sujet = ticket_summary.get('sujet', 'Sans sujet')
# Log des informations de base du ticket
logger.info(f"Analyse du ticket {ticket_code}: {ticket_sujet}")
print(f" Analyse du ticket {ticket_code}: {ticket_sujet[:80]}{'...' if len(ticket_sujet) > 80 else ''}")
# Construire le contexte à partir des messages
messages = ticket_data.get('messages', [])
# Construire un prompt pour analyser le ticket
ticket_prompt = self._construire_prompt_ticket(ticket_summary, messages)
# Analyser le ticket avec le LLM
analyse = self.llm.generate(
system_prompt=self.system_prompt,
prompt=ticket_prompt,
temperature=self.temperature,
top_p=self.top_p,
max_tokens=self.max_tokens
)
# Calcul du temps de génération
generation_time = time.time() - start_time
# Log de l'analyse complétée
logger.info(f"Analyse complétée en {generation_time:.2f} secondes")
print(f" Analyse complétée en {generation_time:.2f} secondes")
return analyse
except Exception as e:
logger.error(f"Erreur lors de l'analyse du ticket: {str(e)}")
return f"ERREUR: Impossible d'analyser le ticket: {str(e)}"
def _construire_prompt_ticket(self, ticket_summary: Dict[str, Any], messages: list) -> str:
"""
Construit un prompt détaillé à partir des données du ticket.
Args:
ticket_summary: Résumé du ticket
messages: Liste des messages du ticket
Returns:
str: Prompt détaillé pour l'analyse
"""
# Construire l'en-tête avec les informations du ticket
prompt = f"# TICKET: {ticket_summary.get('code', 'INCONNU')}\n"
prompt += f"Sujet: {ticket_summary.get('sujet', 'Sans sujet')}\n"
prompt += f"Statut: {ticket_summary.get('statut', 'Inconnu')}\n"
prompt += f"Priorité: {ticket_summary.get('priorité', 'Non définie')}\n"
prompt += f"Date de création: {ticket_summary.get('date_création', 'Inconnue')}\n\n"
# Ajouter la section des messages
prompt += "## MESSAGES DU TICKET\n\n"
for i, message in enumerate(messages, 1):
# Extraire les informations du message
date = message.get('date', 'Date inconnue')
auteur = message.get('auteur', 'Auteur inconnu')
role = message.get('role', 'Rôle inconnu')
contenu = message.get('contenu', '')
# Ajouter l'en-tête du message
prompt += f"### Message {i} - {date}\n"
prompt += f"De: {auteur} ({role})\n\n"
# Ajouter le contenu du message
prompt += f"{contenu}\n\n"
# Ajouter les informations sur les pièces jointes si disponibles
attachments = message.get('attachments', [])
if attachments:
prompt += f"Pièces jointes ({len(attachments)}):\n"
for attachment in attachments:
prompt += f"- {attachment.get('nom', 'Sans nom')} ({attachment.get('type', 'Type inconnu')})\n"
prompt += "\n"
# Ajouter les instructions d'analyse
prompt += "\n## INSTRUCTIONS\n"
prompt += "Effectue une analyse approfondie de ce ticket selon les instructions dans ton system prompt. "
prompt += "Fournis une analyse complète et structurée qui servira de base aux étapes suivantes du traitement."
return prompt