CodeGym /Kursy /ChatGPT Apps /Procesy wieloetapowe: auto-orkiestracja przez model i kon...

Procesy wieloetapowe: auto-orkiestracja przez model i kontrola pętli

ChatGPT Apps
Poziom 12 , Lekcja 3
Dostępny

1. Czym jest wieloetapowy run i czym różni się od „jednorazowego” żądania

Gdy pracowaliście wyłącznie z ChatGPT App i narzędziami MCP, obraz był dość liniowy: przychodził request użytkownika → GPT decydował, czy wywołać jedno lub kilka narzędzi → dawaliście odpowiedź użytkownikowi. To wciąż można uznać za „jeden logiczny krok”, nawet jeśli wewnątrz narzędzia działo się coś bardziej złożonego.

U agenta run to cel + seria kroków. Nie myślimy już kategoriami „jeden prompt — jedna odpowiedź”, lecz traktujemy zadanie jak mini‑projekt, który agent prowadzi od początku do końca.

Różnicę można przedstawić tak:

Typ interakcji Co robi model Gdzie jest logika
Zwykłe wywołanie narzędzia w ChatGPT App Określa, czy wywołać narzędzie, podstawia argumenty, formuje odpowiedź na podstawie wyniku Główna logika biznesowa i sekwencja działań — w jednym narzędziu lub w backendzie
Run agenta (Agents SDK) Planuje kilka kroków, decyduje, kiedy i jaki tool wywołać, analizuje wyniki pośrednie, może przeglądać plan Logika „jak dojść do celu” częściowo w instrukcji systemowej agenta, a częściowo rodzi się „w głowie” modelu

Ważna uwaga: nie musicie oddawać planowania całkowicie modelowi. Zazwyczaj wychodzi hybryda: twardo kodujecie duże fazy scenariusza (np. „najpierw zbierz wymagania, potem dobierz prezenty, potem przygotuj kartę”), a wewnątrz każdej fazy agent może dość swobodnie używać swoich narzędzi.

Mini-analogia

Jednorazowe wywołanie narzędzia — to jak zamówić kuriera: „odbierz jeden dokument i przywieź go do biura”.

Wieloetapowy agentowy run — to jak osobisty asystent: „Przygotuj prezent dla kolegi na urodziny: dowiedz się, co lubi, dobierz kilka opcji, sprawdź dostawę i zbierz wszystko w ładną prezentację”. Asystent sam decyduje, jakie działania po drodze wykonać.

Nieco dalej w wykładzie zobaczymy też, jak takie wieloetapowe runy wpasowują się w znany już wam stos Apps SDK → MCP → backend, tak aby dla ChatGPT i widżetu logika agenta wyglądała jak zwykłe, zgrabne narzędzie MCP.

2. Jak model sam planuje kroki: widok z lotu ptaka

W kategoriach Agents SDK każdy run wygodnie przedstawić jako trójkę:

  1. Goal (cel): tekstowy opis zadania, który trafia do instrukcji system/user agenta.
  2. Tools: zestaw dostępnych narzędzi z dobrymi opisami i JSON Schema.
  3. State: historia kroków i ustrukturyzowany stan, który przechowujecie na zewnątrz (DB, Redis, cokolwiek).

Następnie rusza znajomy cykl run: model patrzy na cel i dostępne narzędzia i na każdym kroku decyduje:

  • „Mam już dość informacji — można zwrócić wynik końcowy użytkownikowi”;
  • albo „Muszę wywołać narzędzie X z takimi argumentami”;
  • albo „Otrzymałem wynik narzędzia, teraz muszę go zinterpretować, przefiltrować, być może wywołać inne narzędzie”.

Na poziomie pseudokodu pomysł wygląda tak (przypominam, to model mentalny, nie rzeczywiste API):

