Docfile commited on
Commit
42180ce
·
verified ·
1 Parent(s): 2b143d9

Create crew_utils.py

Browse files
Files changed (1) hide show
  1. crew_utils.py +187 -0
crew_utils.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # crew_utils.py
2
+ from crewai import Agent, Crew, Process, Task
3
+ from crewai_tools import SerperDevTool
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+ from pydantic import BaseModel, Field
6
+ from typing import List
7
+ from pdf_tool import PDFTool
8
+
9
+ # --- Définition des outils ---
10
+ search_tool = SerperDevTool()
11
+ pdf_tool = PDFTool()
12
+
13
+ # --- Définition du LLM (Gemini) ---
14
+ # Remplace par ta clé API
15
+ api_key = "VOTRE_CLE_API_GOOGLE_AI_STUDIO"
16
+
17
+ # Vérifie si la clé API est définie
18
+ if not api_key:
19
+ raise ValueError("La clé API Google AI Studio n'est pas définie. Veuillez la configurer comme variable d'environnement GOOGLE_API_KEY.")
20
+
21
+ llm = ChatGoogleGenerativeAI(
22
+ model="gemini-pro", google_api_key=api_key, temperature=0.7
23
+ )
24
+
25
+ # --- Définition des agents ---
26
+ # Chef de Projet
27
+ project_manager = Agent(
28
+ role="Chef de Projet",
29
+ goal="Coordonner la création d'un exposé complet et de haute qualité sur le thème donné.",
30
+ backstory="Expert en gestion de projet et en coordination d'équipes, capable de diriger des projets complexes jusqu'à leur aboutissement.",
31
+ verbose=True,
32
+ llm=llm,
33
+ allow_delegation=True,
34
+ )
35
+
36
+ # Planificateur
37
+ planner = Agent(
38
+ role="Planificateur d'Exposé",
39
+ goal="Créer un plan détaillé et pertinent pour l'exposé.",
40
+ backstory="Spécialiste de la structuration de contenu, capable de générer des plans clairs et logiques pour des exposés complexes.",
41
+ verbose=True,
42
+ llm=llm,
43
+ )
44
+
45
+ # Rédacteurs (3 instances pour gérer l'introduction, le développement et la conclusion)
46
+ researcher_intro = Agent(
47
+ role="Rédacteur Spécialisé en Introduction",
48
+ goal="Rédiger une introduction captivante pour l'exposé.",
49
+ backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.",
50
+ verbose=True,
51
+ llm=llm,
52
+ tools=[search_tool],
53
+ )
54
+
55
+ researcher_dev = Agent(
56
+ role="Rédacteur Spécialisé en Développement",
57
+ goal="Rédiger les sections de développement de l'exposé.",
58
+ backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.",
59
+ verbose=True,
60
+ llm=llm,
61
+ tools=[search_tool],
62
+ )
63
+
64
+ researcher_conclusion = Agent(
65
+ role="Rédacteur Spécialisé en Conclusion",
66
+ goal="Rédiger une conclusion percutante pour l'exposé.",
67
+ backstory="Expert en recherche et en rédaction, capable de produire du contenu informatif et bien écrit sur des sujets variés.",
68
+ verbose=True,
69
+ llm=llm,
70
+ tools=[search_tool],
71
+ )
72
+
73
+ # Assembleur
74
+ assembler = Agent(
75
+ role="Assembleur d'Exposé",
76
+ 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.",
77
+ 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.",
78
+ verbose=True,
79
+ llm=llm,
80
+ tools=[pdf_tool],
81
+ )
82
+
83
+ # --- Définition des tâches ---
84
+ # Tâche pour le Planificateur
85
+ create_plan_task = Task(
86
+ description="""
87
+ Créez un plan détaillé pour un exposé sur le thème suivant : {topic}.
88
+ Le plan doit inclure une introduction, plusieurs sections principales (au moins 3), et une conclusion.
89
+ Assurez-vous que le plan est logique et couvre tous les aspects importants du sujet.
90
+ Divisez les sections principales en sous-sections si nécessaire pour une meilleure organisation.
91
+ """,
92
+ expected_output="Un plan d'exposé structuré avec des titres de sections et sous-sections, en format Markdown.",
93
+ agent=planner,
94
+ )
95
+
96
+ class SectionContent(BaseModel):
97
+ title: str = Field(..., description="Titre de la section")
98
+ content: str = Field(..., description="Contenu de la section")
99
+
100
+ # Tâches pour les Rédacteurs (exemple pour 3 sections, à adapter)
101
+ async def write_section_task(
102
+ researcher: Agent, section_title: str, context: List[Any]
103
+ ) -> Task:
104
+ return Task(
105
+ description=f"""
106
+ Rédigez la section '{section_title}' de l'exposé en vous basant sur le plan fourni.
107
+ Effectuez des recherches approfondies en utilisant l'outil de recherche pour enrichir le contenu.
108
+ La section doit être informative, bien écrite et doit respecter le ton académique d'un exposé.
109
+ Voici le contexte: {context}
110
+ """,
111
+ expected_output=f"Texte complet et bien rédigé pour la section '{section_title}' de l'exposé, au format Markdown.",
112
+ agent=researcher,
113
+ tools=[search_tool],
114
+ output_pydantic=SectionContent, # Utilisez le modèle Pydantic ici
115
+ context=context,
116
+ )
117
+
118
+ # Tâche pour l'Assembleur
119
+ compile_report_task = Task(
120
+ description="""
121
+ Compilez toutes les sections rédigées de l'exposé dans un seul document.
122
+ Organisez les sections selon le plan fourni par le planificateur.
123
+ Générez un document PDF final prêt pour la présentation.
124
+ Assurez-vous que le document est bien structuré, facile à lire et qu'il respecte les conventions d'un exposé académique.
125
+ Voici le contexte: {context}
126
+ """,
127
+ expected_output="Un document PDF complet de l'exposé, prêt à être présenté.",
128
+ agent=assembler,
129
+ tools=[pdf_tool],
130
+ )
131
+
132
+ # --- Orchestration des tâches avec un processus hiérarchique ---
133
+ async def process_section_tasks(
134
+ manager: Agent,
135
+ plan: Any, # Remplace Any par le type de retour attendu de la tâche create_plan_task
136
+ researchers: List[Agent],
137
+ ):
138
+ # Assume que plan est une liste de titres de sections
139
+ sections = plan.split("\n") # Adapter selon le format réel du plan
140
+ section_tasks: List[Task] = []
141
+
142
+ for i, section in enumerate(sections):
143
+ if section != "":
144
+ researcher = researchers[i % len(researchers)]
145
+ section_task = await write_section_task(
146
+ researcher=researcher,
147
+ section_title=section.strip(),
148
+ context=[create_plan_task],
149
+ )
150
+ section_tasks.append(section_task)
151
+
152
+ return section_tasks
153
+
154
+ class ExposeCrew(Crew):
155
+ def __init__(self, agents, tasks, process, manager_llm, verbose):
156
+ super().__init__(agents=agents, tasks=tasks, process=process, manager_llm=manager_llm, verbose=verbose)
157
+
158
+ async def kickoff(self, inputs: dict = {}) -> str:
159
+ # Exécuter la tâche de création du plan
160
+ plan = await create_plan_task.execute(context=inputs)
161
+ print(f"Plan de l'exposé : {plan}")
162
+
163
+ # Créer et exécuter les tâches de rédaction de section en parallèle
164
+ section_tasks = await process_section_tasks(
165
+ manager=self.manager_llm,
166
+ plan=plan,
167
+ researchers=[researcher_intro, researcher_dev, researcher_conclusion],
168
+ )
169
+
170
+ section_outputs = await asyncio.gather(*[task.execute() for task in section_tasks])
171
+
172
+ print(f"Sections rédigées : {section_outputs}")
173
+
174
+ # Mettre à jour la description de la tâche de compilation avec les sections rédigées
175
+ compile_report_task.description = f"""
176
+ Compilez toutes les sections rédigées de l'exposé dans un seul document.
177
+ Organisez les sections selon le plan fourni par le planificateur :
178
+ {plan}
179
+ Sections rédigées :
180
+ {section_outputs}
181
+ Générez un document PDF final prêt pour la présentation.
182
+ """
183
+ compile_report_task.context = section_tasks
184
+
185
+ # Exécuter la tâche de compilation
186
+ result = await compile_report_task.execute(context=section_outputs)
187
+ return result