Wróć do katalogu
Season 54 15 Odcinki 57 min 2026

Langflow

v1.8 — Edycja 2026. Kompleksowy techniczny kurs audio na temat budowania aplikacji AI za pomocą Langflow 1.8, przechodzący od wizualnego prototypowania do wdrożenia produkcyjnego backendu.

Orkiestracja LLM Prototypowanie wizualne Frameworki AI/ML
Langflow
Teraz odtwarzane
Click play to start
0:00
0:00
1
Paradygmat Langflow
Ten odcinek omawia podstawową tożsamość frameworka i to, jak jego interfejs wizualny przekłada się na wykonanie po stronie backendu. Słuchacze dowiedzą się, jak logika aplikacji jest ustrukturyzowana jako Directed Acyclic Graph, co pozwala na płynne przejście od szybkiego prototypowania do produkcyjnych API.
3m 55s
2
Architektura komponentów i typy danych
Ten odcinek omawia anatomię komponentu, w tym porty wejściowe i wyjściowe, a także podstawowe typy danych, takie jak Data i Message. Słuchacze dowiedzą się, jak ścisłe typowanie i kolory portów dyktują przepływ informacji w całym grafie.
3m 50s
3
Interakcja z grafem
Ten odcinek omawia komponenty Chat Input i Chat Output, a także wewnętrzną strukturę obiektów Message. Słuchacze dowiedzą się, jak metadane, takie jak session IDs i timestamps, są opakowywane w wiadomości w celu śledzenia kontekstu konwersacji.
3m 50s
4
Abstrakcja modelu językowego
Ten odcinek omawia główny komponent Language Model oraz globalne konfiguracje dostawców. Słuchacze dowiedzą się, jak abstrahować połączenia LLM i dynamicznie przełączać zachowanie portu wyjściowego dla dalszych integracji.
3m 51s
5
Inteligentne silniki wykonawcze
Ten odcinek omawia komponent Agent i jego rolę jako autonomicznego silnika wnioskującego. Słuchacze dowiedzą się, jak wbudowane możliwości pamięci umożliwiają dynamiczne podejmowanie decyzji wykraczające poza proste, statyczne prompty.
3m 56s
6
Wyposażanie agentów w Tool Mode
Ten odcinek omawia mechanikę Tool Mode, która przekształca bierne komponenty w funkcje agenta gotowe do działania. Słuchacze dowiedzą się, jak konfigurować opisy narzędzi, aby idealnie kierować procesem decyzyjnym agenta.
3m 58s
7
Kompozycje Multi-Agent
Ten odcinek omawia strategię architektoniczną zagnieżdżania sub-flows i używania dodatkowych agentów jako narzędzi. Słuchacze dowiedzą się, jak budować hierarchiczne systemy multi-agent do złożonego routingu zadań.
3m 31s
8
Klient Model Context Protocol
Ten odcinek omawia komponent MCP Tools i jego zdolność do łączenia zewnętrznych narzędzi serwerowych bezpośrednio z Twoimi agentami. Słuchacze dowiedzą się, jak Model Context Protocol zastępuje standardowe wrappery REST API dla kontekstu agenta.
3m 45s
9
Udostępnianie flow jako serwerów MCP
Ten odcinek omawia przekształcanie projektów Langflow w uniwersalne narzędzia MCP dla zewnętrznych klientów. Słuchacze dowiedzą się, jak konfigurować strumieniowe transporty HTTP i tworzyć solidne opisy narzędzi dla zdalnych środowisk IDE.
3m 41s
10
Zarządzanie stanem i sesją
Ten odcinek omawia trwałość pamięci i ścisłą izolację sesji pomiędzy turami czatu. Słuchacze nauczą się odróżniać pamięć komponentu Agent od komponentu Message History w celu niezawodnego śledzenia liniowej konwersacji.
4m 15s
11
Ugruntowanie LLM za pomocą Vector Stores
Ten odcinek omawia najlepsze praktyki architektoniczne dotyczące budowania pipeline'ów Retrieval Augmented Generation. Słuchacze dowiedzą się, jak oddzielić asynchroniczne pobieranie danych od wyszukiwania semantycznego w czasie rzeczywistym.
3m 32s
12
Rozszerzanie silnika za pomocą języka Python
Ten odcinek omawia podstawy tworzenia niestandardowych komponentów Python w ramach frameworka. Słuchacze dowiedzą się, jak ścisłe adnotacje na poziomie klasy mapują wewnętrzną logikę kodu na wizualne węzły UI.
3m 45s
13
Zaawansowane hooki komponentów i wykonywanie
Ten odcinek omawia cykl życia wewnętrznego silnika wykonawczego i zaawansowane techniki współdzielenia stanu. Słuchacze nauczą się nadpisywać setup hooks i wykorzystywać słowniki kontekstu do złożonego utrzymywania stanu.
3m 51s
14
API Langflow i dynamiczne Tweaks
Ten odcinek omawia programowe wykonywanie grafów za pośrednictwem REST API. Słuchacze dowiedzą się, jak używać Input Schema do wstrzykiwania nadpisań parametrów w czasie runtime bez zmieniania bazowego flow.
3m 27s
15
Konteneryzacja produkcyjna
Ten odcinek omawia przejście od programowania wizualnego do wdrożeń produkcyjnych typu headless. Słuchacze dowiedzą się, jak konstruować pliki Dockerfile, blokować zależności i bezpiecznie montować niestandardowe komponenty.
4m 09s

Odcinki

1

Paradygmat Langflow

3m 55s

Ten odcinek omawia podstawową tożsamość frameworka i to, jak jego interfejs wizualny przekłada się na wykonanie po stronie backendu. Słuchacze dowiedzą się, jak logika aplikacji jest ustrukturyzowana jako Directed Acyclic Graph, co pozwala na płynne przejście od szybkiego prototypowania do produkcyjnych API.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 1 z 15. Prototypowanie aplikacji AI zazwyczaj oznacza szybkie zbudowanie wizualnej makiety, udowodnienie, że pomysł działa, a następnie wyrzucenie całego UI do kosza, żeby napisać produkcyjny backend od zera. Tracisz dni na przepisywanie wizualnych koncepcji na kod serwera. W tym odcinku omówimy paradygmat Langflow – koncepcję, która całkowicie eliminuje ten etap przepisywania. Langflow to framework zaprojektowany do budowania aplikacji AI. Ponieważ pracujesz z nim głównie przez canvas, na którym przeciągasz i upuszczasz komponenty, bardzo łatwo pomylić go z kolejnym narzędziem UI albo zabawką low-code. To błąd. Zwróć uwagę na tę różnicę. Langflow to pełnoprawny framework backendowy w Pythonie. Wizualny interfejs to tylko okno na działającą pod spodem architekturę Pythona. Każdy wizualny komponent, który umieszczasz na canvasie, mapuje się bezpośrednio na klasę w Pythonie, a graf, który rysujesz, przekłada się wprost na logikę backendowego API. W Langflow aplikacje, które budujesz, nazywają się flows. Kiedy otwierasz workspace, tak naprawdę konstruujesz skierowany graf acykliczny, czyli DAG. Zaczynasz od dodawania node'ów na canvas. Każdy node reprezentuje osobny blok funkcjonalności, jak text parser, data loader czy moduł przetwarzający. Następnie rysujesz linie łączące output handles jednego node'a z input handles drugiego. Te linie nie są tylko na pokaz. Dyktują one zależności wykonywania całej twojej aplikacji. Jeśli połączysz output node'a typu document loader z inputem node'a przetwarzającego, silnik pod spodem odczyta to jako ścisłą regułę zależności. Wie, że musi najpierw wykonać document loader, poczekać na wynik, a następnie przekazać te dane downstream. Dane płyną przez graf ściśle w jednym kierunku, zapewniając przewidywalną i łatwą do prześledzenia ścieżkę od user inputu do ostatecznej odpowiedzi. Framework bierze na siebie type checking między tymi połączonymi handle'ami, upewniając się, że output jednego node'a jest kompatybilny z inputem następnego, zanim w ogóle rozpocznie się wykonywanie. Wyobraź sobie budowanie prototypowego flow dla prostego narzędzia typu question-answering. W workspace łączysz node typu text input z node'em przetwarzającym, a następnie kierujesz to do node'a typu output. Testujesz to od razu w przeglądarce, dostrajając parametry, aż odpowiedzi będą wyglądać tak jak trzeba. W tradycyjnym workflow kolejnym krokiem jest przekazanie specyfikacji do backend developera, żeby przepisał tę logikę w Pythonie. W paradygmacie Langflow całkowicie to pomijasz. W momencie, gdy twój wizualny flow działa, jest to już funkcjonujące API. Po prostu wysyłasz request na wbudowany endpoint run z identyfikatorem twojego flow i zmiennymi wejściowymi. Framework przechodzi przez graf dokładnie tak, jak go zaprojektowałeś, wykonując każdą klasę w Pythonie we właściwej kolejności i zwraca odpowiedź. Przechodzisz od wizualnego prototypu do działającego backendu w Pythonie bez pisania ani jednej linijki kodu konfiguracji serwera. Główną ideą Langflow jest to, że wizualna mapa, którą rysujesz, żeby zrozumieć swoją aplikację, to dokładnie ta sama struktura, której serwer używa do jej wykonania. Jeśli uważasz te odcinki za pomocne i chcesz wesprzeć podcast, znajdź DevStoriesEU na Patreonie. Dzięki za wysłuchanie, udanego kodowania!
2