while (!done && steps < MAX_STEPS) {
  const modelResponse = await callModel({
    system: agentPolicy,
    messages: history,
    tools,
  });

  if (modelResponse.type === "tool_call") {
    const toolResult = await callTool(modelResponse.toolName, modelResponse.args);
    history.push({ role: "tool", content: toolResult });
  } else {
    // odpowiedź końcowa
    done = true;
    return modelResponse.content;
  }

  steps++;
}

W prawdziwym Agents SDK cały ten cykl jest już zaimplementowany i „schowany” w bibliotece. Opisujecie agenta deklaratywnie, a SDK kręci model i narzędzia w pętli, aż do uzyskania wyniku końcowego lub osiągnięcia limitów kroków/czasu.

Zadanie architekta polega na tym, aby:

  • sformułować goal i instrukcję systemową tak, by model planował rozsądne kroki;
  • zbudować zestaw narzędzi bez znaczeniowych nakładek;
  • ustawić ograniczenia kroków i czasu;
  • przemyśleć, które kroki mogą być równoległe.

Gdy mamy cel, narzędzia i wyobrażenie o stanie, następne pytanie brzmi — jakimi krokami iść do celu. Nie wszystkie kroki są takie same: część jest ściśle sekwencyjna, a część da się zrównoleglić.

3. Kroki sekwencyjne i równoległe

Skoro mamy podstawowe zrozumienie cyklu run agenta, warto rozgryźć, jakie w ogóle są kroki w takim procesie. W agentowym workflow są dwa główne typy: sekwencyjne i równoległe.

Kroki sekwencyjne

To sytuacja, gdy wynik kroku A jest krytycznie potrzebny do kroku B. Na przykład w naszym szkoleniowym GiftGenius:

  1. Najpierw trzeba zrozumieć, kto jest odbiorcą prezentu: kolega, krewny, wiek, zainteresowania.
  2. Następnie dobrać zestaw kandydatów przez tool search_gifts.
  3. Później przefiltrować ich pod budżet i ograniczenia.
  4. Potem ładnie przygotować karty do widżetu.
  5. I dopiero potem, ewentualnie, zaproponować przejście do checkoutu.

Każdy kolejny krok zależy od danych poprzedniego, więc wykonanie jest ściśle sekwencyjne.

W pseudokodzie zachowanie agenta może wyglądać jak „wewnętrzny plan” modelu:

1. Dopytać użytkownika o odbiorcę i budżet
2. Wywołać tool search_gifts(profile, budget)
3. Wywołać tool filter_by_constraints(gifts, constraints)
4. Uformować końcową listę i opis

Model nie pisze takiej listy w kodzie, ale możemy popychać go do podobnej struktury przez instrukcje systemowe, przykłady dialogów i opisy narzędzi.

Kroki równoległe

Czasem kroki można wykonywać niezależnie. Na przykład chcemy porównać propozycje prezentów naraz z trzech sklepów:

  • search_gifts_amazon
  • search_gifts_etsy
  • search_gifts_local_store

Z punktu widzenia agenta to trzy niezależne wywołania narzędzi, które można uruchomić równolegle, aby skrócić łączny czas odpowiedzi.

W Agents SDK (i ogólnie we współczesnych frameworkach agentowych) często jest wbudowane wsparcie dla równoległych wywołań narzędzi, jeśli model w jednej odpowiedzi proponuje kilka wywołań naraz. Kanoniczny scenariusz: model w odpowiedzi opisuje listę takich wywołań, SDK uruchamia je współbieżnie, zbiera wyniki i dokłada je jako zestaw wiadomości tool do kolejnego kroku modelu.

Z punktu widzenia planowania wygląda to tak:

// Krok agenta: model zdecydował wywołać trzy narzędzia
const calls = [
  { name: "search_gifts_amazon", args: {...} },
  { name: "search_gifts_etsy", args: {...} },
  { name: "search_gifts_local_store", args: {...} },
];

const results = await Promise.all(
  calls.map(c => callTool(c.name, c.args))
);

