Powrót do bloga

AI dla początkującychPrzewodnik

Zapytaj LLM o CSV: wyślij schemat, nie tabelę

Wyślij nazwy kolumn, typy i 3 przykładowe wiersze, otrzymaj jedną linię pandas, uruchom ją na pełnym pliku. Taniej niż wklejanie wierszy, a liczbę możesz sprawdzić.

Autor: CheapTokens TeamOpublikowano 6 min czytania

Linie kodu, które czytają CSV, pobierają typy kolumn i trzy wiersze i proszą o jedną linię pandas
Na tej stronie
  1. Dlaczego wklejanie całej tabeli się nie sprawdza
  2. Wyślij kształt tabeli, nie tabelę
  3. Skrypt: zapytaj, przeczytaj linię, uruchom ją
  4. Ile to kosztuje: wklej wszystko vs schemat + 3 wiersze
  5. Sprawdź liczbę, zanim jej zaufasz
  6. Jeśli nie działa

Masz plik sales.csv z 5000 wierszami i jedno pytanie: który produkt sprzedał się najlepiej w październiku? Nie wklejaj pliku do czatu. Wyślij modelowi nazwy kolumn, ich typy i trzy przykładowe wiersze, poproś o jedną linię pandas i sam uruchom tę linię na pełnym pliku. Model nigdy nie czyta twoich 5000 wierszy, prompt pozostaje malutki, a liczba, którą dostajesz, pochodzi z kodu, który możesz uruchomić ponownie.

Oto dlaczego to działa lepiej, jak wygląda prompt, skrypt, który możesz skopiować, i ile to kosztuje w porównaniu z wklejaniem wszystkiego.

Dlaczego wklejanie całej tabeli się nie sprawdza#

Oto historia, którą możesz znać. Ktoś wkleja 200 wierszy wydatków do czatu i prosi o sumę. Odpowiedź wraca pewna siebie, z centami i wszystkim. Jest też błędna, a nic na ekranie ci tego nie mówi.

Model przewiduje tekst kawałek po kawałku (te kawałki to tokeny). Suma 200 liczb to 200 małych kroków bez kalkulatora w środku, a jedna przesunięta cyfra wygląda dokładnie jak poprawna odpowiedź. Kod zachowuje się inaczej: df['amount'].sum() dodaje wszystkie wiersze, za każdym razem, i daje ten sam wynik przy drugim uruchomieniu.

Jest drugi problem, związany z rozmiarem. Tabela szybko zjada okno kontekstu, a ty płacisz za każdy wiersz przy każdym pytaniu. Dziesięć pytań o ten sam plik oznacza dziesięć kopii całej tabeli wysłanych jako dane wejściowe.

Szybkie sprawdzenie

Dlaczego linia pandas jest bezpieczniejsza niż proszenie modelu o sumę?

Pokaż odpowiedź

Odpowiedź: Twój komputer uruchamia kod na każdym wierszu, a ty możesz go uruchomić ponownie i sprawdzić

Model nadal może napisać błędną linię. Różnica polega na tym, że linia jest widoczna i powtarzalna: czytasz ją, uruchamiasz i porównujesz wynik z kilkoma wierszami ręcznie.

Wyślij kształt tabeli, nie tabelę#

Model nie potrzebuje twoich danych, żeby napisać kod. Musi wiedzieć, jak wygląda tabela: jakie kolumny istnieją, jakie wartości przechowują i jak zapisany jest wiersz. To schemat plus kilka wierszy.

Załóżmy, że twój sales.csv ma cztery kolumny. To cały 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.

Spodziewaj się odpowiedzi w kształcie df[df['date'].str.startswith('2026-10')].groupby('product')['units'].sum().idxmax(). Dokładne sformułowanie różni się między uruchomieniami, więc przeczytaj linię, zanim ją uruchomisz.

Dlaczego trzy wiersze, a nie same nazwy kolumn? Z powodu daty. Kolumna typu mówi object, co oznacza tylko tekst. Przykładowe wiersze pokazują, że data jest zapisana jako 2026-10-01, więc model wie, że ma dopasować tekst 2026-10, a nie 10/2026 czy nazwę miesiąca. Większość błędnych linii pandas bierze się ze zgadywania formatu, którego tabela nigdy nie miała.

Wklejanie każdego wiersza versus wysyłanie schematu i trzech wierszy
To samo pytanie: lewy prompt rośnie z tabelą, prawy pozostaje tego samego rozmiaru

Skrypt: zapytaj, przeczytaj linię, uruchom ją#

Poniższy skrypt buduje ten prompt z twojego pliku, więc nie musisz wpisywać schematu ręcznie. Wywołuje API CheapTokens przez OpenAI Python SDK: bazowy URL https://api.cheaptokens.dev/v1, identyfikator modelu deepseek-ai/DeepSeek-V4-Flash-0731. Trzymaj klucz w zmiennej środowiskowej, nie w pliku.

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}))

Ostatni blok to część, którą początkujący pomijają. eval uruchamia dowolny tekst napisany przez model, na twoim komputerze, więc skrypt odrzuca linie z import lub __ oraz odpowiedzi, które zostały ucięte (finish_reason inne niż stop; zobacz dlaczego odpowiedź urywa się w połowie zdania). I nadal najpierw czytasz wydrukowaną linię. Jeśli dotyka plików, sieci lub czegokolwiek, o co nie prosiłeś, nie uruchamiaj jej.

Pierwsze uruchomienie wypisuje trzy rzeczy: linię modelu, liczbę tokenów dla tego jednego żądania i odpowiedź. Liczba tokenów to twój licznik dla następnej sekcji.

