W poprzednim wpisie pokazałem specyfikę budowania automatyzacji w środowisku korporacyjnym. Skupiłem się na kluczowych różnicach pomiędzy zwinnym, start-upowym Make a znacznie cięższym, enterprisowym Power Automate. W części praktycznej zbudowaliśmy fundament pod agenta AI działającego w ekosystemie Microsoft 365.
Ten artykuł jest bezpośrednią kontynuacją poprzedniego tutoriala. Domkniemy całą architekturę, dodając warstwę inteligentną — OCR oraz AI odpowiedzialne za klasyfikację dokumentów i generowanie opisów.
Zapraszam do lektury.
Agent AI w Power Automate — część praktyczna
W części pierwszej wyłuskaliśmy linki do załączników z triggera (wiadomość Microsoft Teams), a cały przepływ zakończyliśmy warunkiem, który zatrzymywał przepływ w przypadku ich braku. Teraz przechodzimy krok dalej — zaczniemy od pobrania typów dokumentów z tabeli Excel.
Pobranie danych z pliku Excel w Power Automate
Plik Excel będzie w tym rozwiązaniu pełnił dwie kluczowe funkcje:
- będzie przechowywał informacje o wszystkich przetworzonych dokumentach,
- będzie stanowił konfigurowalną listę typów dokumentów wraz z przypisanymi adresami e-mail.
Gotowy plik Excel możesz pobrać za pomocą formularza na dole strony.
Założenie jest proste, ale bardzo istotne z punktu widzenia utrzymania automatyzacji:
chcemy mieć możliwość dodawania i usuwania kategorii dokumentów wyłącznie poprzez edycję Excela, bez ingerencji w sam przepływ Power Automate.
Z tego powodu automatyzacja:
- za każdym uruchomieniem pobiera pełną listę kategorii,
- a następnie przekazuje ją do AI razem z treścią dokumentu.
Rozbudujmy nasz przepływ.
Zaczniemy od poprawy czytelności całego rozwiązania.
Dodaj blok Scope. Jego jedynym zadaniem jest logiczne pogrupowanie akcji, co:
- poprawia czytelność przepływu,
- ułatwia debugowanie,
- wprowadza porządek w bardziej rozbudowanych scenariuszach.
W naszym przypadku Scope posłuży do wydzielenia wszystkich operacji związanych z pobieraniem danych z Excela.
Przed akcją Scope zainicjuj dwie zmienne:
docu_categories_array— typ:array, wartość początkowa: brakdocu_categories_str— typ:string, wartość początkowa: brak)
Uwaga: wstawienie akcji Initialize variable wewnątrz Scope powoduje błąd przy zapisywaniu przepływu.
Jako pierwszą akcję w Scope dodaj List rows present in a table z konektora Excel Online (Business) i skonfiguruj ją za pomocą list rozwijanych. Celem konfiguracji jest wskazanie tabeli, w której przechowywane są kategorie dokumentów. U mnie wygląda to tak:

W kolejnym kroku dodaj akcję Select z konektora Data Operations. Pozwoli nam ona zbudować prostą mapę, w której powiążemy typy dokumentów z odpowiadającymi im adresami e-mail.
Aby wszystko działało poprawnie, skonfiguruj tę akcję zgodnie z poniższym obrazkiem.

