<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Univio - Tech blog</title>
    <link>https://tech.univio.com/pl</link>
    <description>Praktyczna wiedza o e-commerce B2B, PIM, CMS, integracjach, chmurze i AI. Poradniki i analizy ekspertów, które pomagają rozwijać biznes.</description>
    <language>pl</language>
    <pubDate>Fri, 09 Oct 2026 16:49:55 GMT</pubDate>
    <dc:date>2026-10-09T16:49:55Z</dc:date>
    <dc:language>pl</dc:language>
    <item>
      <title>Sztuka wyboru odpowiedniego modelu. Dlaczego stworzyliśmy Commerce &amp; Enterprise Benchmark (CEB)</title>
      <link>https://tech.univio.com/pl/sztuka-wyboru-odpowiedniego-modelu.-dlaczego-stworzyli%C5%9Bmy-commerce-enterprise-benchmark-ceb</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/pl/sztuka-wyboru-odpowiedniego-modelu.-dlaczego-stworzyli%C5%9Bmy-commerce-enterprise-benchmark-ceb?hsLang=pl" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/wadki_AI_v1-1.png" alt="Sztuka wyboru odpowiedniego modelu. Dlaczego stworzyliśmy Commerce &amp;amp; Enterprise Benchmark (CEB)" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;Wybór modelu AI do systemów produkcyjnych rzadko sprowadza się do prostego porównania wykresów w publicznych rankingach. Marketingowe obietnice dostawców i akademickie testy rzadko dają odpowiedź na kluczowe pytania: jak dany LLM poradzi sobie z naszymi zadaniami, ile będzie kosztować realizacja zadań i jakiej wartości będą dane wyjściowe. Ewaluacja staje się wartościowa dopiero wtedy, gdy odzwierciedla nasze środowisko, w którym dany system ma pracować, gdy operuje problemami i zestawami danych zbieżnych z naszymi potrzebami.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Commerce &amp;amp; Enterprise Benchmark (w skrócie CEB)&lt;/strong&gt; adresuje te wyzwania w jednym pakiecie ewaluacyjnym. Zapewnia powtarzalny sposób badania możliwości i ograniczeń systemów sztucznej inteligencji przy użyciu zadań istotnych dla rozwiązań Commerce&amp;amp;Enterprise.&lt;/p&gt; 
&lt;h2&gt;Dlaczego stworzyliśmy własny benchmark AI?&lt;/h2&gt; 
&lt;p&gt;CEB to narzędzie, które stworzyliśmy na własne potrzeby, aby powtarzalnie badać rzeczywiste możliwości modeli, agentów oraz harnessów w codziennej pracy inżynieryjnej w Univio. Dziś otwieramy je i dzielimy się wnioskami na zewnątrz.&lt;/p&gt; 
&lt;p&gt;Duża część istniejących benchmarków opiera się na danych syntetycznych oraz na zbiorach publicznych. Nie jest zaskoczeniem, że modele są trenowane na tych samych danych. W wielu przypadkach modele zajmują wysokie miejsce w zestawieniach tylko dlatego, że nauczyły się pytań na pamięć podczas treningu (tj. data contamination, czyli przeciek zadań do zbiorów treningowych) co sprawiło, że publiczne benchmarki mierzą pamięć modeli, a nie ich zdolność wnioskowania.&lt;/p&gt; 
&lt;p&gt;Świetny wynik w &lt;a href="https://www.swebench.com/"&gt;&lt;u&gt;SWEBench&lt;/u&gt;&lt;/a&gt;, &lt;a href="https://www.kaggle.com/benchmarks/open-benchmarks/mmlu"&gt;&lt;u&gt;MMLU&lt;/u&gt;&lt;/a&gt; czy &lt;a href="https://deepeval.com/docs/benchmarks-gsm8k"&gt;&lt;u&gt;GSM8K&lt;/u&gt;&lt;/a&gt; nie przekłada się na to, czy model poprawnie odmieni polskie nazwisko, będzie pracował efektywnie z Jirą i Hubspot albo nie zaburzy spójności dokumentu po 10 edycjach.&lt;/p&gt; 
&lt;p&gt;Publiczne leaderboardy i CEB operują w różnych domenach. Te pierwsze bardzo często mierzą uniwersalne kompetencje akademickie. My testujemy odporność modeli na specyficzne wyzwania architektury Enterprise.&lt;/p&gt; 
&lt;h2&gt;Czym jest CEB?&lt;/h2&gt; 
&lt;p&gt;To zamknięty zbiór zadań, wyselekcjonowanych z rzeczywistych problemów na które napotkali pracownicy Univio oraz nasi partnerzy.&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt;Architektura testu bazuje na Inspect AI od UK AI Safety Institute.&lt;/li&gt; 
 &lt;li&gt;Zadania programistyczne uruchamiane są w izolowanych sandboxach.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3&gt;Co dokładnie badamy?&lt;/h3&gt; 
&lt;p&gt;Stosujemy szereg wymiarów ewaluacji:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt;Zadanie językowe: deklinacja, ortografia, interpunkcja, znajomość słownictwa, weryfikowane niezależnie dla j. polskiego, angielskiego i niemieckiego.&lt;/li&gt; 
 &lt;li&gt;Długi kontekst i spójność edycji, działania multimodalne, działania z zadaniami które przekraczają dopuszczalny rozmiar kontekstu.&lt;/li&gt; 
 &lt;li&gt;Praca z danymi, narzędziami biznesowymi i integracjami technicznymi, np. Jira, Confluence, HubSpot, Excel.&lt;/li&gt; 
 &lt;li&gt;Praca z danymi ustrukturyzowanymi i kontraktami.&lt;/li&gt; 
 &lt;li&gt;Walidacja faktów – testy wiedzy identyfikujące knowledge cut-off oraz specjalistyczną wiedzę domenową.&lt;/li&gt; 
 &lt;li&gt;Programowanie i automatyzacja: na ten moment analizowana w językach JS, Python, PHP.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Dzięki prywatnemu charakterowi benchmarku dane testowe nie trafiają do publicznych korpusów treningowych. Nie stosujemy danych syntetycznych, opieramy się na prawdziwych problemach, zanonimizowanych i zamkniętych w przypadkach testowych.&lt;br&gt;&lt;br&gt;Oprócz punktowania wyniku, wyliczamy też ilość zużytych tokenów oraz ich koszt. Rejestrujemy czas działania testu, ale nie bierzemy go pod uwagę w rankingach – nie uważamy tego za miarodajny wymiar w sytuacji, gdy inferencja jest realizowana przez sieć. Dążymy do obiektywnego pomiaru rzeczywistych kompetencji modeli w zastosowaniach komercyjnych.&lt;/p&gt; 