Architektura komponentów i typy danych

3m 50s

Ten odcinek omawia anatomię komponentu, w tym porty wejściowe i wyjściowe, a także podstawowe typy danych, takie jak Data i Message. Słuchacze dowiedzą się, jak ścisłe typowanie i kolory portów dyktują przepływ informacji w całym grafie.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 2 z 15. Łączysz dwa node'y, uruchamiasz pipeline i absolutnie nic się nie dzieje. Połączenie wygląda dobrze, ale wykonanie failuje albo rzuca niezrozumiałym błędem. Problem zazwyczaj sprowadza się do tego, jak dane przepływają między blokami, co prowadzi nas do architektury komponentów i typów danych. Często zakłada się, że komponenty Langflow przekazują sobie luźne payloady JSON, tak jak standardowe web API. Wcale tak nie jest. Każdy komponent w Langflow to odrębne, ściśle typowane wykonanie klasy w Pythonie. Komponent zawiera stan wewnętrzny, porty wejściowe i porty wyjściowe. Dane przepływają ściśle przez te zdefiniowane porty, a te porty wymagają określonych obiektów Langflow. Możesz śledzić te typy danych za pomocą kolorów portów. Każdy port komponentu ma określony kolor, który odpowiada typowi danych, jakie akceptuje lub zwraca. Jeśli połączysz port wyjściowy z portem wejściowym i kolory będą się zgadzać, dane przepłyną płynnie. Jeśli kolory się nie zgadzają, próbujesz przekazać niekompatybilne dane. Komponent downstream nie będzie w stanie sparsować przychodzącego obiektu, a flow sfailuje. Aby budować niezawodne pipeline'y, musisz zrozumieć trzy podstawowe obiekty danych, które podróżują przez te połączenia. Pierwszym z nich jest typ Message. Obiekt Message jest używany do danych konwersacyjnych. Przenosi on samą treść tekstową wraz z informacjami o routingu, a konkretnie o roli, która mówi systemowi, czy tekst pochodzi od użytkownika, system promptu, czy modelu AI. Drugim podstawowym typem jest obiekt Data. Obiekt Data działa jako wrapper dla nieustrukturyzowanych informacji. Przechowuje treść tekstową wraz ze słownikiem metadanych. Kiedy pobierasz dokumenty z wektorowej bazy danych, scrapujesz stronę internetową albo czytasz plik tekstowy, te informacje podróżują przez twój flow jako ustrukturyzowany obiekt Data, a nie jako surowy string. Słownik metadanych pozwala ci przekazać źródłowe adresy URL albo timestampy razem z tekstem, bez psucia logiki przetwarzania downstream. Trzecim typem jest obiekt DataFrame. Jest on używany do dwuwymiarowych danych tabelarycznych. Zachowuje się bardzo podobnie do Pandas DataFrame, co czyni go wymaganym typem, kiedy przekazujesz sparsowane pliki CSV albo ustrukturyzowane wiersze i kolumny między komponentami analitycznymi. Ponieważ porty są ściśle typowane, często spotkasz się z sytuacjami, w których masz jeden typ danych, ale kolejny komponent wymaga innego. Weźmy na przykład scenariusz, w którym pobierasz surowy string z podstawowego bloku wykonawczego Pythona i musisz przekazać go do komponentu przetwarzania tekstu, który jawnie wymaga ustrukturyzowanego obiektu Data. Kolory portów nie będą się zgadzać. Nie możesz wcisnąć na siłę surowego stringa do portu Data. Aby wypełnić tę lukę, używasz komponentu Type Convert. Umieszczasz blok Type Convert pomiędzy dwoma niedopasowanymi komponentami. Najpierw łączysz wyjście stringa z wejściem bloku Type Convert. Następnie łączysz jego wyjście z portem Data twojego komponentu przetwarzania downstream. Blok Type Convert bierze surowy string, opakowuje go w odpowiedni obiekt Data z pustym słownikiem metadanych i bezpiecznie przekazuje do następnego node'a. Zrozumienie ścisłego typowania tych portów to różnica między flow, który działa, a flow, który ciągle się sypie. Jeśli pipeline failuje po cichu, nie debuguj najpierw swojej logiki, tylko sprawdź kolory portów, aby upewnić się, że twoje komponenty rzeczywiście mówią dokładnie tym samym językiem danych. Dzięki za wysłuchanie. Trzymajcie się wszyscy.
3

Interakcja z grafem

3m 50s

Ten odcinek omawia komponenty Chat Input i Chat Output, a także wewnętrzną strukturę obiektów Message. Słuchacze dowiedzą się, jak metadane, takie jak session IDs i timestamps, są opakowywane w wiadomości w celu śledzenia kontekstu konwersacji.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 3 z 15. Zwykła wiadomość na czacie wydaje się po prostu stringiem, ale gdyby tak było, twoja aplikacja straciłaby orientację, kto co powiedział, w momencie podłączenia się drugiego użytkownika. Rozwiązanie tego problemu z routingiem to dokładnie to, czym zajmiemy się dzisiaj: komunikacja z grafem za pomocą Chat Input i Chat Output. Kiedy budujesz flow, punktem wejścia jest zazwyczaj komponent Chat Input. Developerzy często mylą go ze zwykłym polem tekstowym, które ślepo przekazuje stringa do następnego node'a. To błędny model mentalny. Komponent Chat Input działa jak fabryka ustrukturyzowanych danych. Jego główną funkcją jest przechwytywanie surowego tekstu z interfejsu użytkownika i opakowanie go w konkretny typ danych, zwany obiektem Message. Obiekt Message to podstawowa waluta dla tekstu przemieszczającego się przez graf Langflow. Zamiast przekazywać same stringi, graf routuje ten ustandaryzowany pakiet. Wewnątrz obiektu, właściwe słowa wpisane przez użytkownika siedzą w głównym polu tekstowym. Ten tekst otacza warstwa metadanych. Obiekt zawiera pole sender, które kategoryzuje źródło jako User lub Machine. Zawiera pole sender name, które odpowiada za wizualną etykietę wyświetlaną na front endzie. Zapisuje też dokładny czas utworzenia w polu timestamp. Te metadane stają się kluczowe przy obsłudze współbieżnych użytkowników. Wyobraź sobie scenariusz, w którym użytkownik zadaje pytanie w zdeployowanej aplikacji. Komponent Chat Input łapie ten tekst, pakuje go w obiekt Message, ustawia pole sender na User i dołącza unikalny session ID. Ten session ID to mechanizm, który śledzi konkretny wątek konwersacji. Kiedy Message przechodzi przez graf, mijając retrievery czy node'y przetwarzające, ten session ID pozostaje do niego przypięty. Narzędzia do state managementu i komponenty pamięci polegają wyłącznie na tym ID, żeby grupować interakcje. Bez niego graf nie miałby jak odizolować kontekstu jednego użytkownika od drugiego. Masz też kontrolę nad widocznością tego inputu. Komponent Chat Input można skonfigurować tak, żeby ukrywał swoją zawartość w głównym interfejsie czatu. Jest to przydatne przy przekazywaniu domyślnych parametrów systemowych albo instrukcji w tle, których użytkownik nigdy nie musi widzieć, jednocześnie wstrzykując poprawny obiekt Message do grafu. Po drugiej stronie flow siedzi komponent Chat Output. To terminalny node, który prezentuje dane z powrotem w interfejsie użytkownika. Łapie on końcowy obiekt Message wygenerowany przez twoją logikę. Ponieważ otrzymuje w pełni uformowany obiekt, komponent Chat Output odczytuje pola sender i sender name, żeby poprawnie wyrenderować interfejs, zazwyczaj wyświetlając odpowiedź jako pochodzącą od Machine. Jeśli poprzedni node przypadkiem przekaże surowy tekst do Chat Output zamiast obiektu Message, komponent automatycznie to skoryguje. Opakowuje surowy string w świeży obiekt Message przed jego wyświetleniem, wymuszając ścisłą spójność danych na granicach twojego grafu. Komponenty Chat Input i Chat Output to nie są kosmetyczne elementy interfejsu, to kontrolery graniczne twojej aplikacji, gwarantujące, że każdy kawałek tekstu jest czysto opakowany w śledzony obiekt Message, zanim będzie mógł ruszyć dalej. Dzięki za wspólnie spędzony czas. Mam nadzieję, że dowiedziałeś się czegoś nowego.
4

