1. Що таке workflow у контексті ChatGPT App
Якщо ви вже розібралися з авторизацією, то точно заслужили на заохочення. Переходимо до дуже цікавої теми — workflow у ChatGPT App. Саме слово «workflow» у багатьох викликає спогади про BPMN‑діаграми та нудне корпоративне ПЗ. Спокійно: у контексті ChatGPT App нас цікавить значно легша версія.
У нашому курсі під workflow ми розумітимемо багатокроковий сценарій, у якому:
- є зрозуміла мета (наприклад, підібрати подарунок і довести до покупки),
- є послідовні кроки (опитування → генерація варіантів → уточнення → фінал),
- на кожному кроці є свої ролі для GPT, віджета та інструментів.
Важливий момент: workflow — це не «один метод у MCP‑сервері». Це композиція:
- міркувань моделі (які запитання поставити, який інструмент викликати),
- викликів інструментів (MCP/Agents),
- UI‑кроків у віджеті,
- стану на бекенді.
Тобто у вас не один «суперінструмент» solve_everything, а кілька простих, які вмикаються на різних етапах. Так само й не один «мега‑віджет», а невеликий набір екранів/станів — кожен під свою підзадачу.
«Трикутник відповідальності» у workflow
Зручно уявляти workflow як танець трьох учасників:
| Роль | Завдання у workflow | Приклад у GiftGenius |
|---|---|---|
| GPT | Мозок. Розуміє наміри користувача, вирішує, коли крок завершено й який буде наступним. Може викликати інструменти. | Розуміє «хочу щось для ґіка» і вирішує викликати search_items(category="geek"). |
| Віджет | Обличчя. Рендерить поточний крок, показує лише релевантне, збирає кліки та введення. Зберігає UI‑стан. | Показує форму «Кому подарунок?», потім картки подарунків, а далі — кнопку «Купити». |
| MCP/Agent | Руки. Виконує важку й структурну роботу, валідує дані, зберігає бізнес‑стан. | Зберігає профіль отримувача, робить запит до каталогу подарунків, фільтрує за бюджетом. |
Разом ці три ролі реалізують один і той самий сценарій, але на різних рівнях. GPT вирішує «що далі», віджет показує «що зараз», а MCP відповідає за те, що насправді відбувається з даними.
2. Приклад workflow на базі GiftGenius
Візьмемо вже знайомий сценарій GiftGenius — помічник із підбору подарунків. Його можна описати як простий лінійний майстер.
Послідовність кроків може бути такою:
- Зібрати базову інформацію про отримувача.
- Визначити бюджет і обмеження.
- Згенерувати та відфільтрувати ідеї подарунків.
- Показати кандидатів і дати змогу лайкати/приховувати.
- Перейти до оформлення (Checkout) або зберегти підбірку.
Той самий сценарій можна подати як невелику «машину станів»:
stateDiagram-v2
[*] --> Profiling
Profiling --> ProfilingDone: профіль заповнено
ProfilingDone --> Browsing: згенеровано ідеї
Browsing --> Refining: користувач уточнив фільтри
Refining --> Browsing: оновлений список
Browsing --> Checkout: вибрано подарунок
Checkout --> Success: замовлення оформлено
Success --> [*]
Тут:
- Profiling — крок збору відповідей про отримувача,
- Browsing/Refining — робота зі списком кандидатів,
- Checkout — оформлення,
- Success — фінальне підтвердження.
Зверніть увагу: на діаграмі немає жодної кнопки й жодного fetch. Це саме логічні кроки. А конкретні UI‑екрани, інструменти й виклики API ви нашаровуєте поверх них.
3. Навіщо взагалі ділити завдання на кроки
Якщо ви колись робили «анкету на 25 запитань на одному екрані», то вже знаєте відповідь. Але давайте розкладемо все за етапами.
Когнітивне навантаження користувача
Людська увага має обмежені ресурси. Психологи люблять згадувати закон Міллера про 7 ± 2 обʼєкти в короткочасній памʼяті. В UX‑дизайні це перетворюється на дуже практичне правило: що більше полів і варіантів ви показуєте одночасно, то вищий шанс, що користувач «зависне», втомиться або закриє вкладку.
Форма на 12 полів на одному екрані всередині маленького inline‑віджета ChatGPT — це майже гарантований сценарій «закрити вкладку з роздратуванням». Людина кидає все й просто виходить. Адже користувач прийшов «поговорити», а не складати іспит.
Якщо ж ви ділите завдання на кроки:
- «Крок 1 із 4: розкажіть про людину»,
- «Крок 2 із 4: виберіть бюджет»,
- «Крок 3 із 4: перегляньте варіанти»,
- «Крок 4 із 4: підтвердьте вибір»,
то в кожен конкретний момент завдання виглядає посильним. Прогрес‑бар або підпис кроків дає відчуття контролю: зрозуміло, що відбувається і скільки ще залишилося.
Когнітивне навантаження моделі
Несподіванка: у моделі схожа проблема. LLM, звісно, не людина, але в неї теж є обмежене «вікно уваги» — контекст. Якщо ви просите GPT за один прохід:
- зʼясувати все про отримувача,
- розібратися з бюджетом,
- врахувати деталі доставки,
- підібрати 10 варіантів,
- пояснити, чому саме ці варіанти,
то на кожен із підпунктів модель витрачає частину уваги й токенів. Що більше неповʼязаних між собою завдань в одному запиті, то вищий ризик, що частину буде зроблено поверхово або з помилками.
Якщо ж ви будуєте ланцюжок кроків — по суті той самий chain-of-thought, тільки явно розкладений в інтерфейсі, — спочатку модель розвʼязує вузьке завдання «витягнути профіль». Потім — «скоригувати бюджет». А далі — «підібрати кандидатів». Якість міркувань моделі (reasoning) на кожному етапі зазвичай помітно вища.
Підтримуваність і налагодження
Коли все запхано в один інструмент і на один екран, налагодження перетворюється на квест: «А де саме все пішло не так?»
У багатокроковому workflow ви майже автоматично отримуєте:
- точки логування: step_started, step_completed, step_failed,
- зрозумілі місця для вимірювання конверсії (скільки людей дійшло до кроку 3),
- локалізовані проблеми: «падає тільки на кроці генерації ідей».
Усе це знадобиться в модулі про аналітику workflow, але вже зараз корисно звикати мислити кроками.
4. Типи кроків у workflow і як вони виглядають в UI
Ми вже обговорили, навіщо взагалі ділити завдання на кроки. Тепер давайте впорядкуємо самі кроки й подивимося, які типові «цеглинки» найчастіше трапляються в ChatGPT App. Щоб не скотитися до хаотичного набору екранів, зручно мати «бібліотеку» типів кроків. У вашому App майже завжди повторюватиметься кілька шаблонів.
Ось базова таблиця:
| Тип кроку | Мета | Як зазвичай виглядає в ChatGPT App | Приклад у GiftGenius |
|---|---|---|---|
| Збір даних (Wizard) | Заповнити складний обʼєкт частинами | Невелика форма, «чипи», вибір опцій, індикатор прогресу | «Для кого подарунок?», «Вік?», «Інтереси?» |
| Розгалуження | Вирішити, яким шляхом рухатися далі | Питання в чаті + прості варіанти в UI | «Подарунок для дитини → дитячі категорії» |
| Перегляд/підтвердження | Дати користувачеві звіритися з підсумками | Картка‑зведення + кнопки «Назад» / «Підтвердити» | «Ось що я про неї зрозумів — чи все правильно?» |
| Підсумковий крок | Завершити сценарій і запропонувати подальші дії | Фінальний екран із результатом + подальші запитання в чаті | «Ось ваші подарунки. Хочете оформити замовлення?» |
Важливо памʼятати: один і той самий логічний крок може проявлятися і в UI, і в суто текстовому діалозі. Наприклад, крок «збір інтересів» може бути:
- або формою з тегами «спорт», «настільні ігри», «кулінарія»,
- або бесідою, у якій GPT акуратно уточнює: «А чим він захоплюється?».
Часто оптимальний варіант — гібрид. GPT ставить запитання, користувач відповідає текстом і водночас може клікати на «чипах» у віджеті.
5. Хто «веде» workflow: GPT, віджет чи сервер?
Інтуїтивно хочеться сказати: «Звісно, віджет — ми ж фронтендери, усе контролюємо через state». Але у світі ChatGPT App так не працює. Workflow — це спільна робота всіх трьох учасників.
GPT як оркестратор
GPT:
- веде діалог і ставить запитання,
- вирішує, коли крок можна вважати завершеним,
- обирає, коли викликати інструмент (наприклад, «час згенерувати подарунки»).
Для нього ваш workflow виглядає як набір підзадач. У system‑prompt ви можете описати, які підзадачі є і в якому порядку їх зазвичай виконувати. Водночас ви лишаєте моделі трохи свободи, щоб вона могла адаптувати послідовність.
Приклад мініінструкції всередині system‑prompt для GiftGenius (псевдокод, без точного синтаксису):
1. Спочатку уточни профіль отримувача (вік, стосунки, інтереси).
2. Потім уточни бюджет.
3. Коли даних достатньо — виклич інструмент suggest_gifts.
4. Після отримання кандидатів — допоможи користувачеві обрати.
Головне: GPT не знає (і не має знати) подробиць ваших React‑компонентів. Він оперує кроками в термінах мети: «зібрати профіль», «підібрати ідеї».
Віджет як «обличчя» кроку
Віджет:
- відображає саме той крок, який зараз релевантний,
- зберігає UI‑стан (виділена картка, відкритий таб, локальні поля форми),
- може показувати індикатор прогресу за кроками.
Найпростіше подання UI‑workflow у коді:
type GiftWorkflowStep =
| "profiling"
| "budget"
| "candidates"
| "checkout";
type GiftWidgetState = {
step: GiftWorkflowStep;
selectedGiftId?: string;
};
Усередині React‑віджета ви можете зберігати цей стан або у звичайному useState, або — якщо хочете привʼязати його до життєвого циклу віджета в ChatGPT — використовувати useWidgetState з Apps SDK.
const [widgetState, setWidgetState] = useState<GiftWidgetState>({
step: "profiling",
});
Функції‑обробники у віджеті не будуть напряму «купувати подарунок». Натомість вони змінюватимуть крок і передаватимуть потрібні дані назад моделі/бекенду.
MCP‑tools як «руки» workflow
MCP‑сервер:
- зберігає бізнес‑стан (профіль, історію виборів),
- валідує кроки («не можна перейти до Checkout, якщо немає вибраного подарунка»),
- виконує важку роботу: пошук по каталогу, розрахунок цін, інтеграція з ACP.
Наприклад, логічніше, щоб рішення «які подарунки показати» ухвалювалося не у віджеті, а в MCP‑інструменті suggest_gifts. Так модель зможе багаторазово викликати його під час уточнень.
Так у вас виходить поділ:
- GPT — текст і послідовність,
- віджет — візуальне подання поточного кроку,
- MCP — дані та інваріанти.
6. Як описати workflow у коді: міні state‑machine
Памʼятаєте діаграму станів для GiftGenius з початку лекції? Зараз ми запишемо ту саму логіку у вигляді простих типів і функцій — міні state‑machine у коді. При цьому ми не перетворюватимемо ваш App на теоретичний курс із кінцевих автоматів. Однак навіть пара простих типів і функцій помітно спрощує життя.
Типи кроків і конфігурація
Почнемо з декларативного опису кроків. Візьмемо вже знайомий нам тип GiftWorkflowStep (повторимо його тут для наочності) й опишемо для нього конфігурацію:
type GiftWorkflowStep =
| "profiling"
| "budget"
| "candidates"
| "checkout";
type StepConfig = {
label: string;
isFinal?: boolean;
};
export const GIFT_WORKFLOW_STEPS: Record<GiftWorkflowStep, StepConfig> = {
profiling: { label: "Одержувач" },
budget: { label: "Бюджет" },
candidates: { label: "Варіанти" },
checkout: { label: "Оформлення", isFinal: true },
};
Тепер можна додати просту функцію переходу:
export function getNextStep(
current: GiftWorkflowStep
): GiftWorkflowStep | null {
switch (current) {
case "profiling":
return "budget";
case "budget":
return "candidates";
case "candidates":
return "checkout";
default:
return null; // фінал
}
}
Це вже дає вам:
- централізований список кроків,
- явні правила переходів,
- можливість швидко змінювати порядок і логіку.
Використовуємо у віджеті
Найпростіша версія «майстра» у вашому віджеті може виглядати так:
function GiftWizard() {
const [step, setStep] = useState<GiftWorkflowStep>("profiling");
const handleStepComplete = () => {
const next = getNextStep(step);
if (next) setStep(next);
};
return (
<div>
<ProgressBar step={step} />
<StepContent step={step} onComplete={handleStepComplete} />
</div>
);
}
Компонент StepContent уміє відтворювати різні підформи залежно від кроку:
function StepContent(props: {
step: GiftWorkflowStep;
onComplete: () => void;
}) {
const { step, onComplete } = props;
if (step === "profiling") {
return <ProfilingStep onNext={onComplete} />;
}
if (step === "budget") {
return <BudgetStep onNext={onComplete} />;
}
if (step === "candidates") {
return <CandidatesStep onNext={onComplete} />;
}
return <CheckoutStep />;
}
Зверніть увагу: тут ми поки не торкаємося того, як GPT обирає крок, — це локальна UI‑логіка. Згодом ви можете синхронізувати цей step із серверним станом або повідомленнями від інструментів. Але для розуміння багатокроковості цього достатньо.
7. Розвиваємо навчальний застосунок: від «мега‑форми» до майстра
Уявімо, що до цієї лекції ваш GiftGenius‑віджет виглядав як «велика форма»:
- імʼя отримувача,
- вік,
- інтереси,
- бюджет,
- тип події,
- чекбокси «потрібна доставка» і ще пʼять полів,
- і внизу — одна велика кнопка «Підібрати подарунок».
Для прототипу це часто нормально. Але щойно ви хочете продуктовий сценарій — час різати його на кроки.
Як виглядало «до»
Карикатурний приклад:
// Антипатерн: одна величезна форма
function GiftFormAllInOne() {
return (
<form>
{/* 10+ полів впереміш */}
{/* ... */}
<button type="submit">Підібрати подарунок</button>
</form>
);
}
Типові проблеми:
- користувач не розуміє, які поля обовʼязкові,
- незрозуміло, скільки часу це займе,
- GPT складніше пояснити користувачеві, що відбулося, і поставити додаткові запитання.
Як зробити «після»: майстер із трьох екранів
Крок 1 — відокремити профіль від бюджету:
function ProfilingStep(props: { onNext: () => void }) {
const [recipientType, setRecipientType] = useState("");
const [interests, setInterests] = useState<string[]>([]);
const handleSubmit = () => {
// тут можна викликати tool збереження профілю
props.onNext();
};
return (
<div>
<h3>Кому шукаємо подарунок?</h3>
{/* пари радіокнопок / чипсів для типу та інтересів */}
<button onClick={handleSubmit}>Далі</button>
</div>
);
}
Крок 2 — бюджет:
function BudgetStep(props: { onNext: () => void }) {
const [budget, setBudget] = useState<number | null>(null);
const handleSubmit = () => {
// можна викликати tool валідації бюджету
props.onNext();
};
return (
<div>
<h3>Який у вас бюджет?</h3>
{/* слайдер або input */}
<button onClick={handleSubmit} disabled={!budget}>
Підібрати варіанти
</button>
</div>
);
}
Крок 3 — список кандидатів:
function CandidatesStep(props: { onNext: () => void }) {
const [selectedId, setSelectedId] = useState<string | null>(null);
// тут ви вже показуєте картки подарунків
// і даєте змогу вибрати один
return (
<div>
<h3>Виберіть відповідний варіант</h3>
{/* картки з onClick = setSelectedId */}
<button onClick={props.onNext} disabled={!selectedId}>
Перейти до оформлення
</button>
</div>
);
}
Так, коду стало трохи більше, зате логіка стала простішою:
- кожен крок розвʼязує невелике завдання,
- модель може окремо коментувати переходи між кроками,
- ви можете логувати й вимірювати кожен крок окремо.
8. Антипатерни: як не перетворити workflow на монстра
Практика та спостереження за схожими застосунками показують кілька типових помилок, яких дуже хочеться уникнути.
По‑перше, не намагайтеся «намалювати все» складною BPMN‑діаграмою, де 30 станів, 40 стрілок і полотнище A0. У контексті ChatGPT App важливіша інтуїтивно зрозуміла послідовність кроків, а не формальна нотація. Достатньо діаграм на кшталт тієї, яку ми малювали для GiftGenius.
По‑друге, не перетворюйте App на одну величезну форму, особливо всередині inline‑віджета. Користувач уже в чаті, тож додавання щільного UI‑блоку має знижувати, а не збільшувати навантаження. Якщо ви ловите себе на думці «ну тут 12 полів, але ж вони всі важливі», то це майже завжди ознака, що завдання треба різати.
По‑третє, не робіть кроків «для краси». Кожен крок має мати ясну мету: або зібрати дані, або звузити вибір, або дати людині щось підтвердити. Порожній екран на кшталт «ще трохи — і все» з однією кнопкою «далі» рідко допомагає.
Насамкінець, не намагайтеся розкрити всі можливості App уже в перших кроках. Детальні речі на кшталт «розширені фільтри» чи «особливі умови доставки» краще додавати як додаткові кроки — лише для тих, кому це справді потрібно.
9. Проста вправа з проєктування workflow
Щоб краще закріпити матеріал, спробуйте на папері (або в IDE, але без написання коду) зробити таке.
Візьміть одне завдання. Це може бути:
- підбір подарунка (GiftGenius),
- бронювання подорожі,
- побудова плану навчання чомусь.
Розбийте його на 3–5 кроків. Для кожного кроку опишіть:
- мету: що має бути відомо/зроблено після цього кроку,
- формат: що тут доречніше — чистий текст від GPT, віджет чи комбінація.
Наприклад, для простого «плану навчання TypeScript»:
- Крок «Оцінка рівня» — діалог (GPT ставить кілька запитань) + коротка форма із самооцінкою.
- Крок «Цілі» — текстове обговорення + чекбокси цілей у віджеті.
- Крок «План» — генерація плану (список) + кнопки «ускладнити/спростити».
- Крок «Підтвердження» — коротке резюме та кнопка «зберегти план».
Потім прикиньте, які інструменти могли б бути задіяні на кожному кроці. Але не занурюйтеся в деталі: інструменти, їх увімкнення/вимкнення та зберігання стану — теми наступних лекцій цього модуля.
10. Типові помилки під час роботи з багатокроковими workflow
Помилка № 1: спроба вирішити все одним кроком і одним інструментом.
Дуже спокусливо зробити «великий розумний інструмент», який і питає, і аналізує, і сам підбирає, і сам оформлює покупку. На практиці це погіршує і UX (один важкий екран), і якість міркувань моделі (reasoning) — забагато обовʼязків в одному виклику. Простіше, надійніше й дешевше в підтримці — розбити завдання на ланцюжок із 3–5 простих кроків.
Помилка № 2: неявні кроки, заховані в голові розробника.
Іноді в коді ніби є послідовність дій, але її ніде явно не описано: немає типів кроків, немає конфігурації, немає діаграми. У підсумку ніхто в команді не може чітко відповісти, «що відбувається в цьому App від початку до кінця». Мінімальний декларативний опис кроків і переходів економить години налагодження.
Помилка № 3: змішування UI‑кроків і бізнес‑логіки.
Якщо логіка переходів між кроками зашита глибоко в React‑компоненти (у стилі if (isValid && hasBudget && !needsShipping) на onClick кнопки), її стає важко повторно використовувати й тестувати. Краще, коли є відносно явна «машина станів» або принаймні функції getNextStep, а UI лише викликає її та відображає результат.
Помилка № 4: ігнорування ролі GPT як оркестратора.
Буває, що розробник намагається повністю контролювати сценарій із віджета: «я сам запитаю все потрібне, модель нехай тільки підбирає». У результаті ChatGPT перестає виглядати живим асистентом і перетворюється на обчислювальний рушій під формою. Набагато приємніше, коли GPT активно спілкується, підштовхує до наступного кроку й сам ініціює виклики інструментів — а ви допомагаєте йому дизайном кроків та інструкціями.
Помилка № 5: кроки без чіткої мети.
Іноді в майстрі зʼявляються «зайві» кроки — відверто кажучи, просто тому, що дизайнеру так гарніше. Користувач бачить «Крок 2 із 5», але на цьому кроці від нього толком нічого не потрібно й нічого не відбувається. Такі порожні екрани лише підсилюють відчуття складності. Якщо крок не можна сформулювати як «після нього ми точно знаємо X» або «після нього користувач зробив Y», то найімовірніше, він не потрібен.
Помилка № 6: забутий прогрес і відсутність відчуття шляху.
Багатокроковість без візуальної підтримки перетворюється на чорну скриньку: користувач не розуміє, де він і скільки залишилося. Навіть простий текстовий індикатор «Крок 2 із 4» або горизонтальний перелік кроків у верхній частині віджета помітно знижує тривожність. Ігнорування цього ефекту — одна з причин, чому люди «відвалюються» посеред сценарію, хоча реальної складності там може й не бути.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