Ten etap może wydawać się nieco nieintuicyjny, dlatego zatrzymajmy się tu na chwilę i rozłóżmy go na czynniki pierwsze.
Pole value w akcji Select powinno wskazywać output z poprzedniego kroku, czyli:
body('List_rows_present_in_a_table')?['value']
Kolumny Typ Dokumentu oraz E-mail to bezpośrednie nazwy kolumn z tabeli Excel. Możemy się do nich odwołać za pomocą wyrażeń:
- Typ Dokumentu →
item()?['Typ Dokumentu'] - E-mail →
item()?['E-mail']
Funkcja item() odnosi się tutaj do pojedynczego rekordu z tablicy value, czyli jednej linii danych pobranej z Excela.
Dane z tabeli mapujemy do dowolnych kluczy obiektu wynikowego. W moim przypadku są to:
DocuType— typ dokumentuE-mail— adres e-mail przypisany do danej kategorii
Jeżeli działanie akcji Select nie jest jeszcze w pełni jasne, warto w tym miejscu zatrzymać się i przeanalizować output dwóch ostatnich kroków: List rows present in a table oraz Select. Zestawienie tych wyników powinno szybko rozwiać wszelkie wątpliwości.
Teraz chcemy dokonać iteracji po utworzonej mapie i wszystkie typy dokumentów zapisać do zdefiniowanej wcześniej tablicy — docu_categories_array. W tym celu:
- użyj pętli Apply to each, jako danych wejściowych wskazując output z akcji Select,
- wewnątrz pętli dodaj akcję Append to array variable, która będzie zapisywać kolejne typy dokumentów do tablicy.
Na końcu bloku Scope połącz wszystkie zebrane typy dokumentów w jeden ciąg tekstowy. W tym celu użyj akcji Set variable oraz funkcji:
join(variables('docu_categories_array'), ',')

join() w akcji Set variableKilka decyzji architektonicznych – perspektywa enterprise
Choć powyższy fragment przepływu może wyglądać jak zbiór technicznych kroków, w rzeczywistości kryje się za nim kilka istotnych decyzji architektonicznych. To właśnie one sprawiają, że automatyzacja nie jest jednorazowym flow, ale rozwiązaniem gotowym do funkcjonowania w środowisku enterprise.
Excel jako warstwa konfiguracji, a nie logiki
Lista typów dokumentów oraz przypisanych adresów e-mail została przeniesiona do pliku Excel. Dzięki temu:
- zmiana kategorii nie wymaga modyfikacji przepływu,
- konfiguracja może być utrzymywana przez biznes, a nie przez IT,
- automatyzacja jest odporna na częste zmiany organizacyjne.
To klasyczny wzorzec oddzielania konfiguracji od implementacji, bardzo powszechny w systemach korporacyjnych.
Select jako kontrakt danych
Akcja Select nie służy tu jedynie mapowaniu kolumn. Pełni rolę kontraktu danych pomiędzy źródłem (Excel) a dalszymi etapami automatyzacji. Normalizujemy dane do stabilnej struktury, niezależnej od fizycznego układu arkusza.
Dzięki temu zmiany w pliku źródłowym nie „rozlewają się” na kolejne kroki przepływu.
Praca na tablicach zamiast gotowych stringów
Zbieranie typów dokumentów w tablicy, a dopiero na końcu ich serializacja do postaci tekstowej, to świadomy wybór. Takie podejście:
- ułatwia walidację i filtrację danych,
- pozwala w przyszłości zmienić sposób ich wykorzystania,
- zwiększa elastyczność całego rozwiązania.
Łączenie danych w jeden string jest tu dopiero ostatnim etapem — dopasowanym do potrzeb warstwy AI.
Świadome uproszczenie formatu pod AI
Choć formalnie można byłoby przekazać do modelu językowego złożoną strukturę JSON, w tym przypadku prosty tekst z listą kategorii jest:
- mniej podatny na błędy parsowania,
- wystarczający z punktu widzenia klasyfikacji dokumentów.
To przykład pragmatycznego kompromisu pomiędzy czystością architektury a skutecznością AI.
Właśnie suma takich drobnych decyzji sprawia, że automatyzacja nie tylko działa, ale jest skalowalna, utrzymywalna i gotowa na realne warunki organizacyjne.
Warstwa inteligentna — OCR
Zanim przejdziemy do właściwej części przepływu odpowiedzialnej za klasyfikację dokumentów, przygotujmy zestaw zmiennych, które będą wykorzystywane w dalszych krokach automatyzacji.
Dodaj do przepływu następujące zmienne typu String, bez wartości początkowej:
file_namedocument_textemail_addressreply_messagesite_address— tutaj od razu wstaw adres strony SharePoint kanału Teams, na którym działa automatyzacja.
Wskazówka:
Adres strony SharePoint skopiujesz, przechodząc do strony głównej kanału Teams w SharePoint. Standardowo ma on postać: https://nazwa_domeny.sharepoint.com/teams/nazwa_grupy-NazwaKanału
Na tym etapie warto jasno zaznaczyć jedną rzecz: wszystkie dalsze operacje wykonywane przez agenta AI muszą zostać przeprowadzone osobno dla każdego załącznika przesłanego w wiadomości Teams. Dotyczy to w szczególności:
- pobrania treści dokumentu,
- analizy dokumentu przez AI,
- zapisania pliku w odpowiednim katalogu.
Wstaw zatem pętlę Apply to each, która dokona iteracji po wszystkich linkach z tablicy content_links. Każda kolejna akcja automatyzująca ten proces biznesowy, będzie znajdowała się wewnątrz tej pętli.
Pierwszą akcją w pętli będzie Get file content using path, która pobierze binarną reprezentację dokumentu z SharePointa. Skonfiguruj ją w następujący sposób:
- Site Address: zmienna
site_address - Infer Content Type: Yes
- File Path: użyj poniższego wyrażenia, dostosowanego do Twojej struktury folderów:
substring(
items('Apply_to_each'),
indexOf(items('Apply_to_each'), '/Freigegebene Dokumente')
)
API kryjące się pod UI tej akcji wymaga osobnego podania adresu strony oraz ścieżki pliku. Każdy link zapisany w tablicy content_links zawiera oba te elementy, dlatego powyższe wyrażenie wycina wyłącznie ścieżkę pliku. W moim przypadku zaczyna się ona od katalogu „Dokumenty Udostępnione” (w wersji niemieckojęzycznej).
Następnie, korzystając trzykrotnie z akcji Set variable, ustaw wartości następujących zmiennych:
file_name— oryginalna nazwa pliku to ostatni element ścieżki:last(split(items('Apply_to_each'), '/'))document_text— reset do pustego stringa:string('')email_address— reset do pustego stringa:string('')
Ten krok zapewnia, że każda iteracja pętli rozpoczyna się z czystym stanem danych.
W tym miejscu przechodzimy do warstwy OCR. Niestety, architektura narzędzi dostępnych w Power Automate wprowadza tutaj pewne ograniczenie.
Akcja Recognize text in image or document z konektora AI Builder nie obsługuje bezpośrednio dokumentów tekstowych, takich jak .docx. Bez problemu radzi sobie natomiast z plikami typu .pdf czy obrazami.
W praktyce oznacza to konieczność rozdzielenia logiki przetwarzania:
- Pliki nietekstowe (
.pdf,.png, itd.) — trafiają bezpośrednio do OCR, - Pliki tekstowe (
.docx) — są najpierw konwertowane do tymczasowego pliku PDF, a dopiero potem analizowane przez OCR.
Rozwiązanie z tymczasowym PDF-em nie jest idealne, ale zapewnia stabilność i przewidywalność automatyzacji. Idealnym scenariuszem byłby bezpośredni odczyt tekstu z dokumentów Word — jednak w praktyce oznaczałoby to użycie dodatkowych narzędzi spoza ekosystemu Microsoft.
Dodaj więc akcję Condition, która sprawdzi, czy plik jest dokumentem tekstowym (operacja logiczna does not end with). Warunek skonfigurowany zgodnie z dokumentacją akcji będzie wyglądał tak:

