1. Введение
Представьте, что вы пишете обычный веб‑сервис. Там всё просто: у вас есть URL /search, пользователь нажимает кнопку, вы вызываете контроллер searchController. В мире ChatGPT Apps никакого /search пользователь не видит. Он пишет человеческий текст:
«Подбери подарок брату‑геймеру до 50$»
А дальше:
- модель решает: «О, это про подарки, у меня есть GiftGenius, который умеет это делать»;
- GPT сам «нажимает кнопки» — вызывает инструменты вашего App;
- иногда он ещё и предлагает пользователю: «Хочешь, открою GiftGenius и покажу варианты?».
Ключевой сдвиг: пользователь выражает намерение, а кнопки нажимает модель. Если не понимать этот флоу, очень легко:
- написать инструменты с бессмысленными именами (run_func, doStuff),
- получить App, который никогда не предлагается моделью или вызывается не по делу,
- создать виджет, который «выскакивает из куста» и ломает диалог.
Поэтому в этой лекции мы формируем ментальную модель: как GPT вообще узнаёт о вашем App и в каких точках диалога он его «встраивает».
Insight: приложение — это плагин к ChatGPT
В отличии от приложений в телефоне или mini-app в WeChat, приложения в ChatGPT устроены иначе.
ChatGPT сам решает когда запустить ваше приложение и какую его функцию вызвать. Приложения в ChatGPT могут активно вмешиваться (хоть и с ограничениями) в логику чата. Их основная цель и сильная сторона — это расширение возможностей самого ChatGPT.
Если ChatGPT может идеально решить проблему пользователя — ему не нужно вызывать ваше приложение. Если ChatGPT вообще не может решить проблему пользователя — то пользователь об этом и не будет спрашивать. Идеальный вариант, когда ChatGPT может решить запрос пользователя только частично. Это значит, что запросы есть, их много, а результат недостаточный.
Именно тогда ChatGPT вызывает ваше приложение и вы вместе делаете пользователя счастливым. Пользователь становится счастливее, а вы — богаче.
2. Способы запуска ChatGPT App глазами пользователя
У пользователя нет кнопки «вызови MCP‑сервер и call_tool», зато есть текстовое поле и (иногда) меню приложений. С его точки зрения есть две базовые схемы запуска: явная и неявная.
Явный запуск (explicit)
Это сценарий, когда пользователь осознанно выбирает ваш App.
Типичные варианты:
- он находит App в Store ChatGPT и нажимает «Открыть»;
- он выбирает App в лаунчере (например, через кнопку + в поле для ввода текста (Composer));
- он начинает сообщение с имени приложения: «GiftGenius, подбери подарок…» — это называется named mention. Если имя App стоит в начале промпта, ChatGPT автоматически подмешивает ваш App в контекст ответа.
В явном режиме модель с самого начала знает: пользователь пришёл сюда именно поработать с этим App. Поэтому:
- GPT чаще и активнее вызывает ваши tools;
- UI‑виджет вашего App вполне может появляться уже в первом ответе;
- GPT реже «игнорирует» App и отвечает «своими силами».
Любимый пример: пользователь открывает GiftGenius напрямую, потому что хочет «поиграться» с подбором подарков. Он нажимает на App в списке, GPT показывает приветствие в стиле:
«Привет! Я GiftGenius, помогу подобрать подарок. Расскажите, кому и на какой бюджет ищем?»
И дальше активно использует ваши инструменты для поиска.
Неявный запуск (implicit / suggested)
Совершенно другой сценарий: пользователь вообще не думает про App. Он просто пишет в обычном чате:
«Подбери подарок на день рождения маме, она любит садоводство, бюджет до 100$»
GPT анализирует запрос и видит, что:
- в экосистеме есть App GiftGenius, чьи инструменты описаны как «Use this when the user wants to get gift recommendations»;
- задачи и ограничения (подарок, бюджет, интересы) хорошо совпадают с этим App.
В таком случае модель может «скромно вклиниться» с предложением:
«Я могу использовать приложение GiftGenius, чтобы подобрать конкретные варианты подарков и показать их в виде карточек. Открыть его?»
Если пользователь соглашается — GPT вызывает нужный инструмент App и, возможно, рендерит ваш виджет.
Важно, что вы нигде не пишете if (prompt.includes("подарок")) openApp(). Модель принимает решение сама, опираясь на:
- текст запроса и историю диалога;
- метаданные ваших инструментов (названия, описания, схемы параметров);
- состояние подключения пользователя к App (авторизован или нет), корпоративный пользователь или нет.
Вы влияете не на алгоритм, а на то, как ваш App и tools «описаны» для модели.
Гибрид: когда GPT уточняет и потом предлагает App
Иногда пользователь пишет что‑то очень общее:
«Надо что‑то придумать коллеге, вообще не знаю что»
Модель понимает, что GiftGenius может помочь, но информация слишком размыта. Частый паттерн:
- GPT задаёт 1–2 уточняющих вопроса текстом.
- После этого предлагает запустить App: «У меня есть инструмент подбора подарков. Хотите, я открою его и покажу варианты?».
Это хороший UX: пользователь не чувствует, что его «насильно пересадили в другое приложение».
3. Discovery: как GPT находит ваш App
Теперь посмотрим, как всё это выглядит с точки зрения самой модели.
В документации Apps SDK это называется Discovery — все способы, которыми пользователь и модель вообще узнают о вашем App. Это и естественные запросы в чате, и каталог приложений, и специальные «entry points» вроде лаунчера.
Откуда модель вообще знает, что ваш App существует
При регистрации ChatGPT запускает ваш App, а он (через MCP) рассказывает о себе: перечисляет доступные инструменты с их схемами — имя, описание, JSON‑схема входных параметров. Информацию о приложении нужно будет указать при регистрации, а информацию о инструментах ChatGPT сам вытащит через MCP‑метод list_tools.
Модель не видит ваш исходный код, ей доступны только:
- имя инструмента (name);
- описание (description);
- сигнатура входа (inputSchema).
Именно это становится «API для модели». Если вы назвали инструмент run_func с описанием «Executes the function», модель не поймёт, когда его вызывать. Если назовёте suggest_gifts с описанием «Use this when the user wants gift ideas based on recipient, occasion and budget» — всё становится прозрачно.
Named mention и in‑conversation discovery
Официальная спецификация Apps SDK выделяет два ключевых механизма:
- Named mention — когда пользователь начинает сообщение с имени вашего App. В этом случае App почти гарантированно будет поднят и использован в ответе.
- In‑conversation discovery — когда пользователь просто пишет запрос, а модель решает, стоит ли подключить App. При этом учитываются:
- контекст беседы (история сообщений, результаты предыдущих tools, предпочтения пользователя);
- явные упоминания бренда в тексте;
- метаданные ваших tools — названия, описания, документация параметров;
- состояние «линка» — подключен ли пользователь к App (авторизован, разрешены ли нужные пермишены).
Разработчик влияет на этот процесс косвенно: через качественные метаданные и UX‑паттерны, а не через if/else в коде.
Каталог и лаунчер
Помимо диалогового способа, существует ещё Store внутри ChatGPT и лаунчер, доступный из композера. Через них пользователи могут явно выбирать App, как обычное приложение в магазине.
Для нас это важно концептуально: когда мы продумываем флоу GiftGenius, мы должны помнить, что:
- кто‑то зайдёт через каталог и сразу окажется «внутри» App;
- кто‑то никогда не будет лазить по каталогу и увидит App только как предложение в диалоге.
Всё это — про discovery самого App: моменты, когда модель решает, стоит ли вообще «поднять» ваше приложение и предложить его пользователю в текущем разговоре.
4. Анатомия цикла взаимодействия: от фразы до виджета
Пора собрать все уровни из предыдущей лекции — от ChatGPT UI и виджета до Apps SDK и MCP‑сервера — в один понятный логический цикл.
Высокоуровневая схема
С точки зрения процесса, цикл выглядит так:
sequenceDiagram
participant U as Пользователь
participant G as ChatGPT (модель)
participant A as App / MCP-сервер
U->>G: Текстовый запрос
G->>G: Анализ запроса + выбор tools
G->>A: Вызов инструмента (call_tool)
A-->>G: Ответ (данные / structuredContent)
G->>U: Текстовый ответ + (опционально) виджет App
Человеческим языком:
- Пользователь пишет сообщение в ChatGPT.
- Модель анализирует запрос и текущий контекст, решает:
- отвечать ли сама,
- или вызвать один или несколько инструментов.
- Если выбран инструмент вашего App, ChatGPT формирует структурированный запрос (call_tool) и отправляет его MCP‑серверу.
- Ваш backend (или MCP‑сервер) выполняет действие: ходит в базу данных, внешние API, ACP и т.д., формирует результат.
- Результат возвращается в виде структурированных данных (и, возможно, JSON для виджета).
- Модель использует эти данные, чтобы:
- сгенерировать понятный пользователю текст,
- при необходимости — отрисовать виджет App прямо в ответе.
Всё многошаговое планирование — «когда звать что», «спросить ли уточнение», «сделать ли ещё один вызов» — находится на стороне ИИ‑модели. Apps SDK и MCP всего лишь предоставляют единый контракт для инструментов.
Где здесь мы пишем код
В этом цикле есть три точки, где вы реально пишете TypeScript/код:
- Конфигурация App и инструментов — описания tools (имя, описание, схема) и метаданные App (имя, иконка, категории). В вашем проекте это, скорее всего, файл наподобие openai/app-config.ts.
- MCP‑сервер / backend — обработка call_tool: ходим в БД, фильтруем товары, можем вызывать другие API и т.п.
- Виджет (UI) — React‑компонент в приложении Next.js, который отрисовывается в чате и читает результаты инструментов через window.openai или хуки Apps SDK.
Всё остальное — дело модели и платформы.
5. GiftGenius в действии: два сценария пользовательского флоу
Перейдём к более конкретным сценариям, чтобы вы могли «увидеть» этот флоу.
Сценарий 1: пользователь открывает GiftGenius явно
Сценарий:
- Пользователь в ChatGPT открывает каталог App и находит GiftGenius.
- Нажимает «Открыть».
- ChatGPT запускает диалог уже в контексте GiftGenius.
Диалог примерно такой:
Пользователь:
Открывает GiftGenius из каталога.
И пишет: «Привет! Я хочу поддобрать подарок другу»
GPT:
«Отлично, давай помогу подобрать подарок. Расскажите, кому, на какой бюджет и по какому поводу вы ищете подарок?»
На этом шаге GPT может сразу вызвать первый инструмент, например start_gift_session, чтобы инициализировать сессию в вашем backend (создать временную корзину, сгенерировать sessionId и т.п.).
Ваш код на стороне MCP‑сервера может выглядеть так (пока очень условно):
// Псевдо-пример future-TS: описание инструмента GiftGenius
const suggestGiftsTool = {
name: "suggest_gifts",
description: "Use this when the user wants gift ideas by recipient, occasion and budget",
inputSchema: {
type: "object",
properties: {
recipient: { type: "string" },
occasion: { type: "string" },
budgetUsd: { type: "number" },
},
required: ["recipient", "occasion", "budgetUsd"],
},
};
Подробно, как это регистрируется в MCP/Apps SDK, мы разберёмся в отдельном модуле; сейчас нам важна идея: по этому описанию модель понимает, что инструмент подходит для запросов «подбор подарков».
После ответа пользователя GPT вызывает suggest_gifts, получает от вас массив вариантов, а затем:
- оформляет текстом резюме;
- встраивает виджет GiftGenius, где карточки с подарками можно листать и фильтровать.
Сценарий 2: пользователь просит «подбери подарок» в обычном чате
Теперь другой вариант: пользователь вообще не знает про GiftGenius.
Пишет в обычном чате:
«Нужен подарок брату, он обожает настолки, баксов 50 максимум»
Внутри ChatGPT примерно происходит следующее:
- Модель анализирует запрос и список доступных инструментов.
- Она видит инструмент suggest_gifts с подходящим описанием.
- Понимает, что App GiftGenius специально для таких задач.
- Проверяет, устанавливал ли пользователь уже это приложение, был ли авторизован, какие пермишены разрешил.
Дальнейшее поведение может быть разным:
- если запрос достаточно конкретный, GPT может молча вызвать suggest_gifts и вернуть ответ с виджетом;
- если чего‑то не хватает (например, не указан повод или возраст), GPT может сначала спросить уточнение текстом, а потом предложить App.
Такая гибкость — то, что отличает Apps от «жёстких» UI с формами: модель сама выбирает, когда использовать инструменты, а когда поговорить.
6. Семантический роутинг: «LLM как диспетчер»
На уровне discovery модель решает, стоит ли вообще подключать ваш App к текущему запросу. Но дальше, когда App уже «поднят» и его инструменты известны модели в текущей сессии, включается второй уровень — семантический роутинг внутри этих tools: по какому именно инструменту обрабатывать очередную реплику.
В классическом веб‑бэкенде роут выбирается по URL: /checkout — значит вызываем checkout‑контроллер. В ChatGPT Apps роутинга по URL нет, зато есть семантический роутинг: модель сравнивает смысл запроса с описаниями ваших инструментов.
Упрощённо процесс такой:
- При старте сессии ChatGPT получает список tools: их имена, описания, схемы.
- Эти данные встраиваются в системные инструкции модели.
- Когда пользователь пишет запрос, модель сравнивает смысл запроса с описаниями инструментов: где «подбор подарков», где «поиск отелей», где «построить график».
- Если находит хорошее совпадение — формирует структурированный вызов нужного инструмента.
Отсюда следует главный практический вывод:
- описание инструмента — это ваш API для модели; перечитайте это ещё раз. А затем ещё.
- если вы напишете «does stuff», модель действительно не поймёт, когда его вызывать.
Документация и лучшие практики по discovery подчёркивают: к метаданным нужно относиться как к продуктовой копирайтинговой работе. Именно они определяют, в каких разговорах модель вспомнит ваше App.
7. Паттерны диалога вокруг App
Теперь посмотрим на типовые UX‑паттерны, которые возникают, когда GPT взаимодействует с App внутри одной беседы. Это важно, чтобы вы не строили App «в вакууме», без понимания роли GPT‑части.
Все практические гайды по Apps SDK выделяют несколько характерных паттернов:
«Мастер» (The Wizard)
GPT ведёт пользователя шаг за шагом, часто опираясь на App.
На примере GiftGenius:
- GPT: «Расскажите, кому подарок?»
- Пользователь: «Брат, 25 лет, любит настольные игры».
- GPT: «Какой бюджет?»
- Пользователь: «До 50$».
- GPT вызывает suggest_gifts, показывает результаты в виджете и пишет: «Я подобрал несколько вариантов, посмотрите в списке ниже».
В этом паттерне App и его виджет — как бы визуальный слой над многошаговым диалогом. Пользователь большую часть времени пишет текст, а виджет помогает визуализировать выбор.
«Адаптивный виджет» (The Adaptive Widget)
Текст остаётся основным каналом, а App подключается точечно для специальных задач: построить график, показать таблицу, отрисовать карточки товаров.
Пример:
- Пользователь: «Сравни три варианта подарка: настолка, книга, подарок‑впечатление».
- GPT сначала текстом объясняет плюсы и минусы.
- Потом вызывает инструмент, который возвращает структурированный список продуктов, и рендерит небольшую таблицу или карточки.
Здесь App — как визуальное дополнение, а не «режим работы по умолчанию».
«Невидимый агент» (Invisible Agent)
App вообще может не показывать UI. Он работает «под капотом» как источник данных:
- вы реализуете MCP‑tool, который ищет подарки в вашей БД;
- GPT вызывает его, получает список и уже сам пересказывает результаты текстом, без какого‑либо виджета.
Это похоже на классический «плагин‑без‑UI»: пользователь видит только, что GPT знает актуальные цены и ассортимент.
Такой паттерн полезен для tool‑first App, где UI не критичен.
8. Как флоу влияет на дизайн App
Понимание флоу важно не только для философии, но и для очень практичных решений: какие инструменты заводить, как описывать их, когда показывать виджет, а когда лучше ответить текстом.
Принцип «chat‑first»
Ключевая идея экосистемы: чат — главный канал взаимодействия, а UI‑компоненты — вспомогательные.
Это значит:
- не надо пытаться впихнуть «целый сайт» в один виджет;
- виджеты должны помогать там, где чат неудобен: выбор из списка, фильтрация, сравнение, сложные формы.
Для GiftGenius это:
- подобрать список подарков и дать пользователю «тыкать» по карточкам;
- визуализировать фильтры (цена, категория, наличие);
- помочь оформить заказ (checkout) в несколько понятных шагов.
А вот писать в виджете длинные объяснения «как выбрать подарок девушке‑интроверту» — не лучшая идея, это задача чата.
Когда запускать App, а когда нет
Ещё одно последствие: не надо превращать App в «захватчика диалога».
Плохой паттерн:
- пользователь ведёт серьёзную дискуссию;
- App запускается и открывает огромный fullscreen‑виджет без предупреждения;
- пользователь теряется: «куда делся мой чат?».
Лучше:
- вначале всё обсудить текстом, задать пару уточнений;
- потом мягко предложить открыть App, если это реально улучшит UX (сравнение, конфигурация, checkout).
Влияние на набор инструментов
Поскольку модель выбирает инструмент по описанию, каждый инструмент должен:
- решать одну понятную задачу;
- быть хорошо описан в стиле «Use this when…»;
- иметь параметры, которые естественным образом вытекают из вопросов, которые GPT будет задавать пользователю.
Для GiftGenius вместо одного гигантского do_everything логичнее иметь:
- suggest_gifts — подбор списка вариантов;
- get_gift_details — подробности по одному ID;
- create_order — оформление заказа.
Мы подробнее займёмся дизайном инструментов в модуле 4, но общая идея уже сейчас важна: флоу диалога определяет, какие инструменты вообще нужны.
9. Мини‑пример: как описания tools влияют на флоу (TypeScript‑набросок)
Небольшой фрагмент воображаемого openai/app-config.ts, чтобы связать теорию с кодом. Не воспринимайте это как точный синтаксис SDK (его разберём в следующем модуле) — нам сейчас важна идея имен и описаний.
// Условный фрагмент конфигурации GiftGenius (будущий код)
const tools = [
{
name: "suggest_gifts",
description: "Use this when the user wants gift ideas based on recipient, occasion, and budget.",
inputSchema: {/* ... */},
},
{
name: "get_gift_details",
description: "Use this when the user asks for more information about a specific gift from a previous list.",
inputSchema: {/* ... */},
},
];
Если вы замените suggest_gifts на run_func и описание на «Main function», GPT:
- хуже поймёт, для каких запросов стоит звать этот инструмент;
- может реже предлагать ваш App в in‑conversation discovery;
- будет сложнее связывать follow‑ups пользователя с уже показанным списком подарков.
И наоборот, хорошие имена и описания увеличивают шанс, что именно ваш App всплывёт в нужный момент.
10. Типичные ошибки при проектировании пользовательского флоу
Ошибка №1: Ожидание полного контроля — «я сам решу, когда запускать App».
Иногда разработчики мыслят в парадигме «я поймаю все запросы про подарки и подключу свой App». В мире ChatGPT Apps это не так: решения принимает модель. Она учитывает описания инструментов, контекст диалога, состояние пермишенов и насколько пользователь доволен вызовом именно вашего App.
Ошибка №2: Бессмысленные имена и описания инструментов.
Инструменты с именами run, main, tool1 и описаниями «Calls the main function» создают идеальный шторм: модель не понимает, когда их вызывать, in‑conversation discovery практически не работает, а ваш App становится «невидимым». Хорошее описание в стиле «Use this when the user wants…» и понятное имя — гораздо важнее, чем может показаться на первый взгляд.
Ошибка №3: Попытка запихнуть в один App «всё на свете».
Если ваш App одновременно «подбирает подарки, бронирует отели, считает налоги и выводит котиков», модель не сможет надёжно маршрутизировать запросы. Официальные рекомендации и практические гайды подчёркивают принцип «one clear job per tool/App»: лучше несколько специализированных приложений, чем один мегамонолит.
Ошибка №4: Агрессивный автозапуск тяжёлого UI.
Разработчик рад своему красивому fullscreen‑виджету и хочет показывать его «по любому поводу». В результате пользователю кажется, что чат «ломается» и превращается в странное веб‑приложение. Намного лучше, когда GPT сначала общается текстом, задаёт уточняющие вопросы и только потом предлагает открыть App, объясняя, зачем это нужно.
Ошибка №5: Игнорирование роли GPT как UX‑слоя.
Можно спроектировать App как обычный SPA: всё сделать в виджете, а ChatGPT должен «молчать и не мешать». Но это не будет работать. ChatGPT может не отобразить ваш виджет, или отображать новый виджет на новый вызов tool. Хотите успешный продукт — подстраивайтесь под платформу, не ждите, что она подстроится под вас.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