&lt;h3&gt;Czego CEB nie robi?&lt;/h3&gt; 
&lt;p&gt;Nie traktujemy naszego benchmarku jako uniwersalnego rankingu do każdego zastosowania. Mamy też świadomość jego obecnych ograniczeń, przykładowo baza zadań dla języka niemieckiego jest na razie zbyt skromna do wyciągania wiążących wniosków, ale stale ją rozbudowujemy.&lt;br&gt;&lt;br&gt;Nie szukamy też modelu idealnego do wszystkiego. Szukamy rozwiązań optymalnych dla konkretnych zastosowań i budżetów.&lt;br&gt;&lt;br&gt;Na bieżąco sprawdzamy wydajność modeli AI w różnych scenariuszach i branżach. Jeśli ciekawi Cię, jak radzą sobie te, z których korzystasz w swojej firmie, to chętnie zderzymy nasze obserwacje z Twoją branżą i potrzebami.&lt;br&gt;&lt;br&gt;Zainteresował Cię ten temat? Zapraszamy do kontaktu z naszymi Architektami!&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fpl%2Fsztuka-wyboru-odpowiedniego-modelu.-dlaczego-stworzyli%C5%9Bmy-commerce-enterprise-benchmark-ceb&amp;amp;bu=https%253A%252F%252Ftech.univio.com%252Fpl&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Devops</category>
      <category>LLM</category>
      <category>SI &amp; ML</category>
      <pubDate>Fri, 09 Oct 2026 13:36:51 GMT</pubDate>
      <author>lukasz.biegaj@univio.com (Łukasz Biegaj)</author>
      <guid>https://tech.univio.com/pl/sztuka-wyboru-odpowiedniego-modelu.-dlaczego-stworzyli%C5%9Bmy-commerce-enterprise-benchmark-ceb</guid>
      <dc:date>2026-10-09T13:36:51Z</dc:date>
    </item>
    <item>
      <title>KV Cache - jak wykorzystać kluczowy mechanizm LLM w pracy programisty</title>
      <link>https://tech.univio.com/pl/kv-cache-jak-wykorzysta%C4%87-kluczowy-mechanizm-llm-w-pracy-programist</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/pl/kv-cache-jak-wykorzysta%C4%87-kluczowy-mechanizm-llm-w-pracy-programist?hsLang=pl" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/KV%20Cache%20cover-1.png" alt="KV Cache - jak wykorzystać kluczowy mechanizm LLM w pracy programisty" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Cache to pojęcie znane każdemu programiście – przechowujemy wynik operacji, żeby nie trzeba było liczyć go od nowa przy kolejnym zapytaniu. Podobny mechanizm, z równie dobrym skutkiem, działa w modelach językowych. Odpowiednikiem pamięci podręcznej w świecie LLM-ów jest KV Cache (Key Value Cache). Jest to mechanizm działający w tle, ale jego zrozumienie pozwala efektywniej i taniej korzystać z modeli.&lt;/span&gt;&lt;/p&gt;</description>
      <content:encoded>&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Cache to pojęcie znane każdemu programiście – przechowujemy wynik operacji, żeby nie trzeba było liczyć go od nowa przy kolejnym zapytaniu. Podobny mechanizm, z równie dobrym skutkiem, działa w modelach językowych. Odpowiednikiem pamięci podręcznej w świecie LLM-ów jest KV Cache (Key Value Cache). Jest to mechanizm działający w tle, ale jego zrozumienie pozwala efektywniej i taniej korzystać z modeli.&lt;/span&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;strong&gt;&lt;span style="line-height: 21.85px;"&gt;Jak LLM zapamiętuje kontekst?&lt;/span&gt;&lt;/strong&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt;&lt;span style="white-space-collapse: preserve;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt;&lt;br style="white-space-collapse: preserve;"&gt;&lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt;&lt;/span&gt;&lt;span style="background-color: #c6c6c6; line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Na początek trochę teorii. Gdy nasze zapytanie trafia do LLM-a opartego na architekturze transformera, przechodzi przez dwie główne fazy (opis dotyczy modeli działających na GPU):&lt;/span&gt;&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="color: #d51313;"&gt;Faza I: Prefill&lt;/span&gt;&lt;br&gt;Polega na przetworzeniu całego zapytania wejściowego z wykorzystaniem mocy GPU. W tej fazie dla każdego tokena zapisywane są w pamięci stany klucz-wartość (KV). Mówiąc w uproszczeniu: K (Key) odpowiada na pytanie, co reprezentuje dany token, a V (Value) – jaką niesie treść. Pamięć wykorzystywana do tego procesu to VRAM karty graficznej. Przetwarzanie w tej fazie odbywa się równolegle.&lt;br&gt;&lt;br&gt;&lt;span style="color: #d51313;"&gt;Faza II: Decoding&lt;/span&gt;&lt;br&gt;To etap, w którym model generuje odpowiedź, tworząc nowe tokeny jeden po drugim. Podczas generacji model sięga do zaalokowanej wcześniej pamięci VRAM, aby odczytać pary KV. Widać tu wyraźną różnicę w charakterystyce pracy: pierwsza faza (prefill) jest mocno GPU-bound, natomiast druga (decoding) – memory-bound.&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Aby to zobrazować, spójrzmy na poniższy schemat zapisu i odczytu:&lt;/span&gt;&lt;span style="background-color: #c6c6c6; line-height: 21.85px;"&gt; &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Powyższy rysunek przedstawia uproszczony schemat konwersacji z modelem. W pierwszej turze model musi przetworzyć w fazie prefill wszystkie tokeny, zapisując je następnie do KV Cache. W drugiej turze zaczyna pracę od tokena numer 5, a wcześniejszą konwersację (razem ze swoimi własnymi odpowiedziami) pobiera bezpośrednio z pamięci.&lt;/span&gt;&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/p&gt; 
&lt;h2 style="line-height: 2;"&gt;&lt;span&gt;Czy cache jest dostępny w każdym modelu?&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;KV Cache to stały element każdego systemu LLM bazującego na Transformers. Sterowanie nim jest możliwe, jednak zależy od sposobu korzystania z modelu.&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li style="line-height: 2;"&gt;Przez API: gdy sami konstruujemy system prompt, tool calls i user prompt,&lt;/li&gt; 
 &lt;li style="line-height: 2;"&gt;Przez gotowe frameworki agentowe: takie jak np. Claude Code.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 2;"&gt;Każdy z dostawców modeli językowych w inny sposób umożliwia kontrolę. Przykładem jest Anthropic – odpytując ich modele bezpośrednio przez API, możemy przekazać parametr cache_control i jawnie wskazać, które bloki kontekstu mają zostać zapamiętane. Daje to znacznie bardziej granularną kontrolę niż korzystanie z gotowych narzutów agentowych.&lt;/p&gt; 
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2&gt;&lt;span style="font-family: din-2014, 'Helvetica Neue', Helvetica, Arial, sans-serif;"&gt;Jak praktycznie można wykorzystać wiedzę o KV cache?&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;&lt;br&gt;Przeanalizujmy to na przykładzie narzędzia Claude Code i tworzenia własnego harnessu. Okno kontekstu (context window) przekazywane przy każdym zapytaniu składa się z trzech głównych części:&lt;/p&gt; 
&lt;ol style="line-height: 2;"&gt; 
 &lt;li&gt; &lt;p&gt;&lt;span style="font-weight: bold;"&gt;System prompt&lt;/span&gt; – główne instrukcje oraz definicje narzędzi (tools),&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;span style="font-weight: bold;"&gt;Kontekst projektu&lt;/span&gt; – plik CLAUDE.md i reguły projektowe,&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;span style="font-weight: bold;"&gt;Historia konwersacji –&lt;/span&gt; najbardziej dynamiczna część.&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p style="line-height: 2;"&gt;Każda z tych części ma inny cykl życia. W idealnej sytuacji wszystko musiałoby być statyczne, wtedy przy kolejnym odczycie dostalibyśmy 100% cache hit. W praktyce jest to niemożliwe – historia konwersacji zawsze rośnie dopisywanie.&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;Dlatego kluczowe jest to, aby &lt;span style="color: #d51313;"&gt;warstwa systemowa i projektowa zmieniały się jak najrzadziej (były statyczne)&lt;/span&gt;. Należy unikać umieszczania w nich danych dynamicznych, takich jak znacznik czasu (timestamp) czy dynamicznie generowanej struktury katalogów. Każda zmiana w tej części promptu automatycznie unieważnia (invalidate) cały zarejestrowany cache.&amp;nbsp;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="list-style-type: square; line-height: 1.25;"&gt; 
   &lt;li&gt; &lt;p&gt;Nie tylko nasze zapytania mogą wywołać wyzerowanie cache, ale też konkretne akcje w środowisku:&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Zmiana modelu lub poziomu myślenia (Effort level),&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Dodanie lub usunięcie serwerów MCP (zmiana definicji narzędzi w części systemowej),&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Włączanie/wyłączanie wtyczek (plugins),&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Wywołanie komend /clear lub /compact (przeładowują instrukcje projektowe),&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Przesyłanie dużych załączników (obrazy, PDF-y), które przekraczają limity dostawcy.&amp;nbsp;&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 2;"&gt;Warto też zwrócić uwagę na to, jak cache działa między sesjami na jednej maszynie. Sesje działające w ramach tej samej ścieżki (directory) współdzielą ten sam cache. Jeżeli korzystamy z subagentów, każdy z nich posiada własny, odizolowany cache – nie wpływa on na rodzica (agenta nadrzędnego) ani z niego nie dziedziczy. Dopiero instrukcja /fork pozwala jawnie skopiować cache rodzica do nowego subagenta.&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;Cache ma również swój liftime. Dłuższa przerwa w odpytywaniu skutkuje jego zwolnieniem z pamięci dostawcy. Czas ten określa parametr&lt;span style="color: #d51313;"&gt; TTL (Time To Live)&lt;/span&gt; – w zależności od dostawcy i poziomu subskrypcji wynosi on zazwyczaj od 5 minut do 1 godziny.&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="line-height: 2;"&gt;Jak KV Cache wpływa na koszty za tokeny&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;Architektura pamięci przekłada się bezpośrednio na rachunki za API. Stawka za pierwsze wywołanie (pełny prefill bez cache hit) jest wyższa niż za kolejne zapytania trafiające w cache.&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 2;"&gt;&lt;span style="line-height: 21.85px;"&gt;Na powyższym cenniku widać, że opłata za zapis do cache (&lt;/span&gt;&lt;em&gt;Prompt Caching / Write&lt;/em&gt;) jest wyższa niż stawka bazowa (&lt;em&gt;Base Tokens&lt;/em&gt;). Realne oszczędności, gdy zapytanie trafi w cache, wtedy płacimy 0.25$. 5m wirtes, 1h writes to są właśnie ustawienia TTL.&lt;span style="white-space-collapse: preserve;"&gt; &lt;/span&gt;&lt;/p&gt; 
