Przedwstęp
Szukając ciągle dobrego sposobu, żeby zmusić się do regularnego pisania, postanowiłem przyjrzeć się temu, co robię na co dzień, w poszukiwaniu jakiegoś “złota”, które mógłbym opisywać, załatwiając w ten sposób temat poszukiwania tematów 😉 Generalnie nie mogłem znaleźć żadnego konkretu, który mógłbym opisać, bo u mnie ciągle się coś zmienia. Zakochuję się w jednym narzędziu i jest ono dla mnie panaceum na całe zło, by miesiąc później znaleźć jeszcze lepszą alternatywę. Ciągle szukam mojego idealnego stacku technologicznego, w którym mógłbym się zadomowić i wiedzieć, że to jest coś dla mnie, i od teraz WSZYSTKO, co będę robił, będzie właśnie w tym stacku technologicznym.
Znalazłem w tym wszystkim jednak jedną cechę wspólną: ciągłą analizę i testy nowych narzędzi. Postanowiłem więc zrobić z tego mój biedaszyb tematów i postaram się wydoić go, ile będę w stanie 🙂
Dziś na tapet bierzemy narzędzia, które pozwalają mi szybko prototypować. Roll the intro…
THIS WEEK IN “ANALYSIS PARALYSIS”: ADAM AND HOW TO QUICKLY PROTOTYPE, AND THE FUTURE OF CODING <2x thunder strikes>
Hiperfocus i problem z powrotami do projektów
Będąc osobą, jaką jestem, potrafię bardzo intensywnie skupić się na danym temacie, ale przez bardzo ograniczoną ilość czasu. Jest to bardzo ciekawe połączenie, bo przez te 5 minut, a czasem 5 godziny, a czasem 5 dni, jedyna rzecz, o której potrafię myśleć, to ten jeden jedyny temat, który aktualnie kręci mi się w głowie. Jednocześnie, kiedy zapasy dopaminy spadną do poziomu, że zaczynam szukać czegoś nowego, widzę tylko, jak mój poprzedni cel się ode mnie oddala, a wszystkie ambicje i wizje zdobywania świata tym właśnie pomysłem oddalają się w stronę cmentarzyska pomysłów.
Z biegiem lat nauczyłem się trochę wcześniej parkować pomysły, zanim całkowicie je wyeksploatuję, i wdrożyłem tzw. “slow multitasking” – mam otwarte 5 projektów i przeskakuję tam, gdzie aktualnie czuję więcej dopaminy.
Jest to o tyle uciążliwe, że do projektu rozgrzebanego w połowie, gdzie część funkcjonalności była w mojej głowie, a to, co zostało napisane, przypominało tradycyjne włoskie spaghetti, wraca się bardzo ciężko. Stąd też potrzeba, żeby jak najszybciej zrobić SVP (Shitties Viable Product – trademark pending ;)). Poniżej przedstawiam zatem wynik moich doświadczeń, które – jeśli masz ten wyjątkowy układ połączeń synaptycznych, dający Ci skupienie snajpera Navy SEALs, ale attention span wiewiórki na koksie – mogą Ci się przydać. Generalnie piszę to dla siebie z przeszłości… tzn. wiem, że wtedy pewnie bym sam siebie nie posłuchał, no ale co zrobisz? 😀
Język programowania
Moim podstawowym językiem bardzo długo był C# (wcześniej jeszcze JAVA, ale to dawno temu i nieprawda), język bardzo fajny, bardzo komfortowy, ale też cholernie rozbudowany, a narzędzia jak Visual Studio czy Rider dokładają swój narzut. Ciężko w tej konfiguracji siąść, wypluć z siebie kilka linii kodu, odpalić i mieć już gotowe coś.
Jeżeli C# to duży ciężki miecz oburęczny, to ja doszedłem do wniosku, że potrzebuję… Glocka 9mm. Długo zastanawiałem się, na jakie barwy zmienić moje kolory klubowe. JavaScript (a właściwie nawet TypeScript) wydaje się bardzo kuszący ze względu na łatwą odpalalność w przeglądarce i ogólną elastyczność, miałem jeszcze krótki romans z GO, które bardzo cenię, jednak Python jest dużo bardziej ugruntowany, ma większe wsparcie i przede wszystkim w Pythonie 1+1=2, a nie 11 ;). Punkt dla niebiesko-żółtych.
Filozofia
Po podjęciu decyzji o przeprowadzce z C# do Pythona uświadomiłem sobie, że nie tylko język programowania był problemem (zresztą zwykle dochodzę do wniosku, że to ja jestem swoim własnym problemem, a zawsze chcę zwalić winę na narzędzia… ale nie uprzedzajmy faktów ;)). Kłopotem było też przyzwyczajenie z C#, że jak tworzę nowy projekt, to musi on zaczynać się od co najmniej 5 różnych plików i 300 linii boilerplate. „Bo przecież musi być czysty kod i ładnie i maintainable”. Tak naprawdę ta liczba plików i wstępnego kodu nie wynikała z moich potrzeb czy schematów, tylko z tego, że „zawsze tak było”, „tak powinno być” i taki był defaultowy template.
Zaorałem więc wszystkie szablony. Teraz moje projekty zaczynają się od main.py i tyle… no dobra, może jeszcze .env 😉 Dopiero kiedy czuję się komfortowo w danym rozwiązaniu, zaczynam tworzyć własny “framework”, na tyle generyczny, że pasuje do moich wszystkich mini API w Pythonie, a jednocześnie na tyle osobisty, że jest dla mnie w pełni zrozumiały i minimalnie tylko rozrasta projekt. Przykładowo mam własnoręcznie (rękami ChatGPT) napisaną klasę do wysyłania logów do OpenObserve i zwyczajnie kopiuję ją do nowych projektów.
Środowisko deweloperskie
Niezbyt przyjemnym doświadczeniem przy przesiadce na Pythona okazało się zarządzanie paczkami. Gdy robisz jeden projekt, to jasne – instalujesz wszystko w systemie i po sprawie. Ale gdy tylko pojawi się drugi projekt z innymi paczkami (a programowanie w Pythonie to właściwie składnie różnych paczek w jeden program :D), to wchodzisz na teren walk o dominację. Paczki się gryzą, wymagasz różnych wersji itd., a do tego śmiecisz w systemie.
Testowałem środowiska w PyCharmie, w Jupyter Notebook, bawiłem się venv – wszystko to było jakieś „nie takie”. Zapominałem komend żeby aktywować środowisko, albo skonfigurowanie nowego wymagało więcej niż 3 kliknięć, co bywa za dużo dla mojego attention span, i finalnie wszystko lądowało w globalnych paczkach. Sporo fluffu, zamiast jednego „klik” i nowego sandboxa do developowania.
Zbawcą okazały się devcontainers – bardzo przyjemnie integrują się z VSCode, stworzenie nowego kontenera to 2 kliknięcia (czyli o jeden mniej niż wynosi moje maksimum 😉 ), a współpraca jest naprawdę wygodna. No i aplikacja od razu staje się bardziej “docker friendly”.
Wszystko fajnie, ale to ciągle strasznie dużo roboty
Nie ma dla mnie nic gorszego niż złapanie blokady podczas pracy – nie dlatego, że nie wiem, jak coś ogarnąć, tylko dlatego, że ogranicza mnie moja znajomość języka. Faktem jest, że rewolucja LLM-owa mega to ułatwiła i ChatGPT razem z kolegami rozwiązują 90% moich problemów.
Testowałem też Cursora, i może przepaliłem 50 zł na LLMy w ciągu 10 minut, ale przynajmniej nie miałem pojęcia, co się dzieje w moim kodzie i czemu nie działa ;). Niestety, z mojego doświadczenia z programowaniem przy pomocy LLM-ów wynika, że to jednak Ty musisz być programistą. LLM to jedynie bardzo cierpliwy senior, który stoi za Tobą i palcem pokazuje, co masz zrobić. Możesz pytać go o najlepsze rozwiązania w Twojej sytuacji, kopiować fragmenty kodu, ale nigdy nie pozwól, żeby robił za Ciebie za dużo – bo błyskawicznie stracisz orientację w projekcie. A ogarnięcie błędu, którego LLM już nie ogarnia i proponuje w kółko to samo błędne rozwiązanie, zajmie Ci więcej czasu, niż gdybyś napisał wszystko sam (z drobną pomocą).
Ok, pomarudziłem, ale co w zamian?
Szybko i prosto: No-code/Low-code. Jeżeli od strony frontendu moje uwielbienie dla takich rozwiązań (FlutterFlow) już się ujawniło w poprzednich wpisach, to po stronie backendu nie mogę przecenić n8n i ostatnio odkrywanego LangFlow (w temacie frameworków do agentów AI pewnie napiszę jeszcze osobny artykuł).
Dodatkowo mam świetny przykład z życia, jak n8n potrafi oszczędzić czas: przedszkole mojej córki weszło w XXI wiek z przytupem, mają stronę internetową… i tyle. Żadnych Discordów, grup facebookowych ani list mailingowych. Wszystkie newsy z życia placówki trzeba sprawdzać ręcznie na stronie – jak zwierzę. Postanowiłem więc napisać prosty scraper (uczyłem się wtedy GO, więc był to fajny test). Zrobienie go zajęło mi może 3-4h + parę poprawek + konfiguracja kontenera z cronem, który odpala się 2 razy dziennie – łącznie jakieś 6h. Działa, i super. Mniej więcej w tym samym czasie odkryłem n8n i postanowiłem zrobić to samo w nim. Poza jednorazową konfiguracją n8n (jakieś 2h), stworzenie identycznego flow z cronem, wysyłaniem powiadomień przez NTFY itd. zajęło mi MOŻE 30-45minut. Każda zmiana, np. wysyłanie wiadomości na Discorda zamiast przez NTFY? kolejne 5-10 minut.
Możliwość błyskawicznego ustawiania flow, i to jeszcze w formie wizualnej (jestem bardzo wzrokowcem), jest zbawienna i bardzo intuicyjna. Dodatkowo powrót do projektu po kilku tygodniach jest znacznie łatwiejszy, bo wizualna reprezentacja stanowi przy okazji dokumentację. N8n ma mnóstwo wad i czasem mnie wkurza, ale nie da się ukryć, że do tworzenia POC i SVP jest niezastąpione. Można szybko iterować i weryfikować nowe pomysły, a jeśli już mamy coś działającego na „prodzie”, zawsze możemy to przepisać na „prawdziwy” kod w Pythonie i zdeployować w kontenerze – i spać spokojnie, że wciąż jesteśmy prawdziwymi programistami 😉
Przyszłość programowania
Ok, skoro „Jak szybko prototypować” można w miarę wyczytać z powyższego, to o co chodzi z tą „Przyszłością programowania”?
Uważam, że w przyszłości wszyscy (mówiąc wszyscy mam na myśli siebie, bo ja dla siebie jestem wszystkim kim byłem – więc gdy mówię „wszyscy”, mam na myśli mój własny świat, a jeśli czujesz że masz podobnie to zapraszam do niego 😉 ) będziemy tworzyć w low-code. Bawiąc się n8n, już doceniłem tę wartość. Co prawda n8n nie jest super optymalny, nie da się łatwo eksportować flow do osobnej aplikacji czy do „full-code”, ale to i tak krok w dobrą stronę. Możliwość szybkiego dostarczania rozwiązania w w miarę przejrzystej formie jest nie do przecenienia.
Sam się zastanawiałem, czy nie stworzyć czegoś w stylu programmable blocks, czyli takich nodów jak w n8n, ale z custom code w środku. Mógłbym tworzyć pojedyncze moduły z inputami i outputami, spinać je i generować z tego jedną aplikację „full-code”.
Tu dochodzimy do LangFlow, które – poza tym, że służy do budowania agentów AI – gdzieś pod spodem właśnie tym jest: zbiorem bloków kodu, w których możesz napisać, co chcesz, a potem w prosty, wizualny sposób zbudować z tego aplikację. Dla mnie to strzał w 10 – mam jasną reprezentację flow i jednocześnie pełną kontrolę nad każdą linią kodu, przy jednoczesnym korzystaniu z gotowych komponentów.
Podsumowanie
Zauważyłem, że dzięki ciągłemu testowaniu różnych narzędzi i podejść moje „analysis paralysis” jest coraz mniejsze. Każdy kolejny eksperyment ogranicza poczucie bezradności, bo nie muszę już zgadywać, co będzie dla mnie dobrym i wydajnym rozwiązaniem – wiem to po prostu z własnego doświadczenia. Jednocześnie dostrzegłem, że sama ta ciągła wędrówka, ten niekończący się cykl odkrywania alternatyw, testowania i sprawdzania, co działa, jest dla mnie wartością samą w sobie. To ciągłe gonienie króliczka i radość z gonitwy daje mi dużo satysfakcji. Może ten mój wymarzony „idealny stack” wcale nie istnieje, a całe piękno tkwi w poszukiwaniu? Coraz bardziej czuję, że ciągłe odkrywanie nowych narzędzi jest moją prawdziwą drogą, a nie stanem przejściowym do jednego idealnego rozwiązania. I chyba czas się z tym pogodzić 🙂
TL;DR
- Język to Python
- Filozofia to „pisz, nie pierdol” – minimalizm król
- IDE/Dev env – VSCode + DevContainers
- Przyszłość – no-code/low-code (n8n, LangFlow i pewnie jeszcze jakieś kolejne narzędzie no-code, które dopiero powstanie)
Dziękuję za uwagę i do zobaczenia w kolejnym odcinku „Analysis Paralysis” <2x thunder strike>!