// Dalej wszystkie wyniki dodawane są do kontekstu przed następnym krokiem modelu

Jeśli pisaliście frontend w JS/TS, znacie już ideę równoległych zapytań: na przykład, gdy przez Promise.all uruchamiacie kilka fetch() jednocześnie. Teraz ta sama idea pojawia się wewnątrz cyklu run agenta, tylko decyzję co dokładnie można wykonywać równolegle w dużej mierze podejmuje już sam model.

4. Przykład workflow dla GiftGenius: kroki, cele i narzędzia

W części o krokach sekwencyjnych intuicyjnie podzieliliśmy zachowanie GiftGenius na etapy. Teraz sformalizujmy ten wieloetapowy scenariusz jako agentowy workflow: opiszmy cel, kroki i powiążmy je z narzędziami oraz konfiguracją agenta. Na razie nie przywiązujemy się do konkretnego API Agents SDK, opiszemy strukturę i dodamy trochę warunkowego kodu TypeScript, aby utrwalić.

Cel (goal)

Niech cel brzmi tak:

Pomóc użytkownikowi dobrać 3–5 opcji prezentu dla konkretnego odbiorcy, uwzględniając budżet, okazje i ograniczenia dostawy, oraz zwrócić ustrukturyzowaną listę kart prezentów dla widżetu GiftGenius.

Główne kroki

Opiszmy minimalny wariant z 4 kroków:

  1. Doprecyzowanie kontekstu odbiorcy
    Cel: zebrać informacje o tym, komu daje się prezent (wiek, płeć, zainteresowania, relacja z darczyńcą), a także budżet i datę wydarzenia.
    Narzędzia: być może w ogóle bez narzędzi, czysty dialog model ↔ użytkownik.
  2. Wyszukiwanie i wstępna selekcja prezentów
    Cel: uzyskać „surową” próbkę prezentów.
    Narzędzia: search_gifts(profile, budget) — tool, który chodzi do naszego katalogu/systemu wyszukiwania i zwraca listę kandydatów.
  3. Filtrowanie i sortowanie
    Cel: odsiać niepasujące opcje (brak dostawy do regionu, wyjście poza budżet, niepasujące ograniczenia) i posortować po trafności.
    Narzędzia: filter_and_score_gifts(candidates, constraints) — czyste, idempotentne narzędzie.
  4. Formatowanie wyniku dla widżetu
    Cel: doprowadzić dane do formatu wygodnego dla UI: tytuł, krótki opis, obrazek, cena, CTA.
    Narzędzia: format_gift_cards(gifts) — może być zarówno narzędziem kodowym (generacja struktury), jak i LLM‑narzędziem (estetyczne teksty).

Jak może to wyglądać w konfiguracji agenta

Wyobraźmy sobie, że mamy warunkowy konstruktor agenta (pseudokod):

import { createAgent } from "@acme/agents-sdk";
import { tools } from "./gift-tools";

export const giftAgent = createAgent({
  name: "gift-guru",
  system: `
    Jesteś agentem GiftGenius, pomagasz dobierać prezenty.
    Cel: zaproponować 3–5 opcji, które naprawdę da się kupić,
    uwzględniając profil odbiorcy, budżet i ograniczenia dostawy.
    Najpierw doprecyzuj ważne szczegóły, potem używaj narzędzi wyszukiwania i filtrowania.
    Nie wywołuj narzędzi, jeśli jeszcze nie znasz budżetu lub kluczowych zainteresowań.
    Zakończ pracę, gdy masz jasną listę kart prezentów.
  `,
  tools, // tutaj będą search_gifts, filter_and_score_gifts, format_gift_cards
  maxSteps: 12,
  timeoutMs: 15000,
});

