Torna al blog

AI per principiantiGuida

Chiedi a un LLM di un CSV: invia lo schema, non la tabella

Invia nomi delle colonne, tipi e 3 righe di esempio, ricevi indietro una riga di pandas, eseguila sul file completo. Più economico che incollare righe, e puoi verificare il numero.

Di CheapTokens TeamPubblicato il 7 min di lettura

Righe di codice che leggono un CSV, ne prendono i tipi delle colonne e tre righe, e chiedono una riga di pandas
In questa pagina
  1. Perché incollare l'intera tabella va storto
  2. Invia la forma della tabella, non la tabella
  3. Lo script: chiedi, leggi la riga, eseguila
  4. Quanto costa: incollare tutto vs schema + 3 righe
  5. Verifica il numero prima di fidarti
  6. Se non funziona

Hai un sales.csv con 5.000 righe e una domanda: quale prodotto ha venduto di più a ottobre? Non incollare il file in una chat. Invia al modello i nomi delle colonne, i loro tipi e tre righe di esempio, chiedi una riga di pandas ed esegui quella riga sul file completo da solo. Il modello non legge mai le tue 5.000 righe, il prompt resta minuscolo e il numero che ottieni proviene da codice che puoi rieseguire.

Ecco perché funziona meglio, come appare il prompt, uno script che puoi copiare e quanto costa rispetto al modo di incollare tutto.

Perché incollare l'intera tabella va storto#

Ecco una storia che potresti riconoscere. Qualcuno incolla 200 righe di spese in una chat e chiede il totale. La risposta torna sicura, con tanto di centesimi. È anche sbagliata, e nulla sullo schermo te lo dice.

Il modello predice il testo pezzo per pezzo (quei pezzi sono i token). Una somma di 200 numeri è 200 piccoli passi senza una calcolatrice dentro, e una cifra sbagliata sembra esattamente una risposta corretta. Il codice si comporta diversamente: df['amount'].sum() somma tutte le righe, ogni volta, e dà lo stesso risultato a una seconda esecuzione.

C'è un secondo problema, e riguarda le dimensioni. Una tabella consuma la finestra di contesto in fretta, e paghi per ogni riga a ogni domanda. Dieci domande sullo stesso file significano dieci copie dell'intera tabella inviate come input.

Verifica rapida

Perché una riga di pandas è più sicura che chiedere il totale al modello?

Mostra risposta

Risposta: Il tuo computer esegue il codice su ogni riga, e puoi rieseguirlo e verificarlo

Il modello può comunque scrivere una riga sbagliata. La differenza è che una riga è visibile e ripetibile: la leggi, la esegui e confronti il risultato con qualche riga a mano.

Invia la forma della tabella, non la tabella#

Il modello non ha bisogno dei tuoi dati per scrivere il codice. Ha bisogno di sapere che aspetto ha la tabella: quali colonne esistono, che tipo di valori contengono e come è scritta una riga. Questo è lo schema più qualche riga.

Diciamo che il tuo sales.csv abbia quattro colonne. Questo è l'intero prompt:

text
A pandas DataFrame named df has these columns and types:
date        object
product     object
units        int64
price      float64

First 3 rows (CSV):
date,product,units,price
2026-10-01,Oat latte mix,12,4.50
2026-10-01,Cocoa,7,3.20
2026-10-02,Oat latte mix,9,4.50

Question: Which product sold the most units in October 2026?

Reply with ONE line of pandas code that computes the answer from df.
No explanation, no markdown, no imports.

Aspettati una risposta con una forma simile a df[df['date'].str.startswith('2026-10')].groupby('product')['units'].sum().idxmax(). La formulazione esatta cambia da esecuzione a esecuzione, quindi leggi la riga prima di eseguirla.

Perché tre righe e non solo i nomi delle colonne? Per via della data. La colonna del tipo dice object, che significa solo testo. Le righe di esempio mostrano che la data è scritta 2026-10-01, così il modello sa di dover fare corrispondenza sul testo 2026-10, non su 10/2026 o su un nome di mese. La maggior parte delle righe di pandas sbagliate nasce dall'aver indovinato un formato che la tabella non ha mai avuto.

Incollare ogni riga rispetto a inviare lo schema e tre righe
La stessa domanda: il prompt a sinistra cresce con la tabella, quello a destra resta della stessa dimensione

Lo script: chiedi, leggi la riga, eseguila#

Lo script qui sotto costruisce quel prompt dal tuo file, così non devi digitare lo schema a mano. Chiama l'API di CheapTokens tramite l'SDK Python di OpenAI: URL di base https://api.cheaptokens.dev/v1, id del modello deepseek-ai/DeepSeek-V4-Flash-0731. Tieni la chiave in una variabile d'ambiente, non nel file.

python
import os
import pandas as pd
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

df = pd.read_csv("sales.csv")      # for .xlsx: pd.read_excel("sales.xlsx")

schema = df.dtypes.to_string()
sample = df.head(3).to_csv(index=False)
question = "Which product sold the most units in October 2026?"

prompt = f"""A pandas DataFrame named df has these columns and types:
{schema}

First 3 rows (CSV):
{sample}
Question: {question}

Reply with ONE line of pandas code that computes the answer from df.
No explanation, no markdown, no imports."""

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": prompt}],
    max_tokens=500,
)

text = resp.choices[0].message.content.strip()
code = text.removeprefix("```python").removeprefix("```").removesuffix("```").strip()
print("Model's line:", code)
print("Tokens in/out:", resp.usage.prompt_tokens, resp.usage.completion_tokens)