Abstrakcja modelu językowego

3m 51s

Ten odcinek omawia główny komponent Language Model oraz globalne konfiguracje dostawców. Słuchacze dowiedzą się, jak abstrahować połączenia LLM i dynamicznie przełączać zachowanie portu wyjściowego dla dalszych integracji.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 4 z 15. Postanawiasz zmienić dostawcę modelu w swojej aplikacji w trakcie projektu. Zazwyczaj oznacza to tropienie każdego API calla, przepisywanie obiektów konfiguracji i nadzieję, że nie zepsułeś całego prompt chaina. Odpowiednia architektura sprawia, że to przejście jest całkowicie płynne. Komponent Language Model w Langflow zapewnia abstrakcję, która to umożliwia. Kiedy developerzy zaczynają budować flowy, często oczekują, że wrzucą node'a modelu na canvas i od razu wkleją swój API key bezpośrednio w ustawieniach komponentu. Nie rób tego. Langflow jest zaprojektowany tak, aby obsługiwać uwierzytelnianie globalnie przez panel Model Providers. Konfigurujesz swoje credentials, takie jak klucze OpenAI czy Anthropic, dokładnie raz w ustawieniach globalnych. Poszczególne komponenty modelu na twoim canvasie działają jako referencje do tych globalnych konfiguracji. Sam node obsługuje lokalne zachowanie, kontrolując takie rzeczy jak system prompt, maksymalny limit tokenów czy ustawienie temperatury. Globalny provider obsługuje bezpieczne połączenie. To oddzielenie uwierzytelniania od logiki wykonania staje się kluczowe, gdy chcesz poeksperymentować. Wyobraź sobie, że masz złożony prompt chain, który obecnie zasila komponent modelu OpenAI. Chcesz sprawdzić, czy model Anthropic da lepsze rezultaty. Dzięki globalnej abstrakcji po prostu przeciągasz nowy komponent Anthropic na canvas. Podpinasz swoją istniejącą sekwencję promptów do jego wejścia. Ustawiasz żądaną temperaturę na nowym nodzie. Globalny provider automatycznie obsługuje autoryzację w tle na podstawie twoich zapisanych kluczy. Usuwasz starego node'a, a twój flow jest od razu gotowy do testów. Nic w twoim prompt chainie się nie psuje. To tyle, jeśli chodzi o konfigurację komponentu. Teraz spójrz, jak przekazuje dane dalej. Komponent Language Model oferuje podwójne możliwości wyjścia, w zależności od tego, czego faktycznie wymaga reszta twojego flow. Domyślnie komponent emituje Model Response. Wysyłasz mu prompt, model go przetwarza, a komponent zwraca text string. To standardowe zachowanie, którego używasz podczas budowania prostego chatbota lub narzędzia do podsumowań. Node odbiera request, generuje odpowiedź i przekazuje tę gotową odpowiedź dalej. Czasami jednak downstream component nie potrzebuje odpowiedzi. Potrzebuje silnika. Możesz zmienić zachowanie output portu, przełączając go z emitowania Message response na emitowanie instancji LanguageModel. Kiedy to zrobisz, komponent nie ewaluuje już promptu i nie wysyła tekstu. Zamiast tego pakuje sam skonfigurowany model, wraz z credentials providera i ustawieniami temperatury, a następnie przekazuje ten obiekt do następnego node'a. To niezbędne w przypadku bardziej zaawansowanych architektur. Jeśli podłączysz swój setup do złożonego retrieval chaina, ten chain musi wykonać swoje własne wewnętrzne zapytania, aby przeszukać bazę danych na podstawie historii konwersacji. Nie może tego zrobić, jeśli przekażesz mu tylko statyczną odpowiedź tekstową. Wymaga działającego silnika do wykonywania własnych zadań generowania tekstu. Przekazując instancję LanguageModel, dajesz downstream node'owi w pełni skonfigurowane narzędzie, którego może wielokrotnie używać do generowania konkretnych promptów, jakich potrzebuje. Komponent to nie tylko hardcodowany API call. To elastyczny kontener, który oddziela twoje credentials od logiki, pozwalając ci wybrać, czy twoja aplikacja potrzebuje gotowej odpowiedzi, czy silnika wykonawczego. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
5

Inteligentne silniki wykonawcze

3m 56s

Ten odcinek omawia komponent Agent i jego rolę jako autonomicznego silnika wnioskującego. Słuchacze dowiedzą się, jak wbudowane możliwości pamięci umożliwiają dynamiczne podejmowanie decyzji wykraczające poza proste, statyczne prompty.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 5 z 15. Co odróżnia statycznego chatbota od prawdziwego silnika wnioskowania? Zdolność do samodzielnego decydowania o kolejnych krokach. Jeśli twój flow opiera się wyłącznie na zahardkodowanych prompt chainach, posypie się w momencie, gdy użytkownik zada nieoczekiwane pytanie uzupełniające. Właśnie tutaj wkraczają inteligentne silniki wykonawcze, a konkretnie komponent Agent. Wielu programistów wrzuca zwykły node Language Model na canvas i oczekuje, że będzie się zachowywał jak inteligentny, świadomy kontekstu asystent. Wcale tak nie jest. Standardowy node Language Model to w zasadzie kalkulator typu text-in, text-out. Przekazujesz mu string, a on zwraca string bazując wyłącznie na tym jednym wejściu. Komponent Agent działa zupełnie inaczej. To autonomiczny silnik wnioskowania. Zamiast po prostu wykonywać pojedynczy prompt, Agent ocenia bieżący kontekst, decyduje o sekwencji akcji i sam określa kroki egzekucji, aby osiągnąć cel. Kiedy użytkownik wysyła wiadomość do Agenta, komponent nie generuje od razu ostatecznej odpowiedzi. Wchodzi w wewnętrzną pętlę wnioskowania. Analizuje input, sprawdza swój wewnętrzny state i formułuje plan. Ta faza planowania pozwala Agentowi ustrukturyzować złożone odpowiedzi albo zorientować się, że przed pójściem dalej musi przeanalizować wcześniejsze interakcje. To prowadzi nas do wbudowanych możliwości pamięci komponentu Agent. Standardowy node Language Model cierpi na amnezję. Każdy request to czysta karta. Jeśli użytkownik zapyta o stolicę Francji, a w kolejnym pytaniu zapyta o tamtejszą populację, standardowy node nie będzie wiedział, co oznacza słowo tam. Musiałbyś ręcznie zbudować system do przechwytywania, przechowywania, formatowania i wstrzykiwania historii czatu do każdego nowego promptu. Komponent Agent rozwiązuje to natywnie. Automatycznie utrzymuje bieżący context window z poprzednimi pytaniami użytkownika i odpowiedziami systemu. Kiedy pojawia się to drugie pytanie o populację, Agent przechwytuje request. Przed wygenerowaniem odpowiedzi, odpytuje swoją wbudowaną pamięć. Pobiera kontekst pierwszego pytania, skleja historię konwersacji i wnioskuje, że miejscem, o którym mowa, jest Paryż. Wykonuje tę ewaluację kontekstu całkowicie samodzielnie. Nie musisz podpinać osobnych node'ów pamięci, parsować stringów z historią, ani budować skomplikowanych pętli wstrzykujących historię na twoim canvasie. Agent wewnętrznie obsługuje stateful naturę konwersacji. Sam decyduje, kiedy zajrzeć do historii, jaka jej część jest istotna dla bieżącego zapytania i jak użyć tego historycznego kontekstu do ukształtowania kolejnego outputu. To podejście zmienia sposób, w jaki projektujesz flow. Nie mapujesz już każdej możliwej gałęzi konwersacji. Dostarczasz inteligentnemu silnikowi parametry potrzebne do samodzielnego zarządzania konwersacją. Komponent bierze na siebie ciężar state managementu i rozwiązywania kontekstu. Prawdziwa siła komponentu Agent tkwi w tej autonomii. Przechodząc ze statycznych modeli językowych na Agenta, delegujesz control flow do samego silnika. System nie jest już sztywnym pipelinem, ale dynamicznym bytem zdolnym do utrzymywania state'u, zapamiętywania poprzednich interakcji i dostosowywania swojego wnioskowania do intencji użytkownika w locie. Chciałbym poświęcić chwilę, żeby podziękować ci za słuchanie — to bardzo nam pomaga. Miłego dnia!
6