Zwróćcie uwagę na kilka detali:

  • W instrukcji systemowej wyraźnie mówimy, że agent powinien najpierw doprecyzować szczegóły, a dopiero potem wywoływać narzędzia wyszukiwania. To zmniejsza ryzyko, że model zacznie odpalać narzędzia ze zbyt rozmytym kontekstem.
  • Ograniczyliśmy maxSteps, aby agent nie wpadał w nieskończone pętle.
  • Timeout timeoutMs jest po to, by cały run nie zajął pół życia użytkownika.

5. Auto-orkiestracja przez model: co „oddać modelowi”, a co ustalić na sztywno

Agent to balans między swobodą modelu a twardą strukturą, którą projektujecie.

Jeśli dać modelowi zbyt dużo swobody i nie wyznaczyć granic, dostaniecie „twórczy bałagan”: zbędne wywołania tools, powtarzające się kroki, nieoczywiste pętle. Jeśli odwrotnie — wszystko zakodować twardo w backendzie jako automat skończony, model stanie się dekoratorem tekstu, a nie inteligentnym wykonawcą zadań.

Co zwykle pozostawia się modelowi

W kontekście GiftGenius i podobnych scenariuszy rozsądnie zaufać modelowi w kwestiach:

  • formułowania pytań do użytkownika (jak doprecyzować zainteresowania, jak uprzejmie zapytać o budżet);
  • decyzji, kiedy informacji jest dość, by uruchomić wyszukiwanie;
  • wyboru, których dokładnie narzędzi użyć w ramach danej fazy (np. którego toola sklepów użyć, jeśli jest ich kilka);
  • generowania tekstów opisów, wyjaśnień, porównań.

Co lepiej ustalić na sztywno

Warto z góry ustalić:

  • duże fazy scenariusza („Zbieranie informacji” → „Wyszukiwanie” → „Filtrowanie” → „Formatowanie” → „Finał”);
  • limity kroków i czasu;
  • warunki, gdy agent ma obowiązek „zatrzymać się” i szczerze powiedzieć użytkownikowi, że zadanie jest nierozwiązywalne (np. jeśli budżet to 5 dolarów, a potrzebny jest drogi gadżet elektroniczny z dostawą na jutro);
  • politykę idempotencji narzędzi i strategie retry.

Przykład hybrydy: fazy jako stan, detale — po stronie modelu

Można w stanie agenta trzymać pole phase, które przyjmuje wartości "collect_profile" | "search" | "filter" | "format" | "done". Wtedy wasz backend (lub samo Agents SDK, jeśli wspiera własną maszynę stanów) będzie kontrolować, które narzędzia są dostępne w której fazie.

Pseudokod:

type Phase = "collect_profile" | "search" | "filter" | "format" | "done";

interface GiftAgentState {
  phase: Phase;
  profile?: UserProfile;
  candidates?: GiftCandidate[];
  finalGifts?: GiftCard[];
}

Instrukcja systemowa dla agenta może zawierać krótkie opisy faz, a wy w kodzie ograniczycie listę tools, którą pokazujecie modelowi, zależnie od bieżącej fazy. To przykład tool gating, który szerzej omawiamy w module o workflow.

6. Kontrola nieskończonych pętli i bezużytecznych powtórzeń

Jeśli zostawicie agentowi niekontrolowany cykl run, wcześniej czy później zacznie zachowywać się jak student przed deadlinem: w nieskończoność „doprecyzowywać i przepisywać”, byle nie oddać pracy. Naszym zadaniem jest nie pozwolić mu zawisnąć.

Istnieją trzy typowe źródła nieskończonych pętli:

  1. Model nie jest pewny odpowiedzi i wciąż parafrazuje to samo zapytanie do narzędzia z nieistotnymi zmianami.
  2. Narzędzie konsekwentnie zwraca błąd lub pusty wynik, a agent uparcie próbuje „spróbować jeszcze raz”.
  3. Agent utknął między dwoma narzędziami, to wywołując jedno, to drugie, nie posuwając się do wyniku końcowego.

Limit kroków (maxSteps)