Jeśli warunek zwróci False (czyli załącznik jest np. plikiem .pdf), prześlij binarną zawartość dokumentu — body z akcji Get file content using path — bezpośrednio do akcji Recognize text in image or document.
Następnie zapisz wynik Full text of the document do zmiennej document_text, korzystając z Dynamic content.
Jeśli warunek zwróci True (zakładamy, że plik jest dokumentem .docx — to uproszczenie omówię dokładniej później), rozpocznij od akcji Convert Word Document to PDF z konektora Word Online (Business).
Konfiguracja jest prosta:
- wskaż odpowiednią Lokalizację oraz Bibliotekę Dokumentów,
- pole File uzupełnij ścieżką złożoną z nazwy kanału oraz nazwy pliku. W moim przypadku użyłem wyrażenia:
concat('/DocuAssistantInput/', variables('file_name'))
Wskazówka: Format ścieżki możesz łatwo podejrzeć, wybierając statycznie dowolny plik z SharePointa za pomocą ikonki folderu. To najprostszy sposób, by upewnić się, jak poprawnie zbudować ścieżkę przy użyciu konkatenacji.
Dalsza część przepływu jest analogiczna — z tą różnicą, że do akcji Recognize text in image or document przekazujesz wynik konwersji do PDF.

Warstwa inteligentna — Asystent AI
Zacznijmy od skonfigurowania asystenta AI. Procedura będzie bardzo podobna do tej, którą opisywałem w jednym z wcześniejszych wpisów — z tą różnicą, że tym razem pracujemy bezpośrednio wewnątrz Power Automate, a nie w zewnętrznym narzędziu.
Tworzenie Asystenta AI w Power Automate
Przejdź do sekcji Prompts i wybierz Build your own prompt. Następnie wskaż model LLM, który będzie używany przez asystenta. Dostępność modeli zależy od konfiguracji Twojego tenanta i decyzji administratora. Istotne jest, aby nie wybierać podstawowego GPT-4.1 mini, który w tym scenariuszu może okazać się zbyt słaby. Standardowy GPT-4.1 będzie w zupełności wystarczający dla większości przypadków klasyfikacji dokumentów.
Po wybraniu modelu przejdź do ustawień asystenta (··· → Settings), gdzie możesz dostosować parametry jego działania. W szczególności warto zwrócić uwagę na temperaturę modelu — w moim przypadku ustawiłem wartość 0.5, co zapewnia dobrą równowagę pomiędzy deterministycznością odpowiedzi a elastycznością językową.
Najważniejszym elementem konfiguracji asystenta jest oczywiście prompt. Możesz przygotować go samodzielnie lub skorzystać z mojego gotowego wariantu — formularz do pobrania znajduje się na dole strony.
Kluczowe jest to, aby przekazać asystentowi:
- treść dokumentu odczytaną przez OCR,
- listę kategorii dokumentów, pobraną wcześniej z pliku Excel.
Aby wstawić te dane do prompta, kliknij Add content, a następnie wybierz Text. Pamiętaj, aby wcześniej ustawić kursor w odpowiednim miejscu treści prompta — w ten sposób kontrolujesz, w jakim kontekście model otrzymuje dane wejściowe.
Przykładowa konfiguracja asystenta została pokazana na poniższym obrazku.

