Points clés
- Les agents travaillent avec une fenêtre de contexte limitée, et la récupération d'informations échoue de trois manières : une recherche inefficace, trop de contexte d'un coup, et un contexte non pertinent ou périmé.
- Le harnais Deep Agents maintient les recherches de petite taille dès le départ. Les outils de système de fichiers intégrés recherchent avant de lire : glob correspond aux noms de fichiers, grep trouve les lignes correspondantes, et read_file lit une page à la fois. Les résultats d'outils trop volumineux sont déchargés : le résultat complet est sauvegardé dans des fichiers, mais l'agent ne reçoit que le chemin et un aperçu.
- Pour les outils de recherche personnalisés (comme le RAG), utilisez « récupérer, décharger, déléguer » : sauvegardez les résultats dans des fichiers, renvoyez les chemins, et laissez les sous-agents les lire. L'agent principal ne voit que ce qui est pertinent.
Imaginez que vous passez un examen à livre ouvert : vous avez techniquement toutes les réponses, mais étrangement, cela rend encore plus difficile de trouver la bonne réponse.
- Par où commencer même à chercher ?
- Comment savoir que vos sources sont correctes ?
- Comment optimiser votre temps pour ne pas gaspiller toute votre énergie dans des recherches redondantes ?
Trouver la bonne information efficacement n'est pas si simple.
Donnez une question à un agent et il se retrouve dans une situation similaire : il dispose d'une fenêtre de contexte limitée, donc comme nous les humains, il doit récupérer des informations pour accomplir certaines tâches (au lieu de tout avoir mémorisé). Lors des recherches, les agents peinent avec :
- Une recherche inefficace : chaque recherche coûte des tokens et du temps. Un agent qui cherche maladroitement (par exemple, ouvre chaque fichier juste pour voir ce qu'il contient, ou reformule sans cesse la même requête) peut remplir son contexte de résultats de recherche avant de trouver quoi que ce soit d'utile.
- Trop de contexte d'un coup : une seule recherche qui déverse un export complet de données ou une douzaine de documents remplit la fenêtre de contexte en un seul mouvement, ne laissant aucune place au travail lui-même.
- Un contexte non pertinent ou périmé : des informations obsolètes ou hors sujet peuvent sembler tout aussi convaincantes pour un modèle que la bonne réponse. Une fois présentes dans la fenêtre de contexte, l'agent peut s'appuyer dessus (et l'erreur se transmettra à chaque étape suivante).
Heureusement, plusieurs techniques sont à la disposition d'un agent pour lui permettre de récupérer les informations correctes . C'est le rôle d'un harnais d'agent d'appliquer ces techniques de manière stratégique pour fournir au modèle le bon contexte au bon moment pour la tâche donnée.
Cet article de blog couvre les défis de la récupération par les agents (trouver et n'extraire que les informations nécessaires à la tâche en cours), les techniques à notre disposition pour les combattre, et comment les garder à l'esprit lors de la conception d'un harnais d'agent (en utilisant le harnais Deep Agents de LangChain comme exemple).
Pour en savoir plus sur la gestion du contexte une fois qu'il est dans la fenêtre de contexte, consultez ce blog sur le Context Engineering.
Notre exemple : un agent d'analyse concurrentielle
Voyons comment cela peut s'appliquer à un cas d'usage réel : un agent d'analyse concurrentielle. Chaque lundi, un agent recherche des centaines de concurrents et rédige un rapport selon le modèle de l'équipe. Il doit :
- Retrouver les notes de la semaine dernière sur la société A
- Chercher un chiffre de revenus spécifique dans un vaste export de données de marché
- Interroger une archive d'actualités pour tout ce qui est nouveau
Chacune de ces tâches est un type de récupération différent et rencontre donc des problèmes différents. Nous avons construit notre agent à l'aide du harnais Deep Agents si bien qu'il existe quelques techniques applicables prêtes à l'emploi pour minimiser ces problèmes.
1. Recherches inefficaces
Notre agent doit trouver trois choses pour chaque concurrent. Si chacune prend une douzaine d'essais (ouvrir des fichiers juste pour voir ce qu'ils contiennent, ou reformuler une recherche parce que la source utilise d'autres mots), sa fenêtre de contexte se remplit de recherches infructueuses avant même qu'il n'écrive un mot du rapport.
Par conséquent, la meilleure recherche est celle que l'agent n'a pas besoin de répéter, ce qui signifie utiliser le bon outil pour chaque tâche.
Commencer par les outils de système de fichiers intégrés
L'un des moyens les plus courants pour un agent de rechercher dans l'information est d'utiliser un système de fichiers. Cependant, si notre agent ouvre chaque fichier pour voir ce qu'il contient, il recherche de manière très inefficace : chaque fichier lu atterrit dans sa fenêtre de contexte, qui peut donc se remplir rien qu'en regardant.
Une meilleure approche consiste à vérifier d'abord les noms et les mots-clés (comme lorsque vous parcourez l'index d'un livre au lieu de lire chaque page lors d'un examen à livre ouvert). Deux outils de système de fichiers courants font exactement cela :
globtrouve les fichiers selon un motif de nom. Par exemple,**/company-a*.mdtrouve les notes de la semaine dernière sur la société A.greprecherche à l'intérieur des fichiers sans les charger dans la fenêtre de contexte. Il cherche du texte littéral et peut renvoyer les fichiers correspondants, les lignes correspondantes ou des comptages.
Chaque agent profond est livré avec ces outils intégrés, aux côtés de ls, read_file, write_file et edit_file. Les mêmes outils fonctionnent quel que soit l'endroit où se trouvent les fichiers (état de l'agent, disque local, magasin persistant ou bac à sable), car ils passent tous par le backend.
Ajoutez un outil de récupération lorsque les mots-clés ne suffisent pas
Grep est génial quand vous savez quels mots rechercher, mais il ne correspond qu'aux exact « text que vous lui donnez. C'est un problème pour la troisième tâche de notre exemple : chercher dans une archive d'actualités tout ce qui est nouveau. Si notre agent recherche « Company A funding », il manquera un article intitulé « Company A closes $50M Series B », alors que c'est exactement ce qu'il cherche. »
Pour effectuer une recherche par sens plutôt que par mots exacts (recherche sémantique), vous ajoutez une outil de recherche soutenu par un magasin de vecteurs« . Un outil de récupération est tout outil que l'agent peut appeler pour obtenir des informations : il prend une requête, la recherche dans une source de données et renvoie ce qu'il trouve (les correspondances les plus proches). »
La manière dont un outil de recherche établit des correspondances dépend de la source de données qui le soutient. Adossé à un magasin de vecteurs, il trouve des correspondances par le sens, mais un outil de recherche peut aussi reposer sur d'autres sources de données :
- Une base de données SQL, pour les recherches structurées (comme les chiffres de ventes ou les dossiers clients)
- Une API de recherche (pour obtenir des informations récentes du web)
- Un Serveur MCP (pour des outils déjà créés par quelqu'un d'autre, comme une recherche dans la documentation)
Pour un aperçu plus approfondi du fonctionnement de la recherche sémantique, voir le guide de LangChain.
Laisser l'agent décider quand effectuer une recherche
Beaucoup de configurations de récupération effectuent une seule recherche au début, puis répondent. Cela fonctionne pour un bot de FAQ (RAG en 2 étapes), mais pas pour notre agent. Disons qu'à mi-chemin de ses recherches sur la société C, il trouve un article sur le lancement d'un produit qu'il ne connaissait pas, et qu'il a maintenant besoin des tarifs de ce produit (qu'il ne pouvait pas savoir qu'il fallait chercher au départ). Avec une seule recherche, le rapport part sans cette information.
Les agents de recherche ont besoin d'une récupération agentique (au lieu d'un RAG en 2 étapes) : l'agent décide quand rechercher, quoi rechercher, et s'il lui en faut davantage. Avec Deep Agents, cela fonctionne déjà ainsi par défaut : l'agent s'exécute dans une boucle et peut appeler n'importe quel outil autant de fois que nécessaire.
Empaquetez votre savoir-faire en recherche sous forme de skill
Pour aider l'agent à bien effectuer ses recherches, vous pouvez empaqueter votre savoir-faire en matière de recherche sous forme d'un compétence: un ensemble d'instructions pour une tâche spécifique (comme quel index utiliser, comment formuler les requêtes et comment formater les citations).
L'agent ne voit que le nom de chaque compétence et une courte description jusqu'à ce qu'une tâche la requière ; il charge alors les instructions complètes, de sorte que le savoir pointu est disponible au moment nécessaire sans occuper le contexte le reste du temps (une technique appelée divulgation progressive). En voici une explication vidéo.
2. Trop de contexte à la fois
Cependant, malgré l'optimisation du processus de recherche, même le droite la recherche peut renvoyer trop de choses. Notre agent n'a besoin que d'un seul chiffre issu de l'export des données de marché (le chiffre d'affaires trimestriel de la Company B), mais charger les 40,000 lignes pour le trouver remplirait sa fenêtre de contexte. Notre outil de récupération a le même problème : s'il renvoie chaque article de presse directement au modèle, quatre résultats par recherche sur cinq entreprises s'accumulent vite.
Lire de gros fichiers une page à la fois
Les outils de système de fichiers sont conçus pour renvoyer le moins d'informations possible. read_file lit un fichier une page à la fois (100 lignes par défaut), et l'agent peut définir un offset (la ligne à partir de laquelle commencer) et une limite (le nombre de lignes à lire) pour sauter directement à la partie dont il a besoin. Ainsi, pour trouver le chiffre d'affaires de la Company B, l'agent effectue un grep dessus, puis lit uniquement les quelques lignes autour du résultat.
Laissez le harnais décharger les résultats surdimensionnés
Parfois, un outil renvoie quand même plus que prévu. Lorsque le résultat d'un outil est trop volumineux (plus d'environ 20,000 tokens), le harnais l'enregistre dans un fichier sous /large_tool_results/ et fournit à l'agent le chemin ainsi qu'un court aperçu (les premières et dernières lignes). L'agent peut ensuite ne relire que les parties dont il a besoin avec read_file's offset et limit.
Faites en sorte que votre outil de récupération renvoie des chemins de fichiers
Vous pouvez appliquer la même idée à votre propre outil de récupération au lieu d'attendre la limite de taille : lui faire écrire chaque résultat dans un fichier et ne renvoyer que les chemins. Il s'agit de la première partie d'un modèle appelé « retrieve, offload, delegate » (Le guide RAG de LangChain le parcourt intégralement).
Voici un outil de récupération simplifié. Il exécute la recherche, enregistre chaque résultat sous forme de fichier dans le backendde l'agent, et ne renvoie que la liste des chemins de fichiers :
backend = StateBackend()
@tool
def search_news(query: str) -> str:
"""Search the news archive and save each result to a file."""
docs = vector_store.similarity_search(query, k=4)
files = [(f"/retrieved/result_{i}.md", doc.page_content.encode()) for i, doc in enumerate(docs)]
backend.upload_files(files)
return "Saved results to: " + ", ".join(path for path, _ in files)Désormais, l'agent principal voit quatre chemins courts au lieu de quatre articles complets.
3. Un contexte non pertinent ou obsolète
Des résultats compacts ne servent à rien s'il s'agit des mauvais résultats. Chacun de ces quatre fichiers pourrait concerner une entreprise différente portant un nom similaire, ou un article datant de deux ans. Un texte hors sujet ou périmé paraît tout aussi convaincant à un modèle que la bonne réponse, l'objectif est donc de l'exclure entièrement du contexte de l'agent principal.
Laisser les sous-agents filtrer les résultats
Cependant, l'agent principal doit quand même lire ces fichiers pour déterminer lesquels comptent (et chaque article hors sujet qu'il ouvre atterrit bien dans son contexte). C'est là qu'intervient la partie « déléguer » du modèle « récupérer, décharger, déléguer » : un sous-agent lit chaque fichier récupéré et ne renvoie que les faits essentiels.
- Définir le sous-agent : la description indique à l'agent principal quand l'utiliser (un fichier par appel), et le prompt système indique au sous-agent quoi faire avec ce fichier.
chunk_analyst = {
"name": "chunk-analyst",
"description": "Analyze one retrieved file. Pass the question and a single path under /retrieved/.",
"system_prompt": "Use read_file to read the assigned file. Return the key facts and the source URL.",
}- Donner à l'agent principal l'outil de récupération et le sous-agent. Passez le même backend que celui utilisé dans
search_newsafin que le sous-agent puisse lire les fichiers enregistrés par l'outil.
agent = create_deep_agent(
model=model,
tools=[search_news],
backend=backend, # same instance, so read_file can see /retrieved/
subagents=[chunk_analyst],
)Le flux est désormais le suivant :
- Recherche: l'agent principal appelle
search_newset obtient quatre chemins. - Délégation: il envoie chaque chemin à un sous-agent analyste de segments, et ceux-ci peuvent s'exécuter en parallèle.
- Synthèse: chaque analyste renvoie un court résumé avec sa source. L'agent principal les combine et relance une recherche si quelque chose manque.
Les résultats bruts vont dans des fichiers, la lecture bruyante se fait dans des sous-agents dotés de leurs propres fenêtres de contexte, et l'agent principal ne voit jamais que des conclusions. Tout ce qui est hors sujet reste dans le contexte du sous-agent, et la fenêtre de contexte de l'agent principal reste dégagée !
S'appuyer sur des sources à jour
Le filtrage permet bien d'exclure les résultats hors sujet, mais il ne peut pas corriger les résultats périmés. Notre agent d'analyse concurrentielle s'exécute chaque lundi, l'index du mois dernier ne captera donc pas l'actualité de cette semaine.
Une solution : une API de recherche ou un serveur MCP pourrait fournir à l'agent des informations à jour (au lieu de tout ce qui a été indexé il y a des mois). Si vos données comportent des dates, le filtrage par date dans l'outil de récupération permettrait aussi d'exclure les anciens résultats.
Se méfier du texte récupéré
À l'inverse, des résultats actuels et pertinents peuvent aussi poser problème ! Comme le texte récupéré est une donnée et non une instruction, tout ce que vous récupérez pourrait contenir une injection de prompt (et aucune stratégie de prompt ou de délimiteur ne l'empêche totalement). Assurez-vous de valider les sorties : vérifiez que les réponses citent les sources attendues et que les affirmations correspondent à celles-ci.
Stratégies de récupération à garder à l'esprit
Voici ce à quoi il faut faire attention (quel que soit le harnais sur lequel vous construisez) :
- Utilisez l'outil le plus efficace qui fonctionne. Si vous connaissez les mots, grep est plus efficace qu'une recherche par embedding. Réservez la recherche sémantique aux cas où vous en avez réellement besoin.
- Lisez par pages au lieu de tout charger. Lisez les fichiers volumineux par morceaux plutôt qu'en une seule fois.
- Renvoyez des pointeurs au lieu des charges utiles. Écrivez le contenu récupéré dans des fichiers et transmettez les chemins à l'agent.
- Déléguez la lecture. Laissez des sous-agents lire et résumer afin que l'agent principal ne voie que les conclusions.
- Vérifiez l'ancrage. Contrôlez les réponses par rapport à ce qui a été récupéré, et traitez le texte récupéré comme non fiable.
Essayez-le
uv add deepagentsVous voulez en apprendre davantage avec un formateur en direct ? J'aborderai ce sujet le 9 novembre : Inscrivez-vous ICI!
La récupération ne représente que la moitié de l'histoire : la manière dont l'information parvient à l'agent. Comment gérer la fenêtre de contexte de l'agent à mesure que les informations s'accumulent au fil du temps ?
Pour en savoir plus, consultez :
- Un article de blog sur l'ingénierie du contexte avec Deep Agents
- Le cours Deep Agents sur LangChain Academy (gratuit, en ligne et à votre rythme).