&lt;h2 style="line-height: 2;"&gt;&lt;span style="white-space-collapse: preserve;"&gt;&lt;/span&gt;&lt;span style="white-space-collapse: preserve;"&gt;&lt;/span&gt;Testy potwierdzające działanie KV cache&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;Aby zweryfikować teorię w praktyce, przeprowadziłem test pokazujący różnicę w czasie odpowiedzi przy powtórzonym zapytaniu. Użyłem dwóch modeli:&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/p&gt; 
&lt;ol style="list-style-type: decimal; line-height: 2;"&gt; 
 &lt;li&gt;&lt;strong&gt;Bielik-4.5B&lt;/strong&gt; – uruchomiony lokalnie przez Ollama na CPU.&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;GPT-5-mini&lt;/strong&gt; – wywoływany przez firmowy AI Gateway.&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p style="line-height: 2;"&gt;W obu testach użyjemy metryki TTFT, czyli czas do uzyskania pierwszego tokena. Dane testowe to stały prefix z pytaniem. Długość musi być większa niż 1024 tokenów. Jest to warunek konieczny, ponieważ poniżej tej wartości straty wynikające z narzutu są większe niż zyski. &lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/p&gt; 
&lt;table style="border-collapse: collapse; width: 100%; height: 477px;"&gt; 
 &lt;tbody&gt; 
  &lt;tr style="height: 80px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 80px; background-color: #54286a; border-color: #fff;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="color: #ffffff;"&gt;&lt;span style="line-height: 21.85px;"&gt;Parametr &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 80px; background-color: #54286a; border-color: #fff;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="color: #ffffff;"&gt;&lt;span style="line-height: 21.85px;"&gt;Test 1 — Bielik (lokalnie, Ollama/CPU) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 80px; background-color: #54286a; border-color: #fff;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="color: #ffffff;"&gt;&lt;span style="line-height: 21.85px;"&gt;Test 2 — GPT (gpt-5-mini) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr style="height: 79px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;Turn 1 cold (TTFT) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;45 501 ms &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;5 257 ms &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr style="height: 79px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;Turn 2 hot (TTFT) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;2 833 ms &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;3 112 ms &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr style="height: 79px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;Różnica czasu &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;−42 668 ms (szybciej o ~93,8%) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;−2 145 ms (szybciej o ~40,8%) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr style="height: 79px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;Hit 1 (cached_tokens) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;brak danych &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;0 &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr style="height: 79px;"&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;Hit 2 (cached_tokens) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;brak danych &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
   &lt;td style="vertical-align: top; width: 23.3721%; border: 1px solid; height: 79px;"&gt; &lt;p style="margin-top: 0px; margin-right: 0px;"&gt;&lt;span style="line-height: 21.85px;"&gt;17 920 (99,4% prefiksu) &lt;/span&gt;&lt;span style="line-height: 21.85px;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p style="line-height: 2;"&gt;&lt;br&gt;W przypadku GPT-5-mini dostajemy bezpośrednie potwierdzenie w metryce cached_tokens (17 920 tokenów odczytanych z pamięci). Ollama nie zwraca tej metryki wprost, ale skrócony czas mówi sam za siebie. Długi czas początkowy dla Bielka wynika z ograniczeń inferencji na CPU. Tak wysoki spadek procentowy (93,8%) jest efektem bardzo wolnej fazy Prefill i nie świadczy o tym, że cache zadziałał lepiej w tym przypadku.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2&gt;Mechanizm jest ukryty, ale masz wpływ na to jak działa – wnioski&lt;/h2&gt; 
