Spaces:
Sleeping
Sleeping
| # crew_utils.py | |
| import asyncio | |
| from typing import Any, List | |
| from crewai import Agent, Crew, Process, Task | |
| from crewai_tools import SerperDevTool | |
| from crewai import LLM | |
| from pydantic import BaseModel, Field | |
| # --- Installation des dépendances (si nécessaire) --- | |
| # Assure-toi que les packages nécessaires sont installés. | |
| # Tu peux exécuter `crewai install` si tu as utilisé le CLI de CrewAI pour initialiser le projet. | |
| # Sinon, installe-les manuellement avec : | |
| # pip install crewai crewai-tools langchain-google-genai reportlab | |
| # --- Outil de génération de PDF (exemple avec reportlab) --- | |
| # Crée un fichier `pdf_tool.py` dans le même répertoire que ce script, par exemple. | |
| from pdf_tool import PDFTool | |
| # --- Définition des outils --- | |
| search_tool = SerperDevTool() | |
| pdf_tool = PDFTool() | |
| # --- Définition du LLM (Gemini) --- | |
| # Remplace par ta clé API | |
| GEMINI_API_KEY = "AIzaSyD6yZxfVOnh63GXBJjakAupk9aP4CZrgrQ" | |
| llm = LLM( | |
| model="gemini/gemini-1.5-flash", | |
| temperature=0.7, | |
| timeout=120, # Seconds to wait for response | |
| max_tokens=8000, | |
| ) | |
| # --- Définition des agents --- | |
| # Chef de Projet | |
| project_manager = Agent( | |
| role="Chef de Projet", | |
| goal="Coordonner la création d'un exposé complet et de haute qualité sur le thème donné.", | |
| backstory="Expert en gestion de projet et en coordination d'équipes, capable de diriger des projets complexes jusqu'à leur aboutissement.", | |
| verbose=True, | |
| llm=llm, | |
| allow_delegation=True, | |
| ) | |
| # Planificateur | |
| planner = Agent( | |
| role="Planificateur d'Exposé", | |
| goal="Créer un plan détaillé et pertinent pour l'exposé.", | |
| backstory="Spécialiste de la structuration de contenu, capable de générer des plans clairs et logiques pour des exposés complexes.", | |
| verbose=True, | |
| llm=llm, | |
| ) | |
| # Rédacteurs (3 instances pour gérer l'introduction, le développement et la conclusion) | |
| researcher_intro = Agent( | |
| role="Rédacteur Spécialisé en Introduction", | |
| goal="Rédiger une introduction captivante pour l'exposé.", | |
| backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.", | |
| verbose=True, | |
| llm=llm, | |
| tools=[search_tool], | |
| ) | |
| researcher_dev = Agent( | |
| role="Rédacteur Spécialisé en Développement", | |
| goal="Rédiger les sections de développement de l'exposé.", | |
| backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.", | |
| verbose=True, | |
| llm=llm, | |
| tools=[search_tool], | |
| ) | |
| researcher_conclusion = Agent( | |
| role="Rédacteur Spécialisé en Conclusion", | |
| goal="Rédiger une conclusion percutante pour l'exposé.", | |
| backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.", | |
| verbose=True, | |
| llm=llm, | |
| tools=[search_tool], | |
| ) | |
| # Assembleur | |
| assembler = Agent( | |
| role="Assembleur d'Exposé", | |
| goal="Compiler toutes les sections rédigées de l'exposé dans un seul document et générer un document PDF final de qualité professionnelle.", | |
| backstory="Expert en mise en forme et en compilation de documents, capable de transformer des contenus distincts en un document final harmonieux et esthétique.", | |
| verbose=True, | |
| llm=llm, | |
| tools=[pdf_tool], | |
| ) | |
| # --- Définition des tâches --- | |
| # Tâche pour le Planificateur | |
| create_plan_task = Task( | |
| description=""" | |
| Créez un plan détaillé pour un exposé sur le thème suivant : {topic}. | |
| Le plan doit inclure une introduction, plusieurs sections principales (au moins 3), et une conclusion. | |
| Assurez-vous que le plan est logique et couvre tous les aspects importants du sujet. | |
| Divisez les sections principales en sous-sections si nécessaire pour une meilleure organisation. | |
| """, | |
| expected_output="Un plan d'exposé structuré avec des titres de sections et sous-sections, en format Markdown.", | |
| agent=planner, | |
| ) | |
| class SectionContent(BaseModel): | |
| title: str = Field(..., description="Titre de la section") | |
| content: str = Field(..., description="Contenu de la section") | |
| # Tâches pour les Rédacteurs (exemple pour 3 sections, à adapter) | |
| async def write_section_task( | |
| researcher: Agent, section_title: str, context: List[Task] | |
| ) -> Task: | |
| return Task( | |
| description=f""" | |
| Rédigez la section '{section_title}' de l'exposé en vous basant sur le plan fourni. | |
| Effectuez des recherches approfondies en utilisant l'outil de recherche pour enrichir le contenu. | |
| La section doit être informative, bien écrite et doit respecter le ton académique d'un exposé. | |
| Voici le contexte: {context} | |
| """, | |
| expected_output=f"Texte complet et bien rédigé pour la section '{section_title}' de l'exposé, au format Markdown.", | |
| agent=researcher, | |
| tools=[search_tool], | |
| output_pydantic=SectionContent, # Utilisez le modèle Pydantic ici | |
| context=context, | |
| ) | |
| # Tâche pour l'Assembleur | |
| compile_report_task = Task( | |
| description=""" | |
| Compilez toutes les sections rédigées de l'exposé dans un seul document. | |
| Organisez les sections selon le plan fourni par le planificateur. | |
| Générez un document PDF final prêt pour la présentation. | |
| Assurez-vous que le document est bien structuré, facile à lire et qu'il respecte les conventions d'un exposé académique. | |
| Voici le contexte: {context} | |
| """, | |
| expected_output="Un document PDF complet de l'exposé, prêt à être présenté.", | |
| agent=assembler, | |
| tools=[pdf_tool], | |
| ) | |
| # --- Orchestration des tâches avec un processus hiérarchique --- | |
| async def process_section_tasks( | |
| manager: Agent, | |
| plan: Any, # Remplace Any par le type de retour attendu de la tâche create_plan_task | |
| researchers: List[Agent], | |
| ): | |
| # Assume que plan est une liste de titres de sections | |
| sections = plan.split("\n") # Adapter selon le format réel du plan | |
| section_tasks: List[Task] = [] | |
| for i, section in enumerate(sections): | |
| if section != "": | |
| researcher = researchers[i % len(researchers)] | |
| section_task = await write_section_task( | |
| researcher=researcher, | |
| section_title=section.strip(), | |
| context=[create_plan_task], | |
| ) | |
| section_tasks.append(section_task) | |
| return section_tasks | |
| class ExposeCrew(Crew): | |
| def __init__(self, agents, tasks, process, manager_llm, verbose): | |
| super().__init__(agents=agents, tasks=tasks, process=process, manager_llm=manager_llm, verbose=verbose) | |
| async def kickoff(self, inputs: dict = {}) -> str: | |
| # Exécuter la tâche de création du plan | |
| plan = await create_plan_task.execute(context=inputs) | |
| self.log.info(f"Plan de l'exposé : {plan}") | |
| # Créer et exécuter les tâches de rédaction de section en parallèle | |
| section_tasks = await process_section_tasks( | |
| manager=self.manager_llm, | |
| plan=plan, | |
| researchers=[researcher_intro, researcher_dev, researcher_conclusion], | |
| ) | |
| sections_results = await asyncio.gather(*[task.execute() for task in section_tasks]) | |
| section_outputs = [result.content for result in sections_results] | |
| self.log.info(f"Sections rédigées : {section_outputs}") | |
| # Mettre à jour la description de la tâche de compilation avec les sections rédigées | |
| compile_report_task.description = f""" | |
| Compilez toutes les sections rédigées de l'exposé dans un seul document. | |
| Organisez les sections selon le plan fourni par le planificateur : | |
| {plan} | |
| Sections rédigées : | |
| {section_outputs} | |
| Générez un document PDF final prêt pour la présentation. | |
| """ | |
| compile_report_task.context = section_tasks | |
| # Exécuter la tâche de compilation | |
| result = await compile_report_task.execute() | |
| return result |