2025-03-27 14:08:10 +01:00

183 lines
9.4 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Agent LLM pour la génération de résumés
"""
import requests
from typing import Dict, Optional, Union
from .base import LLMBaseAgent
class SummaryAgent(LLMBaseAgent):
"""
Agent LLM spécialisé dans la génération de résumés et d'analyses de texte
"""
def __init__(self, model_name: str = "deepseek-r1", **config):
"""
Initialise l'agent de résumé
Args:
model_name (str): Nom du modèle de résumé (défaut: deepseek-r1)
**config: Paramètres de configuration supplémentaires
"""
super().__init__(model_name, **config)
# Définir les prompts de résumé par type de contenu et langue
self.prompts = {
"fr": {
"standard": "Résume le texte suivant en capturant les points essentiels "
"de manière concise et précise. Préserve les informations clés "
"tout en réduisant la longueur.\n\n"
"Texte à résumer :\n{text}",
"analytique": "Analyse le texte suivant en identifiant les concepts clés, "
"les arguments principaux et les implications. Fournis un résumé "
"qui met en évidence les insights importants.\n\n"
"Texte à analyser :\n{text}",
"schéma": "Décris ce schéma de manière concise en expliquant sa structure, "
"son organisation et les relations entre ses éléments. Identifie "
"le message principal qu'il communique.\n\n"
"Description du schéma :\n{text}",
"tableau": "Résume les informations essentielles présentées dans ce tableau "
"en identifiant les tendances, les valeurs importantes et les "
"relations entre les données.\n\n"
"Description du tableau :\n{text}",
"formule": "Explique cette formule mathématique de manière concise et accessible, "
"en précisant son contexte, sa signification et ses applications "
"pratiques.\n\n"
"Description de la formule :\n{text}"
},
"en": {
"standard": "Summarize the following text by capturing the essential points "
"in a concise and accurate manner. Preserve key information "
"while reducing length.\n\n"
"Text to summarize:\n{text}",
"analytical": "Analyze the following text by identifying key concepts, "
"main arguments, and implications. Provide a summary "
"that highlights important insights.\n\n"
"Text to analyze:\n{text}",
"schéma": "Describe this diagram concisely by explaining its structure, "
"organization, and relationships between elements. Identify "
"the main message it communicates.\n\n"
"Diagram description:\n{text}",
"tableau": "Summarize the essential information presented in this table "
"by identifying trends, important values, and relationships "
"between the data.\n\n"
"Table description:\n{text}",
"formule": "Explain this mathematical formula concisely and accessibly, "
"specifying its context, meaning, and practical applications.\n\n"
"Formula description:\n{text}"
}
}
def generate(self, text: str, summary_type: str = "standard", selection_type: Optional[str] = "") -> str:
"""
Génère un résumé ou une analyse du texte fourni
Args:
text (str): Texte à résumer ou analyser
summary_type (str): Type de résumé ("standard" ou "analytique")
selection_type (str, optional): Type de contenu ("schéma", "tableau", "formule")
Si fourni, remplace summary_type
Returns:
str: Le résumé ou l'analyse générée par le modèle
"""
if not text:
return ""
# Déterminer le type de prompt à utiliser
lang = self.config.get("language", "fr")
# Utiliser selection_type seulement s'il est non vide et existe dans les prompts
if selection_type and selection_type in self.prompts.get(lang, {}):
prompt_type = selection_type
else:
prompt_type = summary_type
# Obtenir le prompt approprié
if lang not in self.prompts or prompt_type not in self.prompts[lang]:
lang = "fr" # Langue par défaut
prompt_type = "standard" # Type par défaut
prompt_template = self.prompts[lang][prompt_type]
prompt = prompt_template.format(text=text)
try:
# Construire la payload pour l'API Ollama
payload = {
"model": self.model_name,
"prompt": prompt,
"options": {
"temperature": self.config.get("temperature", 0.2),
"top_p": self.config.get("top_p", 0.95),
"top_k": self.config.get("top_k", 40),
"num_predict": self.config.get("max_tokens", 1024)
}
}
# Dans une implémentation réelle, envoyer la requête à l'API Ollama
# response = requests.post(f"{self.endpoint}/api/generate", json=payload)
# json_response = response.json()
# return json_response.get("response", "")
# Pour cette démonstration, retourner un résumé simulé
length = len(text.split())
if prompt_type == "schéma":
return ("Ce schéma illustre une structure organisée présentant les relations "
"entre différents éléments clés. Il met en évidence la hiérarchie et "
"le flux d'information, permettant de comprendre rapidement le processus "
"ou le système représenté. Les composants principaux sont clairement "
"identifiés et leurs connections logiques sont bien établies.")
elif prompt_type == "tableau":
return ("Ce tableau présente des données structurées qui révèlent des tendances "
"significatives. Les valeurs clés montrent une corrélation entre les "
"différentes variables présentées. L'organisation des données permet "
"d'identifier rapidement les informations importantes et de comprendre "
"les relations entre elles. Les catégories principales sont clairement "
"distinguées.")
elif prompt_type == "formule":
return ("Cette formule mathématique exprime une relation fondamentale entre "
"plusieurs variables. Elle permet de calculer précisément les valeurs "
"recherchées en fonction des paramètres d'entrée. Son application "
"pratique concerne principalement la modélisation du phénomène décrit "
"dans le contexte. La structure de l'équation révèle la nature des "
"interactions entre les différentes composantes du système.")
elif prompt_type == "analytique":
return ("L'analyse approfondie du texte révèle plusieurs concepts clés interconnectés. "
"Les arguments principaux s'articulent autour d'une thèse centrale qui est "
"étayée par des preuves pertinentes. Les implications de ces idées sont "
"significatives pour le domaine concerné. Cette analyse met en lumière "
"les points essentiels tout en préservant la profondeur intellectuelle "
"du contenu original.")
else: # standard
# Génération d'un résumé approximativement 70% plus court
words = text.split()
summary_length = max(3, int(length * 0.3)) # Au moins 3 mots
if length < 20:
return text # Texte déjà court
return ("Ce texte présente de manière concise les informations essentielles "
"du contenu original. Les points clés sont préservés tout en éliminant "
"les détails superflus. La synthèse capture l'essence du message "
"en mettant l'accent sur les éléments les plus pertinents pour "
"la compréhension globale du sujet traité.")
except Exception as e:
return f"Erreur lors de la génération du résumé: {str(e)}"