Wyposażanie agentów w Tool Mode

3m 58s

Ten odcinek omawia mechanikę Tool Mode, która przekształca bierne komponenty w funkcje agenta gotowe do działania. Słuchacze dowiedzą się, jak konfigurować opisy narzędzi, aby idealnie kierować procesem decyzyjnym agenta.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 6 z 15. Możesz myśleć, że zbudowanie narzędzia dla agenta wymaga pisania własnych wrapperów w Pythonie albo przeszukiwania biblioteki w poszukiwaniu wyspecjalizowanych tool node'ów. Wcale tak nie jest. Prawie każdy komponent, który masz już na swoim canvasie, możesz zamienić w aktywną funkcjonalność jednym kliknięciem. Dzisiaj przyjrzymy się wyposażaniu agentów w Tool Mode. Częstym błędem jest myślenie, że żeby zasilić agenta, potrzebujesz dedykowanych, hardkodowanych komponentów narzędziowych. W Langflow Tool Mode to funkcja wbudowana bezpośrednio w standardowe node'y. Niezależnie od tego, czy pracujesz z API callerem, retrieverem bazy danych, czy node'em do przetwarzania tekstu, możesz przełączyć go w Tool Mode. Kiedy aktywujesz ten przełącznik na komponencie, jego interfejs się zmienia. Standardowe porty wyjściowe, które normalnie podpiąłbyś do kolejnego kroku w liniowym chainie, znikają. Zamiast tego komponent wystawia pojedynczy port wyjściowy typu Tool. Bierzesz ten nowy output Tool i podłączasz go bezpośrednio do portu wejściowego Tools w komponencie agenta. Pasywny krok przetwarzania staje się teraz aktywnym narzędziem, które agent może wywołać na żądanie. Zamiana komponentu w narzędzie to tylko mechaniczny krok. Agent wciąż musi wiedzieć, jak go użyć. Kiedy włączysz Tool Mode, na node'zie pojawia się przycisk Edit Action. Jego kliknięcie odsłania trzy pola konfiguracyjne. Pierwsze pole to Slug. To identyfikator czytelny dla maszyny, zazwyczaj formatowany z podkreślnikami zamiast spacji. Drugie to Name, czyli standardowy tytuł czytelny dla człowieka. Trzecie pole to Description. I to jest ta najważniejsza część. Pole Description to nie jest dokumentacja dla developera. To dosłowny prompt tekstowy, który czyta Large Language Model, żeby zdecydować, czy powinien wywołać to konkretne narzędzie. Jeśli twój opis będzie niejasny, agent będzie zgadywał, kiedy go użyć, a to doprowadzi do nieprzewidywalnego zachowania i zmarnowanych tokenów. Weźmy jako przykład komponent Web Search. Normalnie przyjmuje on po prostu string i zwraca wyniki wyszukiwania. Jeśli włączysz Tool Mode na tym node'zie, staje się on narzędziem dla agenta. Teraz otwierasz menu Edit Action. Jeśli wpiszesz ogólny opis, na przykład przeszukuje sieć, agent może wywołać wyszukiwanie dla podstawowych pytań o fakty, które ma już w swoich danych treningowych. Zamiast tego, piszesz bardzo restrykcyjny opis. Definiujesz dokładne warunki. Piszesz: używaj tego narzędzia wyłącznie do wyszukiwania najświeższych wiadomości, bieżących wydarzeń lub pogody w czasie rzeczywistym. Agent parsuje to konkretne zdanie podczas swojego cyklu rozumowania. Ewaluuje prompt w oparciu o twój opis, upewniając się, że node Web Search odpala się tylko wtedy, gdy użytkownik pyta o najnowsze wiadomości. Możesz to skalować, włączając Tool Mode na kilku różnych komponentach. Po prostu podłączasz wszystkie ich porty wyjściowe Tool do jednego wejścia Tools w node'zie agenta. Agent przegląda opisy każdego podłączonego narzędzia, wybiera to właściwe, wykonuje je i syntetyzuje zwrócone dane, żeby sformułować swoją ostateczną odpowiedź. Logika pod spodem node'a jest całkowicie niewidoczna dla agenta. Jedyną rzeczą, która kontroluje proces decyzyjny twojego agenta, jest precyzja opisów twoich narzędzi. Dzięki za wysłuchanie. Do usłyszenia następnym razem!
7

Kompozycje Multi-Agent

3m 31s

Ten odcinek omawia strategię architektoniczną zagnieżdżania sub-flows i używania dodatkowych agentów jako narzędzi. Słuchacze dowiedzą się, jak budować hierarchiczne systemy multi-agent do złożonego routingu zadań.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 7 z 15. Wymuszanie na jednym modelu językowym obsługi podstawowego routingu i ciężkiej analizy danych w tym samym czasie zazwyczaj skutkuje wolnymi odpowiedziami i wysokimi rachunkami za API. Rozwiązaniem jest podział obciążenia poznawczego i właśnie tu wkraczają kompozycje Multi-Agent. Wiele osób postrzega flowy w Langflow wyłącznie jako odizolowane endpointy. Uderzasz do API, dostajesz odpowiedź i wykonanie się kończy. To błędne przekonanie. Flowy to nie tylko aplikacje najwyższego poziomu; można je zagnieżdżać hierarchicznie. Weźmy na warsztat system do parsowania requestów od użytkowników. Konfigurujesz głównego agenta routingu, używając szybkiego i taniego modelu. Jego jedynym zadaniem jest zorientowanie się, czego chce użytkownik. Kiedy użytkownik prosi o analizę wielkiego raportu finansowego, główny agent nie przetwarza dokumentu samodzielnie. Zamiast tego, podpinasz drugiego agenta bezpośrednio w tool input głównego agenta. Ten drugi agent odpala zupełnie inny model ze znacznie większym context window, wyspecjalizowany konkretnie w ekstrakcji danych. Routing opiera się w całości na tool description. Kiedy podpinasz drugiego agenta, musisz podać jasny, tekstowy opis tego, co on robi. Główny agent czyta ten opis razem z user promptem. Kiedy request pasuje do opisu, główny agent zatrzymuje własną generację, pakuje odpowiedni kontekst i wywołuje drugiego agenta. Dla głównego agenta, ten cały złożony setup wygląda jak pojedyncza funkcja. Drugi agent wykonuje własny reasoning loop, przetwarza duży dokument i zwraca końcowy tekst z powrotem do głównego agenta, który następnie odpowiada użytkownikowi. Możesz pójść z tą abstrakcją jeszcze dalej, używając całego flow jako toola. Możesz zbudować zaawansowany flow, który scrapuje stronę internetową, wyciąga tekst, formatuje go i ewaluuje output. Kiedy go zbudujesz, po prostu go zapisujesz. W zupełnie innym projekcie, wrzucasz komponent Flow Tool na canvas i wybierasz swój zapisany flow. Przenosząc flow do innego workspace'u, definiujesz konkretne komponenty input i output wewnątrz tego child flow. Parent agent mapuje argumenty swojego toola bezpośrednio na te zdefiniowane inputy. Wykonuje child flow, czeka na odpalenie końcowego komponentu output i zaciąga wynikowy tekst z powrotem w górę chaina. Langflow jest zbudowany na architekturze grafowej opartej na node'ach. Dzięki tej strukturze, silnik pozwala na rekurencyjną kompozycję. Cały graf może zostać zenkapsulowany i potraktowany jako pojedynczy node w większym grafie. Główny agent nie ma pojęcia o tej zagnieżdżonej złożoności. Widzi tylko toola o nazwie scrape_and_evaluate, który przyjmuje URL i zwraca podsumowanie. Siłą kompozycji Multi-Agent jest abstrakcja. Pozwala ci to ukryć złożone, wieloetapowe reasoning loopy za pojedynczym tool callem, utrzymując główną logikę routingu czystą i przewidywalną. Jeśli chcesz wesprzeć program, znajdziesz nas, wyszukując DevStoriesEU na Patreon. Dzięki za słuchanie. Trzymajcie się wszyscy.
8