Dodawanie asystenta AI do przepływu
Jeśli asystent AI został utworzony i zapisany, możemy przejść do jego praktycznego wykorzystania w przepływie. Bezpośrednio po bloku Condition dodaj akcję Run a prompt z konektora AI Builder.
W konfiguracji akcji:
- wybierz prompt utworzony w poprzednim kroku,
- przekaż do niego dwie zmienne:
document_text— treść dokumentu odczytaną przez OCR,docu_categories_str— listę kategorii dokumentów pobraną z pliku Excel.
Na tym etapie przepływ wchodzi w swoją właściwą, „inteligentną” fazę — cała wcześniejsza logika służyła wyłącznie przygotowaniu kontekstu wejściowego dla modelu językowego.
To jeszcze nie wszystko. Zgodnie z instrukcją, asystent zwróci format JSON o następującej strukturze:
{
"file_name": "Your generated file name",
"category": "Selected category",
"summary_english": "Your English summary",
"summary_polish": "Your Polish summary",
"keywords_polish": "Your Polish keywords, comma-separated"
}
Wykorzystajmy ponownie akcję Parse JSON, żeby w kolejnych krokach móc łatwo korzystać z danych zwróconych przez sztuczną inteligencję. Schemat danych wygeneruj za pomocą powyższej próbki JSON. Po poprawnym skonfigurowaniu parsowania struktura przepływu powinna wyglądać jak na poniższym rysunku.

