Schéma de boucle de recherche approfondie
Requête → lecture → extraction → synthèse → nouvelle requête : recherche multi-sauts.
Schéma de boucle de recherche approfondie est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que la boucle de recherche approfondie ?
Une boucle de recherche approfondie est un modèle d'agent dans lequel l'agent effectue des recherches successives, lit les résultats, repère les lacunes dans ses connaissances, puis effectue de nouvelles recherches jusqu'à avoir recueilli suffisamment d'informations pour rédiger une réponse complète.
Contrairement à une recherche unique, ce modèle imite le travail d'un chercheur humain : explorer → apprendre → découvrir ce qui est inconnu → approfondir.
Vue d'ensemble de l'architecture de la boucle
La boucle de recherche approfondie comprend cinq phases qui se répètent :
- Requête initiale — effectuer une recherche à partir de la question originale de l'utilisateur
- Lire les meilleurs résultats — extraire les faits essentiels des 3 meilleures sources
- Repérer les lacunes — quelles questions importantes restent-elles sans réponse ?
- Requêtes de suivi — générer des recherches ciblées pour combler les lacunes
- Synthétiser — combiner tous les faits recueillis dans une réponse finale
def deep_research(question, max_iterations=3):
all_facts = []
queries_used = [question]
for iteration in range(max_iterations):
results = search_and_rank(queries_used[-1])
facts = extract_facts(results, question)
all_facts.extend(facts)
gaps = identify_knowledge_gaps(question, all_facts)
if not gaps:
print(f'Research complete after {iteration + 1} iterations')
break
follow_up = generate_follow_up_query(gaps)
queries_used.append(follow_up)
print(f'Iteration {iteration + 1}: {follow_up}')
return synthesize_answer(question, all_facts)Phase 1 : recherche initiale
La première recherche utilise la question originale de l'utilisateur. Récupérez 3 à 5 résultats et extrayez leur contenu textuel brut. Cette phase vise la couverture : obtenir une vue d'ensemble du sujet.
from tavily import TavilyClient
import os
client = TavilyClient(api_key=os.getenv('TAVILY_API_KEY'))
def initial_search(question, n_results=5):
results = client.search(
query=question,
max_results=n_results,
search_depth='advanced' # deeper extraction for research tasks
)
return results.get('results', [])
# Also capture the direct answer if available
def get_direct_answer(question):
results = client.search(query=question, max_results=3)
return results.get('answer', '') # Tavily's synthesized answerPhase 2 : extraction des faits essentiels
Transmettez les résultats de recherche bruts au LLM et demandez-lui d'extraire des faits précis et vérifiables qui concernent la question de recherche. Les faits doivent être unitaires : une seule affirmation par élément.
EXTRACT_FACTS_PROMPT = '''You are a research assistant.
From the search results below, extract all factual claims relevant to the question.
Question: {question}
Search results:
{results_text}
Return a JSON list of facts:
["GPT-4 was released in March 2023",
"GPT-4 supports 128k context window",
...]
Only include verifiable facts. No opinions or summaries. JSON:'''
def extract_facts(results, question):
import json
results_text = '\n\n'.join(
f"[{i+1}] {r['title']}\n{r['content'][:600]}"
for i, r in enumerate(results)
)
response = llm_call(EXTRACT_FACTS_PROMPT.format(
question=question, results_text=results_text
))
return json.loads(response)Phase 3 : repérage des lacunes dans les connaissances
Après chaque itération de recherche, demandez au LLM : compte tenu de ce que nous savons jusqu'à présent, quels aspects importants de la question originale n'ont-ils toujours pas été abordés ?
Ces lacunes deviennent les requêtes de recherche de la prochaine série.
GAPS_PROMPT = '''You are a research analyst.
Original research question: {question}
Facts gathered so far:
{facts}
What important aspects of the question are still NOT covered by these facts?
List 2-3 specific knowledge gaps as a JSON array of strings.
If the question is fully answered, return an empty array [].
JSON:'''
def identify_knowledge_gaps(question, facts):
import json
facts_text = '\n'.join(f'- {f}' for f in facts)
response = llm_call(GAPS_PROMPT.format(
question=question, facts=facts_text
))
return json.loads(response)Phase 4 : génération des requêtes de suivi
Transformez les lacunes dans les connaissances en requêtes de recherche efficaces. Une lacune comme « Nous ne connaissons pas le modèle tarifaire » devient une requête ciblée comme « tarification de l'API GPT-4 par jeton 2024 ».
QUERY_GEN_PROMPT = '''Convert these knowledge gaps into specific web search queries.
Original topic: {topic}
Knowledge gaps:
{gaps}
Return a JSON array of search query strings.
Make each query specific and searchable.
JSON:'''
def generate_follow_up_queries(topic, gaps):
import json
gaps_text = '\n'.join(f'- {g}' for g in gaps)
response = llm_call(QUERY_GEN_PROMPT.format(
topic=topic, gaps=gaps_text
))
queries = json.loads(response)
return queries[:3] # max 3 follow-up queries per iterationCritères d'arrêt
Sans critères d'arrêt clairs, la boucle s'exécute indéfiniment. Arrêtez-la lorsque : (1) aucune lacune n'est repérée, (2) le nombre maximal d'itérations est atteint, (3) le budget de jetons est épuisé ou (4) les nouveaux faits sont trop similaires aux faits existants, ce qui indique des rendements décroissants.
MAX_ITERATIONS = 4
MAX_FACTS = 50
MIN_NEW_FACTS_TO_CONTINUE = 3
def should_continue(gaps, all_facts, new_facts, iteration):
if iteration >= MAX_ITERATIONS:
print(f'Stopping: max iterations ({MAX_ITERATIONS}) reached')
return False
if not gaps:
print('Stopping: no knowledge gaps found')
return False
if len(all_facts) >= MAX_FACTS:
print(f'Stopping: fact budget ({MAX_FACTS}) reached')
return False
if len(new_facts) < MIN_NEW_FACTS_TO_CONTINUE:
print(f'Stopping: diminishing returns ({len(new_facts)} new facts)')
return False
return True
if __name__ == '__main__':
print('Continue?', should_continue(gaps=['gap1'], all_facts=['f'] * 10, new_facts=['f1', 'f2', 'f3'], iteration=1))
print('Continue?', should_continue(gaps=[], all_facts=['f'] * 10, new_facts=['f1'], iteration=1))
Phase 5 : synthèse de la réponse finale
Une fois la boucle terminée, transmettez tous les faits recueillis au LLM pour leur synthèse. Le rôle du LLM consiste à organiser les faits en une réponse cohérente et bien structurée, avec attribution des sources.
SYNTHESIS_PROMPT = '''You are a research writer.
Original question: {question}
Researched facts (gathered from {n_iterations} search iterations):
{facts}
Write a comprehensive, well-structured answer based on these facts.
Format with clear sections. Be specific and cite facts where relevant.
If any aspect of the question could not be fully answered, say so.
Answer:'''
def synthesize_answer(question, all_facts, n_iterations):
facts_text = '\n'.join(f'- {f}' for f in all_facts)
return llm_call(SYNTHESIS_PROMPT.format(
question=question,
facts=facts_text,
n_iterations=n_iterations
))Suivi des sources au fil des itérations
Dans une boucle comportant plusieurs itérations, vous recueillez des faits provenant de nombreuses sources différentes. Notez la source de chaque fait afin que la réponse finale puisse les citer avec précision.
def extract_facts_with_sources(results, question):
import json
PROMPT = '''Extract facts from these search results. For each fact include the source URL.
Question: {question}
Results: {results_text}
Return JSON list:
[{{"fact": "GPT-4 supports 128k context", "source": "https://openai.com/..."}}, ...]
JSON:'''
results_text = '\n\n'.join(
f"[URL: {r['url']}]\n{r['content'][:500]}"
for r in results
)
response = llm_call(PROMPT.format(
question=question, results_text=results_text
))
return json.loads(response)Exécution parallèle des recherches
Lorsque vous avez plusieurs requêtes de suivi, exécutez-les en parallèle avec asyncio afin de réduire la durée totale de la recherche. Cela peut faire passer une boucle de 3 itérations de 30 secondes à 15 secondes.
import asyncio
async def async_search(client, query):
# Tavily has async support
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(
None,
lambda: client.search(query=query, max_results=3)
)
return result.get('results', [])
async def parallel_search(queries):
tasks = [async_search(client, q) for q in queries]
results_list = await asyncio.gather(*tasks)
# Flatten
return [r for results in results_list for r in results]
# Run in event loop
all_results = asyncio.run(parallel_search(follow_up_queries))Déduplication des faits
Différentes sources énoncent souvent le même fait avec des mots différents. Avant la synthèse, dédupliquez les faits à l'aide de la similarité des représentations vectorielles afin d'éviter de répéter plusieurs fois les mêmes informations dans la réponse finale.
def deduplicate_facts(facts, similarity_threshold=0.92):
if not facts:
return facts
# Get embeddings for all facts
embeddings = [embed(f) for f in facts]
unique_indices = [0] # always keep first
for i in range(1, len(facts)):
is_duplicate = False
for j in unique_indices:
sim = cosine_similarity(embeddings[i], embeddings[j])
if sim > similarity_threshold:
is_duplicate = True
break
if not is_duplicate:
unique_indices.append(i)
unique_facts = [facts[i] for i in unique_indices]
print(f'Deduplicated: {len(facts)} -> {len(unique_facts)} facts')
return unique_factsVérification des connaissances
Quelle est la bonne condition d'arrêt d'une boucle de recherche approfondie lorsqu'aucune lacune dans les connaissances n'est trouvée ?
Récapitulatif : modèle de boucle de recherche approfondie
Le modèle de boucle de recherche approfondie suit le processus suivant : rechercher → extraire les faits → repérer les lacunes → générer des requêtes de suivi → répéter → synthétiser. Il reproduit le travail d'un chercheur humain.
Principales décisions de conception : critères d'arrêt (nombre maximal d'itérations, absence de lacunes, rendements décroissants), suivi des sources pour l'attribution, recherches parallèles pour accélérer le processus et déduplication des faits avant la synthèse. Limitez-vous à 3 ou 4 itérations afin d'équilibrer la profondeur, le coût et la latence.
Questions Fréquemment Posées
La leçon « Schéma de boucle de recherche approfondie » est-elle gratuite ?
Oui — le texte complet de « Schéma de boucle de recherche approfondie » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Schéma de boucle de recherche approfondie » ?
Requête → lecture → extraction → synthèse → nouvelle requête : recherche multi-sauts. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Schéma de boucle de recherche approfondie » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Tavily et SerpAPI pour la recherche des agents
- Classer et filtrer les résultats de recherche
- Schéma de boucle de recherche approfondie
- Combiner recherche Web et RAG