Najprostszy i obowiązkowy mechanizm — ograniczenie liczby kroków. W większości implementacji Agents SDK możecie wskazać maxSteps przy uruchamianiu run lub w konfiguracji agenta. Gdy tylko limit zostanie osiągnięty, SDK kończy run specjalnym statusem (np. aborted_by_max_steps). Dalej decydujecie, jak to pokazać użytkownikowi.

W GiftGenius możemy uznać, że sensowny dobór prezentów mieści się w ~10 krokach (kilka doprecyzowań, kilka wyszukiwań, filtrowanie, formatowanie). Ustawiamy np. 12–15 kroków z zapasem i ostrożnie obsługujemy sytuację, gdy limit został osiągnięty:

const run = await giftAgent.run({
  input: userGoal,
  maxSteps: 12, // nadpisujemy domyślną wartość
});

if (run.status === "max_steps_exceeded") {
  // Pokazujemy użytkownikowi uczciwy komunikat
}

Limit czasu (timeout)

Czasem problemem nie jest liczba kroków, tylko łączny czas trwania. Narzędzia mogą być wolne, sieć — niestabilna. Dlatego warto wskazywać timeoutMs i na poziomie pojedynczego wywołania narzędzia, i na poziomie całego run.

Na przykład możecie zdecydować, że:

  • każde wywołanie zewnętrznego API (wyszukiwanie prezentów u partnera) nie powinno trwać dłużej niż 3–5 sekund;
  • cały run doboru prezentów powinien zmieścić się w 15 sekundach.

Jeśli zadziała timeout, grzecznie kończycie run, być może pokazując użytkownikowi częściowy wynik i szczere wyjaśnienie, że „część źródeł nie odpowiedziała na czas”.

Wykrywanie powtórzeń

Bardziej zaawansowany (ale przydatny) wzorzec — wykrywać powtarzające się wywołania narzędzi z tymi samymi argumentami. Jeśli widzicie, że agent już trzy razy pod rząd wywołał search_gifts(profile, budget) z tymi samymi parametrami, to sygnał, że utknął.

Możecie dodać do stanu licznik wywołań po kluczu (toolName, argsHash) i jeśli licznik przekracza próg, to albo:

  • przerwać run i zwrócić użytkownikowi zrozumiały błąd;
  • albo podsunąć modelowi dodatkową instrukcję: „już trzykrotnie próbowałeś wywołać to narzędzie z tymi samymi parametrami, spróbuj zmienić strategię lub zapytaj użytkownika”.

Pseudokod:

function shouldAbortToolCall(toolName: string, args: unknown, state: GiftAgentState) {
  const key = `${toolName}:${hashArgs(args)}`;
  const count = state.toolCallCounts[key] ?? 0;

  if (count >= 3) return true;

  state.toolCallCounts[key] = count + 1;
  return false;
}

Gdzie hashArgs — dowolna deterministyczna funkcja serializacji argumentów (np. JSON.stringify z sortowaniem kluczy).

7. Jasne kryteria zakończenia zadania

Jedna z kluczowych różnic między „zabawkowym” agentem a agentem produkcyjnym to jasne kryteria zakończenia. Jeśli ich nie ma, model może albo porzucić zadanie zbyt wcześnie („oto jakieś prezenty, dalej sami”), albo przeciwnie — w nieskończoność ulepszać wynik.

W GiftGenius można sformułować prostą zasadę:

  • Agent kończy pracę, gdy ma od 3 do 5 prezentów z uzupełnionymi polami: id, title, shortDescription, price, imageUrl, purchaseUrl, i które przeszły filtrowanie pod kątem budżetu i dostawy.
  • Jeśli po maksymalnie N próbach wyszukiwania i filtrowania pasujących prezentów jest mniej niż 3, agent szczerze informuje użytkownika, że nie udało się nic sensownego znaleźć, i proponuje zwiększyć budżet lub poluzować ograniczenia.