Ile to kosztuje: wklej wszystko vs schemat + 3 wiersze#

Aby porównać, potrzebujemy rozmiaru wiersza. Załóżmy, że wiersz taki jak 2026-10-01,Oat latte mix,12,4.50 zajmuje około 20 tokenów. To założenie: zależy od tokenizera modelu i twoich kolumn, a liczenie tokenów przed wysłaniem pokazuje twoją rzeczywistą liczbę. Przy 20 tokenach na wiersz 5000 wierszy to 5000 × 20 = 100 000 tokenów wejściowych. Prompt ze schematem i trzema wierszami to około 300 tokenów, łącznie z instrukcjami. Odpowiedź jest krótka w obu przypadkach, powiedzmy 60 tokenów, więc różnica leży całkowicie po stronie wejścia, tej, która rośnie z twoją tabelą (więcej w tokeny wejściowe vs wyjściowe).

Jedno pytanie o tabelę z 5000 wierszy na DeepSeek-V4-Flash, 60 tokenów odpowiedzi
  • Wklej wszystkie 5000 wierszy$0.0015
  • Schemat + 3 wiersze$0.000011

Obie liczby są małe w dolarach i to jest uczciwe: tani model sprawia, że nawet marnotrawny sposób jest przystępny. Różnica to to, co rośnie. Zadaj 20 pytań dziennie, a prompt z wklejaniem wszystkiego jest wysyłany 20 razy. Podwój tabelę, a jej koszt się podwoi, podczas gdy prompt ze schematem się nie zmienia. I jest twarda ściana: przy oknie kontekstu 380K tokenów 380 000 ÷ 20 = 19 000 wierszy to maksimum, jakie kiedykolwiek mógłbyś wkleić, zanim zostawisz jakiekolwiek miejsce na odpowiedź. Eksport z 50 000 wierszy po prostu się nie mieści. Prompt ze schematem mieści się niezależnie od rozmiaru tabeli.

Podstaw swoją tabelę i zobacz dzienny koszt:

Kalkulator kosztów

Twoja tabela wklejona w całości: 20 pytań dziennie

Tokeny wejściowe na żądanie: 100 000 · Tokeny wyjściowe na żądanie: 60 · Żądania dziennie: 20

ModelDziennieMiesięcznie
GLM-5.3-Flash$0.04$1.20
DeepSeek-V4-Flash$0.0301$0.904
MiniMax-M2.7$0.10$3.01

Zmień in na 300, aby zobaczyć sposób ze schematem. DeepSeek-V4-Flash na CheapTokens ma jedną cenę o każdej porze, bez dopłaty w godzinach szczytu, a jedno saldo obejmuje każdy model, więc możesz zamienić identyfikator modelu na zai-org/GLM-5.3-Flash (kontekst 390K) bez drugiego konta. Aktualne ceny są na stronie z cenami.

Sprawdź liczbę, zanim jej zaufasz#

Pętla jest zawsze taka sama. Rób to za każdym razem, a błędna odpowiedź zostanie złapana na czwartym kroku, a nie w raporcie.

Ustaw w kolejności

Ułóż pętlę w kolejności

  1. Opisz tabelę: typy kolumn i 3 przykładowe wiersze
  2. Poproś o jedną linię pandas, nic więcej
  3. Przeczytaj linię, a następnie uruchom ją na pełnym pliku
  4. Sprawdź wynik ręcznie na kilku wierszach
Pętla: tabela, schemat i trzy wiersze, jedna linia pandas, twoja liczba
Model widzi tylko środkowy krok; pełna tabela nigdy nie opuszcza twojego komputera

Czwarty krok jest tani. Przefiltruj plik do kilku wierszy (df[df['product'] == 'Cocoa'].head(10)), zsumuj je w głowie lub w arkuszu kalkulacyjnym i porównaj. Jeśli linia modelu jest błędna, zwykle jest błędna w oczywisty sposób: policzył wiersze zamiast sumować units albo wybrał niewłaściwy miesiąc.

Więcej takich nawyków znajdziesz w dlaczego AI zmyśla i 4 nawyki w promptach, które to ograniczają.

Jeśli nie działa#

  • KeyError: 'Date'. Model napisał nazwę kolumny z innymi wielkimi literami. Wklej prawdziwy wiersz nagłówka do promptu, co już robią trzy przykładowe wiersze, i dodaj "używaj nazw kolumn dokładnie tak, jak pokazano".
  • Odpowiedź ma zdanie przed kodem. Twój eval kończy się niepowodzeniem z SyntaxError. Powtórz "JEDNA linia kodu pandas, bez wyjaśnień" na końcu promptu, ostatnia instrukcja liczy się najbardziej.
  • Odpowiedź to tabela, nie liczba. Powiedz, jaki kształt chcesz: "zwróć pojedynczą liczbę" lub "zwróć Series posortowany malejąco".
  • Daty wychodzą źle. Przykładowe wiersze pokazują prawdziwy format. Jeśli twoje daty są w formacie 14/10/2026, model musi to zobaczyć; dodaj pd.to_datetime(df['date'], dayfirst=True) do promptu jako sposób, w jaki chcesz czytać daty.
  • finish_reason to length. Odpowiedź została ucięta przez max_tokens. Pojedyncza linia mieści się w 500 tokenach, więc sprawdź prompt: model może wyjaśniać rozwlekle.

Pełna konfiguracja pierwszego żądania, od klucza do odpowiedzi, jest w dokumentacji CheapTokens.