Csv agent
La classe CsvAgent è un layer di manipolazione dei file .csv. Consente di leggere, modificare e creare fogli tabellari operando internamente su un pandas.DataFrame (composizione, non sottoclasse) ed espone un'API row/col coerente con le altre classi del framework. CSV è single-sheet per definizione: per file multi-foglio è previsto un futuro ExcelAgent.
Costruttore
CsvAgent(
file_bytes: bytes | None = None,
delimiter: str | None = None,
encoding: str = "utf-8",
has_header: bool = True,
)
file_bytes(bytes | None): il contenuto binario del file.csv. SeNone, viene creato un foglio vuoto.delimiter(str | None): separatore di colonna. SeNone, viene rilevato automaticamente tramitecsv.Sniffertra,,;,\t,|.encoding(str): encoding del file. Defaultutf-8.has_header(bool): seTrue, la prima riga è interpretata come header. SeFalse, vengono generati header automaticicol_0,col_1, ...
Tutte le celle vengono caricate come stringhe per evitare coercion impreviste (es. codici fiscali con zeri iniziali, partite IVA). I tipi logici vengono inferiti solo per la visualizzazione tramite get_structure.
Metodi
save
Serializza lo stato corrente del foglio come bytes CSV.
save() -> bytes
Il delimiter e l'encoding usati per la serializzazione sono quelli rilevati o specificati alla costruzione, garantendo round-trip coerente.
get_structure
Restituisce una mappa testuale leggera del foglio: shape, elenco colonne con tipo inferito e anteprima delle prime/ultime righe.
get_structure(preview_len: int = 40) -> str
preview_len(int): numero massimo di caratteri per le anteprime delle celle.
L'output è una stringa con un formato simile a:
CSV STRUCTURE (4 rows × 3 cols, delimiter=',')
────────────────────────────────────────────────────────────
Columns:
[0 ] 'name' (string)
[1 ] 'age' (int)
[2 ] 'city' (string)
Preview (first 5 rows):
R0: Alice | 30 | Milan
R1: Bob | 25 | Rome
R2: Carol | 35 | Naples
R3: Dave | 40 | Genova
Per fogli con più di 10 righe, vengono mostrate le prime 5 e le ultime 3 righe con un separatore ....
I tipi logici riportati (int, float, datetime, bool, string, empty) sono inferiti da un campione delle prime 100 righe non vuote e servono solo come hint per l'LLM. Il dato sottostante resta sempre stringa.
get_text
Restituisce una rappresentazione testuale del foglio in formato markdown table.
get_text(max_rows: int | None = None) -> str
max_rows(int | None): numero massimo di righe da includere.Noneinclude tutto.
Utile per passare il contenuto integrale (o un estratto) a un LLM in un formato leggibile.
shape
Restituisce le dimensioni del foglio come tupla (n_rows, n_cols).
shape() -> tuple[int, int]
get_headers
Restituisce la lista dei nomi di colonna nell'ordine corrente.
get_headers() -> list[str]
get_row
Restituisce una riga come dizionario {nome_colonna: valore}.
get_row(idx: int) -> dict
idx(int): indice della riga (0-based).
Solleva IndexError se l'indice è fuori range.
get_col
Restituisce una colonna come lista di valori.
get_col(name_or_idx: str | int) -> list
name_or_idx(str | int): nome della colonna oppure indice posizionale.
Solleva KeyError se il nome non esiste, oppure IndexError se l'indice è fuori range.
get_cell
Restituisce il valore di una singola cella.
get_cell(row: int, col: str | int) -> Any
row(int): indice di riga (0-based).col(str | int): nome della colonna oppure indice posizionale.
edit_cell
Modifica il valore di una singola cella. Il valore viene sempre serializzato come stringa.
edit_cell(row: int, col: str | int, value: Any) -> None
row(int): indice di riga (0-based).col(str | int): nome della colonna oppure indice posizionale.value(Any): nuovo valore. Viene convertito tramitestr().
edit_cells
Modifica più celle in una singola chiamata.
edit_cells(edits: list[dict]) -> None
edits(list): lista di dizionari, ciascuno conrow,colevalue(stesso formato diedit_cell).
add_row
Aggiunge una nuova riga al foglio.
add_row(values: list | dict, after: int | None = None) -> int
values(list | dict): valori della nuova riga. Selist, vengono assegnati per posizione alle colonne (le mancanti restano vuote). Sedict, le chiavi devono corrispondere ai nomi di colonna.after(int | None): inserisce dopo questa riga.Noneaggiunge in coda.
Restituisce l'indice della nuova riga.
Solleva ValueError se values è una lista con più elementi delle colonne disponibili.
add_col
Aggiunge una nuova colonna al foglio.
add_col(name: str, default: Any = "", after: str | int | None = None) -> int
name(str): nome della nuova colonna.default(Any): valore predefinito per tutte le righe esistenti.after(str | int | None): inserisce dopo questa colonna.Noneaggiunge in coda.
Restituisce l'indice della nuova colonna.
Solleva ValueError se una colonna con quel nome esiste già.
remove_rows
Rimuove una o più righe dal foglio.
remove_rows(ids: list[int]) -> None
ids(list[int]): lista degli indici da rimuovere.
Dopo la rimozione, gli indici vengono ricompattati. È necessario rileggere la struttura per ottenere i nuovi indici.
remove_col
Rimuove una colonna dal foglio.
remove_col(name_or_idx: str | int) -> None
name_or_idx(str | int): nome della colonna oppure indice posizionale.
search
Cerca una stringa in tutte le celle (o in una sola colonna), con contesto circostante.
search(
query: str,
col: str | int | None = None,
context_chars: int = 30,
) -> list[dict]
query(str): testo da cercare (case-insensitive).col(str | int | None): se specificato, limita la ricerca a una sola colonna.context_chars(int): numero di caratteri di contesto prima e dopo il match.
Restituisce una lista di dizionari:
[
{
"row": 2,
"col": "city",
"snippet": "…**Milan**o…"
}
]
La ricerca non richiede alcun LLM ed è eseguita direttamente sul DataFrame.
filter
Filtra le righe del foglio usando la sintassi di pandas.DataFrame.query. Le colonne numeriche vengono coerizzate automaticamente per consentire confronti aritmetici.
filter(query: str) -> pd.DataFrame
query(str): espressione di filtro in sintassi pandas (es."age > 30 and city == 'Milan'").
Restituisce un nuovo DataFrame (lo stato dell'agente non viene modificato).
Operazione di sola lettura. Per modificare il foglio in base a un filtro, combinare filter con remove_rows passando gli indici risultanti.
as_dataframe
Restituisce una copia del DataFrame sottostante. Escape hatch per chi vuole usare direttamente l'API pandas.
as_dataframe() -> pd.DataFrame
Modificare la copia non altera lo stato dell'agente. Per riapplicare cambiamenti pandas-side è necessario passare per i metodi pubblici.