Ingénierie du contexte pour un agent de recherche quantitatif : niveaux de preuve et stocks de données
Ingénierie de contexte pour un agent de recherche WorldQuant : règles, observations et croyances à des niveaux de preuve distincts, réparties sur un registre, un stock d’événements et un graphe.
Sources: My AI Agent is in ~Top-0.01% of WorldQuant Challenge #4: Context Engineering
Décider de ce en quoi un agent peut avoir confiance
Imaginez un environnement de recherche géré par une intelligence artificielle conçu pour la compétition quantique WorldQuant BRAIN. Avant même l’existence d’agents spécialisés, de vérifications liées au cycle de vie ou de boucles autonomes, il y a un problème de conception plus fondamental : quels énoncés le système peut-il considérer comme vrais ? Les données brutes arrivent sous quatre formes qui ont peu en commun.
Le premier élément est la documentation officielle de la plateforme et du tournoi, qui explique en détail le fonctionnement du langage d’expression, quels opérateurs et ensembles de données sont disponibles, ainsi quels paramètres de simulation sont autorisés. Le deuxième élément est la méthodologie : les trois livres de Marcos López de Prado fournissent des outils pour raisonner sur les statistiques de backtest, le risque stratégique, les tests multiples, la structure du portefeuille et la falsification, tandis que *Finding Alphas* d’Igor Tulchinsky aborde de manière pratique la construction d’idées, le taux de rotation, la corrélation, le surajustement, le biais et la durabilité. Le troisième élément est un ensemble d’articles et de notes de recherche approfondie sur les anomalies économiques, les acteurs du marché et le flux d’informations, qui peuvent être organisés sous forme de graphe reliant des axiomes, des théories, des anomalies, des mécanismes et des modalités d’implémentation. Le quatrième élément correspond à tout ce que le projet génère au cours de son exécution : les résultats des simulations, les courbes de profits et pertes quotidiennes, les corrélations des portefeuilles, les statistiques de résilience, les vérifications de la plateforme, les historiques des expériences, les événements opérationnels, les compilations échouées ainsi que les leçons tirées de celles-ci.
Chacun de ces éléments constitue un contexte, mais ils n’ont pas tous la même valeur de vérité, et aucun ne s’intègre facilement dans une seule instruction, un seul format de document ou une seule base de données. Par conséquent, l’ingénierie du contexte dans ce cadre commence ailleurs que par les budgets de tokens. Elle commence par la définition de niveaux de preuve, ainsi que par les systèmes de données qui permettent de préserver l’intégrité de chacun de ces niveaux.
À gauche se trouve la première conception naïve, dans laquelle les règles, les livres, les articles et les résultats du système eux-mêmes sont regroupés en une seule requête, tous ayant le même poids. À droite, chaque affirmation conserve son propre niveau : les règles forment les murs, les croyances proposent des tests, les observations affinent ces croyances, et rien à l’intérieur de ces murs ne peut les modifier.
Trois niveaux de preuve
Le terme « preuve » a un sens pratique. Pour toute affirmation, il faut se demander quelle preuve est suffisante, qui en est responsable et ce qui peut la contredire. Trois niveaux permettent de répondre à ces questions.
L1 recueille ce que la plateforme déclare être le jeu, en s’appuyant sur les documents officiels de la plateforme et des tournois. Lorsque l’agent a besoin de savoir quels paramètres existent, ce qu’un opérateur fait, quels contrôles un candidat doit passer ou comment le tournoi calcule son score, c’est là qu’il cherche. Une copie locale peut devenir obsolète, mais aucun experiment inattendu ne peut modifier une règle.
L2 recueille ce que le système a réellement observé. Les résultats de simulation y figurent, tout comme les séries de PnL quotidiennes, le portefeuille du jour, les contrôles de la plateforme, les événements opérationnels et l’état le plus récent du classement. Chaque mesure est accompagnée de l’heure à laquelle elle a été enregistrée. Une nouvelle exécution ne supprime rien ; elle génère une nouvelle observation, de sorte que l’historique n’est jamais mis à jour a posteriori.
L3 recueille ce que le système considère actuellement comme utile. Livres, articles, théories économiques, spécifications, lectures de graphes de connaissances, leçons écrites et éléments permettant de contredire des affirmations se trouvent dans cette couche. Ils guident les prochaines actions et restent susceptibles d’être remis en question.
L’ordre n’est pas strict : L1 l’emporte toujours sur L2, et L2 l’emporte toujours sur L3. Chaque niveau répond à un type de question différent. En cas de désaccord factuel entre sources, la version la plus directe et la plus solide l’emporte ; ainsi, une règle officielle prime sur une paraphrase contenue dans une instruction donnée à un agent, et une réponse mesurée prime sur ce à quoi un livre pourrait amener quelqu’un à s’attendre. Cependant, pour déterminer ce qu’il convient d’essayer ensuite, les règles et les mesures ne suffisent pas. C’est alors que L3 est nécessaire pour faire un choix fondé.
Trois idées sont suivies dans ce tableau. Le phénomène de dérive post-résultats n’a pas été éliminé par son facteur de falsification, qui a plutôt identifié la construction défaillante, ce qui a permis de reconstruire l’idée en se basant sur les révisions des analystes, deux versions ayant ainsi été soumises. Une idée basée sur un panier de pairs a débuté en tant que simple croyance sans aucune preuve et a tout de même été acceptée. Une idée liée à un calendrier de dividendes a échoué avec les dix constructions testées, et la leçon tirée a limité cette croyance aux seules dates de versement des dividendes. Les carrés verts ont réussi les vérifications de la plateforme, ceux en rose ont échoué, ceux en gris ne présentent aucune vérification enregistrée, et ceux entourés ont été soumis.
Une seule base de données peut contenir à la fois une mesure (L2) et la lecture que quelqu’un en fait (L3), ce qui signifie que le niveau s’attache à l’affirmation elle-même, et non à son emplacement de stockage. Un enregistrement de contexte utile est donc plus riche qu’un simple texte. Il doit enregistrer l’affirmation elle-même, son niveau épistémique, sa source, son propriétaire, son champ d’application, l’heure de l’observation ou de l’examen, l’incertitude, un identifiant stable ainsi que toute preuve pouvant la modifier. Pour les faits qui évoluent dans le temps, une paire de chronologies est utile : quand quelque chose était vrai, et quand le système l’a découvert. Les API qui répondent tardivement et complètent a posteriori les données historiques rendent cette lacune importante.
Le contexte est en réalité une petite plateforme de données
Chaque magasin est représenté en fonction de son comportement. Le registre empile les preuves en couches, et une chaîne d’ascendance les relie ; les événements anciens s’estompent, le graphique correspond à une paire de tables qui se transforme en multigraphe en mémoire, et les fichiers sont regroupés selon leur cycle de vie. Les identifiants stables maintiennent tout ensemble. Le résultat quotidien est toujours stocké à l’endroit que la spécification du projet indique comme étant le sien.
Lorsque des niveaux de preuve existent, un autre point devient évident : le contexte n’est pas un corpus unique. Il se comporte comme une plateforme de données modeste. La plus grande partie est le registre de recherche, qui, sur l’ordinateur de travail examiné, constitue une base de données SQLite transactionnelle. Le qualifier de table d’expérience est une sous-estimation, car il fonctionne comme un registre des preuves contenant plusieurs familles de données. Une famille concerne les intentions de recherche, c’est-à-dire les mécanismes, les hypothèses, les prédictions ainsi que l’évolution des implémentations. Une autre famille concerne les mesures, qui stocke les réponses de la plateforme, les statistiques intra-échantillon, les vérifications, le PnL quotidien et les indicateurs de tests de résistance. Une troisième famille concerne l’interprétation, avec des attributions, des leçons apprises et des éléments permettant de contredire les hypothèses. Enfin, une quatrième famille concerne la gouvernance, en suivant les décisions envisagées, les approbations et ce qui s’est passé lors de la soumission. La dernière catégorie est l’analyse matérialisée : deltas de portefeuille, écrans de corrélation, caches de motifs et résumés de tests de résistance, tous pouvant être régénérés à partir d’entrées canoniques.
L’audit a révélé une incohérence. Un document de conception indique que les résultats PnL quotidiens ont été transférés dans des fichiers Parquet, mais la base de données conserve encore chaque ligne. Le document représente une croyance (Niveau 3), tandis que la base de données constitue une observation (Niveau 2) ; en cas de conflit, c’est l’observation qui l’emporte.
Vient ensuite un stockage d’événements opérationnels, conservé en tant que base de données SQLite distincte. Ces événements peuvent contenir des identifiants de cycle, de lot, de candidat, d’hypothèse, d’agent et de processus, ainsi qu’un en-tête JSON versionné. Il serait tentant de les intégrer au registre, mais les exigences de conservation diffèrent. Les données de recherche étant canoniques, elles doivent perdurer. Les résultats de débogage, les événements d’envoi, les transitions en file d’attente et les interventions temporaires augmentent rapidement et peuvent être compressés ou périmés. En les gardant séparés, une vague soudaine de données d’observabilité ne peut ni alourdir ni bloquer le registre scientifique.
Il y a ensuite le graphe de connaissances, un graphe de propriétés transactionnel doté d’une structure physique délibérément simple : une table de nœuds, une table d’arêtes et des attributs JSON pour les preuves spécifiques à chaque type, tous chargés dans un graphe en mémoire afin de pouvoir être parcourus. La couche transactionnelle évite les problèmes de corruption et de concurrence liés à un seul fichier YAML géant, tandis que la représentation en mémoire permet un raisonnement plus fluide.
Le système de fichiers est également considéré comme un système de données. Un répertoire contient des documents de plateforme intouchables, des livres, des articles et des rapports dérivés, et il serait erroné de tout charger en mémoire, car leurs cycles de vie diffèrent. Les documents de plateforme ne changent jamais. Les spécifications font partie des priorités de conception gérées sous contrôle de version. Les rapports sont des dérivés qui nécessitent des données d’entrée enregistrées ainsi qu’un moyen de les regénérer. Les fichiers en mémoire sont de courts pointeurs lisible menant à des leçons réutilisables. Les fichiers de file d’attente, les caches et les journaux représentent un état opérationnel temporaire, tandis que les binaires de modèles, les exportations de PnL et les gros snapshots sont des artefacts qu’il vaut mieux conserver dans un stockage d’objets plutôt que dans Git.
Les histoires d’échec sont éloquentes. Un algorithme à très bon rendement a failli être rejeté parce que le registre indiquait que tous les contrôles étaient réussis, tandis qu’un script lisait un fichier de suivi indiquant un score de Sharpe égal à 0. L’un des premiers gagnants ne disposait d’aucun enregistrement de décision jusqu’à ce qu’une opération de rapprochement en fournisse un six semaines plus tard. Une décision de pari contre le modèle beta n’existait que dans un fichier de mémoire Markdown, de sorte que le registre lui-même n’aurait rien fait pour empêcher une nouvelle tentative.
On constate ainsi l’existence d’un système de contexte à multiples types, même si presque tout fonctionne encore sur un seul ordinateur portable. SQLite gère les transactions, le graphe gère les relations, Parquet est le format prévu pour les grandes séries temporelles, Markdown contient des connaissances que les gens peuvent consulter, et les fichiers temporaires coordonnent les processus locaux.
Ici apparaît un mécanisme réel dont les noms ont été supprimés. La partie gauche montre son ascendance dans le graphe de connaissances, tandis que la partie droite présente chaque hypothèse, expérience et candidat qui l’ont mis à l’épreuve. Certaines défaillances se sont reproduites dans toutes les constructions, tandis que d’autres étaient propres à une implémentation donnée. Les deux parties ne partagent rien d’autre que l’ID situé le long de la jointure, et cette seule clé suffit à les relier en un paquet de contexte compact.
Les mécanismes servent de lien entre les deux bases de données. Dans le graphe, ils apparaissent sous forme d’idées économiques accompagnées de leurs sources, tandis que dans le grand livre, ils se manifestent sous forme d’étiquettes sur chaque hypothèse et chaque candidat qui les a mis en œuvre. Les résumés empiriques peuvent être rattachés aux nœuds du graphe afin de faciliter la navigation, mais il s’agit seulement de reflets ; c’est dans la base de données expérimentale que se trouvent réellement les chiffres. Un bon paquet de contexte est donc constitué en reliant différents systèmes. Il combine un petit voisinage graphique, l’origine des sources, les agrégations empiriques actuelles, les échecs récents dans un cadre précis, ainsi que les contraintes de la plateforme en vigueur. Le modèle n’a pas besoin du graphe complet ni de chaque ligne de résultat PnL. Ce qui est utile, c’est le chemin le plus court menant aux preuves nécessaires pour la décision à prendre.
Lorsque le graphe et le registre partagent un identifiant de mécanisme, il est possible de voir ensemble toute une branche : la théorie, les expériences, chaque candidat, ainsi qu’un résumé sur le nœud du graphe qui reflète le registre. L’idée d’une autorisation de rachat provient directement d’un article de 1995, mais elle n’a jamais été associée à la branche des rachats partiels, de sorte que aucun de ses résultats n’est accessible depuis le graphe.
Il serait utile de rendre plusieurs contrats de données plus stricts. Les objets qui traversent différents entrepôts devraient indiquer explicitement la version du schéma JSON. Toute métrique dérivée devrait mentionner la version du code, le snapshot de la source ainsi que la version de la méthode qui l’a générée. Chaque expérience mérite un manifeste à adresse de contenu pour assurer sa reproductibilité, listant le commit du code, le résumé de l’environnement, les paramètres de la plateforme, ainsi que les identifiants de l’hypothèse et de l’implémentation. De plus, la réconciliation devrait être testée comme toute autre question liée à la qualité des données, et non considérée comme une opération sans risque.
En résumé, la conception repose sur le fait que le graphique constitue un contexte, le registre en est un autre, et le lien entre eux l’est également. Ce lien mérite les mêmes soins d’ingénierie que le code du modèle.
Où cela rencontre l’ingénierie des systèmes de gestion
Aucune demande n’est transmise dans son intégralité aux stores. Chaque store contribue d’une petite partie à un paquet structuré, et chaque spécialiste reçoit uniquement ce dont il a besoin. Les résultats sont renvoyés selon leur type vers les destinataires appropriés, les règles ne sont jamais écrites dessus, et deux boucles rechargent le paquet suivant à des vitesses différentes.
Ce point marque la frontière entre l’ingénierie du contexte et l’ingénierie du système d’exploitation. La gestion du contexte est responsable des niveaux L1 à L3 : elle gère les sources, les mesures, les priorités, l’origine, les timestamps, le champ d’application ainsi que les identifiants stables. Le niveau L4, qui correspond au système d’exploitation agent, décide quelles preuves doivent être récupérées, quelle quantité est autorisée au-delà d’une limite de niveau, quel spécialiste les reçoit et quelles conclusions sont valables. En dessous se trouvent le code source (L5), l’infrastructure locale (L6) et l’infrastructure distribuée (L7). Ces couches exécuteront une décision erronée sans faille, mais elles n’ont aucun pouvoir décisionnel quant au fait qu’une entrée soit une règle, une observation ou une croyance.
Dans une première version, cette séparation était moins nette. Le fichier d’instructions principal est devenu un wiki de 627 lignes regroupant les règles du tournoi, l’état en temps réel, les méthodes ainsi que les leçons de la journée précédente. Une fois réduit à un petit routeur, le contexte parvenait à l’agent par quatre voies différentes. Une couche courte reste toujours chargée. Un paquet de démarrage transmet des leçons et des avertissements à jour. Les règles spécifiques à une zone ne s’activent que lorsque une tâche concerne cette zone, et les rôles spécialisés avec leurs mémoires sont chargés uniquement en cas de besoin.
Une seule demande, suivie pas à pas
Considérez la question « Qu’est-ce qui doit être essayé ensuite ? ». Le système commence par composer un paquet de pré-vol. À partir de L1, il extrait l’expression pertinente, ainsi que les contraintes de paramétrage et d’évaluation. De L2 proviennent le portefeuille actuel, les mesures récentes, la partie de l’espace de recherche couverte et les résultats encore non résolus. De L3, il prend la branche du graphe la plus pertinente, l’origine théorique, les éléments de falsification ciblés, les spécifications de recherche et les leçons empiriques.
Les sous-agents interviennent ensuite. Un spécialiste en hypothèses travaille à partir de ce paquet pour proposer quelques angles économiques, sans masquer les raisonnements fragiles derrière les formules. Une fois un angle choisi, un spécialiste en modélisation prend l’hypothèse enregistrée et crée des implémentations qui diffèrent réellement les unes des autres. Un spécialiste en expérimentation reçoit l’arbre d’implémentations ainsi que les limites de la plateforme, puis enregistre ce qui est mesuré.
Chaque étape a sa propre destination. Le niveau L2 du registre reçoit les résultats bruts de la plateforme ainsi que des mesures normalisées. Les événements opérationnels tels que le démarrage des exécutions, les appels d’outils, les tentatives de réessai et le trafic de coordination sont stockés dans le stock d’événements. Lorsqu’un résultat permet d’extraire une leçon ou un élément de falsification ciblé, il est classé sous le niveau L3. Les agrégations graphiques proviennent de la conciliation avec le registre et ne sont jamais modifiées manuellement, tandis que de grandes séries de résultats PnL, des graphiques et des modèles ajustés deviennent des artefacts vers lesquels pointent d’autres enregistrements.
Les deux versions alpha soumises partaient toutes deux de paquets contenant déjà des éléments de preuve. Une famille avait précédemment amélioré le portefeuille, tandis que l’autre idée réutilisait une version qui avait déjà produit des versions alpha non corrélées. Une idée visant un changement de notation a également reçu un paquet, une cellule non testée sur la carte des opportunités ainsi qu’un gagnant antérieur à imiter, mais toutes ses 18 constructions ont malgré tout échoué.
Phasage de l’infrastructure
Mouvoir tout en même temps serait une erreur. Chaque voie évolue à son propre rythme, et une porte ne s’ouvre que lorsque un déclencheur mesurable le justifie. Le côté droit illustre le seul chemin d’écriture fiable (commit, outbox, exporter, projection), par opposition à une écriture double qui génère deux vérités concurrentes.
La pile locale actuelle peut faire plus qu’il n’y paraît. SQLite constitue un excellent choix par défaut pour un chercheur isolé, offrant des transactions réelles, des sauvegardes simples, des requêtes locales rapides et presque aucun surcoût opérationnel. Cependant, des contraintes apparaissent : une base de données de plusieurs gigaoctets contient des dizaines de millions de lignes de séries temporelles, plusieurs processus peuvent rivaliser pour les écritures locales, les événements en temps réel se multiplient, les artefacts et les captures d’écran sont liés à une seule machine, et reproduire un résultat ailleurs nécessite plus d’état caché que quiconque ne le souhaite. Une évolution en cinq phases semble donc pertinente.
La phase 0 vise à faire correspondre la conception à la réalité : soit on termine la migration partielle du PnL, soit on la révise consciemment, puis on automatise l’audit qui compare la documentation avec le stockage en temps réel. La phase 1 déplace les fichiers volumineux vers des systèmes de stockage d’objets compatibles avec S3, où le PnL est divisé en partitions Parquet compressées, soutenues par des manifestes immuables, des checksums et des règles de cycle de vie. La phase 2 ne transfère les métadonnées qu’une seule fois, lorsque la concurrence le rend nécessaire. Lorsque des travailleurs à distance, plusieurs machines ou des collaborateurs doivent écrire en même temps, le registre et le stockage d’événements sont placés dans PostgreSQL géré, sous forme de bases de données distinctes ou au moins de schémas séparés disposant de leurs propres politiques de conservation. La phase 3 intègre MLOps en tant que projection et non comme source unique de vérité, de sorte que des outils comme Weights & Biases ou MLflow peuvent être utilisés sans remplacer le registre ou le graphe. La phase 4 sépare l’orchestration de l’état : les travailleurs de recherche s’exécutent dans des conteneurs avec des fiches de tâches immuables, tandis qu’un mécanisme de file d’attente ou un moteur de flux de travail distribue des tâches idempotentes accompagnées de mécanismes de location, de tentatives répétées et de délais d’expiration. La phase 5 offre des analyses plus poussées uniquement lorsque la charge de travail le justifie. Un format de table de type lakehouse, une base de données graphique dédiée ou une plateforme de streaming pourraient finalement s’avérer utiles, mais seulement une fois que des requêtes spécifiques commencent à poser des problèmes, comme des scans sur des milliards d’observations, de nombreuses traversées de graphes simultanées, une évolution du schéma sur de grandes collections Parquet ou des consommateurs d’événements à faible latence.
Aucun gain de performance exact ne peut être attribué à cette architecture, car son effet n’a jamais été isolé. Sa véritable contribution consiste à permettre au système de se contredire honnêtement. Un article le suggère, une simulation est en désaccord, un falsificateur réduit la confiance, mais la règle du tournoi reste inchangée.
Lectures complémentaires
- Les cinq couches d’un agent harness, avec du code qui échoue sans elles — Une présentation pratique des cinq endroits où un agent harness applique des règles dans le code, des limites d’exécution aux pipelines de contexte, ainsi de ce que la recherche peut et ne peut pas prouver.
- Les agents qui s’améliorent eux-mêmes grâce aux compétences : réutilisation, sélection, réparation et vérification — Une conception en quatre étapes pour des agents qui améliorent leurs propres compétences : enregistrer du code fonctionnel, affiner les descriptions, proposer des corrections vérifiées et valider les résultats avant la transmission.