Klient Model Context Protocol

3m 45s

Ten odcinek omawia komponent MCP Tools i jego zdolność do łączenia zewnętrznych narzędzi serwerowych bezpośrednio z Twoimi agentami. Słuchacze dowiedzą się, jak Model Context Protocol zastępuje standardowe wrappery REST API dla kontekstu agenta.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 8 z 15. Czasy pisania customowych wrapperów API dla każdego nowego źródła danych minęły. Nie musisz już ręcznie mapować endpointów, formatować nagłówków i parsować surowego JSON-a, tylko po to, żeby agent mógł przeczytać stronę internetową albo odpytać lokalną bazę danych. Ten problem eliminuje Model Context Protocol Client. Ludzie często mylą to ze standardowymi integracjami REST API. To nie jest zwykły node HTTP request, w którym samemu składasz payload. Model Context Protocol, czyli MCP, to otwarty standard zaprojektowany specjalnie w celu dostarczania kontekstu i wykonywalnych funkcji do modeli AI. Jest to uniwersalny język do tool use. W tej architekturze Langflow działa jako MCP Client. Łączy się z zewnętrznym MCP Serverem, pyta, jakie możliwości on oferuje, i je wystawia. Osiągniesz to za pomocą komponentu MCP Tools. Wrzucasz ten komponent na canvas i podpinasz jego output bezpośrednio do inputu tools w komponencie Agent. Po nawiązaniu połączenia, Langflow otrzymuje ścisły schema definiujący narzędzia, ich opisy i wymagane parametry. Automatycznie tłumaczy je na natywne narzędzia. Agent sam z siebie wie dokładnie, jak sformatować dane i striggerować zewnętrzne funkcje. Aby nawiązać to połączenie, wybierasz metodę transportu. Komponent MCP Tools obsługuje dwie opcje: HTTP przez Server-Sent Events oraz STDIO. HTTP to właściwy wybór dla zdalnych serwerów działających bezpiecznie na innej maszynie. Po prostu podajesz URL endpointu. STDIO używasz, kiedy chcesz, żeby Langflow odpalił lokalny proces i komunikował się przez standardowe streamy wejścia i wyjścia. Spójrzmy na konkretny scenariusz z użyciem STDIO. Załóżmy, że chcesz, żeby twój agent podsumowywał tech newsy bezpośrednio z zewnętrznych URL-i. Możesz użyć gotowego narzędzia o nazwie fetch MCP server. W komponencie MCP Tools ustaw transport na STDIO. Ustaw command na uvx, narzędzie w Pythonie, które pobiera i odpala pakiety w izolowanych środowiskach. W polu arguments wpisz mcp dash server dash fetch. Podłącz output komponentu do swojego agenta. Kiedy spromptujesz agenta, żeby podsumował konkretny artykuł, agent natywnie wywoła fetch tool. Streamuje on docelowy URL przez STDIO do izolowanego background processu, odczytuje zwrócony tekst ze strony i generuje twoje podsumowanie. Nie napisałeś absolutnie żadnego kodu, żeby zrobić tę integrację. Wiele narzędzi wymaga autentykacji, jak hasło do bazy danych albo prywatny API key. Komponent MCP Tools zawiera pole Environment Variables, które przyjmuje dictionary par key-value. Jeśli wchodzisz w interakcję ze swoim grafem Langflow programatycznie przez API, możesz dynamicznie wstrzykiwać te credentials za pomocą tweaks dictionary. Po prostu targetujesz ID komponentu MCP Tools i bezpiecznie przekazujesz environment variables w swoim request payload. Największą zaletą MCP Clienta jest całkowity decoupling. Deployujesz zewnętrzną funkcjonalność raz, w dowolnym języku programowania, i natychmiast dajesz każdemu agentowi Langflow natywny dostęp do niej, bez jakiejkolwiek zmiany logiki grafu. Dzięki za wysłuchanie — do usłyszenia następnym razem.
9

Udostępnianie flow jako serwerów MCP

3m 41s

Ten odcinek omawia przekształcanie projektów Langflow w uniwersalne narzędzia MCP dla zewnętrznych klientów. Słuchacze dowiedzą się, jak konfigurować strumieniowe transporty HTTP i tworzyć solidne opisy narzędzi dla zdalnych środowisk IDE.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 9 z 15. Piszesz customowy pipeline AI i chcesz, żeby twój edytor kodu uruchamiał go natywnie jako zintegrowane narzędzie. Zadajesz pytanie swojemu IDE, a ono płynnie uruchamia złożony system retrievalu, który zbudowałeś wczoraj. Wystawianie flow jako serwerów MCP to umożliwia. Najpierw musimy wyjaśnić, czym właściwie jest serwer MCP. Słuchacze czasami mylą go ze standardowym endpointem deploymentu używanym jako backend aplikacji webowej. To zupełnie coś innego. Model Context Protocol, czyli MCP, to ustandaryzowany sposób serwowania możliwości bezpośrednio innym agentom AI. Standardowy endpoint przekazuje dane do interfejsu użytkownika. Serwer MCP udostępnia toole dla reasoning engine. Langflow pozwala automatycznie zamienić dowolny projekt w serwer MCP. Kiedy to zrobisz, cały twój flow jest pakowany jako wykonywalne narzędzie. Do komunikacji z zewnętrznymi klientami, Langflow używa streamowanego transportu HTTP, a konkretnie opiera się na Server-Sent Events. Oznacza to, że twój zewnętrzny klient łączy się przez standardowe protokoły webowe i może odbierać streamowane odpowiedzi bezpośrednio z twojego flow, bez potrzeby skomplikowanej konfiguracji sieci lokalnej. Techniczna konfiguracja jest prosta, ale jest jeden absolutny wymóg, który musisz spełnić. Musisz zdefiniować nazwę i opis toola. Kiedy zewnętrzny agent łączy się z twoim serwerem Langflow MCP, prosi o listę dostępnych tooli. Agent używa dostarczonych opisów, żeby zdecydować, którego toola wywołać i kiedy. Jeśli zostawisz domyślny opis albo napiszesz coś niejasnego, zewnętrzny agent go zignoruje. Musisz napisać opis jako precyzyjną instrukcję dla agenta AI. W ten sposób tak naprawdę promptujesz zewnętrzny system, jak ma używać twojego flow. Spójrzmy na konkretny scenariusz. Budujesz flow Document QA w Langflow, który przeszukuje wewnętrzny dokument o architekturze firmy. Chcesz, żeby twój lokalny agent w edytorze Cursor natywnie odpytywał ten dokument. Wystawiasz ten flow jako serwer MCP. Nazywasz toola query company architecture i ustawiasz opis tak, żeby informował, że przeszukuje on wewnętrzny dokument o architekturze firmy, aby odpowiadać na techniczne pytania dotyczące serwisów backendowych. Następnie konfigurujesz Cursora, żeby łączył się z twoim URL Langflow MCP. Teraz piszesz kod w Cursorze i pytasz agenta, jak działa system uwierzytelniania. Cursor sprawdza podłączone serwery MCP, czyta twój szczegółowy opis i orientuje się, że twój tool z Langflow to dokładnie to, czego potrzebuje. Cursor przekazuje twoje pytanie jako argument do toola. Langflow odbiera request przez transport HTTP, uruchamia cały flow Document QA i streamuje odpowiedź z powrotem do twojego edytora. Twoje IDE właśnie użyło złożonego projektu Langflow jako natywnej funkcji. Sukces integracji MCP zależy całkowicie od jakości promptu, który ukryjesz w opisie toola. Jeśli zewnętrzny agent nie zrozumie opisu, twój tool w praktyce nie istnieje. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
10

