Intermédiaire
🧠 Fondamentaux
20 XP
0 personnes ont réussi
Outil : recherche web avec Tavily
Ton agent a besoin d'yeux sur le web. Quand l'utilisateur demande "Quelles sont les dernieres nouvelles sur Python 3.13 ?", l'agent doit pouvoir chercher des informations en temps reel. C'est ce qui differencie un agent d'un simple chatbot : il ne se contente pas de ses connaissances, il va chercher.
Tavily est une API de recherche web concue specialement pour les agents IA. Elle renvoie des resultats propres avec titre, URL, et un extrait de texte. Tu peux aussi utiliser SerpAPI ou l'API Google, mais Tavily est la plus simple pour commencer.
La reponse contient une liste de resultats avec des cles comme "title", "url", "content".
Ecris une fonction rechercher_web(query, max_results=5, search_fn=None) qui prend une requete, un nombre maximum de resultats, et une fonction de recherche optionnelle. Si search_fn est None, elle utilise Tavily. Sinon, elle utilise la fonction fournie (injection de dependances pour les tests).
La fonction doit renvoyer une liste de dictionnaires, chaque dictionnaire ayant les cles "titre", "url", et "extrait". L'extrait doit etre tronque a 500 caracteres maximum.
Ecris aussi une fonction formater_resultats(resultats) qui prend cette liste et renvoie une chaine de texte formatee, lisible par un LLM. Chaque resultat doit etre numerote avec son titre, son URL et son extrait.
def fake_search(query, max_results):
return [
{"title": f"Resultat pour {query}", "url": "https://example.com/1", "content": "Contenu du premier resultat"},
{"title": "Deuxieme resultat", "url": "https://example.com/2", "content": "Contenu du second resultat"},
][:max_results]
r = rechercher_web("Python", max_results=2, search_fn=fake_search)
assert isinstance(r, list), "La fonction doit retourner une liste"
assert len(r) == 2, f"Attendu 2 resultats, obtenu {len(r)}"
assert "titre" in r[0] and "url" in r[0] and "extrait" in r[0]
assert "Python" in r[0]["titre"]
Extrait tronque a 500 caracteres
def fake_search(query, max_results):
return [{"title": "Long", "url": "https://x.com", "content": "A" * 1000}]
r = rechercher_web("test", search_fn=fake_search)
assert len(r[0]["extrait"]) <= 500, f"L'extrait doit etre tronque a 500 max, obtenu {len(r[0]['extrait'])}"
Formatage des resultats
resultats = [
{"titre": "Premier", "url": "https://a.com", "extrait": "Contenu A"},
{"titre": "Second", "url": "https://b.com", "extrait": "Contenu B"},
]
texte = formater_resultats(resultats)
assert "[1]" in texte and "[2]" in texte, "Les resultats doivent etre numerotes"
assert "https://a.com" in texte and "https://b.com" in texte
assert "Contenu A" in texte and "Contenu B" in texte
Formatage liste vide
texte = formater_resultats([])
assert isinstance(texte, str), "Le formatage doit retourner un string"
assert len(texte) > 0, "Le formatage d'une liste vide doit retourner un message"
+ 0 tests cachés
Indices (3 disponibles)
Solution officielle
def rechercher_web(query, max_results=5, search_fn=None):
if search_fn is None:
from tavily import TavilyClient
import os
client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
response = client.search(query, max_results=max_results)
raw_results = response.get("results", [])
else:
raw_results = search_fn(query, max_results)
resultats = []
for r in raw_results:
extrait = r.get("content", "")[:500]
resultats.append({
"titre": r.get("title", "Sans titre"),
"url": r.get("url", ""),
"extrait": extrait
})
return resultats
def formater_resultats(resultats):
if not resultats:
return "Aucun resultat trouve."
parties = []
for i, r in enumerate(resultats, 1):
partie = f"[{i}] {r['titre']}\nURL: {r['url']}\nExtrait: {r['extrait']}"
parties.append(partie)
return "\n\n".join(parties)