W praktyce systemy rzadko są jednorodne. Węzeł prowadzący własny graf jest normą, a nie ciekawostką — i tworzy trzy problemy, których w grafie płaskim nie ma.
Przez dziesięć artykułów tego toru graf był płaski: węzły, krawędzie, jeden poziom. To wygodne przy tłumaczeniu i nieprawdziwe przy budowaniu systemów w praktyce.
Realne systemy zagnieżdżają się na kilka sposobów. Węzeł grafu przepływu prowadzi wewnątrz własny graf wykonania. Węzeł grafu wykonania jest agentem, który ma własną pętlę z własnymi narzędziami. Cały graf wykonania bywa wywoływany jako pojedynczy krok w czymś większym.
Nic w tym złego — to naturalna konsekwencja tego, że różne fragmenty pracy mają różny charakter. Ale trzy rzeczy, które w grafie płaskim były proste, przestają takie być w rzeczywistości.
Trzy typowe zagnieżdżenia
Agent jako węzeł. Najczęstsze i najmniej problematyczne. Węzeł prowadzi wewnętrzną pętlę — dla grafu nadrzędnego jest jednym krokiem, który dostał wejście i zwrócił wyjście. Zagnieżdżenie jest tu na granicy definicji, bo pętla nie jest grafem.
Podgraf jako węzeł. Węzeł uruchamia własny graf wykonania z własnymi węzłami i krawędziami. Dla poziomu nadrzędnego to jedno wywołanie. W środku dzieje się cały przebieg z własnym stanem, własnymi awariami i własnymi rozstrzygnięciami krawędzi.
Graf wykonania wewnątrz grafu przepływu. Deterministyczny schemat, w którym jeden krok jest oddany autonomii. To jest wzorzec, który opisywaliśmy jako dwie warstwy — integracyjna i decyzyjna — i najczęstszy sensowny układ produkcyjny.
Problem pierwszy: gdzie mieszka stan
W grafie płaskim odpowiedź była jednoznaczna: stan jest wspólny, węzeł dostaje wycinek. Przy zagnieżdżeniu pojawia się drugi stan — wewnętrzny, należący do podgrafu.
Trzy pytania, na które trzeba odpowiedzieć świadomie, bo domyślne odpowiedzi bywają złe.
Czy podgraf widzi stan nadrzędny? Jeśli tak, granica przestaje istnieć i wracasz do jednego wielkiego stanu z wszystkimi problemami współbieżności. Jeśli nie, musisz jawnie przekazać to, czego potrzebuje.
Co zostaje po zakończeniu podgrafu? Przebieg wewnętrzny czy tylko wynik? Zapisanie wszystkiego jest kosztowne i zaśmieca stan nadrzędny. Zapisanie tylko wyniku oznacza, że przy debugowaniu nie odtworzysz, co działo się w środku.
Kto jest właścicielem pól, które podgraf zapisuje na zewnątrz? Jeśli podgraf pisze bezpośrednio do stanu nadrzędnego, masz kilku zapisujących w miejscu, gdzie sądziłeś, że jest jeden.
Zasada, która to porządkuje: podgraf zwraca wynik, nie pisze do stanu nadrzędnego. Granica poziomu ma być granicą zapisu. Wtedy zagnieżdżenie jest hermetyzacją, a nie rozproszeniem odpowiedzialności.
Problem drugi: uprawnienia się dziedziczą
To jest miejsce, w którym zagnieżdżenie robi się niebezpieczne, bo domyślne zachowanie jest odwrotne do pożądanego.
Podgraf uruchomiony wewnątrz węzła dziedziczy zwykle środowisko tego węzła — jego dostęp do sieci, jego tokeny, jego katalog roboczy. A węzeł nadrzędny mógł mieć uprawnienia szersze, niż potrzebuje którykolwiek z węzłów wewnętrznych, bo był projektowany jako całość.
Efekt: uprawnienia podgrafu są sumą uprawnień poziomu nadrzędnego, a to, co wewnątrz wygląda na trzy role z rozłącznym dostępem, na zewnątrz jest jednym procesem, który może wszystko.
Zasada z artykułu o granicach obowiązuje na każdym poziomie osobno: granica postawiona na poziomie nadrzędnym nie wynika automatycznie z tego, że wewnątrz są jakieś podziały. Jeśli chcesz, żeby węzeł wewnętrzny nie miał dostępu do sieci, musi go nie mieć na tym poziomie, na którym się wykonuje.
Problem trzeci: awaria przekracza granicę
Węzeł podgrafu zawiódł. Co widzi poziom nadrzędny?
Najczęstsza domyślna odpowiedź: podgraf zwraca błąd, a poziom nadrzędny traktuje to jako awarię swojego węzła. To bywa właściwe i bywa katastrofalne — bo poziom nadrzędny nie wie, czy zawiódł cały podgraf, czy jeden z jego dziesięciu węzłów, i czy praca w środku została częściowo wykonana.
Trzy warianty, które warto rozstrzygnąć przy projektowaniu:
Podgraf obsługuje własne awarie i zwraca wynik albo jawną informację o braku. Preferowane, bo zachowuje hermetyzację. Wymaga, żeby podgraf miał własną politykę ponowień i objazdów.
Podgraf przepuszcza awarię wyżej. Prostsze, ale poziom nadrzędny musi wiedzieć, co z tym zrobić — a nie ma wglądu w to, co się stało w środku.
Podgraf zwraca wynik częściowy. Najtrudniejszy i czasem jedyny sensowny: trzy z pięciu węzłów zrobiły swoje, dwa nie. Wtedy poziom nadrzędny musi umieć zdecydować, czy taki wynik wystarcza.
Uwaga praktyczna, która wraca z artykułu o awariach: przy zagnieżdżeniu ponowienie węzła oznacza ponowienie całego podgrafu. Jeśli w środku były operacje zapisujące, powtórzą się wszystkie — także te, które za pierwszym razem się udały. To jest najczęstszy sposób, w jaki niewinne ustawienie „powtórz przy błędzie” produkuje duplikaty.
Log musi znać poziom
Jedna rzecz techniczna, bez której debugowanie zagnieżdżonego grafu jest zgadywaniem.
Identyfikator zadania spinający cały przebieg musi być wspólny dla wszystkich poziomów — inaczej masz dwa niepowiązane zbiory logów. Ale sam identyfikator nie wystarcza: potrzebna jest też ścieżka poziomu, czyli informacja, że ten wpis pochodzi z podgrafu uruchomionego przez węzeł C w grafie głównym.
Bez tego, patrząc na log, nie odróżnisz węzła głównego od węzła wewnętrznego o podobnej nazwie — a przy dwóch instancjach tego samego podgrafu uruchomionych równolegle nie odróżnisz nawet, który wpis do której instancji należy.
Kiedy zagnieżdżać, a kiedy spłaszczyć
Zagnieżdżenie ma sens, gdy fragment pracy jest samodzielny i powtarzalny — da się go opisać jako jedno zadanie z jednym wejściem i jednym wyjściem, a używasz go w więcej niż jednym miejscu.
Warto spłaszczyć, gdy:
Podgraf ma dwa węzły. Zagnieżdżenie kosztuje warstwę abstrakcji, granicę stanu i osobne logowanie. Przy dwóch węzłach to jest cena za nic.
Poziom nadrzędny i tak musi wiedzieć, co dzieje się w środku. Jeśli przy każdej awarii i tak zaglądasz do podgrafu, hermetyzacja jest pozorna i tylko utrudnia.
Podgraf potrzebuje ciągłego dostępu do stanu nadrzędnego. To jest sygnał, że granica została poprowadzona w złym miejscu.
Jak to sprawdzić u siebie
Weź system, który już masz, i narysuj go na dwóch poziomach — osobno górny, osobno każdy podgraf. Potem przy każdej granicy między poziomami odpowiedz na cztery pytania:
Co przechodzi w dół? Jeśli odpowiedź brzmi „cały stan”, nie masz granicy.
Co wraca w górę? Jeśli odpowiedź brzmi „wynik i przebieg”, sprawdź, czy przebieg jest komukolwiek potrzebny poza logiem.
Jakie uprawnienia dziedziczy podgraf? Jeśli nie umiesz odpowiedzieć, dziedziczy wszystkie.
Co się dzieje, gdy w podgrafie coś zawiedzie w połowie? To jest pytanie, na które w większości systemów nikt nie odpowiedział świadomie — a odpowiedź domyślna to zwykle ponowienie całości.
Na koniec
Rozdział pierwszy tego toru rozdzielał trzy znaczenia słowa „graf” i uprzedzał, że podział jest narzędziem, nie taksonomią. Ten artykuł jest tego konsekwencją: w realnym systemie warstwy się mieszają, a pytanie „to jest graf przepływu czy wykonania” ma sens dopiero razem z pytaniem „na którym poziomie”.
Ta sama struktura bywa jednym i drugim naraz — deterministyczna z zewnątrz, autonomiczna w środku. To nie jest wyjątek od reguły. To jest najczęstszy układ produkcyjny, i jedyny powód, dla którego warto było rozdzielić te pojęcia na początku: żeby dało się powiedzieć, co dokładnie jest czym i gdzie.
Stan na sierpień 2026. Zakres wsparcia dla podgrafów różni się znacznie między narzędziami orkiestrującymi — część traktuje je jako pełnoprawny typ węzła z własnym stanem, część wymaga zbudowania granicy samodzielnie.





