Zarządzanie stanem i sesją

4m 15s

Ten odcinek omawia trwałość pamięci i ścisłą izolację sesji pomiędzy turami czatu. Słuchacze nauczą się odróżniać pamięć komponentu Agent od komponentu Message History w celu niezawodnego śledzenia liniowej konwersacji.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 10 z 15. Jeśli dwóch użytkowników rozmawia z twoją aplikacją AI dokładnie w tym samym czasie, jak system unika przekazywania odpowiedzi jednego użytkownika drugiemu? Odpowiedź tkwi w tym, jak izolujesz wątki, i dokładnie tym zajmuje się zarządzanie stanem i sesją. Najpierw wyjaśnijmy sobie jedną, bardzo często myloną kwestię. Musimy wyraźnie oddzielić chat memory od semantycznej pamięci wektorowej. Pamięć wektorowa polega na zapisywaniu dokumentów jako embeddings i pobieraniu ich na podstawie znaczenia. Tym nie będziemy się tutaj zajmować. Chat memory to po prostu liniowy, chronologiczny log z konwersacji. To mechanizm, który pozwala modelowi językowemu pamiętać, co użytkownik powiedział trzy wiadomości temu. Domyślnie Langflow zapisuje tę liniową historię wiadomości lokalnie, używając bazy danych SQLite. Za każdym razem, gdy wiadomość przechodzi przez system, jest zapisywana. Ale baza danych pełna wiadomości jest bezużyteczna, jeśli system nie wie, która wiadomość należy do kogo. I tutaj do gry wchodzi session ID. Session ID to unikalny string, który spina ze sobą sekwencję interakcji. Kiedy używasz interfejsu Langflow, system automatycznie generuje dla ciebie session ID w tle. Na produkcji prawdopodobnie będziesz komunikować się z Langflow przez API. Jeśli masz dwóch różnych użytkowników uderzających do twojego serwera w tym samym czasie, musisz przekazać konkretny session ID dla każdego z nich w swoim API request. Standardową praktyką jest użycie unikalnego user ID z twojej własnej bazy danych jako session ID w Langflow. Kiedy twój pierwszy użytkownik wysyła wiadomość, przekazujesz jego konkretne ID. Langflow odpytuje bazę SQLite o ten konkretny string, wyciąga tylko jego historię, dokleja ją do prompta i generuje odpowiedź. Kiedy twój drugi użytkownik wykonuje akcję milisekundę później ze swoim własnym ID, Langflow robi dokładnie to samo w pełnej izolacji. Jeśli nie przekażesz session ID w swoim API call, Langflow potraktuje tę interakcję jako zupełnie nowe zdarzenie. Kontekst całkowicie przepada. Aby utrzymać wątek, twoja zewnętrzna aplikacja musi wysyłać ten identyfikator z każdym pojedynczym requestem. To, jak wystawiasz tę historię do modelu językowego, zależy całkowicie od komponentów, które wybierzesz. Langflow oferuje dwa różne podejścia. Jeśli używasz standardowego komponentu Agent, zarządzanie pamięcią jest wbudowane od razu. Agent automatycznie ogarnia odczyt i zapis do bazy SQLite, używając aktywnego session ID. Nie musisz podpinać niczego dodatkowego, żeby zapamiętał konwersację. Agenty mają wysoki poziom abstrakcji, więc jeśli budujesz customowy chain od zera, używając bazowych komponentów i surowych promptów, ta wbudowana pamięć nie istnieje. I tutaj używasz dedykowanego komponentu Message History. Wrzucasz ten komponent do swojego flow i łączysz jego output ze zmienną w komponencie Prompt. Kiedy flow startuje, komponent Message History łapie aktywne session ID, wyciąga odpowiedni chronologiczny log z bazy danych i formatuje go jako tekst. To fizycznie przekazuje zapisany dialog do context window, zanim model językowy w ogóle go zobaczy. Kontrolowanie session ID na poziomie API to absolutnie najważniejszy wymóg przy skalowaniu interfejsu konwersacyjnego, ponieważ ścisłe powiązanie stanu z przekazanym identyfikatorem gwarantuje pełną izolację dla dowolnej liczby jednoczesnych użytkowników. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
11

Ugruntowanie LLM za pomocą Vector Stores

3m 32s

Ten odcinek omawia najlepsze praktyki architektoniczne dotyczące budowania pipeline'ów Retrieval Augmented Generation. Słuchacze dowiedzą się, jak oddzielić asynchroniczne pobieranie danych od wyszukiwania semantycznego w czasie rzeczywistym.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 11 z 15. Największym błędem, jaki popełniają developerzy podczas budowania Retrieval Augmented Generation, jest łączenie powolnego indeksowania danych i chat retrievalu w czasie rzeczywistym w jeden pipeline. Za każdym razem, gdy użytkownik zadaje pytanie, system próbuje od nowa przeczytać stustronicowy PDF. Rozwiązaniem jest grounding LLM-a w Vector Stores przy użyciu architektury decoupled. Niezwykle często zdarza się łączenie wszystkich komponentów na jednym canvasie. Podłączasz file loader do text splittera, przekazujesz to do embedding modelu, wrzucasz do vector store'a i podpinasz bezpośrednio pod chat interface. To tworzy ogromny bottleneck. Data ingestion i chat retrieval to zupełnie inne lifecycle events. Nie powinny znajdować się w tym samym execution path. Standardowa architektura RAG w Langflow dzieli ten proces na dwa odrębne flow. Po pierwsze, masz ingestion subflow. To tutaj dzieją się te najcięższe operacje. Bierzesz swoje dokumenty źródłowe, takie jak duże pliki PDF, i przepuszczasz je przez document loader. Następnie text splitter dzieli te dokumenty na mniejsze chunki. Konfigurując text splitter, musisz dopasować rozmiar chunków do maksymalnego limitu tokenów wybranego embedding modelu. Jeśli rozmiar chunka przekroczy ten limit, embedding model po cichu zrobi truncate tekstu. Końcowe zdania zostaną zignorowane, a te brakujące dane nigdy nie trafią do twojej vector database. Kiedy tekst jest już odpowiednio podzielony na chunki, przekazujesz go do komponentu embedding, aby wygenerować wektory. Na koniec te wektory są zapisywane w określonej collection wewnątrz twojego komponentu vector store. Cały ten ingestion flow wykonuje się tylko wtedy, gdy zmieniają się dane, całkowicie niezależnie od interfejsu użytkownika. Drugim elementem tej architektury jest retrieval flow. To jest ta część konwersacyjna, z którą ma do czynienia użytkownik. Ponieważ ciężkie indeksowanie zostało już zrobione gdzie indziej, ten flow pozostaje szybki i responsywny. Zaczyna się od chat inputu, który przechwytuje pytanie użytkownika. To pytanie jest przekazywane do komponentu embedding. Musisz skonfigurować ten komponent tak, aby używał dokładnie tego samego embedding modelu, którego użyłeś w fazie ingestion. Jeśli zaindeksujesz dane jednym modelem, a zrobisz query innym, vector store nie znajdzie żadnych trafnych dopasowań. Komponent vector store w tym flow jest skonfigurowany tak, aby przeszukiwać dokładnie tę samą collection w bazie danych, którą wypełniłeś wcześniej. Bierze on pytanie użytkownika po embeddingu, wykonuje similarity search na wcześniej załadowanych danych i zwraca najbardziej trafne chunki tekstu. Następnie kierujesz te pobrane chunki, razem z oryginalnym pytaniem użytkownika, do komponentu prompt template. Ten wzbogacony prompt jest ostatecznie wysyłany do language modelu, który formułuje odpowiedź. Dzieląc swoją implementację RAG na asynchroniczny write flow dla dokumentów i szybki read flow dla czatu, chronisz swój chat interface przed opóźnieniami w przetwarzaniu na backendzie. Złota zasada architektury RAG mówi, że user query powinno jedynie triggerować wyszukiwanie, a nigdy indexing job. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
12

Rozszerzanie silnika za pomocą języka Python

3m 45s

