Prompty do analizy danych: 6 promptów do CSV, Excela i tabeli w n8n (z wynikiem w JSON)
Damian GębalaAutorDo analizy danych w n8n wystarczy sześć promptów - po jednym na typ zadania: audyt kolumn, porównanie okresów, klasyfikacja wierszy, wyciąganie danych z tekstu, uzgadnianie dwóch źródeł i rekomendacja z założeniami. Wszystkie sześć kończy się tym samym: model musi zwrócić JSON z ustalonym schematem, a nie tekst do przeczytania przez człowieka. Dzięki temu wynik wchodzi prosto do następnego węzła, do arkusza albo do bazy, bez ręcznego przepisywania.
Poniżej masz gotowe prompty do wklejenia, schematy odpowiedzi i węzły n8n, które wymuszają poprawny format. Pisane pod polskie dane - tam najczęściej wraca problem z separatorem dziesiętnym i z datą w innym formacie niż w arkuszu.
Dlaczego „zrób analizę tego arkusza” nie wystarcza
Model językowy odpowiada tekstem. Taki wynik jest czytelny dla człowieka, ale bezużyteczny dla przepływu - nie da się go zapisać do kolumny ani porównać z poprzednim miesiącem. Drugi problem jest poważniejszy: liczby w tekście bywają inne niż w pliku.
Poprawny prompt analityczny działa inaczej. Nie prosi o opis, tylko o konkretne pola: co zsumować, po czym grupować, jak nazwać kolumnę wynikową i co zrobić, gdy danych brakuje. Format wymusza węzeł Structured Output Parser, który wstrzykuje instrukcje do promptu automatycznie.
Zanim prompt zadziała: przygotowanie pliku w n8n
Plik z tabelą dociera do przepływu jako obiekt binarny. Węzeł Extract From File zamienia go na dane, z którymi pracuje reszta przepływu, i ma jedenaście operacji: CSV, XLSX, XLS, ODS, HTML, JSON, ICS, PDF, RTF, plik tekstowy i base64. Pole z plikiem nazywa się Input Binary Field, a domyślna wartość to data. Plik z webhooka wymaga w tym węźle opcji Raw body.
CSV wraca z tego węzła jako seria obiektów JSON. Zanim cokolwiek wyślesz do modelu, uporządkuj dane zwykłym węzłem Code: usuń puste wiersze, ujednolic nazwy kolumn, zamień daty na jeden format i przecinek dziesiętny na kropkę. Ma dwa tryby - Run Once for All Items (domyślny) i Run Once for Each Item. Nie ma w nim dostępu do plików ani do HTTP, więc zapis na dysk idzie osobnym węzłem.
Tu jest pierwsza pułapka przy CSV-ach: wiele polskich plików ma ; zamiast przecinka jako separator. Jeśli dane po wczytaniu wyglądają jak jedna kolumna tekstu, problem jest w separatorze, a nie w prompcie.
Sześć promptów do analizy danych
W każdym prompcie trzymam się tej samej konstrukcji: rola, dane, zadanie, format odpowiedzi, zasada przy brakach. Ten sam układ stosuję przy promptach do pracy biurowej - tam znajdziesz też wersje, które psują wynik.
1. Audyt kolumn: co jest w tabeli i gdzie są dziury
Pierwszy prompt warto odpalić zanim cokolwiek policzysz. Zwraca spis kolumn z typem danych, liczbą pustych wartości i wykrytymi podejrzanymi wartościami.
Jesteś analitykiem danych. Poniżej jest tabela sprzedażowa w formacie JSON.
ZADANIE:
1. Dla każdej kolumny ustal: nazwę, typ (tekst / liczba / data / boolean), czy zawiera wartości puste i ile.
2. Wskaż wartości, które wyglądają na błędne: daty w przyszłości, liczby ujemne tam, gdzie nie powinno być, teksty w kolumnie liczb.
3. Nie poprawiaj danych. Nie licz sum. Nie dopisuj kolumn, których nie ma.
FORMAT ODPOWIEDZI: JSON zgodny ze schematem.
W każdej kolumnie, której dotyczy problem, wpisz powód w jednym zdaniu.
Schemat odpowiedzi trzyma się reguł wymaganych przez parser: bez referencji $ref, wszystkie pola obowiązkowe, obiekt zamknięty przez additionalProperties: false.
{
"type": "object",
"properties": {
"kolumny": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nazwa": {"type": "string"},
"typ": {"type": "string", "enum": ["tekst", "liczba", "data", "boolean"]},
"puste_wartosci": {"type": "number"},
"problem": {"type": "string"}
},
"required": ["nazwa", "typ", "puste_wartosci", "problem"],
"additionalProperties": false
}
}
},
"required": ["kolumny"],
"additionalProperties": false
}
2. Porównanie dwóch okresów
Ten prompt zastępuje comiesięczne porównanie sprzedaży w arkuszu. Model dostaje oba okresy i zwraca różnicę liczbową, różnicę procentową oraz kategorie, które rosną najszybciej.
Jesteś analitykiem sprzedaży. Masz dwie tabele: okres Bieżący i okres Poprzedni.
ZADANIE:
1. Policz sumę i liczbę pozycji w każdym okresie.
2. Dla każdej kategorii policz różnicę kwotową i procentową.
3. Wypisz 3 kategorie z największym spadkiem i 3 z największym wzrostem.
4. Jeśli w jednej z tabel brakuje kategorii, wpisz 0 i dodaj notatkę.
Nie zaokrąglaj do pełnych złotych. Nie wymyślaj kategorii, których nie ma w danych.
Proszę o wartości brak zamiast zera tam, gdzie różnica jest nieznana - zero sugeruje „nie było sprzedaży”, a nie „nie wiem”.
3. Klasyfikacja wierszy do Twojej listy
Klasyfikacja jest najczęstszym zastosowaniem w realnych przepływach: księgowość, magazyn, sprzedaż. Wariant działa też w drugą stronę - opisujesz kategorie po ludzku, a model przypisuje każdy wiersz do jednej z nich.
Jesteś klasyfikatorem. Dla każdego wiersza przypisz jedną kategorię z listy:
["nowy_klient", "powracajacy_klient", "hurtownia", "sprzedaz_m detaliczna", "zwrot", "nieznane"]
Dodaj pewnosc od 0 do 1 oraz jednozdaniowe uzasadnienie.
Jesli wiersz pasuje do wiecej niz jednej kategorii, wybierz te najlepsza
i zaznacz to w uzasadnieniu. Nie tworz nowych kategorii.
Pewności nie możesz ufać bez sprawdzenia - model potrafi zwrócić poprawny JSON z polem confidence równym 1,5. Dlatego próg pewności ustawiam w węźle, nie w prompcie.
4. Wyciąganie pól z tekstu
Tu wchodzą dane, których nie da się policzyć: treść reklamacji, opis produktu, notatka z rozmowy. Wariant na n8n Information Extractor albo na Structured Output Parser, gdy dane idą z pliku.
Jesteś systemem ekstrakcji informacji. Z tekstu ponizej wyciagnij:
numer_zgloszenia (string)
kategorie_problemu (string, jedna z: platnosc, dostawa, jakosc, inne)
pilnosc (string, jedna z: niska, srednia, wysoka)
opis_krotko (string, maksymalnie 200 znakow)
potrzebny_kontakt_do_klienta (boolean)
Nie dopisuj informacji, ktorych nie ma w tekscie.
Jesli pole nie wystepuje, zwroc pusty string albo false.
Jeśli model ma zwracać dokładnie taki format, warto skorzystać ze structured outputs zamiast liczyć na samo polecenie w prompcie. Anthropic przyjmuje schemat w output_config.format, OpenAI w response_format z strict: true. Oba gwarantują poprawny JSON na poziomie składni - ale żaden nie gwarantuje, że liczba wewnątrz będzie prawdziwa.
5. Uzgadnianie dwóch źródeł
To najbardziej doceniany prompt w finansach: masz arkusz sprzedażowy i wyciąg z systemu księgowego, a chcesz listę różnic. Albo zamówienia z CRM i faktury z magazynu.
Jestesz kontrolerem. Masz dwie tabele: Tabela A i Tabela B.
Klucz laczenia to numer_zamowienia.
ZADANIE:
1. Znajdz rekordy wylacznie w Tabeli A.
2. Znajdz rekordy wylacznie w Tabeli B.
3. Znajdz rekordy z ta sama wartoscia w obu tabelach.
4. Znajdz rekordy, w ktorych kwota rozni sie o wiecej niz 1 grosz.
5. Wypisz liste roznosci. Nie usuwaj zadnego rekordu z raportu.
6. Rekomendacja z jawnymi założeniami
Tu model nie policzy, tylko zinterpretuje - i musi pokazać, na czym opiera wniosek. Ten układ chroni przed klasycznym trybem, w którym model podaje konkret wykonania jako fakt.
Jesteś analitykiem. Na podstawie tabeli przygotuj 3 rekomendacje.
Kazda rekomendacja musi zawierac:
co zmienic (string)
dlaczego (string, maksymalnie 2 zdania)
na jakich danych to opierasz (string, nazwy konkretnych kolumn)
jakies zalozenie (string - czego w tabeli nie ma, a co wplywa na wniosek)
ryzyko (string, jedno zdanie)
Jesli danych do rekomendacji nie ma, zwroc pusty string w polu
"co zmienic" zamiast zgadywac.
Jak wymusić JSON: trzy węzły, jeden schemat
W AI Agent włącz Require Specific Output Format. Pojawi się punkt podłączenia parsera, a n8n pokaże trzy opcje: Auto-fixing Output Parser, Item List Output Parser i Structured Output Parser. Do analizy tabeli pasuje ten ostatni. Jeśli dopiero składasz takie przepływy, wzorce architektury AI w n8n pokażą, gdzie parser wchodzi w całość. W nim wybierasz Schema Type: Generate from JSON Example buduje schemat z przykładowego obiektu - n8n bierze z niego nazwy i typy, ignoruje wartości i robi każde pole obowiązkowym - albo Define using JSON Schema i wklejasz schemat ręcznie.
Dwie zasady, które oszczędzają godziny. Schemat nie obsługuje referencji $ref - rozwijaj strukturę jawnie. A dokumentacja n8n sama ostrzega, że parsowanie struktury przy agentach „często nie jest niezawodne”, i rekomenduje osobny węzeł LLM, który parsuje to, co zwrócił agent.
Na poziomie API zastrzeżenia są poważniejsze. Anthropic gwarantuje zgodność ze schematem przez constrained decoding, ale nie w każdym przypadku: przy odmowie modelu dostajesz kod HTTP 200, płacisz za wygenerowane tokeny, a odpowiedź nie musi pasować do schematu - tak samo przy uciętym max_tokens. API ma też twarde limity: 20 narzędzi ścisłych na żądanie, 24 opcjonalne parametry, 16 parametrów z typami unii i 180 sekund na kompilację gramatyki. Schemat zbyt zagnieżdżony kończy się błędem „Schema is too complex for compilation”. Po stronie OpenAI Structured Outputs wymaga strict: true, każdy obiekt musi mieć additionalProperties: false i komplet pól w required. Tryb JSON mode bez strict daje poprawny JSON, ale nie gwarantuje zgodności ze schematem - i to jest częsta przyczyna „działa u kolegi, nie działa u mnie”.
Trzy miejsca, w których wynik z modelu jest zły
Parser bierze pierwszy wiersz. Sub-nody w n8n rozwiązują wyrażenia zawsze do pierwszego elementu wejścia. Przy pięciu rekordach {{ $json.kolumna }} zwróci wartość z pierwszego, a nie z piątego. Przy analizie tabeli to nie jest drobnostka, tylko podstawa: albo łączysz dane do jednego rekordu przed promptem, albo przetwarzasz je w pętli po jednym.
Poprawny JSON nie znaczy poprawnych danych. Walidacja po parserze ma sprawdzać wartości, a nie tylko strukturę. W węźle Code sprawdź typ confidence i jego zakres, długość podsumowania oraz to, czy kategoria istnieje na Twojej liście. Potem routujesz wynik: pewność powyżej 0,85 idzie dalej automatycznie, zakres 0,60-0,85 leci z flagą do przeglądu, a poniżej 0,60 do człowieka. Przy błędzie formatu nie kończ przepływu - wróć do kroku AI z komunikatem błędu w prompcie i ustaw limit prób na dwie lub trzy.
Dane wrażliwe w pliku. Arkusz z nazwiskami klientów, kwotami i adresami to dane osobowe. Przed wysłaniem do modelu zewnętrznego usuń kolumny, których analiza nie potrzebuje, i zanonimizuj identyfikatory. Przy takich danych wybieraj model prowadzony na własnym serwerze.
Przepływ od pliku do arkusza
Całość w jednym przepływie: Webhook lub pobranie pliku z Raw body → Extract From File (CSV albo XLSX) → Code z czyszczeniem danych → AI Agent z promptem z tej listy → Structured Output Parser → Code z walidacją → Convert to File. Ten ostatni węzeł ma dziesięć operacji - przy CSV, XLSX i ODS ustawiasz w nim Header Row, a przy XLSX także nazwę arkusza. Tryb All Items to One File zapisuje wszystkie rekordy do jednego pliku - domyślna opcja tworzy osobny plik dla każdego rekordu.
Jeśli to pierwszy przepływ, który w ogóle budujesz, zacznij od samego odczytu pliku i zapisu go z powrotem bez AI. Kolejny krok dorzuć, gdy plik wraca poprawnie.
Jak sprawdzić, że prompt działa
Ten sam prompt daje różne odpowiedzi przy kolejnych uruchomieniach, więc trzy ręczne próby niczego nie dowodzą. W n8n testujesz to wbudowanymi węzłami: zbierasz przypadki w Data Table lub Google Sheet, uruchamiasz przepływ węzłem Evaluation Trigger, a wyniki ocenia węzeł Evaluation. Wbudowane metryki to zgodność stringów, klasyfikacja i użyte narzędzia, a własne dopisujesz jako wyrażenie regularne. Metryki oceniane przez model (Correctness, Helpfulness) mają skalę 1-5.
Testuj tanim modelem produkcyjnym, a droższym oceniaj wyniki na małej próbce. Zapisuj wynik bieżącego promptu jako punkt odniesienia i po zmianie porównuj oba przebiegi obok siebie - średnia potrafi ukryć regresję na jednym ważnym przypadku.
Najczęstsze pytania o analizę danych w n8n
Czy model policzy mi sprzedaż lepiej niż arkusz?
Nie. Arkusz ma najlepsze narzędzia do liczenia i jest deterministyczny. Jeśli dziś robisz to w Excelu przez kopiuj-wklej, zamiast tego masz gotowy przepływ raportowania. Model przyjmuje się tam, gdzie trzeba zrozumieć tekst: nazwy kategorii, opisy, komentarze.
Ile danych można wsadzić do jednego promptu?
Tyle, ile wejdzie w okno kontekstu modelu. Kilkaset rekordów za jednym razem utrudnia utrzymanie spójności, a koszt rośnie z każdym uruchomieniem - duże zbiory dziel na partie.
Czy Information Extractor wystarczy zamiast agenta?
Tak, jeśli nie potrzebujesz narzędzi ani kilku kroków. Information Extractor ma trzy sposoby opisu wyniku: listę atrybutów z opisami, schemat wygenerowany z przykładowego JSON-a albo ręczny JSON Schema. To węższe narzędzie, ale przy jednym zadaniu często działa stabilniej niż agent.
Co, jeśli model zwróci za dużo tekstu?
Limit max_tokens ucina odpowiedź i wynik przestaje pasować do schematu. Zmniejsz zakres danych w prompcie albo podnieś limit, a w węźle Code dodaj walidację długości odpowiedzi.
Jeśli stoisz przed wyborem, od którego procesu zacząć - audyt danych, klasyfikacja, uzgadnianie źródeł - napisz do mnie i powiedz, jakie pliki dostajesz dziś ręcznie. Odpowiadam zwykle tego samego dnia.