Zapisanie pliku i zarejestrowanie go w tabeli
Na tym etapie mamy już wszystko, aby zapisać przetwarzany dokument w folderze odpowiadającym jego kategorii. W praktyce nie tyle „przenosimy” plik, co tworzymy jego nową wersję na podstawie binarnej reprezentacji pobranej wcześniej z SharePointa.
Zacznij od utworzenia na OneDrive katalogów odpowiadających poszczególnym kategoriom dokumentów.
Następnie wstaw akcję Create file z konektora OneDrive for Business i skonfiguruj ją odpowiednio:
- Folder Path — Zbuduj ścieżkę docelową za pomocą konkatenacji tekstów. Jednym z jej elementów powinna być kategoria zwrócona przez asystenta AI. W moim przypadku wygląda to tak:
concat('/Pulpit/Agent_kategorie/',body('Parse_JSON:_AI_RESPONSE')?['category']) - File Name — Nazwę pliku zbuduj z nazwy wygenerowanej przez AI oraz rozszerzenia pobranego z oryginalnej nazwy pliku. Przykładowe wyrażenie:
concat(body('Parse_JSON:_AI_RESPONSE')?['file_name'], '.', last(split(variables('file_name'), '.'))) - File Content — tutaj przekaż postać binarną pliku (output z akcji Get file content using path)
Ważne: Rozszerzenie pliku jest kluczowe. Bez niego plik zostanie co prawda zapisany, ale w praktyce będzie bezużyteczny.
Ostatnim krokiem w tym fragmencie przepływu jest „zostawienie śladu” po przetworzonym dokumencie w pliku Excel. W tym celu użyj akcji Add a row into a table z konektora Excel Online (Business). W konfiguracji:
- statycznie wskaż plik oraz tabelę,
- uzupełnij kolumny tabeli danymi:
- większość wartości pochodzi bezpośrednio z akcji Parse JSON,
- Link do pliku — użyj pola Path z akcji Create file,
- Status — ustaw na stałą wartość: „Przetworzone przez AI”.
Poprawnie skonfigurowana akcja powinna wyglądać jak na poniższym rysunku.

Wysłanie maila i odpowiedzi na Microsoft Teams
Zanim wyślemy maila, musimy ustalić właściwy adres e-mail odbiorcy. W tym celu wracamy do akcji Select, którą wykorzystaliśmy wcześniej. Jej output to tablica zawierająca kategorie dokumentów wraz z przypisanymi do nich adresami e-mail — dokładnie tych danych potrzebujemy na tym etapie.
Dopasowanie adresu e-mail do kategorii dokumentu
Wstaw pętlę Apply to each, aby wykonać iterację po całej tablicy zwróconej przez akcję Select. Wewnątrz pętli dodaj warunek, który sprawdzi, czy kategoria wybrana przez AI odpowiada aktualnie przetwarzanemu elementowi tablicy.
items('Apply_to_each_email_and_category')?['DocuType']
is equal to
body('Parse_JSON:_AI_RESPONSE')?['category']
Jeśli warunek zostanie spełniony, przypisz do zmiennej email_address adres e-mail z bieżącego elementu:
items('Apply_to_each_email_and_category')?['E-mail']
Na tym etapie przepływ powinien wyglądać jak na poniższym rysunku.

Przyznaję — nie jest to najbardziej eleganckie rozwiązanie tego problemu. W praktyce testowałem kilka „sprytniejszych” podejść, jednak wszystkie kończyły się błędami wykonania. Zwykła pętla Apply to each okazała się stabilna i w pełni wystarczająca, co w środowiskach produkcyjnych często bywa ważniejsze niż idealna forma.
Wysyłka maila i aktualizacja statusu
Mając już przypisany adres e-mail, możemy przejść do finalnego etapu: wysłania wiadomości oraz poinformowania użytkownika na Microsoft Teams o wyniku przetwarzania dokumentu.
W tym miejscu możliwe są dwa scenariusze:
1. Adres e-mail istnieje
Agent AI:
- wysyła maila z załączonym dokumentem,
- aktualizuje status w tabeli Excel na „E-mail wysłany”.
2. Adres e-mail nie istnieje
- status w tabeli Excel zostaje ustawiony na „E-mail nie wysłany”.
W obu przypadkach odpowiednio dostrajamy również treść komunikatu wysyłanego na Teams, zapisując ją w zmiennej reply_message.
Implementację w Power Automate rozpocznij od warunku, który sprawdzi, czy zmienna email_address zawiera znak „@”. Jest to prosta, ale skuteczna walidacja wystarczająca dla tego scenariusza.
Wysyłka maila
Jeśli warunek jest spełniony, wstaw akcję Send an email (V2) z konektora Office 365 Outlook.
Konfiguracja tej akcji jest dość intuicyjna:
- uzupełnij adres odbiorcy,
- temat,
- treść wiadomości (do dyspozycji masz pełnoprawny edytor HTML).
Kluczowy element znajduje się w Advanced parameters — wybierz Attachments i dodaj załącznik w następującej postaci:
[
{
"Name": @{outputs('Create_file')?['body/Name']},
"ContentBytes": @{body('Get_file_content_using_path')}
}
]
Moją konfigurację tej akcji przedstawiłem na rysunku 10.