&lt;p style="line-height: 2;"&gt;Mimo iż nie mamy pełnej kontroli nad mechanizmem cachowania w LLM, nadal możemy tak konstruować zapytania, aby model odpowiadał szybciej, z korzyścią dla kondycji naszego portfela:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li style="line-height: 2;"&gt; &lt;p&gt;Im mniej dynamicznych elementów w stałych częściach kontekstu (system, projekt), tym wyższy wskaźnik cache hit.&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="line-height: 2;"&gt; &lt;p&gt;Pliki konfiguracyjne projektu (np. CLAUDE.md) wpływają na cache tak samo jak treść samego promptu.&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="line-height: 2;"&gt; &lt;p&gt;Bezpośrednie wywołania przez API dają pełniejszą kontrolę nad punktami zapisu cache niż gotowe frameworki agentowe.&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="line-height: 2;"&gt; &lt;p&gt;Projektując przepływy pracy (workflows), warto brać pod uwagę parametr TTL, aby nie tracić stanu pamięci podczas zbyt długich przerw między zapytaniami.&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="line-height: 2;"&gt; &lt;p&gt;&lt;span style="line-height: 21.85px;"&gt;Oba testy wyraźnie pokazują spadek wskaźnika TTFT przy powtórzonym prefiksie.&lt;/span&gt;&lt;span style="background-color: #c6c6c6;"&gt; &lt;/span&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fpl%2Fkv-cache-jak-wykorzysta%C4%87-kluczowy-mechanizm-llm-w-pracy-programist&amp;amp;bu=https%253A%252F%252Ftech.univio.com%252Fpl&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Backend &amp; Data</category>
      <category>SI &amp; ML</category>
      <pubDate>Fri, 09 Oct 2026 13:16:42 GMT</pubDate>
      <guid>https://tech.univio.com/pl/kv-cache-jak-wykorzysta%C4%87-kluczowy-mechanizm-llm-w-pracy-programist</guid>
      <dc:date>2026-10-09T13:16:42Z</dc:date>
      <dc:creator>Michał Pawlik</dc:creator>
    </item>
    <item>
      <title>Aplikacje SaaS i wykonywanie zadań w tle z AWS Batch i AWS Step Functions</title>
      <link>https://tech.univio.com/pl/aplikacje-saas-i-wykonywanie-zadan-w-tle-z-aws-batch-i-aws-step-functions</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/pl/aplikacje-saas-i-wykonywanie-zadan-w-tle-z-aws-batch-i-aws-step-functions?hsLang=pl" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/unity_220606_unity_team_of_teams_v1-kopia-2%20(1)-1.png" alt="Aplikacje SaaS i wykonywanie zadań w tle z AWS Batch i AWS Step Functions" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Każda, nawet najprostsza aplikacja webowa wykonuje wiele zadań w tle, takich jak zmiana rozmiaru obrazów, importowanie informacji o produktach czy tworzenie sitemapy. Do tego, jeśli firma ma produkt objęty dystrybucją w modelu Saas, większość z tych zadań musi być wykonywana dla każdego klienta.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Każda, nawet najprostsza aplikacja webowa wykonuje wiele zadań w tle, takich jak zmiana rozmiaru obrazów, importowanie informacji o produktach czy tworzenie sitemapy. Do tego, jeśli firma ma produkt objęty dystrybucją w modelu Saas, większość z tych zadań musi być wykonywana dla każdego klienta.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;A to – zależnie od popularności produktu – może wymagać potężnej mocy obliczeniowej. Poza tym trzeba znaleźć sposób na szybkie dodawanie i aktualizowanie zadań bez popadania w technologiczny dług.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;I przydałoby się nie wysadzić przy tym aplikacji, gdy każemy jej wykonać jakieś bardziej wymagające zadanie.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Na początku jest pokusa, by pozwolić aplikacji webowej, żeby sama sobie planowała i wykonywała zadania.&lt;/span&gt; W środowisku Java można dodać adnotację @Scheduled, a gdzie indziej wykorzystać node-cron i po sprawie – mamy mechanizm do obsługi zadań.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Wszystko pięknie… ale pojawia się parę fundamentalnych problemów.&lt;/span&gt; Zaraz po uruchomieniu drugiej instancji aplikacji trzeba zsynchronizować stan między aplikacjami, żeby to samo zadanie nie zostało zaplanowane dwukrotnie. Co gorsza, wszelkie zmiany w wykorzystaniu zasobów np. z powodu bardziej intensywnego zadania czy nagłego wzrostu liczby żądań mogą istotnie spowolnić działanie aplikacji. &lt;span style="color: #d51313;"&gt;Nietrudno przewidzieć, że gdy jedno zadanie znacznie obciążające CPU zużyje wszystkie dostępne zasoby, nasza usługa może stać się niedostępna dla użytkowników.&lt;/span&gt; Jest to sytuacja jak z koszmaru, szczególnie w świecie SaaS, gdzie trzeba liczyć się z &lt;span style="color: #d51313;"&gt;„problemem hałaśliwego sąsiada”&lt;/span&gt;.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Oczywiście można zastosować odpowiedni mechanizm synchronizacji zadań (zakodować procedury obsługi awarii, liczbę powtórzeń czy kolejkowanie) i np. zaplanować tylko przetwarzanie nocne. To często najszybsza metoda, ale jest mało skalowalna i zostawia nas z ogromnym długiem technologicznym.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Czy da się lepiej?&lt;/strong&gt; Może jeszcze &lt;span style="color: #d51313;"&gt;podzielić aplikację na część app-web i app-worker, wyłączając tę drugą z obsługi żądań sieciowych&lt;/span&gt;. Są różne frameworki, w tym Django, które sobie z tym poradzą, chociaż wymaga to zastosowania kolejek takich jak Celery czy RabbitMQ. W ten sposób awarie i błędy pamięci przestaną już zagrażać użytkownikom, a nagłe skoki w ruchu sieciowym nie wykoleją zadania w tle. Takie rozwiązanie jest dużo lepsze, ale wymaga odpowiedniego zarządzania i skalowania klastra roboczego w zależności od zapotrzebowania. Trzeba też pamiętać, że app-web i app-worker współdzielą sporą ilości kodu, co może dezorientować developerów i jeszcze bardziej zwiększać dług technologiczny.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Czy da się (jeszcze) lepiej?&lt;/strong&gt; &lt;span style="color: #d51313;"&gt;A gdyby tak aplikacja webowa zajmowała się tylko częścią webową? A aplikacje worker zajmowały się jedynie tym, do czego służą?&lt;/span&gt; Wrzućmy więc wszystkie zadania do lekkich, osobnych i uruchamianych na żądanie kontenerów, a metadane bierzmy z zewnątrz. To powszechna praktyka w świecie data engineering/science, w którym codziennie planowany i wykonywany jest olbrzymi graf DAG (Directed Acyclic Graph) z różnymi powiązanymi zadaniami. Gdy ma się odpowiednie narzędzia, takie usprawnienie działania aplikacji webowych nie wymaga umiejętności na poziomie data engineer – wystarczy tylko w pełni wykorzystać potencjał chmury.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Do tego potrzebne są dwie rzeczy:&lt;/p&gt; 
&lt;ul style="color: #181716; background-color: #ffffff; list-style-type: square; line-height: 1.5;"&gt; 
 &lt;li&gt; &lt;p&gt;Po pierwsze, łatwe w obsłudze środowisko do zarządzania klastrami kontenerowymi, które automatycznie zapewni odpowiednie zasoby i uruchomi zadania z kontenera.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Po drugie, coś do synchronizacji całego procesu. Tutaj z pomocą przychodzi AWS wraz z dwiema technologiami wspomnianym w tytule artykułu (kto by się spodziewał?).&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;AWS Batch&lt;/strong&gt;, jak nazwa wskazuje, służy do przetwarzania wsadowego. Usługa ta pozwala na uruchomienie setek kontenerów, dostarczając tyle zasobów, ile tylko potrzeba. Dzięki wbudowanej kolejce wystarczy określić zadanie i moment jego uruchomienia, a AWS Batch zajmie się resztą.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Z kolei &lt;strong&gt;AWS Step Functions&lt;/strong&gt; to usługa do synchronizacji bazująca na maszynie stanowej. W tym przypadku mamy tylko określić elementy do wykonania i ich kolejność. Tymi elementami mogą być funkcja Lambda, kontener Fargate, AWS Glue job czy AWS Batch. Usługa uruchamia te elementy, które są konieczne, przekazuje dane między nimi, wykonuje zadania równoległe i wykorzystuje zależności logiczne if/else. Cały proces można zaplanować według potrzeb.&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Nasze know-how&lt;/h2&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Komponenty&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przedstawiona poniżej architektura ma charakter ogólny i radzi sobie z większością naszych zadań. Z jej pomocą można bez problemu wydobyć logikę potrzebną dla danego zadania i wykorzystać nawet 90% Infrastructure as Code (IaC) przy napotkaniu podobnego problemu. Nie można też zapominać o CDK czy Terraform – to świetne rozwiązania i warto z nich skorzystać.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Ogólnie cały proces wygląda następująco:&lt;/p&gt; 