if resp.choices[0].finish_reason != "stop" or "import" in code or "__" in code:
    raise SystemExit("Not running this one. Read the line above and decide.")

print("Answer:", eval(code, {"df": df, "pd": pd}))

L'ultimo blocco è la parte che i principianti saltano. eval esegue qualunque testo abbia scritto il modello, sulla tua macchina, quindi lo script rifiuta righe con import o __ e risposte troncate (finish_reason diverso da stop; vedi perché una risposta si interrompe a metà frase). E leggi comunque prima la riga stampata. Se tocca file, la rete o qualsiasi cosa che non hai chiesto, non eseguirla.

La prima esecuzione stampa tre cose: la riga del modello, i conteggi dei token per questa singola richiesta e la risposta. I conteggi dei token sono il tuo contatore per la sezione successiva.

Quanto costa: incollare tutto vs schema + 3 righe#

Per confrontare, ci serve una dimensione per una riga. Diciamo che una riga come 2026-10-01,Oat latte mix,12,4.50 occupi circa 20 token. È un'ipotesi: dipende dal tokenizer del modello e dalle tue colonne, e contare i token prima di inviare mostra il tuo numero reale. Con 20 token a riga, 5.000 righe sono 5.000 × 20 = 100.000 token di input. Il prompt con schema e tre righe è di circa 300 token, istruzioni incluse. La risposta è breve in entrambi i casi, diciamo 60 token, quindi la differenza sta interamente sul lato input, quello che cresce con la tua tabella (ne parliamo in token di input vs output).

Una domanda su una tabella da 5.000 righe su DeepSeek-V4-Flash, 60 token di risposta
  • Incolla tutte le 5.000 righe$0.0015
  • Schema + 3 righe$0.000011

Entrambi i numeri sono piccoli in dollari, ed è onesto: un modello economico rende conveniente anche il modo sprecone. Il divario è ciò che cresce. Fai 20 domande al giorno e il prompt che incolla tutto viene inviato 20 volte. Raddoppia la tabella e il suo costo raddoppia, mentre il prompt con lo schema non si muove. E c'è un muro invalicabile: con una finestra di contesto di 380K token, 380.000 ÷ 20 = 19.000 righe è il massimo che potresti mai incollare, prima di lasciare spazio per la risposta. Un export da 50.000 righe semplicemente non ci sta. Il prompt con lo schema sì, qualunque sia la dimensione della tabella.

Inserisci la tua tabella e vedi il costo giornaliero:

Calcolatore di costi

La tua tabella incollata per intero: 20 domande al giorno

Token di input per richiesta: 100.000 · Token di output per richiesta: 60 · Richieste al giorno: 20

ModelloAl giornoAl mese
GLM-5.3-Flash$0.04$1.20
DeepSeek-V4-Flash$0.0301$0.904
MiniMax-M2.7$0.10$3.01

Cambia in in 300 per vedere il modo con lo schema. DeepSeek-V4-Flash su CheapTokens ha un unico prezzo a qualsiasi ora, nessun sovrapprezzo nelle ore di punta, e un solo saldo copre ogni modello, così puoi sostituire l'id del modello con zai-org/GLM-5.3-Flash (contesto 390K) senza un secondo account. I prezzi attuali sono nella pagina dei prezzi.

Verifica il numero prima di fidarti#

Il ciclo è sempre lo stesso. Fallo ogni volta, e una risposta sbagliata viene intercettata al quarto passo invece che in un report.

Metti in ordine

Metti in ordine il ciclo

  1. Descrivi la tabella: tipi delle colonne e 3 righe di esempio
  2. Chiedi una riga di pandas, nient'altro
  3. Leggi la riga, poi eseguila sul file completo
  4. Verifica il risultato a mano su qualche riga
Il ciclo: tabella, schema e tre righe, una riga di pandas, il tuo numero
Il modello vede solo il passo centrale; la tabella completa non lascia mai il tuo computer

Il quarto passo costa poco. Filtra il file fino a poche righe (df[df['product'] == 'Cocoa'].head(10)), sommali a mente o in un foglio di calcolo e confronta. Se la riga del modello è sbagliata, di solito lo è in modo evidente: ha contato le righe invece di sommare units, oppure ha scelto il mese sbagliato.

Per altre abitudini come questa, vedi perché l'AI inventa le cose e 4 abitudini di prompting che lo riducono.

Se non funziona#

  • KeyError: 'Date'. Il modello ha scritto un nome di colonna con maiuscole diverse. Incolla la riga di intestazione reale nel prompt, cosa che le tre righe di esempio già fanno, e aggiungi "usa i nomi delle colonne esattamente come mostrato".
  • La risposta ha una frase prima del codice. Il tuo eval fallisce con un SyntaxError. Ripeti "UNA riga di codice pandas, nessuna spiegazione" alla fine del prompt, l'ultima istruzione conta di più.
  • La risposta è una tabella, non un numero. Dì che forma vuoi: "restituisci un singolo numero" o "restituisci una Series ordinata in modo decrescente".
  • Le date vengono sbagliate. Le righe di esempio mostrano il formato reale. Se le tue date sono 14/10/2026, il modello deve vederlo; aggiungi pd.to_datetime(df['date'], dayfirst=True) al prompt come modo in cui vorresti leggere le date.
  • finish_reason è length. La risposta è stata troncata da max_tokens. Una singola riga sta in 500 token, quindi controlla il prompt: il modello potrebbe stare spiegando a lungo.

La configurazione completa per la tua prima richiesta, dalla chiave alla risposta, è nella documentazione di CheapTokens.