|
import os |
|
import gradio as gr |
|
import requests |
|
from crewai import Agent, Task, Crew, Process |
|
from dotenv import load_dotenv |
|
from langchain_openai import ChatOpenAI |
|
from langchain_community.tools import DuckDuckGoSearchRun, DuckDuckGoSearchResults |
|
from crewai_tools import tool, SeleniumScrapingTool, ScrapeWebsiteTool |
|
from duckduckgo_search import DDGS |
|
|
|
from newspaper import Article |
|
|
|
load_dotenv() |
|
|
|
|
|
openai_api_key = os.getenv('OPENAI_API_KEY') |
|
if not openai_api_key: |
|
raise EnvironmentError("OPENAI_API_KEY is not set in environment variables") |
|
|
|
def fetch_content(url): |
|
try: |
|
article = Article(url) |
|
article.download() |
|
article.parse() |
|
return article.text |
|
except Exception as e: |
|
print("ERROR: " + str(e)) |
|
return f"Error fetching content: {e}" |
|
|
|
|
|
@tool('DuckDuckGoSearchResults') |
|
def search_results(search_query: str) -> dict: |
|
""" |
|
Effectue une recherche sur le Web pour rassembler et renvoyer une collection de résultats de recherche. |
|
Cet outil automatise la récupération d'informations Web liées à une requête spécifiée. |
|
Args : |
|
- search_query (str) : La chaîne de requête qui spécifie les informations à rechercher sur le Web. Il doit s'agir d'une expression claire et concise des besoins d'information de l'utilisateur. |
|
Retours : |
|
- list : Une liste de dictionnaires, où chaque dictionnaire représente un résultat de recherche. Chaque dictionnaire comprend un « extrait » de la page et le « lien » avec l'URL qui y renvoie. |
|
""" |
|
results = DDGS().text(search_query, max_results=5, timelimit='m') |
|
results_list = [{"title": result['title'], "snippet": result['body'], "link": result['href']} for result in results] |
|
return results_list |
|
|
|
@tool('WebScrapper') |
|
def web_scrapper(url: str, topic: str) -> str: |
|
""" |
|
Un outil conçu pour extraire et lire le contenu d'un lien spécifié et générer un résumé sur un sujet spécifique. |
|
Il est capable de gérer différents types de pages Web en effectuant des requêtes HTTP et en analysant le contenu HTML reçu. |
|
Cet outil est particulièrement utile pour les tâches de web scraping, la collecte de données ou l'extraction d'informations spécifiques à partir de sites Web. |
|
|
|
Args: |
|
- url (str) : L'URL à partir de laquelle récupérer le contenu. |
|
- topic (str) : Le sujet spécifique sur lequel générer un résumé. |
|
Returns: |
|
- summary (str): résumé de l'url sur le sujet |
|
""" |
|
|
|
content = fetch_content(url) |
|
|
|
|
|
prompt = f"Générer un résumé du contenu suivant sur le sujet ## {topic} ### \n\nCONTENT:\n\n" + content |
|
|
|
|
|
openai_llm = ChatOpenAI(temperature=0.4, model_name="gpt-3.5-turbo") |
|
response = openai_llm.invoke(prompt) |
|
|
|
summary_response = f"""### |
|
Summary: |
|
{response.content} |
|
|
|
URL: {url} |
|
### |
|
""" |
|
|
|
return summary_response |
|
|
|
def kickoff_crew(topic: str, model_choice: str) -> str: |
|
try: |
|
|
|
openai_llm = ChatOpenAI(temperature=0, model_name=model_choice) |
|
|
|
|
|
researcher = Agent( |
|
role='Researcher', |
|
goal=f'Rechercher et collecter des informations détaillées sur le sujet ## {topic} ##', |
|
tools=[search_results, web_scrapper], |
|
llm=openai_llm, |
|
backstory=( |
|
"Vous êtes un chercheur méticuleux, habile à parcourir de grandes quantités d'informations pour en extraire des informations essentielles sur un sujet donné. " |
|
"Votre souci du détail garantit la fiabilité et l'exhaustivité de vos découvertes. " |
|
"Avec une approche stratégique, vous analysez et documentez soigneusement les données, dans le but de fournir des résultats précis et fiables." |
|
), |
|
allow_delegation=False, |
|
max_iter=15, |
|
max_rpm=20, |
|
memory=True, |
|
verbose=True |
|
) |
|
|
|
|
|
editor = Agent( |
|
role='Editor', |
|
goal=f'Compiler et affiner les informations dans un rapport complet sur le sujet ## {topic} ##', |
|
llm=openai_llm, |
|
backstory=( |
|
"En tant qu'éditeur expert, vous êtes spécialisé dans la transformation de données brutes en rapports clairs et attrayants. " |
|
"Votre maîtrise de la langue et votre souci du détail garantissent que chaque rapport ne transmet pas seulement des informations essentielles" |
|
"mais il est également facilement compréhensible et attrayant pour des publics divers." |
|
), |
|
allow_delegation=False, |
|
max_iter=5, |
|
max_rpm=15, |
|
memory=True, |
|
verbose=True |
|
) |
|
|
|
|
|
research_task = Task( |
|
description=( |
|
f"Utilisez l'outil DuckDuckGoSearchResults pour collecter des extraits de recherche initiaux sur ## {topic} ##. " |
|
f"Si des recherches plus détaillées sont nécessaires, générez et exécutez de nouvelles requêtes liées à ## {topic} ##. " |
|
"Ensuite, utilisez l'outil WebScrapper pour approfondir les URL importantes identifiées à partir des extraits de code, en extrayant ainsi des informations et des insights supplémentaires. " |
|
"Compilez ces résultats dans un avant-projet, en documentant toutes les sources, titres et liens pertinents associés au sujet. " |
|
"Assurez une grande précision tout au long du processus et évitez toute fabrication ou fausse représentation des informations." |
|
), |
|
expected_output=( |
|
"Un projet de rapport structuré sur le sujet, comprenant une introduction, un corps principal détaillé organisé par différents aspects du sujet et une conclusion. " |
|
"Chaque section doit citer correctement les sources, fournissant un aperçu complet des informations recueillies." |
|
), |
|
agent=researcher |
|
) |
|
|
|
|
|
edit_task = Task( |
|
description=( |
|
"Révisez et affinez le projet de rapport initial de la tâche de recherche. Organisez le contenu de manière logique pour améliorer le flux d'informations. " |
|
"Vérifiez l'exactitude de toutes les données, corrigez les écarts et mettez à jour les informations pour vous assurer qu'elles reflètent les connaissances actuelles et qu'elles sont bien étayées par les sources. " |
|
"Améliorez la lisibilité du rapport en améliorant la clarté du langage, en ajustant les structures de phrases et en maintenant un ton cohérent. " |
|
"Inclure une section répertoriant toutes les sources utilisées, formatée sous forme de puces suivant ce modèle : " |
|
"- titre : url'." |
|
), |
|
expected_output=( |
|
f"Un rapport soigné et complet sur le sujet ## {topic} ##, avec un récit clair et professionnel qui reflète fidèlement les résultats de la recherche. " |
|
"Le rapport doit comprendre une introduction, une section de discussion approfondie, une conclusion concise et une liste de sources bien organisée. " |
|
"Assurez-vous que le document est grammaticalement correct et prêt à être publié ou présenté." |
|
), |
|
agent=editor, |
|
context=[research_task] |
|
) |
|
|
|
|
|
crew = Crew( |
|
agents=[researcher, editor], |
|
tasks=[research_task, edit_task], |
|
process=Process.sequential, |
|
) |
|
|
|
|
|
result = crew.kickoff() |
|
if not isinstance(result, str): |
|
result = str(result) |
|
return result |
|
except Exception as e: |
|
return f"Error: {str(e)}" |
|
|
|
def main(): |
|
"""Set up the Gradio interface for the CrewAI Research Tool.""" |
|
with gr.Blocks() as demo: |
|
gr.Markdown("## Martian CrewAI Research Tool") |
|
topic_input = gr.Textbox(label="Entrer le sujet de recherche", placeholder="Écrivez le sujet ici..") |
|
model_choice = gr.Radio(choices=["gpt-3.5-turbo", "gpt-4"], label="Choissisez un modèle") |
|
submit_button = gr.Button("Commencez la Recherche!") |
|
output = gr.Markdown(label="Résultats") |
|
|
|
submit_button.click( |
|
fn=kickoff_crew, |
|
inputs=[topic_input, model_choice], |
|
outputs=output |
|
) |
|
|
|
demo.launch(debug=True) |
|
|
|
if __name__ == "__main__": |
|
main() |