Salta ai contenuti

Esplora i dati in un kernel persistente

Questa guida mostra come far caricare a un agente qualcosa di costoso una volta sola e poi rivolgergli diverse domande, invece di pagare il caricamento a ogni domanda.

Lo strumento eval esegue un interprete persistente. Variabili, import e dati caricati sopravvivono tra una chiamata e l’altra.

Un python -c one-shot paga il setup a ogni domanda. Caricare un dataframe costa secondi e un centinaio di megabyte; farne un grafico costa millisecondi. Quando ogni domanda costa il caricamento, un agente fa meno domande di quante dovrebbe — e ogni risposta torna come testo che deve poi analizzare di nuovo.

Carica data/runs.csv e dimmi la durata p95 per agente.

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

L’ultima espressione viene riprodotta come farebbe un notebook, così len(runs) riporta il numero di righe senza un print.

Poi, in una chiamata separata:

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

runs è ancora caricato. Un frame pandas torna renderizzato come tabella anziché come repr.

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

Le figure vengono acquisite dopo la cella e restituite come immagini, che la trascrizione renderizza. Vedi il grafico; lo vede anche l’agente.

Le figure vengono chiuse dopo l’acquisizione. Una figura non raccolta verrebbe ridisegnata e rinviata anche dalla cella successiva, quindi una sessione da cinque celle emetterebbe il primo grafico cinque volte.

Vengono riscritti in codice semplice anziché generare un errore:

Digiti Cosa succede
%pip install x Esegue pip, poi svuota la cache dei moduli così il prossimo import lo vede
%cd path os.chdir
!command Un sottoprocesso acquisito
%%bash Il resto della cella come script di shell
%%timeit 1000 esecuzioni cronometrate

L’eliminazione della cache di %pip è quella che conta: installare in un interprete già avviato non fa nulla per un modulo già importato, quindi senza di essa la versione appena installata non è quella in esecuzione.

Chiamare i tuoi strumenti dall’interno di una cella

Sezione intitolata “Chiamare i tuoi strumenti dall’interno di una cella”
paths = tool("find", {"pattern": "**/*.dart", "path": "lib"})
for path in paths.splitlines()[:100]:
contents = tool("read", {"path": path})
...

tool(name, args) rientra nel registro degli strumenti dell’agente stesso. Questo significa che una cella può diramarsi su un centinaio di file, o delegare tramite task, senza che il modello spenda un turno per ogni elemento.

Una chiamata via bridge sospende il timeout della cella finché è in corso. Il budget misura l’inattività, non il tempo trascorso — una cella che si dirama verso sottoagenti e attende quattro minuti non è bloccata, e ucciderla a metà diramazione perderebbe l’intero stato del kernel.

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

Scarta l’interprete e ne avvia uno pulito. Tutto ciò che era caricato è perso, che è esattamente il punto.

Nel recinto della conversazione quando ne ha uno, altrimenti sull’host.

Un interprete persistente guidato da un modello che legge un repo non attendibile è esattamente il motivo per cui esiste l’esecuzione confinata al recinto: una chiamata bash one-shot almeno finisce, mentre un kernel è una shell che ricorda.

Non avvia un recinto per arrivarci — la stessa regola che impedisce a una scheda rig di avviarsi automaticamente. Se vuoi il kernel in un recinto, apri prima la shell della conversazione. Vedi Assegna a un agente una macchina su cui testare.

  • Una cella alla volta per kernel. Due celle che corrono nello stesso interprete sono due metà di due programmi intrecciate in un unico namespace.
  • L’output è limitato. Una cella dentro un ciclo di print viene troncata invece di poter riempire la finestra di contesto.
  • Quattro immagini per cella. Un ciclo che disegna grafici può emettere una figura per iterazione, e ogni immagine è un costo fisso elevato nella richiesta che la trasporta.
  • Il kernel muore con l’esecuzione. Un kernel che conserva ancora un dataframe dopo la fine della conversazione è una perdita.