&lt;ul style="color: #181716; background-color: #ffffff; list-style-type: square; line-height: 1.5;"&gt; 
 &lt;li&gt; &lt;p&gt;Zadanie dzieli się na mniejsze części, które można poukładać równolegle (w aplikacjach SaaS to nic trudnego – wystarczy uruchomić to samo zadanie dla każdego tenanta).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Następnie każdą z tych części uruchamia się w osobnym kontenerze.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5;"&gt;W razie konieczności proces można odpowiednio zaplanować.&lt;/p&gt; 
&lt;p style="line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="font-weight: normal;"&gt;Metadata Lambda&lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Na początku procesu &lt;span style="color: #d51313;"&gt;za pomocą funkcji Lambda określa się liczbę zadań do wykonania w AWS Batch&lt;/span&gt;. Wszystko zależy od tego, z jaką sytuacją mamy do czynienia – jeśli zadanie polega na zmianie rozmiaru obrazów, to „częścią zadania” może być tablica z 1000 ID. Wtedy każdy kontener miałby do przeprocesowania 1000 zdjęć. Jeśli celem zadania jest wygenerowanie sitemapy lub listy produktów do zaimportowania, to jedno zadanie przypadłoby dokładnie na jednego tenanta.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;W tym miejscu warto też zająć się specjalną logiką: może akurat dany tenant potrzebuje dodatkowych parametrów? Albo niektóre parametry są niepotrzebne? Czy ostatnie zadanie dla tenanta zakończyło się pomyślnie i na razie można sobie darować dodatkowe obliczenia? Trzeba sobie odpowiedzieć na te wszystkie pytania i odpowiednio zakodować logikę. Warto też pamiętać, że &lt;span style="color: #d51313;"&gt;kontener dobrze zastosować zamiast Lambdy, kiedy 15 minut to za mało na realizację zadania&lt;/span&gt;.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Metadata Lambda generuje n zestawów parametrów (każdy z nich odpowiada „części zadania”) i zapisuje je w buckecie S3. Moglibyśmy również pozwolić, by usługa Step Functions przekazywała wyniki z Lambda bezpośrednio do AWS Batch (bez użycia S3), ale stan Step Functions może podlegać różnym limitom (w kilobajtach). To pokazuje, że nasze rozwiązanie jest bardziej przyszłościowe.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Batch Job i kontener&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Tworzenie Batch Job jest dość proste – wystarczy określić, ile vCPU czy pamięci powinno przypadać na jedno ECS Task i oraz przypisać mu konkretny obraz Docker. W tym przypadku używamy zadania o nazwie Array Job i ustalamy, że w Compute Environment ma być uruchomionych n równoległych, niezależnych kontenerów.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Kontener to niewielka aplikacja, która ma uruchomić zadanie o odpowiednich parametrach. I na tym jej rola się kończy.&lt;/span&gt; Tym samym bardziej przypomina ona plik skryptowy niż pełnoprawną aplikację.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Jeszcze jedno – zastosowany kod musi być w maksymalnym stopniu ogólny i możliwy do ponownego wykorzystania – żadnego hardkodowania! Pierwszym krokiem jest odczytanie pliku S3 Bucket przy użyciu zmiennej środowiskowej AWS_BATCH_JOB_ARRAY_INDEX, by uzyskać dokładne parametry – każda instancja kontenera ma swój unikalny numer. Ten utworzony przez funkcję Lambda plik powinien zawierać wszystkie informacje potrzebne do wykonania zadania: nazwę tenanta, nazwę bucketu i tysiąc ID obrazów do przetworzenia.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Batch Compute Environment i Job Queue&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Po zaplanowaniu Batch Job zadania przechodzą do Job Queue, gdzie czekają na wykonanie w Compute Environment. Są to de facto różnego typu ECS Clusters połączone z ASG/Spot Fleet. Można użyć swojego ECS Cluster albo pozwolić, by Batch zarządzał nim samodzielnie. Sami używamy klastrów zarządzanych przez Batch z instancjami Spot, co jest całkiem ekonomicznym rozwiązaniem. Wystarczy tylko określić minimalną i maksymalną liczbę vCPU. Przy minimum ustawionym na 0 klaster automatycznie wyzeruje swoje zapotrzebowanie na zasoby, jeśli w tle nie będą wykonywane żadne zadania. Nie korzystamy, nie płacimy!&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Na tym etapie można także pośrednio ustalić maksymalną liczbę równolegle wykonywanych zadań. Jeśli kontener wymaga czterech vCPU, a cały klaster używa maksymalnie dwóch instancji EC2 po cztery vCPU w każdej, to w danym momencie będą wykonywane maksymalnie dwa zadania. Cała reszta będzie sobie zakolejkowana w Job Queue czekając na przeprocesowanie we właściwym czasie. Podobną zasadę można zastosować do alokacji pamięci. To dobry sposób, by oszczędzić swoją bazę danych i nie nadwerężyć innych zasobów.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przy okazji trzeba pamiętać, że &lt;span style="color: #d51313;"&gt;Job Queue może mieć przypisanych wiele Compute Environments&lt;/span&gt;. Można spróbować uruchomić zadanie najpierw w ramach instancji spot (wykorzystując dowolne Compute Environment A), a w przypadku braku zasobów przejść na instancje on demand (wykorzystując Compute Environment B). Można też określić kilka typów instancji EC2, które mogą być uruchomiane w Compute Environment. Wtedy AWS Batch – zależnie od obciążenia – spróbuje znaleźć w Job Queue instancję odpowiednią do zapotrzebowania.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Przebieg Step Functions&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Usługa Step Functions zarządza całym procesem, spinając ze sobą wszystkie komponenty. Dzięki łatwości integracji z innymi usługami AWS można za jej pomocą uruchomić funkcję Lambda (lub kontener Fargate) i zaplanować Batch Job.&lt;/span&gt; W tym miejscu za pomocą maszyny stanowej definiuje się cały workflow i kolejność wykonywania zadań. Funkcja ta pozwala również określić procedurę obsługi błędów, na wypadek gdyby w workflow poszło coś nie tak. Podany przykład jest dość prosty, ale Step Functions ma nieograniczony potencjał: może służyć do zbierania danych historycznych o wszystkich udanych zadaniach i błędach, uruchamiania kolejnych zadań po zakończeniu Array Job, wysyłania e-maili do każdego tenanta czy uruchamiania zadań analitycznych w AWS Glue.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Pozostałe funkcjonalności AWS Batch&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przedstawiony wyżej workflow składa się z szeregu równoległych, niezależnych zadań, i jest dość prosty. Ale AWS Batch może dużo więcej. Zadania mogą być ze sobą powiązane i przekazywać sobie parametry w ramach samej funkcji AWS Batch.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Zadania N to N&lt;/strong&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Często się zdarza, że do każdego tenanta trzeba zaimportować wiele danych. W takim przypadku można pomyśleć o podzieleniu zadania na mniejsze części.&lt;span style="color: #d51313;"&gt; Import to nie tylko pobieranie metadanych z zasobów zewnętrznych i zapisywanie ich w bazie danych. Proces ten często obejmuje wiele mniejszych kroków, takich jak weryfikacja danych, pobieranie dodatkowych załączników (dokumentów lub obrazów) czy przekształcanie danych do wymaganego modelu lub formatu i w ustalonej kolejności.&lt;/span&gt; Importując obrazy często je skalujemy, zmieniamy format i wykonujemy parę innych, z pozoru prostych operacji, które mogą zabierać sporo zasobów systemowych (a przy okazji przysporzyć pracy zespołowi Site Reliability Engineering (SRE), jeśli wszystko dzieje się w aplikacji webowej obsługującej żądania).&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Na szczęście dzięki funkcji AWS Batch możemy podzielić ten długi proces na mniejsze części.&lt;/span&gt; Zamiast jednego kontenera do wykonywania wszystkich operacji możemy wykorzystać mniejsze kontenery z odpowiednio mniejszym zakresem zadań. Pierwszy kontener pobiera dane do systemu, drugi pobiera obrazy, a trzeci zmienia ich rozmiar. Jeśli ze skalowaniem pójdzie coś nie tak, obrazów nie trzeba ponownie importować – wystarczy powtórzyć tylko tę część, która odpowiada za skalowanie. To jednocześnie ułatwia rozwijanie i testowanie tych małych aplikacji.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Batch Array N to N Job pozwala na stworzenie listy zależności: najpierw wykonywane jest zadanie A, które po zakończeniu przekazuje dane do zadania B, a gdy ono się zakończy, rozpoczyna się zadanie C. Cały proces to zarazem Array Job, więc może być wykonany niezależnie dla każdego tenanta.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #181716; background-color: #ffffff;"&gt;Można się zastanawiać, czy nie prościej byłoby użyć tutaj Step Functions i zaprojektować cały workflow w ten sposób:&lt;/span&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Widać tu jednak delikatną różnicę – jeśli workflow określi się jako N to N, każda sekwencja zadań będzie przebiegać osobno. Może być tak, że tenant z małą ilością danych szybko zakończy swoją sekwencję, a inne będą jeszcze na etapie zadania A. Natomiast przy użyciu Step Functions Job B może się zacząć dopiero po zakończeniu wszystkich zadań w ramach Job A. Jeśli nie chodzi nam akurat o taki workflow, lepiej zostać przy N to N, bo to pozwala na szybsze zakończenie całego procesu i gwarantuje lepszą paralelizację zadań.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Multi-Node Parallel Jobs&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;To kolejna ciekawa funkcjonalność AWS Batch, która &lt;span style="color: #d51313;"&gt;pozwala uruchomić wybrane zadanie na wielu instancjach EC2&lt;/span&gt;, podczas gdy standardowo zadania zajmują tylko jedną instancję EC2. Multi-Node Jobs używa się w wysokowydajnych aplikacjach obliczeniowych oraz w modelach uczenia rozproszonego GPU. Funkcja ta jest kompatybilna z większością frameworków uczenia maszynowego wspierających rozwiązania oparte na komunikacji międzywęzłowej takie jak Apache MXNet, TensorFlow czy Caffe2.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Aby wykorzystać Multi-Node Parallel Jobs w AWS Batch, aplikacja musi być przystosowana do działania w systemach wielowęzłowych, więc kod musi wykorzystywać struktury odpowiednie do komunikacji rozproszonej.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Każde zadanie tego typu obejmuje uruchomienie głównego węzła, od którego zaczyna się cały proces, po którym uruchamiane są węzły potomne. Można sobie od razu darować środowiska wykorzystujące Spot Instances, gdyż funkcja Multi-Node Parallel Jobs ich nie wspiera. Mimo wszystko, gdy szukamy przystępnych środowisk obliczeniowych dla data science, AWS Batch wydaje się być najwłaściwszym rozwiązaniem.&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Niespodzianki w pracy z AWS Batch&lt;/h2&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Mało użyteczny UI&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Niestety interfejs użytkownika nie daje szansy na uzyskanie zbyt wielu informacji. Kiedy tylko coś pójdzie nie tak, znalezienie błędu i jego przyczyny wymaga przełączania się między Batch, ECS, CloudWatch i Step Functions. Społeczność podjęła tutaj inicjatywę i przygotowała kilka projektów, np. batchiepatchie, by wyeliminować tę niedogodność i stworzyć nowy interfejs użytkownika dla AWS Batch, ale po stronie AWS cicho w tej sprawie.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Szybkość reakcji Batcha to gwarancja szybkiej irytacji. Wszystko przebiega sobie jednym, niespiesznym tempem:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="color: #181716; background-color: #ffffff; line-height: 1.5; list-style-type: square;"&gt; 
   &lt;li&gt; &lt;p&gt;Planujemy zadanie i czekamy aż trafi do Job Queue.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Następnie czekamy, aż Compute Environment zauważy zadania w kolejce. Zauważył, ale brak vCPU, by je wykonać.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Teraz czekamy aż system dostosuje się do zapotrzebowania.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Tyn razem trzeba poczekać na sygnał do skalowania zasobów dla Spot Fleet/ASG.&lt;/p&gt; &lt;/li&gt; 
   &lt;li&gt; &lt;p&gt;Potem czekamy, następnie jeszcze trochę czekamy – i zadanie uruchomione.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Nic tam nie sprawia wrażenia, jakby chciało zadziałać szybko. Nie jest to problem w przypadku żmudnych zadań w tle, ale gdy pracujemy nad rozwojem rozwiązania, może nieźle zirytować. Feedback loop można opisać jako niemrawy.&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Debugowanie (i rozwój) Step Functions – łatwo nie jest&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Definiowanie maszyny stanowej to nieuchronne spotkanie z plikiem JSON. Kiedy tam popełnimy błąd (a jeszcze do tego dodamy interpolację łańcuchów z Terraform), to ratunku nie znajdziemy w żadnym IDE. A komunikaty o błędach wysyłane przez edytor w AWS Console dużo nie pomagają. Testy? Darujmy sobie.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Po za tym IDE nie jest przydatne, jeśli chodzi o składnię przetwarzania input/output SFN. Do tych wszystkich $ i .$ też trzeba się chwilę przyzwyczajać.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Polecamy &lt;a href="https://www.reddit.com/r/aws/comments/hju8or/does_anyone_else_feel_that_step_functions_have/"&gt;ciekawą dyskusję&lt;/a&gt; na temat Step Functions w serwisie Reddit. Dzięki niej można się dowiedzieć, że nic nie łączy developerów mocniej niż wspólne problemy.&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Konfiguracja uruchamiania Managed Compute Environment za pomocą Spot Instances&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przy tworzeniu Managed Compute Environments z wykorzystaniem Spot Instances za kulisami jest bardzo ciekawie. W ramach tego procesu można określić szablon serwera wirtualnego (Launch Template) do wykorzystania przez EC2. Jeśli przy tym wybierze się jeszcze Spot Instances, to Batch wyśle w naszym imieniu Spot Fleet Request (oczywiście mamy AmazonEC2SpotFleetTaggingRole?).&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Spot Fleet Request również wymaga Launch Templates, więc szablon z Compute Environment zostaje skopiowany. &lt;span style="color: #d51313;"&gt;Niestety okazuje się, że jeśli zmienimy Launch Template w Compute Environment, zmiany te już nie pojawią się w Fleet Request’s Launch Template.&lt;/span&gt; Zastosowane przez nas narzędzie IaC (Terraform) na wiele się tutaj nie zdało. Musieliśmy zabrać się za debugowanie, zadając sobie pytanie: „skoro wprowadzamy zmiany do Launch Template to dlaczego nic nie zmienia się w skrypcie cloud-init?”.&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Content-Type dla Launch Template&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Jest to oczywiście opisane gdzieś w dokumentacji – warto upewnić się, że Launch Template ma postać MIME multi-part file (jak pokazano poniżej).&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Uwierzytelnianie w prywatnym repozytorium&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;ECS umożliwia zaciąganie obrazów z niepublicznych rejestrów dzięki przydatnemu repositoryCrendentials w definicji zadania. Szkoda tylko, że Batch nie obsługuje tego parametru. Gdy chcemy skorzystać z zabezpieczonego, prywatnego repozytorium, trzeba skonfigurować ECS_ENGINE_AUTH_DATA dla EC2, na którym uruchamia się ECS agent. Można to zrobić w AMI albo dodać skrypt podobny to tego niżej w Launch Template dla Compute Environment. Ten kod pobiera dane uwierzytelniające z AWS Secrets Manager. Trzeba tylko sprawdzić, czy dana instancja ma wystarczające uprawnienia, aby wywołać API.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Rozterki data engineeringu&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przedstawiliśmy nasz szablon do przetwarzania wsadowego i zarządzania zadaniami w tle, który stanowi element jednego z rozwijanych przez nas projektów SaaS.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Czy da się (jeszcze) lepiej?&lt;/strong&gt; W tym miejscu w zasadzie należałoby się zapytać: &lt;span style="color: #d51313;"&gt;czy Step Functions ma być pełnoprawnym narzędziem do zarządzania workflowem z Batchem w roli silnika wykonawczego?&lt;/span&gt; Czy taki układ sprawdzi się w projektach z zakresu data engineering?&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Na początku, na etapie MVP projektu czy produktu – na pewno tak. Usługę Step Functions można łatwo zaadoptować i zintegrować z innymi usługami AWS (takimi jak Glue czy Batch – bardzo przydatnymi w świecie danych) i naprawdę nieźle sobie ona radzi w nieskomplikowanych środowiskach.&lt;strong&gt; &lt;/strong&gt;&lt;span style="color: #d51313;"&gt;Jednak gdy powiązania i zależności między zadaniami stają się bardziej skomplikowane, zaczynają pojawiać się problemy.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Usługa Step Functions opiera się na modelu maszyny stanowej – analizujemy obecny stan procesu i na tej podstawie określamy kolejne zadania. Można uznać, że Step Functions to w zasadzie skomplikowana maszyna o logice if/else. W data engineering dużo wygodniej jest posługiwać się grafami DAG (Directed Acyclic Graphs), które działają według modelu: ukończ pierwsze zadanie, następnie zrób dwa równocześnie, a w kolejnym kroku połącz wyniki itd. Niestety ani Step Functions, ani żadna inna usługa AWS takich operacji nie obsługują.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;W takim razie co z innymi rodzajami Batch Jobs, które wspomnieliśmy w artykule? Czy nie można dzięki nim stworzyć czegoś, co naśladowałoby DAG? Cóż, gdy się spełni określone wymagania, to przez chwilę wszystko będzie działać. Jednak wcześniej czy później poziom skomplikowania zależności logicznych wzrośnie i Batch dostanie zadyszki. A walka z frameworkiem, takim jak SFN czy Batch, nie będzie łatwa.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Dodatkowo parę rzeczy powinno nam dać do myślenia – kiedy jedno z zadań SFN się wysypie, nie można tak po prostu zastosować poprawki i działać dalej od tego samego miejsca, gdyż całe zadanie oznaczane jest jako błędne i graf trzeba zacząć od nowa. Samo to już sprawia, że SFN nie nadaje się do projektów z zakresu data engineering, gdzie obliczenia często ciągną się godzinami (do tego jeszcze trzeba pamiętać o niedogodnościach związanych z debugowaniem/ testowaniem, obliczeniami równoległymi i zależnościami logicznymi). Co prawda możemy wykorzystać mechanizmy ponownych prób, ale to wiele nie zmienia. Jednak na potrzeby data engineering raczej polecamy Apache Airflow albo podobne narzędzie do obsługi planowania DAG, które można uruchomić w AWS EKS i w pełni zintegrować z resztą usług AWS.&lt;/p&gt; 
