mirror of
https://github.com/Ladebeze66/llm_ticket3.git
synced 2025-12-16 00:06:53 +01:00
178 lines
7.5 KiB
Python
178 lines
7.5 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_MistralMedium")
|
|
|
|
class AgentTicketAnalyser(BaseAgent):
|
|
"""
|
|
Agent spécialisé pour analyser un ticket et en extraire les informations clés.
|
|
Version optimisée pour Mistral Medium.
|
|
"""
|
|
|
|
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.2 # Température plus basse pour une analyse factuelle
|
|
self.top_p = 0.95
|
|
self.max_tokens = 2048
|
|
|
|
# System prompt spécifique pour l'analyse de tickets
|
|
self.system_prompt = """Tu es un assistant spécialisé dans l'analyse des tickets de support technique.
|
|
Ton rôle est d'analyser le contenu du ticket pour extraire les informations essentielles et de structurer cette analyse.
|
|
|
|
À partir du ticket que l'on te fournit, tu dois :
|
|
|
|
1. Extraire et synthétiser les points clés du ticket
|
|
2. Identifier les informations techniques importantes
|
|
3. Comprendre le problème principal et son contexte
|
|
4. Déterminer si des images sont mentionnées ou semblent nécessaires pour comprendre le problème
|
|
|
|
Ta réponse doit suivre un format strictement structuré :
|
|
|
|
```
|
|
1. Résumé du contexte
|
|
- Client : [Nom du contact client si mentionné]
|
|
- Sujet du ticket : [Sujet principal du ticket en une phrase]
|
|
- Description technique synthétique : [Synthèse technique du problème en 1-2 phrases]
|
|
|
|
2. Informations techniques détectées
|
|
- Logiciels/modules mentionnés : [Liste des logiciels, applications ou modules mentionnés]
|
|
- Paramètres évoqués : [Paramètres, configurations ou variables mentionnés]
|
|
- Fonctionnalités impactées : [Fonctionnalités ou processus touchés par le problème]
|
|
- Conditions spécifiques : [Conditions particulières où le problème se manifeste]
|
|
|
|
3. Analyse du problème
|
|
- Problème principal : [Description claire du problème principal]
|
|
- Impact pour l'utilisateur : [Comment ce problème affecte l'utilisateur]
|
|
- Contexte d'apparition : [Quand et comment le problème survient]
|
|
- Complexité estimée : [FAIBLE/MOYENNE/ÉLEVÉE] avec justification
|
|
|
|
4. Pertinence des images
|
|
- Images mentionnées : [OUI/NON] et leur importance [FAIBLE/MOYENNE/ÉLEVÉE]
|
|
- Justification : [Pourquoi les images sont importantes ou non pour comprendre le problème]
|
|
|
|
5. Questions pour clarification (si nécessaire)
|
|
- [Questions que le support technique devrait poser pour mieux comprendre le problème]
|
|
```
|
|
|
|
Reste factuel et concis dans ton analyse. N'invente pas d'information qui ne serait pas présente dans le ticket.
|
|
Concentre-toi uniquement sur l'analyse du contenu du ticket, pas sur la résolution du problème.
|
|
"""
|
|
|
|
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 += "Analyse ce ticket selon les instructions dans ton system prompt. "
|
|
prompt += "Réponds uniquement avec l'analyse structurée demandée."
|
|
|
|
return prompt |