Ten odcinek omawia podstawy tworzenia niestandardowych komponentów Python w ramach frameworka. Słuchacze dowiedzą się, jak ścisłe adnotacje na poziomie klasy mapują wewnętrzną logikę kodu na wizualne węzły UI.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 12 z 15. Programowanie wizualne pozwala ci osiągnąć cel w dziewięćdziesięciu procentach, ale w końcu nieuchronnie trafiasz na ścianę. Musisz uruchomić specyficzną logikę biznesową albo połączyć się z customowym, wewnętrznym API, a gotowe node'y po prostu tego nie ogarniają. Rozszerzenie engine'u za pomocą Pythona odblokowuje te ostatnie dziesięć procent absolutnej kontroli. Łatwo pomyśleć, że customowy komponent to po prostu standardowy skrypt w Pythonie, który wrzucasz do katalogu. Ale tak nie jest. Customowy komponent wymaga ścisłej konfiguracji na poziomie klasy. Bez tej konkretnej struktury, engine Langflow nie ma pojęcia, jak wyrenderować twój node w edytorze wizualnym, ani jak wpiąć jego dane w graf wykonania. Wizualny node i logika backendu są ze sobą ściśle powiązane. Żeby zbudować customowy komponent, zawsze zaczynasz od utworzenia subclassy bazowej klasy Component dostarczanej przez Langflow. Wewnątrz tej nowej klasy nie piszesz standardowej metody inicjalizacyjnej do zbierania zmiennych. Zamiast tego definiujesz dwie ścisłe tablice: inputs i outputs. Spójrzmy na praktyczny scenariusz. Załóżmy, że budujesz customowy komponent Text Analyzer, który liczy słowa i zwraca ustrukturyzowany obiekt Data do grafu. Najpierw konfigurujesz tablicę inputs. Wypełniasz ją używając specjalistycznych klas input dostarczanych przez Langflow. W przypadku Text Analyzer potrzebujesz stringa z tekstem, więc wrzucasz obiekt text input do tablicy i nadajesz mu nazwę. I to jest najważniejsza część. Deklarując konkretną klasę input w swoim kodzie w Pythonie, dyktujesz interfejs wizualny. Langflow czyta tę tablicę i automatycznie generuje pole tekstowe na twoim node'zie w edytorze drag-and-drop. Gdybyś dodał obiekt integer input do tej samej tablicy, UI natychmiast wyrenderowałoby number spinner. Definiujesz wymagania na dane w kodzie, a engine buduje UI za ciebie. Kiedy inputs są już zdefiniowane, konfigurujesz tablicę outputs. To jawnie mówi otaczającemu grafowi, jaki typ danych wyprodukuje twój node. W przypadku Text Analyzer chcemy przekazać nasz wynik dalej w dół chaina, więc dodajesz obiekt Data output do tablicy. Konfiguracja output robi jeszcze jedną kluczową rzecz. Mapuje wizualny output handle na główną metodę wykonawczą wewnątrz twojej klasy. Jawnie mówisz engine'owi, którą funkcję w Pythonie ma odpalić, gdy kolejny node zażąda danych. Ostatnim krokiem jest napisanie tej zmapowanej metody wykonawczej. To tutaj żyje twoja standardowa logika w Pythonie. Metoda automatycznie odbiera wartości, które twoje inputs zebrały z UI. Bierzesz przychodzący string z tekstem, dzielisz go i liczysz słowa. Następnie, ponieważ graf oczekuje ustandaryzowanego formatu, opakowujesz swój końcowy integer w obiekt Data z Langflow i go zwracasz. Ta struktura wymusza czystą separację. Tablica inputs buduje interfejs i zbiera dane, metoda wykonawcza je przetwarza, a tablica outputs przekazuje je z powrotem do wizualnego grafu. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
13

Zaawansowane hooki komponentów i wykonywanie

3m 51s

Ten odcinek omawia cykl życia wewnętrznego silnika wykonawczego i zaawansowane techniki współdzielenia stanu. Słuchacze nauczą się nadpisywać setup hooks i wykorzystywać słowniki kontekstu do złożonego utrzymywania stanu.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 13 z 15. Możesz myśleć o node'zie jak o prostej czarnej skrzynce, do której wchodzą dane, wykonuje się funkcja, dane wychodzą, a node natychmiast o wszystkim zapomina. Ale co się stanie, gdy twój pipeline wymaga od node'a zainicjowania złożonego połączenia z bazą danych albo śledzenia liczby elementów, które właśnie przetworzył, zanim zwróci wynik? To wymaga wyjścia poza proste funkcje i użycia zaawansowanych hooków oraz execution komponentu. Często zakłada się, że komponenty to operacje stricte stateless, które tylko ewaluują inputy. Wcale tak nie jest. Komponent to instancja klasy w Pythonie, która przechodzi przez określony lifecycle zarządzany przez wewnętrzny execution engine. Podczas tego lifecycle'u komponent może utrzymywać wewnętrzny state, orkiestrować złożone setupy i współdzielić dane między swoimi wewnętrznymi metodami. Kiedy Langflow triggeruje komponent, engine inicjuje ścisłą sekwencję. Najpierw, zanim zacznie się generowanie jakiegokolwiek outputu, engine szuka wewnętrznego hooka o nazwie pre run setup. Nadpisujesz tę metodę, gdy twój komponent musi wykonać cięższą pracę, zanim odpali się główna logika. Jeśli twój komponent musi się uwierzytelnić w zewnętrznym API, załadować do pamięci duży model machine learningowy albo ustawić zmienne lokalne, umieszczasz tę logikę w setup hooku. Gdy setup jest gotowy, engine przechodzi do fazy execution, wywołując run hook. To tutaj znajduje się twój główny payload i odbywa się właściwe przetwarzanie danych. Oddzielenie logiki setupu od logiki execution pozwala utrzymać porządek w kodzie i zapobiega nadmiarowym operacjom. Rodzi to jednak od razu techniczne pytanie. Jak przekazać uwierzytelnionego API clienta albo zmienną lokalną z setup hooka w dół, do run hooka? Używasz context dictionary. Każdy custom component ma atrybut o nazwie self dot ctx. Jest to dictionary podpięty bezpośrednio do instancji komponentu. Działa jak dedykowany bank pamięci na czas tego konkretnego runu komponentu. Wszystko, co podepniesz do tego context dictionary podczas fazy setupu, jest natychmiast dostępne, gdy engine przechodzi do fazy run. Przejdźmy przez praktyczny scenariusz, w którym takie współdzielenie state'u jest konieczne. Wyobraź sobie custom component, który przetwarza stream przychodzących dokumentów i musi zwrócić na output zarówno wyczyszczony tekst, jak i końcową liczbę dokumentów, które zostały pomyślnie zmodyfikowane. Najpierw nadpisujesz pre run setup hook. Wewnątrz tej metody uzyskujesz dostęp do context dictionary i tworzysz zmienną licznika, ustawiając jej początkową wartość na zero. Możesz tu również zainicjować swoją bibliotekę do czyszczenia tekstu i podpiąć ją do contextu. Następnie engine triggeruje run hook. Twoja metoda przechodzi w pętli przez przychodzące dokumenty. Dla każdego dokumentu, który pomyślnie przejdzie przez bibliotekę czyszczącą, odwołujesz się do context dictionary, pobierasz obecną wartość licznika i inkrementujesz ją o jeden. Ponieważ context dictionary utrzymuje się pomiędzy tymi różnymi wywołaniami metod lifecycle'u, twój komponent bezpiecznie zachowuje swój wewnętrzny state. Kiedy run hook w końcu zakończy swoją pętlę, może zwrócić przetworzone dokumenty i wyciągnąć ostateczną, dokładną liczbę bezpośrednio z context dictionary, aby przekazać ją do następnego node'a. Opanowanie execution engine i hooków komponentu zmienia twój mindset z pisania prostych skryptów pass-through na budowanie solidnych, samowystarczalnych aplikacji, które w pełni zarządzają swoimi własnymi lifecycle'ami danych. Jeśli chcesz pomóc w utrzymaniu podcastu, możesz wyszukać DevStoriesEU na Patreonie. Jak zawsze, dzięki za słuchanie. Do zobaczenia w kolejnym odcinku.
14

API Langflow i dynamiczne Tweaks

3m 27s