&lt;h3 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Werdykt&lt;/h3&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Na szczęście w przypadku większości aplikacji webowych zadania w tle nie są aż tak skomplikowane i uzależnione od innych operacji.&lt;/span&gt; Nic nie stoi na przeszkodzie, by zadania takie jak zmiana wymiarów obrazów, generowanie sitemapy czy raportów odbywały się niezależnie. A w świecie SaaS mogą one być procesowane równolegle dla każdego tenanta. &lt;span style="color: #d51313;"&gt;Jak już pokazywaliśmy, to doskonałe uzasadnienie dla sięgnięcia po SFN i Batcha.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Czy to najlepsze rozwiązanie na rynku? Jak to zwykle bywa w IT, odpowiedź zależy od skali i wymagań projektu. Pewnie sprawę załatwiłby periodic job na poziomie frameworka, z którego korzysta nasza aplikacja. Takie rozwiązanie można by wdrożyć szybko i bez ingerowania w infrastrukturę projektu.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Niemniej to jest niebezpieczny kompromis, którego efektem mogłoby być zbytnie obciążenie systemu, szczególnie jeśli działamy w modelu biznesowym SaaS. W takiej sytuacji nawet niewielki wzrost liczby tenantów wprost przełożyłby się na gorszą wydajność aplikacji i zwiększyłby dług technologiczny. Wyobraźmy sobie, że aplikacja pada, bo jeden z klientów miał trochę więcej obrazków do przetworzenia. Takie coś na pewno nie wyjdzie na zdrowie naszemu biznesowi.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Uwzględniając fakt, że w kodzie produktu głęboko osadzone są różne technologie AWS, a sam produkt zyskuje na popularności, długo nie musieliśmy się zastanawiać. &lt;span style="color: #d51313;"&gt;Dzięki połączeniu CloudWatch, Step Functions, Batch, Lambda i S3 możemy przetwarzać duże ilości danych bez szkody dla systemu. I to rozwiązanie zdecydowanie polecamy każdemu, kto jest na podobnym etapie, co my.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fpl%2Faplikacje-saas-i-wykonywanie-zadan-w-tle-z-aws-batch-i-aws-step-functions&amp;amp;bu=https%253A%252F%252Ftech.univio.com%252Fpl&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Cloud &amp; Infra</category>
      <category>Backend &amp; Data</category>
      <pubDate>Tue, 06 Oct 2020 13:16:44 GMT</pubDate>
      <guid>https://tech.univio.com/pl/aplikacje-saas-i-wykonywanie-zadan-w-tle-z-aws-batch-i-aws-step-functions</guid>
      <dc:date>2020-10-06T13:16:44Z</dc:date>
      <dc:creator>Tomasz Dudek</dc:creator>
    </item>
    <item>
      <title>Proces testowy a zapewnienie jakości – Quality Assurance i Quality Control</title>
      <link>https://tech.univio.com/pl/proces-testowy-a-zapewnienie-jakosci-quality-assurance-i-quality-control</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/pl/proces-testowy-a-zapewnienie-jakosci-quality-assurance-i-quality-control?hsLang=pl" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/unity_230509_unity_omnichannel_illustration_v3@2x%20(1)-1-1.png" alt="Proces testowy a zapewnienie jakości – Quality Assurance i Quality Control" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Artykułów o samym procesie Quality Assurance było już wiele, natomiast czy przypadkiem nie utraciliśmy zrozumienia tego terminu? Odnoszę wrażenie, że wokół projektów IT krąży informacja, która przedstawia, że za zapewnienie jakości oprogramowania w projekcie odpowiada elitarna jednostka „Quality Assurance”, w skład której wchodzą tylko testerzy oprogramowania. Dodatkowo działy HR potęgują stwierdzenie poszukując: „QA Specialist” i oferując im wykonywanie testów i zgłaszanie defektów.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Artykułów o samym procesie Quality Assurance było już wiele, natomiast czy przypadkiem nie utraciliśmy zrozumienia tego terminu? Odnoszę wrażenie, że wokół projektów IT krąży informacja, która przedstawia, że za zapewnienie jakości oprogramowania w projekcie odpowiada elitarna jednostka „Quality Assurance”, w skład której wchodzą tylko testerzy oprogramowania. Dodatkowo działy HR potęgują stwierdzenie poszukując: „QA Specialist” i oferując im wykonywanie testów i zgłaszanie defektów.&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Różnice pomiędzy procesem Quality Assurance a Quality Control&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Z czego mogą wynikać wspomniane wyżej różnice? Otóż przede wszystkim Quality Assurance obejmuje swoimi aktywnościami wszystkie czynności w pracach projektowych. Rozpoczynając od współpracy z klientem (transparentność w komunikacji), określeniu ról i odpowiedzialności w zespole (definicja sposobu pracy, komunikacja, określenie procesu wytwarzania oprogramowania), kończąc na definiowaniu wymagań i cyklu ich życia.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Proces obejmuje wszystkich uczestników projektu, dając im możliwość wpływu na kształt i definicję jakości. Dzieje się to na podstawie kontekstu projektu, jego wartości biznesowej. Warto pamiętać o możliwości mierzenia i ocenianiu jednocześnie jakości oprogramowania.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Proces QA jest działaniem prewencyjnym, zorientowanym w dużej mierze na cały proces wytwórczy zarówno w firmie, jak również w stosowanym projekcie.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Natomiast Quality Control koncentruje się w dużej mierze na poszukiwaniu błędów/nieprawidłowości w działaniu aplikacji, poprzez testowanie oprogramowania na różnych poziomach testów i typach. To czynności, które weryfikują i walidują produkt pod kątem zgodności z wymaganiami i oczekiwaniami użytkownika. W dużej mierze odpowiedzialność spoczywa na roli testera oprogramowania. Jest czynnością detekcyjną.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Ilustracja poniżej, pokazuje proporcje pomiędzy czynnościami wokół testowania oprogramowania, a całym procesem zapewnienie jakości.&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Inne spojrzenie na proces Quality Assurance&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Schemat ten może posłużyć jako „StarterPack” w zakresie zrozumienia procesu Quality Assurance i roli testera. Nie będzie receptą na każdą sytuację, ale może pomóc w zwróceniu uwagi na zapewnienie jakości przez pryzmat zwiększonej aktywności działań w projekcie.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Zacznijmy od pracy z wymaganiami. (Więcej o terminie &lt;a href="http://itsadeliverything.com/three-amigos-meeting-agree-the-tests-before-development-starts"&gt;„3 Amigos”&lt;/a&gt; znajdziesz tutaj).&lt;/p&gt; 