Aktualizacja statusu w Excelu i przygotowanie odpowiedzi na Teams
Po wysłaniu maila zaktualizuj odpowiedni wiersz w tabeli Excel za pomocą akcji Update a row.
Konfiguracja jest analogiczna do wcześniej użytej akcji Add a row into a table. Kluczowe są dwa pola:
- Key Column — kolumna, na podstawie której identyfikujesz właściwy wiersz,
- Key Value — wartość, która musi się znaleźć w tej kolumnie.
Najlepiej odwołać się do linku lub ścieżki pliku. W moim przypadku wygląda to tak:
- Key Column = „Link do Pliku”
- Key Value =
outputs('Create_file')?['body/Path']
Oznacza to, że edytowany będzie dokładnie ten wiersz, który odpowiada plikowi utworzonemu w akcji Create file.
Na koniec ustaw wartość kolumny Status na tekst „E-mail wysłany”, zgodnie z rysunkiem poniżej.

Kolejnym krokiem jest ustawienie treści zmiennej reply_message, która zostanie wykorzystana w komunikacie wysyłanym na Microsoft Teams. Treść możesz sformatować prostym HTML-em, na przykład:
<p><b>Sukces!</b></p>
<p>
Plik <b>@{outputs('Update_a_row:_email_sent')?['body/Nazwa dokumentu']}</b> został przetworzony.<br>
Trafił do katalogu: <b>@{body('Parse_JSON:_AI_RESPONSE')?['category']}</b><br>
E-mail został wysłany do: @{variables('email_address')}
</p>
Jeśli adres e-mail nie istnieje, wystarczą dwie akcje:
- Update a row — ustaw status na „E-mail nie wysłany”,
- Set variable — przygotuj odpowiednią treść wiadomości dla Teams.
Wysłanie komunikatu na Microsoft Teams
Ostatnim elementem dużej pętli Apply to each, a jednocześnie finalną akcją całej automatyzacji, jest Post message in a chat or channel.
W konfiguracji:
- Post as ustaw na User,
- Post in ustaw na Kanał,
- wskaż zespół oraz kanał — ten sam, który obserwujesz w triggerze na początku przepływu,
- treść komunikatu ustaw jako wartość zmiennej
reply_message.
Cały przepływ powinien więc wyglądać tak, jak pokazałem na rysunku poniżej.

Tak skonfigurowana automatyzacja wysyła odpowiedź w imieniu użytkownika. W niektórych tenantach możliwe jest ustawienie opcji Post as = Bot oraz dodanie bota Power Automate do kanału Teams, jednak z perspektywy tego konkretnego agenta AI nie ma to istotnego znaczenia.
Efekt końcowy w Microsoft Teams przedstawiłem na poniższym rysunku.

