Aller au contenu

Explorer des données dans un noyau persistant

Ce guide vous montre comment amener un agent à charger une fois quelque chose de coûteux, puis à l’interroger à plusieurs reprises, au lieu de payer le chargement à chaque question.

L’outil eval exécute un interpréteur persistant. Les variables, les imports et les données chargées survivent d’un appel à l’autre.

Un python -c ponctuel paie la préparation à chaque question. Charger un cadre de données coûte des secondes et une centaine de mégaoctets; en tracer un graphique coûte des millisecondes. Quand chaque question coûte le chargement, un agent pose moins de questions qu’il ne le devrait — et chaque réponse revient sous forme de texte qu’il doit ensuite réanalyser.

Chargez data/runs.csv et donnez-moi la durée p95 par agent.

import pandas as pd
runs = pd.read_csv("data/runs.csv")
len(runs)

La dernière expression est renvoyée comme le ferait un carnet de notes, de sorte que len(runs) indique le nombre de lignes sans print.

Puis, dans un appel distinct :

runs.groupby("agent")["duration_ms"].quantile(0.95).sort_values()

runs est toujours chargé. Un cadre de données pandas revient rendu sous forme de tableau plutôt que sous forme de représentation brute.

import matplotlib.pyplot as plt
runs.groupby("agent")["duration_ms"].mean().plot.bar()

Les figures sont capturées après la cellule et renvoyées sous forme d’images, que la transcription affiche. Vous voyez le graphique, et l’agent aussi.

Les figures sont fermées après la capture. Une figure non récupérée serait redessinée et renvoyée par la cellule suivante elle aussi, de sorte qu’une session de cinq cellules émettrait le premier graphique cinq fois.

Ceux-ci sont réécrits en code ordinaire plutôt que de produire une erreur :

Ce que vous tapez Ce qui se passe
%pip install x Exécute pip, puis vide le cache des modules pour que le prochain import le voie
%cd path os.chdir
!command Un sous-processus capturé
%%bash Le reste de la cellule comme script shell
%%timeit 1000 exécutions chronométrées

L’éviction du cache de %pip est celle qui compte : installer dans un interpréteur en cours d’exécution ne change rien pour un module déjà importé, donc sans elle, la version que vous venez d’installer n’est pas celle qui s’exécute.

Appeler vos propres outils depuis l’intérieur d’une cellule

Section intitulée “Appeler vos propres outils depuis l’intérieur d’une cellule”
paths = tool("find", {"pattern": "**/*.dart", "path": "lib"})
for path in paths.splitlines()[:100]:
contents = tool("read", {"path": path})
...

tool(name, args) revient dans le propre registre d’outils de l’agent. Une cellule peut donc se ramifier sur une centaine de fichiers, ou déléguer par l’entremise de task, sans que le modèle dépense un tour par élément.

Un appel relayé par le pont suspend le délai d’expiration de la cellule tant qu’il est en cours. Le budget mesure l’inactivité, pas le temps réel — une cellule qui se ramifie vers des sous-agents et attend quatre minutes n’est pas figée, et la tuer en pleine ramification ferait perdre l’état de tout le noyau.

eval(code: "…", reset: true, description: "Start a clean interpreter")

Abandonne l’interpréteur et en démarre un propre. Tout ce qui était chargé disparaît, et c’est précisément le but.

Dans l’enceinte de la conversation lorsqu’elle en a une, sur l’hôte autrement.

Un interpréteur persistant piloté par un modèle qui lit un dépôt non fiable est exactement le cas pour lequel l’exécution en enceinte seulement existe : un appel bash ponctuel finit au moins par se terminer, alors qu’un noyau est un shell qui se souvient.

Il ne démarre pas d’enceinte pour y arriver — la même règle qui empêche l’onglet d’un rig de démarrer automatiquement. Si vous voulez que le noyau soit isolé dans une enceinte, ouvrez d’abord le shell de la conversation. Voir Donner une machine de test à un agent.

  • Une cellule à la fois par noyau. Deux cellules qui se disputent un même interpréteur, ce sont deux moitiés de deux programmes entrelacées dans un même espace de noms.
  • La sortie est plafonnée. Une cellule prise dans une boucle d’impression est tronquée plutôt que de laisser remplir la fenêtre de contexte.
  • Quatre images par cellule. Une boucle de traçage peut produire une figure par itération, et chaque image représente un coût fixe élevé dans la requête qui la transporte.
  • Le noyau meurt avec l’exécution. Un noyau qui retient encore un cadre de données après la fin de la conversation est une fuite.