Czy z 14GB e-maili da się zrobić sensowne FAQ przy pomocy AI?
Cześć — tu Piotr z Depcore. Szef podszedł do mnie z zadaniem, które brzmiało jak idealna robota na spokojne popołudnie: „Piotr, zrób mi listę najczęstszych pytań, chcę z tego zbudować FAQ”.
W głowie od razu odpalił mi się ten obrazek z Internetu, że sztuczna inteligencja (Artificial Intelligence) wszystko umie: wrzucasz dane, klik, a po chwili masz gotową odpowiedź.
Mój pierwszy plan był prosty. Wezmę maile, zrobię embedding (czyli taką „mapę podobieństwa”), potem clustering i wyciągnę grupy, w których siedzą pierwsze pytania od klientów. Brzmi jak klasyczna data science i machine learning: dane → model → wynik.
Tylko że potem zobaczyłem plik. Około 14 GB. Około 40 tysięcy maili. I to nie 40 tysięcy ładnych, krótkich wiadomości. To świat, w którym stopki mają większą objętość niż treść, cytowane odpowiedzi ciągną się przez pół ekranu, a ludzie potrafią zadać pytanie tak, że nie ma ani znaku zapytania, ani interpunkcji, ani czasem nawet pełnego zdania. I wtedy zrozumiałem coś, co dziś uważam za najważniejszą lekcję: AI tools typu ChatGPT są świetne, ale „czat” nie jest rozwiązaniem na wszystko.
Jeśli chcesz zrobić coś powtarzalnego i sensownego biznesowo, to wchodzisz w AI automation i automatyzację procesów. A automatyzacja w praktyce zaczyna się od danych.
Ten wpis jest o tym, jak z naiwnego „wrzućmy to do AI” zrobił się pipeline, który finalnie oddał tabelę ~110 pytań do FAQ (pytanie + krótki kontekst). Bez matematyki na siłę, za to z historią, bo to była seria decyzji, potknięć i kilku momentów „okej, teraz to ma sens”.
Pracowałem na danych firmowych, więc w tekście nie ma treści maili 1:1. W samym pipeline’ie usunąłem też wrażliwe elementy (np. linki, adresy e-mail, numery telefonów), bo to jest część odpowiedzialnego podejścia do AI governance w praktyce.
Jak wyglądał proces analizy maili krok po kroku
- Etap 1 — zrozumienie problemu
- Etap 2 — parsowanie maili
- Etap 3 — czyszczenie danych
- Etap 4 — wykrywanie pytań
- Etap 5 — embedding i podobieństwo
- Etap 6 — wyszukiwanie podobnych przypadków
- Etap 7 — generative AI na końcu procesu
Dlaczego generative AI nie wystarczy do analizy maili?
To nie było „po prostu wrzuć do ChatGPT” - dlaczego? Gdy ktoś mówi „zróbmy FAQ z maili”, wielu ludzi widzi to jak jedną rozmowę. Tylko że tu nie ma jednej rozmowy. Są tysiące mikrohistorii, różne języki, różne style, konteksty rozrzucone po wątkach. I przede wszystkim: koszt.
Generative AI jest mocne, ale jeśli przepuścisz przez duży model wszystko jak leci, to płacisz (zwykle pieniędzmi lub czasem, a nawet oboma naraz) za analizowanie stopek, cytowań i szumu.
Żeby to w ogóle miało sens, musisz najpierw ograniczyć problem. Zrobić tanią filtrację, a dopiero potem użyć cięższych narzędzi. To jest w sumie klasyczny pattern w digital transformation: najpierw porządkujemy proces i dane, potem automatyzujemy.
Najpierw porządek: maile nie są tekstem, tylko bałaganem w przebraniu
Zacząłem od parsowania skrzynki. Wyciągnąłem sam tekst (HTML -> plain text), wywaliłem załączniki i zachowałem nagłówki, które później pozwalają odtworzyć wątki (m.in. message-id, in-reply-to).
To brzmi technicznie, ale efekt jest prosty: zamiast „śmieciowej masy”, dostałem uporządkowaną tabelę, na której da się pracować. Potem przyszła pierwsza ściana. W mailach bardzo często historia rozmowy siedzi w treści jako cytaty. Jeśli tego nie utniesz, to każdy kolejny krok - analiza podobieństwa, wyszukiwanie tematów, cokolwiek - miesza kilka wiadomości naraz.
Niby masz „jednego maila”, ale semantycznie to bywa pięć wiadomości w płaszczu. Dołożyłem też proste usuwanie szumu: linki, adresy, telefony zamieniałem na neutralne tokeny. Nie dlatego, że to „ładniej wygląda”, tylko dlatego, że to są rzeczy, które potrafią sztucznie łączyć ze sobą zupełnie różne przypadki.
Najważniejszy pivot przyszedł wtedy, kiedy odpuściłem „magiczne” wykrywanie kontekstu po cytatach. Zamiast tego zacząłem budować thready po headerach czyli wątki po nagłówkach (message-id i in-reply-to). Brzmi jak detal, ale w praktyce to była różnica między zgadywaniem a stabilnym odtwarzaniem rozmowy.
Jak znaleźć pytania, których nie widać?
Kolejny problem jest zaskakująco ludzki: pytanie nie zawsze ma znak zapytania. Czasem ktoś pisze „potrzebuję pomocy z instalacją” i to jest pytanie, mimo że wygląda jak oświadczenie. Czasem ktoś pisze „to działa u was” i też wiesz, że to pytanie. To jest intuicja.
Ja potrzebowałem tej intuicji w kodzie. Zamiast budować dziesiątki reguł, poszedłem w machine learning.
Dostroiłem mały model językowy do klasyfikacji zdań: czy to jest pytanie, czy nie. To jest ten fragment, gdzie w tle pojawia się deep learning i sieci neuronowe - tylko w wersji „praktycznej”: nie interesuje mnie teoria, interesuje mnie to, czy filtr działa na prawdziwych mailach. Druga kluczowa decyzja była nietypowa: nie zrobiłem dwóch klas (pytanie/niepytanie), tylko trzy.
Rozdzieliłem pytania z „?” i pytania bez interpunkcji, bo przy dwóch klasach model za bardzo przyklejał się do znaku zapytania. Po tej zmianie zaczął patrzeć na intencję zdania, nie na symbol.
Dataset zbudowałem z polskich danych QA, a trenowanie ogarniałem typowo po juniorowemu: python, pandas, numpy, trochę rzeczy z ekosystemu data science. Efekt praktyczny? Z około 97 tysięcy zdań w mailach zostało mi około 11 tysięcy zdań, które brzmiały jak pytania. I to był pierwszy moment, kiedy poczułem, że to się robi realne. Bo nagle nie pracujesz na 14 GB wszystkiego, tylko na małym kawałku, który ma sens.
„Mapa podobieństwa” i największy sabotażysta: stopki
Kiedy masz pytania, naturalny odruch jest prosty: embeddowanie i grupowanie podobnych. Tylko że w realnym świecie pytania bez kontekstu są często… puste. „Czy to działa?”, „mogę wrzucać?”, „jak to zrobić?” - to są zdania, które żyją dopiero w mailu. Drugie odkrycie było jeszcze bardziej bolesne: stopki potrafią zepsuć wszystko.
Są powtarzalne, więc system zaczyna grupować maile „po stopce” albo „po nadawcy”, a nie po temacie. To jest klasyczny przypadek, gdzie intelligent document processing brzmi dumnie, a w praktyce przegrywa z jedną powtarzalną linijką tekstu. Stopki wyciąłem prostą metodą: dzieliłem treść na małe bloki linii, sprawdzałem, co powtarza się często, i usuwałem takie fragmenty z całego korpusu. Niby banalne, ale to był jeden z największych skoków jakości w całym projekcie.
W tym miejscu zrobiłem jeszcze jeden pivot, który mi później bardzo pomógł: zamiast embedować jedno pytanie na raz, zacząłem embedować „pakiet pytań z jednego maila”. Jeśli ktoś pyta o wdrożenie technologii, to często zadaje kilka pytań w jednym wątku - i to jest sygnał, nie przeszkoda. Embedding liczyłem lokalnie, bez wysyłania treści do publicznych usług. To była dla mnie ważna część podejścia: z jednej strony AI-powered, z drugiej rozsądek i kontrola.
Moment prawdy: klastrów „samych z siebie” nie da się prosić o odpowiedzialność.
Próbowałem podejścia całkowicie unsupervised: niech algorytm sam znajdzie grupy tematów. Czasem to działało, czasem prowadziło w krzaki. I tu wchodzi najprostsza myśl, jaką można mieć: ja przecież wiem, czego szukam.
Zrobiłem więc „sadzonki” - kilka przykładów maili/pytań, które idealnie pasują do docelowego FAQ. Oznaczyłem też próbkę ręcznie. Nie po to, żeby zrobić wielki projekt adnotacji, tylko po to, żeby nadać kierunek. To jest trochę jak w biznesie: zanim zautomatyzujesz proces, musisz wiedzieć, co jest „dobrym wynikiem”.
Od tego momentu zamiast szukać idealnych klastrów, szukałem podobnych rzeczy do sadzonek. Prościej, skuteczniej.
Najciekawszy kawałek: jak „odczuliłem” podobieństwo na wspólny kontekst.
Mimo sprzątania wciąż czułem, że system łapie wspólne cechy kontekstu, które nie powinny decydować o podobieństwie intencji. I tutaj zrobiłem coś, co bardzo lubię w projektach AI: nie dorzuciłem większego modelu, tylko dodałem małą, kontrolowaną korektę.
W praktyce wyglądało to tak: embeddingi najpierw sprowadziłem do stabilniejszej, zapisanej transformacji, a potem nałożyłem prostą warstwę, która potrafi delikatnie przesunąć punkty w „mapie”, żeby lepiej oddawały intencję.
Skąd wiedziałem, w którą stronę je przesuwać? Tu pojawiło się LLM-as-a-judge. Mały model dostawał pary i zwracał liczbę 0–1: „na ile te dwa przypadki są podobne intencyjnie”. To nie było idealne, ale było zaskakująco użyteczne jako sygnał treningowy. Po serii iteracji dostałem przestrzeń, w której podobne sprawy rzeczywiście były bliżej.
To jest dla mnie esencja praktycznego AIOps na małą skalę: uczysz system na feedbacku i poprawiasz go iteracyjnie, zamiast wierzyć w jedną magiczną konfigurację.
Finał: generative AI dopiero wtedy, gdy to ma sens.
Na końcu zrobiłem coś odwrotnego niż „wrzućmy wszystko do modelu generującego”. Najpierw zawęziłem dane tak mocno, że zostało około 1–2% maili najbardziej zbliżonych do sadzonek. Dopiero na tym małym, sensownym zbiorze odpaliłem generative AI do wyciągania pytań i budowania krótkiego kontekstu.
Wymusiłem format wyjścia (żeby nie było „ładnego tekstu bez struktury”), a wynik był prosty i biznesowy: lista pytań, które naprawdę da się wkleić do FAQ. Około 110 sztuk.
Z perspektywy firmy to jest różnica między „mamy chaotyczną skrzynkę” a „mamy customer support faq, które odpowiada na realne pytania”. A z perspektywy procesu - to jest FAQ automation i FAQ generator w praktyce, tylko bez marketingowego dymu.
Co z tego wynika?
Najprościej: sztuczna inteligencja jest świetna, ale nie działa jak zaklęcie. W takich projektach 80% roboty to dane i kontekst. Dopiero potem przychodzą modele.
Jeśli miałbym zostawić jedną myśl dla potencjalnych klientów: to podejście da się przenieść na inne miejsca, gdzie jest dużo tekstu i dużo chaosu - tickety, CRM, czaty wsparcia.
To nie jest „projekt AI dla sportu”. To jest narzędzie do porządkowania wiedzy, które daje realną przewagę: szybciej widzisz, o co ludzie pytają i gdzie firma traci czas.
Efekt biznesowy:
Chaotyczna skrzynka mailowa została zamieniona w:
- listę realnych pytań klientów
- gotowe FAQ dla customer support
- bazę wiedzy dla zespołu
FAQ
Czy da się automatycznie stworzyć FAQ z maili klientów?
Tak, ale nie polega to na prostym wrzuceniu wszystkich maili do modelu generatywnego. Najpierw trzeba oczyścić dane (np. usunąć cytowania, stopki i linki), a dopiero później analizować treść i szukać powtarzających się pytań.
Czy wystarczy wkleić maile do ChatGPT?
Nie. W realnych skrzynkach większość tekstu to:
- cytowane odpowiedzi
- stopki
- linki
- dane kontaktowe
Jeśli model analizuje wszystko naraz, to zamiast pytań klientów zaczyna grupować maile po stopkach lub kontekście rozmowy.
Jak AI znajduje pytania bez znaku zapytania?
W tym celu można użyć modelu klasyfikującego zdania według intencji. Zdania typu: „potrzebuję pomocy z instalacją” nie zawierają znaku zapytania, ale semantycznie są pytaniami. Model uczony na przykładach potrafi je wykrywać.
Dlaczego embedding jest potrzebny przy analizie maili?
Embedding zamienia tekst w reprezentację numeryczną, która pozwala mierzyć podobieństwo znaczeniowe między zdaniami. Dzięki temu system może znaleźć pytania o podobnej intencji nawet wtedy, gdy są napisane innymi słowami.
Czy dane klientów mogą być analizowane przez AI bezpiecznie?
Tak, jeśli pipeline usuwa dane wrażliwe przed analizą. W praktyce oznacza to np.:
- zamianę adresów e-mail na tokeny
- usunięcie numerów telefonów
- usunięcie linków Dzięki temu model pracuje na treści pytania, a nie na danych osobowych.