Gratulacje!
Jeśli przeszedłeś cały tutorial, jesteś w stanie samodzielnie tworzyć inteligentne przepływy w Power Automate. Przedstawiony projekt jest w pełni funkcjonalny, choć zawiera pewne uproszczenia. W kolejnym rozdziale podzielę się uwagami dotyczącymi aspektów, które warto rozważyć przy wdrażaniu takiego agenta AI w wersji produkcyjnej.
Agent AI w Power Automate w wersji produkcyjnej
Na początek jedna ogólna, ale bardzo istotna wskazówka. Dobrą praktyką przy wdrażaniu produkcyjnych automatyzacji w Power Automate jest zapisywanie ich na dedykowanym koncie, utworzonym specjalnie do tego celu.
Takie podejście ma dwie kluczowe zalety:
- ułatwia zarządzanie przepływami przez zespoły (a nie pojedyncze osoby),
- eliminuje ryzyko destabilizacji systemu w przypadku odejścia z pracy osoby, z której kontem powiązane są automatyzacje.
Deklaracja zmiennych i stabilność ścieżek
Pierwszym elementem, który zmieniłbym w omówionej automatyzacji, jest sposób deklaracji zmiennej site_address. W zbudowanym przepływie adres strony pojawia się już wcześniej — w linkach załączników (tablica content_links) — i to właśnie stamtąd pobrałbym go na potrzeby konfiguracji kolejnych akcji.
Dodatkowo, w akcji Get file content using path użyłbym funkcji uriComponentToString(), aby mieć pewność, że ewentualne kodowanie URL nie wpłynie na stabilność działania przepływu. Wówczas parametr Path wyglądałby następująco:
substring(
uriComponentToString(items('Apply_to_each_content_link')),
indexOf(uriComponentToString(items('Apply_to_each_content_link')), '/Freigegebene Dokumente')
)
Takie podejście znacząco ogranicza ryzyko błędów wynikających z różnic w formatowaniu linków.
Obsługa sytuacji, gdy plik już istnieje
Nie obsłużyliśmy również sytuacji, w której plik już istnieje. Jest to bardzo ważny element do poprawy przed implementacją wersji produkcyjnej takiego Agenta AI w Power Automate. Obecnie, jeśli plik o danej nazwie znajduje się już w katalogu docelowym, zostanie on po prostu po cichu nadpisany — bez żadnej informacji zwrotnej. Jedynym śladem będzie wiersz w rejestrze Excel ze statusem „Przetworzone przez AI”. Status nie zmieni się na „E-mail wysłany”, ponieważ w tabeli będą dwa wiersze z tą samą nazwą pliku, a akcja Update a row zmieni status w tym wcześniejszym.
Jest to sytuacja skrajnie niepożądana w środowisku produkcyjnym.
Teoretycznie ryzyko można zmniejszyć, ustawiając wyższą temperaturę modelu GPT, co zwiększy losowość generowanych nazw. Takie podejście może mieć sens w wersji demo, ale nie ma zastosowania w środowisku enterprise, gdzie automatyzacja nie może nadpisywać istotnych dokumentów.
W wersji produkcyjnej właściwym rozwiązaniem jest:
- sprawdzenie przed zapisem, czy plik już istnieje,
- a jeśli nazwa jest zajęta — wygenerowanie nowej, unikalnej.
Walidacja kategorii zwróconej przez AI
Teoretycznie może się również zdarzyć, że asystent AI zwróci kategorię, która nie istnieje. Prawdopodobieństwo takiej sytuacji jest bardzo niskie — szczególnie przy modelu deterministycznym z niską temperaturą. Mimo wszystko, w wersji produkcyjnej warto zadbać także o takie niuanse — to one często przesądzają o stabilności i niezawodności całej automatyzacji.
Akcja Create file w OneDrive:
- utworzy brakujący katalog,
- nie zgłosi błędu.
Z perspektywy środowiska biznesowego jest to jednak zachowanie, które warto kontrolować. Przed wdrożeniem automatyzacji do produkcji w środowisku biznesowym rozważyłbym więc dodatkowe sprawdzenie, czy kategoria znajduje się na liście kategorii z Excela.
Zatrzymywanie przepływu i zapobieganie zapętleniom
Warto również wrócić do fragmentu, którym zakończyłem poprzedni wpis — czyli zatrzymywania automatyzacji w przypadku braku załączników.
Zwróć uwagę, że:
- odpowiedzi agenta AI wysyłane są na kanał obserwowany przez trigger,
- każda taka odpowiedź ponownie uruchamia przepływ.
Zastosowane rozwiązanie:
- przerywa automatyzację wywołaną odpowiedzią automatyczną,
- zapobiega zapętleniu w nieskończoność,
- chroni przepływ przed generowaniem błędów.
Uruchomienia wywołane odpowiedzią automatyczną możesz obserwować w historii uruchomień. Warto ustawić w akcji Terminate status Cancelled, aby łatwo identyfikować je w rejestrze.
Obsługa innych typów plików
Choć kwestię obsługi innych typów plików zostawiłem na koniec, jest to jedna z ważniejszych spraw spośród wymienionych w tym rozdziale. W podrozdziale „Warstwa inteligentna — OCR” zwróciłem uwagę na pewne uproszczenie polegające na tym, że każdy plik inny niż .pdf, .jpg itd. będzie traktowany jako dokument tekstowy. Jest to dość naiwne założenie. W zastosowaniu produkcyjnym użytkownik może przez pomyłkę wysłać dowolny typ pliku, który wcale nie jest dokumentem (np. .csv, .xml). Przy obecnej architekturze przepływu agent będzie próbował konwertować taki plik do PDF. W wersji produkcyjnej zadbałbym o to, aby:
- wszystkie pozostałe pliki były przechwytywane
- i trafiały na przykład do katalogu „inne”.
W stworzeniu takiej logiki mogłaby pomóc funkcjonalność Run after, dostępna w ustawieniach każdej akcji. Pozwala ona określić, kiedy dana akcja — lub cały blok Scope — ma zostać wykonana, na przykład po niepowodzeniu innej akcji. Umożliwia to kontrolę nad przebiegiem automatyzacji analogiczną do mechanizmu try…except… znanego z Pythona i jest jednym z kluczowych narzędzi przy budowie stabilnych przepływów produkcyjnych.
Zachęcam Cię do samodzielnego wdrożenia opisanych powyżej usprawnień. Dzięki nim przedstawiony agent AI:
- przestaje być jedynie demonstracją możliwości,
- staje się solidną, odporną na błędy automatyzacją,
- realnie rozwiązuje problem biznesowy.
A teraz możemy przejść do dalszej części artykułu, w której podsumuję całą serię.
Podsumowanie
To był ostatni — szósty — artykuł z serii o wykorzystaniu agentów AI w automatyzacji procesów biznesowych. Myślę, że cała seria stanowi dość kompleksowe kompendium wiedzy w tej tematyce.
W części poradnikowej pokazałem Ci, jak zbudować agenta AI w dwóch światach: low-code startupowym i enterprise’owym. Wierzę, że było to dobre uzupełnienie zagadnień teoretycznych i solidny fundament pod dalszą naukę oraz rozwijanie zainteresowań tą tematyką.
Pracowaliśmy z Make.com oraz Power Automate. Ten pierwszy — zwinny i elastyczny — świetnie sprawdza się w mniejszych przedsiębiorstwach oraz zastosowaniach prywatnych. Ten drugi — nieco cięższy i bardziej skomplikowany — może być nieoceniony wszędzie tam, gdzie procesy biznesowe, role i autoryzacje są mocno zakorzenione w ekosystem narzędzi Microsoft 365.
Mogłeś odnieść wrażenie, że Make jest prosty i intuicyjny.
W pewnym sensie tak jest.
Żadnej automatyzacji nie da się jednak po prostu “wyklikać”. Potrzebna jest koncepcja, umiejętność integrowania różnych narzędzi za pomocą API, czy też zapewnienie właściwej struktury danych.
Mogłeś odnieść wrażenie, że Power Automate jest toporny.
I to jest prawda.
Enterprise automation wygląda gorzej, ale — bardzo często — działa lepiej.
A sama specyfika pracy na zasobach SharePointa po pewnym czasie staje się jakby bardziej oczywista i naturalna.
Obydwa narzędzia, które zbudowaliśmy — zarówno finansowy asystent stworzony w Make.com, jak również asystent dokumentów — to MVP, które da się rozwijać.
Weźmy jako przykład przepływ z Power Automate. Ten sam schemat można bez zmiany logiki:
- podpiąć pod SharePoint,
- zastąpić Excela usługą Dataverse,
- dodać role i approvals.
Nie zapominaj jednak, że wszystko zaczyna się od MVP. Nie wdrożysz od razu wszystkich funkcjonalności, ani nie uwzględnisz wszystkich warunków brzegowych, które przychodzą Ci do głowy.
Zmapuj proces.
Opracuj plan (co zrobisz i czego nie zrobisz) i działaj.
Automatyzacja nie zaczyna się od narzędzia, tylko od zrozumienia procesu.
Powodzenia.



