from typing import Any, Optional from smolagents.tools import Tool import duckduckgo_search class DuckDuckGoSearchTool(Tool): name = "web_search" description = ( "Effectue une recherche web DuckDuckGo et renvoie un court résumé en français " "des principaux résultats." ) inputs = { "query": { "type": "string", "description": "La requête de recherche à effectuer.", } } output_type = "string" def __init__(self, max_results: int = 5, **kwargs): super().__init__() self.max_results = max_results try: from duckduckgo_search import DDGS except ImportError as e: raise ImportError( "Vous devez installer le paquet `duckduckgo-search` pour utiliser ce tool " "(ex: `pip install duckduckgo-search`)." ) from e self.ddgs = DDGS(**kwargs) def forward(self, query: str) -> str: # Récupération des résultats bruts results = self.ddgs.text(query, max_results=self.max_results) # Aucun résultat trouvé → message clair plutôt qu'exception if not results: return ( f'Aucun résultat trouvé pour la requête "{query}". ' "Essaie une formulation plus courte ou plus générale." ) # On ne garde que les premiers résultats les plus utiles top_results = results[:3] # Construction d'un résumé lisible en français lines = [f'Voici quelques résultats pour la requête "{query}" :', ""] for idx, r in enumerate(top_results, start=1): title = r.get("title", "").strip() url = r.get("href", "").strip() snippet = r.get("body", "").strip() # On coupe les extraits trop longs if len(snippet) > 220: snippet = snippet[:217].rstrip() + "..." lines.append(f"{idx}. {title or '(titre manquant)'}") if url: lines.append(f" Lien : {url}") if snippet: lines.append(f" Résumé : {snippet}") lines.append("") # ligne vide entre les résultats return "\n".join(lines).strip()