&lt;p style="line-height: 1.5;"&gt;W kontekście jakości oprogramowania, musimy mieć na uwadze początek bliskiej współpracy pomiędzy 3 Amigos. Pojawiają się tutaj 3 role, których charakterystyka została przedstawiona poniżej:&lt;/p&gt; 
&lt;p style="padding-left: 40px; line-height: 1.5;"&gt;1.&amp;nbsp; Analityk biznesowy – ta rola może być zamienna, na pewno musi być to osoba, która jest związana z biznesem np. ProductOwner.&lt;/p&gt; 
&lt;p style="padding-left: 40px; line-height: 1.5;"&gt;2.&amp;nbsp; Programista.&lt;/p&gt; 
&lt;p style="padding-left: 40px; line-height: 1.5;"&gt;3.&amp;nbsp; Tester oprogramowania.&lt;/p&gt; 
&lt;br&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;W opisanym modelu, 3 osoby spełniające powyższe funkcje, współpracują razem przy definiowaniu Wymagań (Story). To ważny moment zwrócenia uwagi na szczegół, że każda ze stron przedstawia swój punkt widzenia oraz jak rozumie poszczególne funkcjonalności (zderzenie wizji na temat Wymagania). Na tym etapie pojawia się szybki feedback i wzajemne zrozumienie. „Nie rozmawiamy po zaimplementowaniu funkcjonalności, tylko przed”. Takie działania mają duży wpływ prewencyjny w projekcie i często ujawniają wiele ryzykownych sytuacji, które jeszcze nie zmaterializowały się, więc koszt ich eliminacji może być niższy.&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Przykładowe pytania np. z perspektywy testera oprogramowania:&lt;/h2&gt; 
&lt;ul style="line-height: 1.5;"&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="list-style-type: square;"&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;Do czego klient potrzebuje tej funkcjonalności&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;Jak wyglądają makiety, albo czy są &#x1f642;&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;Czy nowe wymaganie, wpływa na inne komponenty w aplikacji&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Oczywiście każda ze stron będzie miała inny zestaw pytań. W efekcie powinno pojawić się wspólne zrozumienie tego, co mamy dostarczyć, jaką wartość.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;W wyniku takiego spotkania powstają zrozumiałe wymagania, forma natomiast jest już mocno zależna od kontekstu, zespołu. Tutaj dowiesz się, &lt;a href="https://itsadeliverything.com/three-amigos-meeting-agree-the-tests-before-development-starts"&gt;jak 3 Amigos może wyglądać w praktyce&lt;/a&gt;.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Gdy już wiemy, co powinno zostać dostarczone oraz co ma być wynikiem pracy, przechodzimy płynnie do etapu implementacji wymagań. Na tym etapie możemy użyć wielu metod poprawiających jakość oprogramowania, poczynając od dobrych praktyk w zakresie projektowania, pisania aplikacji poprzez zestaw czynności zorientowanych wokół testów:&lt;/p&gt; 
&lt;ul style="line-height: 1.5;"&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="list-style-type: square;"&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;pokrycie testami jednostkowymi % zakresu kodu,&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;przegląd kodu i testy integracyjne włącznie,&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Ciekawy zakres tego etapu prac, to włączenie &lt;a href="https://martinfowler.com/bliki/TestPyramid.html"&gt;piramidy testów automatycznych&lt;/a&gt;, która może nieco zmienić kształt i zakres naszych testów.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Kolejnym miejscem w procesie są aktywności, które najczęściej przypadają dla szeroko rozumianych testerów oprogramowania. Jest to zbiór aktywności w zakresie weryfikacji/walidacji oprogramowania, pod kątem wspomnianych wymagań, jak również obszarów z zakresu charakterystyk jakościowych (np. Wydajność, Bezpieczeństwo).&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Co dalej?&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Proces Quality Assurance to coś więcej, niż tylko testowanie oprogramowania. Warto mieć to z tyłu głowy i dzielić się tą odpowiedzialnością z całym zespołem. Zapraszając i angażując ich do definiowania czynności wokół jakości oprogramowania tak, aby nasi klienci mogli być zbliżeni do motta Gucci: „Jakość pamięta się dłużej niż cenę”.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Jeżeli chcesz się dowiedzieć więcej o temacie zarządzania jakością w IT, zapraszamy do zapoznania się z naszymi &lt;a href="https://www.univio.com/blog/category/agile/"&gt;publikacjami o agile i praktyce wytwarzania oprogramowania&lt;/a&gt;.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fpl%2Fproces-testowy-a-zapewnienie-jakosci-quality-assurance-i-quality-control&amp;amp;bu=https%253A%252F%252Ftech.univio.com%252Fpl&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Quality Control</category>
      <category>Jakość Oprogramowania</category>
      <pubDate>Thu, 14 Feb 2019 13:16:40 GMT</pubDate>
      <guid>https://tech.univio.com/pl/proces-testowy-a-zapewnienie-jakosci-quality-assurance-i-quality-control</guid>
      <dc:date>2019-02-14T13:16:40Z</dc:date>
      <dc:creator>Tomasz Jański</dc:creator>
    </item>
  </channel>
</rss>