Te kryteria można zakodować bezpośrednio w instrukcji systemowej agenta i/lub w weryfikacji wyniku po run.

Przykład weryfikacji wyniku po run:

if (run.status === "completed") {
  const gifts = run.output.gifts; // załóżmy, że nasz agent zwraca ustrukturyzowany JSON

  if (!gifts || gifts.length < 3) {
    // Agent się "zakończył", ale wynik jest słaby — można:
    // 1) pokazać szczere wyjaśnienie,
    // 2) zaproponować użytkownikowi zmianę warunków.
  } else {
    // Jest OK — pokazujemy widżet z prezentami
  }
}

Ważne, by nie oczekiwać od modelu magicznego rozumienia sukcesu biznesowego. Jako deweloperzy musicie jasno sformułować warunki „zadowalającego” wyniku i je sprawdzać.

8. Gdzie dokładnie realizowana jest orkiestracja: agent, backend, widżet

Wcześniej mówiliśmy już, że orkiestracja może żyć na różnych poziomach: w agencie, w backendzie, w widżecie.

Z punktu widzenia procesów wieloetapowych logika jest mniej więcej taka.

Agent (Agents SDK) odpowiada za „mentalny” workflow:

  • jak rozbić cel na kroki;
  • jakie narzędzia wywołać i w jakiej kolejności;
  • jakie dodatkowe pytania zadać użytkownikowi.

Backend zwykle zapewnia:

  • implementację narzędzi (wyszukiwanie, filtr, commerce itp.);
  • przechowywanie stanu i checkpointów;
  • twarde ograniczenia biznesowe (limity budżetu, uprawnienia, dostępność regionów).

Widżet (Apps SDK) zarządza:

  • wyświetlaniem postępu (stepper, pasek postępu, „krok 2 z 4”);
  • formularzami wejściowymi;
  • drobnostkami UX, jak np. przyciski disable, gdy nie wszystkie dane są uzupełnione.

Dobra praktyka — myśleć tak: agent reżyseruje pracę narzędzi i dialog, a widżet reżyseruje doświadczenie wizualne użytkownika. Dogadują się przez dane ustrukturyzowane (ToolOutput, agent run output).

9. Mini-przykład kodu: uruchomienie wieloetapowego agenta GiftGenius z narzędzia MCP

Teraz, jak obiecaliśmy na początku wykładu, połączymy nową koncepcję ze znanym już wam stosem Apps SDK → MCP → backend i pokażemy krótki przykład, jak narzędzie MCP może wywołać agentowy run.

Załóżmy, że w waszym app/mcp/route.ts jest tool run_gift_workflow, który:

  • przyjmuje tekstowy request użytkownika (jego cel);
  • uruchamia agenta giftAgent;
  • zwraca ustrukturyzowany rezultat dla widżetu.

Kod uproszczony i umowny, ale daje wyobrażenie o połączeniu:

// app/mcp/route.ts
import { server } from "@modelcontextprotocol/sdk/server";
import { z } from "zod";
import { giftAgent } from "@/agents/giftAgent";

server.registerTool(
  "run_gift_workflow",
  {
    title: "Dobrać prezenty",
    description: "Uruchamia wieloetapowego agenta doboru prezentów",
    inputSchema: {
      userGoal: z
        .string()
        .describe("Zadanie użytkownika, np.: chcę prezent dla kolegi do $50"),
    },
  },
  async ({ userGoal }) => { 		
    const run = await giftAgent.run({		// tutaj uruchamiamy agenta na 12 kroków i timeout 15 s
      input: userGoal,
      maxSteps: 12,
      timeoutMs: 15000,
    });

    return {
      status: run.status,
      gifts: run.output?.gifts ?? [],
      debug: run.debugInfo, // można potem usunąć
    };
  }
);