Ten odcinek omawia programowe wykonywanie grafów za pośrednictwem REST API. Słuchacze dowiedzą się, jak używać Input Schema do wstrzykiwania nadpisań parametrów w czasie runtime bez zmieniania bazowego flow.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 14 z 15. Masz pięćdziesięciu klientów i każdy z nich potrzebuje nieco innej wersji twojego agenta wsparcia AI. Pierwsza myśl to skopiować twój graph pięćdziesiąt razy, podmieniając w każdym system prompt albo klucz API. To koszmar w utrzymaniu. Potrzebujesz tylko jednego graphu, a różnice możesz obsługiwać w locie, korzystając z API Langflow i dynamicznych tweaks. Kiedy budujesz graph w interfejsie wizualnym, parametry wewnątrz twoich komponentów są stałe. Łatwo założyć, że aby zmienić drobną zmienną, taką jak ustawienie temperatury czy instrukcja systemowa, musisz sklonować cały flow. To nieprawda. Tweaks rozwiązują to dynamicznie w runtime, pozwalając ci nadpisać parametry komponentu bez edytowania bazowego graphu. Robisz to, komunikując się z Langflow całkowicie headless za pośrednictwem jego REST API. Aby wykonać flow programowo, wysyłasz żądanie HTTP POST do endpointu run, a dokładnie ukośnik v jeden ukośnik run, po którym następuje twój unikalny flow ID. Body tego żądania zawiera twoje standardowe inputy, takie jak wiadomość tekstowa od użytkownika. Obok tych danych wejściowych, możesz dołączyć obiekt tweaks. Ten obiekt to słownik, który mapuje konkretne komponenty w twoim graphie na nowe wartości, które chcesz wstrzyknąć dla tego jednego wykonania. Aby namierzyć komponent, potrzebujesz jego node ID. W Langflow, node ID zazwyczaj składa się z nazwy komponentu i losowego stringa, na przykład Prompt myślnik a b c d e. Kiedy konstruujesz swój payload tweaks, używasz dokładnie tego node ID jako klucza. Wartością jest kolejny słownik, zawierający konkretne pola, które chcesz nadpisać. Weźmy pod uwagę podstawowy flow obsługi klienta, używany na wielu stronach internetowych. Graph zawiera komponent Prompt, który definiuje, jak zachowuje się agent. Dla twojego klienta bankowego, prompt musi być bardzo formalny. Dla klienta gamingowego, musi być nieformalny. Zamiast utrzymywać dwa identyczne graphy, twój backend robi API call do dokładnie tego samego flow ID. W payloadzie żądania podajesz node ID tego komponentu Prompt. Wewnątrz niego wskazujesz pole template i przekazujesz formalne instrukcje dla banku. Później, kiedy strona gamingowa wyzwoli call, twój backend wysyła dokładnie to samo żądanie, ale podmienia string w słowniku tweaks na nieformalne instrukcje. Logika wykonania jest całkowicie sekwencyjna. Najpierw przygotowujesz swój payload z zapytaniem użytkownika i konkretnym słownikiem tweaks. Następnie wysyłasz żądanie POST do endpointu run. Langflow odbiera call, tymczasowo aplikuje twoje nadpisania do wskazanych node'ów i wykonuje graph. Zwraca końcowy output do twojej aplikacji, podczas gdy oryginalny, zapisany flow na serwerze pozostaje nienaruszony. Nie ograniczasz się tylko do tekstowych promptów. Możesz modyfikować niemal wszystko, co jest wystawione w input schema komponentu. Możesz dynamicznie podmieniać nazwę modelu, dostosowywać temperaturę albo wstrzykiwać inne dane uwierzytelniające do bazy danych dla każdego requestu. To zmienia statyczny, wizualny graph w wielorazową, wysoce elastyczną funkcję backendową. Możliwość oddzielenia logiki aplikacji od danych konfiguracyjnych to coś, co sprawia, że headless execution faktycznie skaluje się na produkcji. Dzięki za wysłuchanie. Do usłyszenia następnym razem!
15

Konteneryzacja produkcyjna

4m 09s

Ten odcinek omawia przejście od programowania wizualnego do wdrożeń produkcyjnych typu headless. Słuchacze dowiedzą się, jak konstruować pliki Dockerfile, blokować zależności i bezpiecznie montować niestandardowe komponenty.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Langflow, odcinek 15 z 15. Edytor wizualny jest świetny do budowania twojej aplikacji. Ale jeśli zrobisz deploy tego samego interfejsu drag-and-drop na swoje serwery produkcyjne, pożerasz pamięć i wystawiasz logikę swojej aplikacji na zewnątrz. Kiedy przychodzi czas na ruch produkcyjny, potrzebujesz lekkiego, headlessowego kontenera z backendem. I dokładnie tym zajmiemy się dzisiaj, omawiając produkcyjną konteneryzację. Niezwykle często zdarza się, że zespoły kończą budować flow i po prostu robią deploy całej aplikacji Langflow, razem z interfejsem użytkownika, na serwer w chmurze. Interfejs służy wyłącznie do developmentu. W środowisku produkcyjnym nie chcesz, żeby ktokolwiek przeciągał i upuszczał node'y. Chcesz mieć niezmienne, bezpieczne API, które po prostu przetwarza requesty. Langflow udostępnia specjalny tryb, żeby obsłużyć to przejście. Kiedy uruchamiasz usługę, używasz flagi o nazwie backend-only. To mówi Langflow, żeby całkowicie wyłączył frontend w React. Serwer nadal się uruchamia, ale wystawia tylko endpointy API niezbędne do działania twoich flow. To drastycznie zmniejsza zużycie pamięci. Zwiększa to również bezpieczeństwo poprzez zmniejszenie powierzchni ataku, dając pewność, że nikt nie uzyska wizualnego dostępu ani nie zmieni struktury aplikacji. Żeby spakować to do deploymentu, piszesz Dockerfile. Zaczynasz od standardowego obrazu bazowego Pythona. Ponieważ Langflow opiera się na nowoczesnych narzędziach Pythona, zarządzasz swoimi pakietami, blokując zależności za pomocą UV. Przed zbudowaniem obrazu, eksportujesz swoje dokładne drzewo zależności do lockfile'a. Wewnątrz Dockerfile'a używasz tego lockfile'a do instalacji swoich pakietów. To gwarantuje, że twój kontener produkcyjny uruchomi dokładnie te same wersje pakietów, które testowałeś podczas developmentu. Następnie przenosisz logikę swojej aplikacji do obrazu. W Langflow twoja aplikacja to w gruncie rzeczy tylko dane. Kiedy skończysz budować w edytorze wizualnym, eksportujesz swój flow jako plik JSON. Wewnątrz Dockerfile'a kopiujesz ten plik JSON bezpośrednio do struktury obrazu. To jest ta część, która ma znaczenie dla customowej logiki. Wiele złożonych flow opiera się na customowych komponentach, czyli małych skryptach w Pythonie, które napisałeś do obsługi konkretnych zadań. JSON twojego flow odwołuje się do tych komponentów, ale nie zawiera samego kodu w Pythonie. Musisz jawnie skopiować katalog zawierający pliki twoich customowych komponentów do obrazu Dockera. Następnie ustawiasz zmienną środowiskową, która dokładnie wskazuje kontenerowi, gdzie ma szukać ścieżki do tego komponentu podczas startu serwera. Ostatnim elementem Dockerfile'a jest komenda uruchomieniowa. Ta komenda uruchamia moduł Langflow, przekazuje ścieżkę do wbudowanego JSON-a z twoim flow, wskazuje na twoje customowe komponenty i zawiera flagę backend-only. Kiedy ten kontener startuje, jest całkowicie zamknięty. Edytor wizualny znika, konfiguracja flow jest statyczna, a zależności są zamrożone. Zostajesz z szybkim, headlessowym API, gotowym do odbierania promptów i zwracania odpowiedzi. Najważniejszy wniosek jest taki, że twoje środowisko developmentu i produkcyjny runtime mają fundamentalnie różny kształt. Buduj wizualnie, ale rób deploy headlessowo. Ponieważ to ostatni odcinek, zachęcam cię do zanurkowania w oficjalnej dokumentacji i samodzielnego spróbowania konteneryzacji prostego flow. Jeśli masz pomysły na to, co powinniśmy omówić w naszej kolejnej serii, wpadnij na dev stories dot eu i daj nam znać. Dzięki za spędzenie ze mną tych kilku minut. Do następnego razu, trzymaj się.