To, co najbardziej rzuca się w oczy we współczesnym świecie IT, to nie skala problemów technicznych. Błędy były zawsze. Prawdziwy problem polega na czymś innym: wiele z tych błędów nie wynika już z ograniczeń technologii, lecz z całkowicie świadomego przyzwolenia na niedbalstwo.
Przez lata pracy przy projektach informatycznych obserwowałem, jak systemy tworzone są nie wokół potrzeb użytkownika, ale wokół potrzeb procesu dostarczania. W praktyce oznacza to sytuację, w której ważniejsze staje się „żeby dowieźć sprint”, niż żeby użytkownik był w stanie normalnie korzystać z produktu.
To nie jest teoria. To nie jest cyniczna obserwacja z zewnątrz. To jest sposób działania, który bardzo często bywa komunikowany wprost przez osoby zarządzające projektami. W jednym z projektów padło wręcz stwierdzenie:
„Na day 1 robimy po prostu to, co jest szybsze, a to co jest dobre dla usera to day 2.”
To jedno zdanie doskonale podsumowuje ogromną część problemów współczesnego oprogramowania.
„Day 2” w wielu projektach nie nadchodzi nigdy.
W efekcie użytkownicy codziennie korzystają z systemów, które formalnie działają, ale praktycznie są pełne absurdów wynikających z braku staranności, testowania i zrozumienia realnego sposobu używania aplikacji.
Przykładowo, Alior Bank nie potrafi poprawnie rozpoznać kwoty przelewu, jeśli użytkownik wklei ją z dokumentu wraz ze spacją na początku wartości. Ten sam system ma problem z wyszukiwaniem numerów faktur zawierających ukośniki, mimo że taki format występuje masowo w realnych dokumentach księgowych.
To nie są problemy sztucznej inteligencji, fizyki kwantowej ani skalowania infrastruktury na miliony użytkowników. To są podstawowe przypadki wejściowe, których ktoś po prostu nie przetestował albo uznał, że „wystarczy”.
mBank z kolei przez lata potrafił prezentować użytkownikowi saldo konta niespójne z sumą widocznych transakcji. Operacje były zaksięgowane w różnych miejscach systemu według różnych momentów synchronizacji. Dla inżyniera być może wszystko miało swoje techniczne uzasadnienie. Dla użytkownika wyglądało to po prostu jak system, który nie potrafi policzyć pieniędzy na koncie.
Jeszcze ciekawsze są sytuacje, w których aplikacja zgłasza błąd wykonania operacji, mimo że operacja została wykonana poprawnie. Użytkownik otrzymuje komunikat „nie udało się potwierdzić”, podczas gdy system już wcześniej zatwierdził operację po stronie serwera.
Takie rzeczy nie wynikają z braku możliwości technologicznych. One wynikają z niedbalstwa projektowego, braku pełnych testów scenariuszy oraz braku odpowiedzialności za końcowe doświadczenie użytkownika.
Czasami te problemy przyjmują wręcz absurdalną formę.
Kiedyś Allegro miało problem, który powodował odrzucanie praktycznie co drugiej płatności. Regularność błędu była tak duża, że można było przewidzieć, iż pierwsza próba zakupu się nie powiedzie, a druga przejdzie poprawnie. Po zgłoszeniu problemu reakcją początkowo było niedowierzanie. Dopiero nagrania i konkretne dowody doprowadziły do wdrożenia poprawki po stronie jednego z serwerów.
Najbardziej niepokojące jest jednak to, że podobne zjawiska stały się w branży normalne.
Wiele zespołów działa dziś w modelu, w którym:
- programiści nie mają czasu rozumieć biznesu,
- testerzy nie znają realnych scenariuszy użytkownika,
- analitycy nie korzystają z produktów, które projektują,
- menedżerowie mierzą sukces szybkością dostarczenia funkcji,
- a użytkownik końcowy staje się problemem do obsłużenia, zamiast celem całego projektu.
W rezultacie powstają systemy, które formalnie spełniają wymagania backlogu, ale nie rozwiązują realnych problemów ludzi.
Co ciekawe, właśnie w tym miejscu modele językowe zaczynają pokazywać swoją przewagę nad wieloma zespołami projektowymi.
Nie dlatego, że „myślą” lepiej od ludzi. Nie dlatego, że są świadome. Ale dlatego, że potrafią cierpliwie analizować kontekst, dokumentację, zależności oraz instrukcje użytkownika bez typowego dla człowieka znużenia, pośpiechu i organizacyjnej presji.
Model językowy:
- przeczyta więcej dokumentacji,
- sprawdzi więcej wariantów,
- wygeneruje więcej przypadków testowych,
- lepiej opisze własne założenia,
- i częściej zada pytanie „co stanie się, jeśli użytkownik zrobi coś inaczej niż zakładaliśmy?”
To szczególnie istotne dlatego, że ogromna część współczesnych problemów oprogramowania nie wynika z trudności implementacyjnych. Wynika z ignorowania kontekstu użytkownika.
Nawet popularne systemy operacyjne pokazują ten problem. Ubuntu jest stosunkowo proste do pobrania — dopóki wszystko działa poprawnie. W momencie wystąpienia problemu użytkownik trafia na strony mirrorów i repozytoriów, których interfejsy bywają praktycznie niezrozumiałe dla przeciętnej osoby próbującej po prostu pobrać stabilną wersję systemu.
To jest właśnie współczesny problem branży IT: systemy tworzone są często z perspektywy ludzi, którzy już wiedzą, jak działają.
A użytkownik końcowy nie należy do tej grupy.
Przez dekady branża tłumaczyła takie sytuacje „złożonością systemów”, „długiem technologicznym”, „priorytetami biznesowymi” albo „zwinnym dostarczaniem”. Problem polega na tym, że bardzo często pod tymi pojęciami ukrywa się po prostu świadoma zgoda na obniżenie jakości.
Formalnie mówi się o agile. W praktyce często oznacza to:
- dostarczenie szybsze zamiast lepszego,
- ograniczenie testów,
- pomijanie przypadków brzegowych,
- odkładanie użyteczności „na później”,
- oraz budowanie produktu podporządkowanego procesowi wytwarzania, a nie użytkownikowi.
Najbardziej niebezpieczne jest jednak to, że wiele organizacji przestało nawet zauważać ten problem. Niedziałające lub źle działające systemy stały się czymś normalnym. Użytkownicy przyzwyczaili się do omijania błędów, wykonywania operacji dwa razy, restartowania aplikacji i interpretowania komunikatów, które nie mają sensu.
A przecież tak nie powinno wyglądać dobre oprogramowanie.
Rozwiązanie tego problemu nie wymaga magicznych technologii. Wymaga przede wszystkim powrotu do podstawowej odpowiedzialności inżynierskiej.
To oznacza:
- testowanie rzeczywistych scenariuszy użytkownika,
- obowiązkowe używanie własnych systemów przez zespoły projektowe,
- mierzenie liczby problemów użytkownika zamiast liczby dostarczonych funkcji,
- traktowanie UX jako części jakości technicznej,
- projektowanie komunikatów błędów jako elementu produktu,
- oraz premiowanie jakości i stabilności, a nie wyłącznie szybkości wdrożeń.
Modele językowe mogą tutaj pomóc. Mogą wspierać analizę, testowanie, dokumentowanie i wykrywanie niespójności. Ale same nie rozwiążą problemu kultury organizacyjnej, która uznaje użytkownika za przeszkodę w szybkim dostarczaniu funkcji.
Bo ostatecznie problem współczesnego IT nie polega na tym, że nie potrafimy budować dobrego oprogramowania.
Problem polega na tym, że zbyt wiele organizacji przestało uważać, że warto.