Dalej ChatGPT App może wywoływać ten MCP‑tool jak każdy inny, a wasz widżet GiftGenius — budować UI na podstawie gifts. Otrzymaliście wieloetapowy workflow „pod maską”, a na zewnątrz dla ChatGPT wszystko wygląda jak jedno zgrabne narzędzie.

10. Typowe błędy przy projektowaniu procesów wieloetapowych

Błąd nr 1: „Niech model sam się połapie, ja po prostu dam mu wszystkie narzędzia”.
Gdy agent ma dostęp do dziesiątki narzędzi nakładających się znaczeniowo, bez jasnej instrukcji systemowej i faz, model zaczyna się miotać: wywoływać to samo na różne sposoby, dublować zapytania, wpadać w pętle. Lepiej poświęcić czas na projekt: podzielić scenariusz na fazy, ograniczyć listę narzędzi w każdej fazie i jasno opisać strategię w system‑prompcie.

Błąd nr 2: Brak limitów kroków i czasu.
Jeśli nie ustawić maxSteps i timeout, w produkcji szybko pojawią się „błąkające się” runy, które zjadają zasoby, a użytkownicy nic nie widzą. Limity to nie „opcja”, tylko podstawowa higiena. Ważne też sensownie obsługiwać sytuacje przekroczenia limitów, a nie po prostu kończyć niemym 500.

Błąd nr 3: Brak wyraźnych kryteriów zakończenia.
Model kończy run, gdy „wydaje mu się, że już wystarczy”, ale jego wyobrażenie „wystarczy” bywa dalekie od wymagań biznesowych. Jeśli nie sformalizować kryteriów sukcesu (ile prezentów, jakie pola, jakie filtry przeszły) i ich nie sprawdzać, dostaniecie niestabilny UX: dziś pięć świetnych opcji, jutro jedna „taka sobie” i jeszcze trzy duplikaty.

Błąd nr 4: Brak śledzenia powtarzających się wywołań narzędzi.
Agent może utknąć w schemacie „otrzymał błąd → sparafrazował zapytanie o 2 słowa → znów wywołał to samo narzędzie”. Jeśli nie śledzicie powtórzeń po (toolName, args), te pętle będą niewidoczne, dopóki nie zajrzycie w logi i się nie przerazicie. Proste liczniki i hash argumentów bardzo pomagają.

Błąd nr 5: Mieszanie orkiestracji i implementacji logiki biznesowej w jednym narzędziu.
Czasem próbuje się schować cały workflow w jednym narzędziu MCP lub funkcji agenta: i wyszukiwanie, i filtr, i formatowanie, i podejmowanie decyzji. W efekcie agent traci sens — model nie może krok po kroku kontrolować procesu, tracicie przejrzystość i możliwość ponownego użycia części scenariusza. Lepiej wynieść osobne etapy do samodzielnych tools i dać agentowi ich kompozycję.

Błąd nr 6: Brak powiązania ze stanem i checkpointami.
Proces wieloetapowy bez zapisywania stanu pośredniego i checkpointów zamienia się w kruchy monolit: jeśli coś padnie w połowie, użytkownik musi zaczynać od nowa. To szczególnie krytyczne w scenariuszach, gdzie użytkownik krąży między krokami lub wraca po czasie. Używajcie state store, zapisujcie fazę, profil, kandydatów i dawajcie agentowi możliwość kontynuacji z właściwego miejsca.

Błąd nr 7: Ignorowanie warstwy UX.
Zdarza się, że deweloperzy wkręcają się w wewnętrzny workflow agenta i zapominają, że użytkownik widzi tylko widżet i wiadomości w czacie. Jeśli w UI nie ma zrozumiałego postępu, statusów „szukamy prezentów…”, „filtrujemy opcje…”, użytkownik będzie myślał, że aplikacja „zawiesiła się” albo „nic nie robi”, nawet jeśli agent orkiestruje złożony proces. Planując wieloetapowy run, od razu myślcie, jak odbije się on w interfejsie.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION