JavaRush /Курси /ChatGPT Apps /Зв’язка system‑prompt

Зв’язка system‑prompt, описів інструментів і follow‑ups: як боротися з галюцинаціями

ChatGPT Apps
Рівень 5 , Лекція 2
Відкрита

1. Вступ

Іноді на курсах із prompt‑інжинірингу показують «магічне заклинання»:

«Не вигадуй фактів і кажи “я не знаю”, якщо немає інформації.»

На жаль (або, якщо подивитися інакше, на щастя), для ChatGPT App це не працює як срібна куля. Причина проста: модель бачить не лише ваш system‑prompt, а й:

  • список інструментів із їхніми описами та схемами;
  • результати роботи цих інструментів;
  • історію діалогу, зокрема попередні follow‑up‑и.

Якщо ці три шари — system‑prompt, описи tools, патерни follow‑up‑ів — суперечать один одному або просто «просідають», модель починає поводитися як типовий джуніор‑розробник: дуже старається, але час від часу вигадує зайве.

У межах курсу ви працюватимете з ідеєю «трирівневого захисту від галюцинацій» (defense in depth):

  • рівень 1 — глобальні правила в system‑prompt;
  • рівень 2 — локальні обмеження у визначенні кожного інструмента;
  • рівень 3 — обробка помилок, порожніх результатів і follow‑up‑ів.

У цій лекції ви зведете всі три рівні в один узгоджений контракт для нашого навчального застосунку GiftGenius.

Інсайт

У новій архітектурі ChatGPT Apps поле для system‑prompt зникло — формально його більше немає. Але це не означає, що вам треба відмовлятися від глобальних інструкцій для моделі. Є простий прийом: для ChatGPT описи інструментів — це такий самий промпт‑текст, як і класичний system. Саме через них можна повернути повноцінну «прошивку» застосунку.

Створіть службовий інструмент, наприклад about або about_app. Він не призначений для частих викликів, зате його description модель читає нарівні з описами інших інструментів. Тож у цей опис можна вбудувати повний system‑prompt.

Практичне правило: розміщуйте system‑prompt після короткого технічного опису самого інструмента. Тоді на старті модель отримує ваш system‑prompt у «чистому» вигляді й застосовує його до всього подальшого діалогу та викликів tools.

Щоб спростити супровід, раджу на початку system‑prompt додавати явну версію, наприклад SYSTEM_PROMPT_VERSION: v3. Так ви легко зрозумієте, чому модель поводиться інакше: одразу видно, за яким набором інструкцій вона працює. Якщо в продакшені зʼявляється дивна поведінка, простіше перевірити, чи це проблема старої версії промпта, чи нової.

Приклад:

tool description 

### Global assistant behavior for the entire GiftGenius App (ver 3.01)
*(system-level guidelines, not user-facing text)*

system prompt text

2. Які галюцинації бувають у ChatGPT App (на прикладі каталогу подарунків)

Щоб розуміти, чим лікувати, корисно спершу назвати хворобу. У контексті каталогу (подарунки, товари, тарифи) найчастіше трапляються такі типи галюцинацій.

По‑перше, вигадані позиції каталогу. Користувач просить «цифровий сертифікат на річну підписку на конкретний сервіс» або дуже екзотичний подарунок, якого у вашому фіді немає. А модель, прагнучи бути корисною, охоче вигадує «Super Space Flight 3000 — політ у космос», якого в базі GiftGenius ніколи не існувало.

По‑друге, вигадані атрибути. Подарунок у каталозі є, але модель «прикрашає» реальність: змінює ціну, тип подарунка (цифровий vs фізичний), наявність доставки в країну користувача або строк дії сертифіката. Бо так «логічніше» чи «звучить краще».

По‑третє, галюцинаторні дії. Модель пише: «Я вже купив цей подарунок і надіслав код на вашу електронну пошту, з картки списано $49», хоча ваш бекенд GiftGenius навіть не намагався нічого купувати й жоден ACP/Stripe‑процес не запускався.

Нарешті, є комбінований випадок: інструмент повернув порожній список (немає подарунків під такі фільтри й бюджет), а модель, щоб не засмучувати користувача, вигадує кілька «приблизних варіантів» і не пояснює, що в каталозі їх немає.

Наше завдання — зробити так, щоб у цих ситуаціях модель:

  • чесно визнавала, що у каталозі немає точного збігу;
  • не вигадувала нові подарунки й не змінювала значення полів;
  • пояснювала користувачу, що саме сталося, і пропонувала зрозумілий наступний крок.

І що важливо: робити це не за рахунок «заклинань» у довільних місцях, а через повʼязаний контракт system‑prompttoolsfollow‑ups.

3. Рівень 1: посилюємо system‑prompt проти галюцинацій

Щоб зупинити вигадані подарунки, атрибути й дії з попереднього розділу, спершу посилимо верхній шар — system‑prompt. Тобто задамо моделі загальну «філософію» поведінки в каталозі.

У першій лекції модуля ви вже написали базовий system‑prompt на кшталт: «Ти — GiftGenius, допомагаєш добирати подарунки…». Там само ви зафіксували межі відповідальності асистента та правила роботи з інструментами.

Тепер додамо до нього явні антигалюцинаційні правила.

Логіка проста: system‑prompt задає загальну філософію поведінки. Він не знає деталей кожного інструмента, зате може:

  • заборонити вигадувати подарунки, ціни та наявність поза каталогом;
  • прописати поведінку, якщо інструменти повернули порожній результат або помилку;
  • вимагати чіткого розрізнення між даними з каталогу подарунків і будь‑якими «загальними знаннями моделі».

Приклад фрагмента system‑prompt (TypeScript‑константа в нашому Next.js‑проєкті, наприклад config/systemPrompt.ts):

// config/systemPrompt.ts
export const SYSTEM_PROMPT = `
# Роль
Ти — GiftGenius, асистент з добору подарунків
на основі каталогу подарунків нашого застосунку.

# Дані та обмеження
- Не вигадуй подарунки, яких немає в каталозі або у відповідях інструментів.
- Не вигадуй ціни, наявність, тип подарунка (цифровий/фізичний),
  регіони доставки чи інші атрибути.
- Якщо інструмент не повернув потрібних даних або сталася помилка,
  чесно повідомляй про це і не намагайся вгадувати значення.

# Робота з інструментами
- Завжди використовуй інструменти каталогу подарунків для будь-яких фактичних даних:
  списку подарунків, цін, типів, доступності, SKU.
- Якщо інструмент повернув порожній результат, скажи, що за поточних умов
  відповідних подарунків немає, і запропонуй варіанти послабити фільтри
  (змінити бюджет, категорію, тип подарунка).
`;

Тут важливо кілька моментів.

По‑перше, ми розділяємо «загальні знання моделі» й «дані застосунку». Модель усе ще може пояснити, чим цифровий подарунок відрізняється від фізичного або які бувають приводи. Але будь‑які конкретні подарунки, ціни та SKU мають надходити лише з інструментів GiftGenius.

По‑друге, ми прямо описуємо, що робити у випадку помилок або порожньої відповіді. Не мовчати й не «креативити», а чесно сказати користувачу, що нічого не знайшлося, і запропонувати змінити параметри.

По‑третє, ми зосереджуємося не на абстрактному «не галюцинуй», а на конкретних типах поведінки, привʼязаних до нашого домену (каталог подарунків і купівля цифрових або фізичних SKU).

Цей шар сам по собі вже дуже допомагає. Але його легко «перебити» неакуратним описом інструмента. Тож переходимо до tool descriptions.

4. Рівень 2: описи інструментів (tool descriptions) і схеми як формальна частина контракту

Модель вирішує, коли і як викликати ваш інструмент, насамперед за:

  • назвою інструмента;
  • description інструмента;
  • inputSchema / outputSchema (JSON Schema, що описує поля).

Тобто опис інструмента (tool description) — це не документація «для людей», а така сама частина промпта, тільки більш формалізована. І чимало галюцинацій народжується саме тут.

Уявімо наш інструмент recommend_gifts, який бекенд реалізує як добір подарунків із каталогу GiftGenius.

Поганий варіант опису міг би виглядати так:

// ПОГАНО: надто розпливчасто
const recommendGiftsTool = {
  name: "recommend_gifts",
  description: "Підбирає подарунки для користувача",
  inputSchema: {
    type: "object",
    properties: {
      profile: { type: "string" }
    }
  }
};

Формально все коректно, але з такого опису модель не розуміє:

  • де межі інструмента;
  • що робити, якщо подарунків не знайдено;
  • що не можна вигадувати подарунки й ціни поза каталогом.

Хороший опис робить кілька речей одночасно: чітко задає домен, пояснює, коли викликати tool, і жорстко фіксує, що не можна вигадувати результати.

Приклад (адаптований під контракт GiftGenius із segments, budget, locale, occasion):

// config/tools.ts
export const recommendGiftsTool = {
  name: "recommend_gifts",
  description: `
Добір подарунків у каталозі GiftGenius.

Використовуй цей інструмент, коли потрібно отримати список реальних подарунків
за сегментами профілю отримувача, бюджетом, локаллю та приводом.
Інструмент повертає тільки ті подарунки, які реально є
в каталозі GiftGenius.

НЕ вигадуй подарунки та їх атрибути поза результатами цього інструмента.
Якщо інструмент повернув порожній список, не вигадуй альтернатив,
а переходь до діалогу: запропонуй змінити бюджет, тип подарунка,
привід або інші параметри.
  `.trim(),
  inputSchema: {
    type: "object",
    properties: {
      segments: {
        type: "array",
        description:
          "Сегменти профілю отримувача, наприклад ['tech', 'fitness'].",
        items: { type: "string" }
      },
      budget: {
        type: "object",
        description: "Діапазон бюджету на подарунок.",
        properties: {
          min: {
            type: "number",
            description: "Мінімальна сума, невід’ємна.",
            minimum: 0
          },
          max: {
            type: "number",
            description: "Максимальна сума, більша за 0.",
            exclusiveMinimum: 0
          },
          currency: {
            type: "string",
            description: "Трилітерний код валюти, наприклад 'USD' або 'UAH'.",
            minLength: 3,
            maxLength: 3
          }
        },
        required: ["min", "max", "currency"]
      },
      locale: {
        type: "string",
        description:
          "Локаль користувача (формат мови/регіону), наприклад 'uk-UA' або 'en-US'.",
        minLength: 2
      },
      occasion: {
        type: "string",
        description:
          "Привід для подарунка: наприклад 'birthday', 'anniversary', 'new_year'."
      }
    },
    required: ["segments", "budget", "locale", "occasion"]
  }
};

Тут description робить кілька корисних речей.

По‑перше, він прямо каже, що інструмент працює лише з каталогом подарунків GiftGenius. А отже, будь‑які конкретні подарунки та ціни потрібно брати тільки з його результату.

По‑друге, він пояснює, коли використовувати інструмент: коли вам потрібен саме список конкретних подарунків за параметрами отримувача, а не загальна теорія про подарунки.

По‑третє, він задає поведінку за порожнього результату: не вигадувати, а переходити до діалогу (те, що потім ми зафіксуємо у follow‑up‑ах).

А inputSchema допомагає моделі надійніше витягати сутності з користувацького запиту: сегменти, бюджет, локаль і привід. Явна структура та обмеження полів (min, max, currency із фіксованою довжиною) теж знижують імовірність дивних комбінацій і помилок під час парсингу.

За потреби можна додати й «зворотний бік»: не лише «коли викликати», а й коли не викликати. Наприклад, якщо запит явно теоретичний:

description: `
...
Не використовуй цей інструмент, якщо користувач ставить загальне питання
про подарунки без запиту на добір для конкретної людини
(наприклад, "які бувають популярні подарунки на Новий рік загалом").
У таких випадках відповідай сам у чаті.
`.trim()

Так ви синхронізуєте опис інструмента з правилами з system‑prompt про «теоретичні» та «практичні» запити.

5. Рівень 3: follow‑ups як UX‑ та safety‑шар

Навіть якщо system‑prompt і описи tools написані ідеально, у реальності все одно трапляються збої:

  • бекенд може повернути помилку;
  • каталог може повернути порожній список;
  • результати можуть бути неоднозначними або надто численними.

Якщо не прописати, що саме казати після виклику tool, модель почне імпровізувати. Іноді це спрацює добре, а іноді призведе до вигаданих фактів.

У лекції 2 ви вже бачили базові UX‑інструкції: як модель анонсує запуск застосунку, як завершує сценарій і що говорить користувачу «на виході». Тепер додамо до цього патерни follow‑up‑ів, які знижують ризик галюцинацій.

Такі патерни зазвичай описують прямо в system‑prompt окремим блоком — наприклад, «Діалог після роботи з інструментами».

Приклад фрагмента:

// продовження SYSTEM_PROMPT
export const SYSTEM_PROMPT = `
# ... попередні секції ...

# Діалог після роботи з інструментами

- Якщо інструмент добору подарунків повернув порожній список:
  1) чесно скажи, що за поточних фільтрів відповідних подарунків не знайдено;
  2) запропонуй користувачу змінити 1–2 ключові параметри
     (бюджет, тип подарунка, інтереси отримувача, привід).

- Якщо інструмент повернув надто багато варіантів:
  1) обери 3–7 найбільш релевантних;
  2) явно скажи, за якими критеріями ти їх відібрав
     (збіг за інтересами, попадання в бюджет, рейтинг).

- Якщо сталася помилка інструмента:
  1) не вигадуй дані;
  2) скажи, що сталася технічна помилка, і запропонуй
     спробувати пізніше або спростити запит.
`.trim();

Так ми «прошиваємо» в модель приблизні follow‑up‑репліки. Вона сформулює їх своїми словами, але збереже задану структуру:

  • констатація факту (порожньо / багато / помилка);
  • чесне визнання обмеження;
  • акуратна пропозиція наступного кроку.

Для каталогу подарунків це критично: замість «усе гаразд, ось вам три подарунки» у випадку порожнього результату модель скаже щось на кшталт:

«За вашими поточними умовами (цифровий подарунок про космос до $5 з доставкою тільки в США) у нашому каталозі нічого немає. Хочете, я спробую розширити бюджет або запропоную інші категорії?»

Зверніть увагу: це вже не код інструмента, а інструкції в промпті, які задають очікуваний UX.

6. Пов’язуємо все разом: еволюція нашого GiftGenius

Розгляньмо мініеволюцію нашого застосунку й крок за кроком зменшимо рівень галюцинацій.

Початкова версія: де все ламається

Припустімо, у нас був дуже мінімалістичний system‑prompt:

export const SYSTEM_PROMPT = `
Ти — помічник із добору подарунків.
Допомагай користувачу знаходити підхожі ідеї.
`;

А інструмент було описано так:

export const recommendGiftsTool = {
  name: "recommend_gifts",
  description: "Підбирає подарунки для користувача",
  inputSchema: { type: "object" }
};

І — жодних інструкцій для follow‑up‑ів.

Що відбуватиметься на практиці:

  • якщо користувач попросить «цифровий подарунок другові‑геймеру до $10», а в базі під такі фільтри нічого немає, модель може:
    • або взагалі не викликати tool і вигадати подарунки «з голови»;
    • або викликати tool, отримати порожній список, але не сказати про це й натомість запропонувати вигадані варіанти;
  • якщо бекенд поверне помилку, модель може вирішити, що «щось та має бути», і почати вгадувати.

Так і виникає класична ситуація: у чаті — гарна відповідь, у базі — нічого схожого.

Нова версія system‑prompt

Перепишемо system‑prompt, врахувавши три рівні захисту. Частину ви вже бачили вище — тепер зберемо все докупи:

// config/systemPrompt.ts
export const SYSTEM_PROMPT = `
# Роль
Ти — GiftGenius, асистент з добору подарунків
на основі каталогу подарунків нашого застосунку.

# Зона відповідальності
- Твоє завдання — допомогти користувачу обрати відповідні подарунки
  з каталогу, пояснюючи плюси й мінуси варіантів.
- Не давай обіцянок щодо фактичної купівлі або відправлення подарунка —
  ти лише допомагаєш підібрати й порівняти варіанти.
  Купівлю та видачу коду/посилання виконує backend після явної згоди користувача.

# Дані та обмеження
- Не вигадуй подарунки, яких немає в каталозі або у відповідях інструментів.
- Не вигадуй ціни, тип подарунка, наявність або регіони доставки.
- Якщо інструмент не повернув даних або сталася помилка,
  не намагайся вгадувати, а повідом про це.

# Робота з інструментами
- Використовуй інструменти каталогу подарунків (наприклад, profile_to_segments,
  recommend_gifts, get_gift) для будь-яких фактичних даних
  (список подарунків, ціни, типи, SKU, описи).
- Відповідай сам (без інструментів), якщо питання теоретичне
  і не вимагає добору конкретного подарунка.

# Діалог після роботи з інструментами
- За порожнього результату: чесно поясни, що нічого не знайдено
  за поточних умов, і запропонуй змінити 1–2 параметри.
- За великої кількості варіантів: обери 3–7 найбільш придатних
  і поясни критерії вибору.
- За помилки інструмента: не вигадуй дані, вибачся за збій
  і запропонуй спробувати ще раз або спростити запит.
`.trim();

Тепер модель чітко розуміє:

  • де вона консультант із подарунків, а де «бек‑офіс» (він у нас за інструментами);
  • які саме дані не можна вигадувати;
  • як поводитися в типових неідеальних ситуаціях.

Новий description і схема для recommend_gifts

Системний промпт ми посилили. Тепер наведімо лад в описі інструмента й зберімо фінальну версію на основі ідей із розділу 4.

// config/tools.ts
export const recommendGiftsTool = {
  name: "recommend_gifts",
  description: `
Добір подарунків у каталозі GiftGenius.

Використовуй цей інструмент, коли потрібно:
- отримати список реальних подарунків з актуальними цінами, типом
  (digital/physical) і тегами;
- звузити вибір за сегментами інтересів, бюджетом, локаллю та приводом.

НЕ ВИКОРИСТОВУЙ інструмент:
- якщо користувач ставить загальне теоретичне питання про подарунки
  без запиту на добір для конкретної людини;
- для вигадування подарунків, яких немає в каталозі.

Якщо результат порожній, НЕ вигадуй подарунки самостійно,
а поверни керування в діалог (дотримуйся інструкцій system-prompt).
  `.trim(),
  inputSchema: {
    type: "object",
    properties: {
      segments: {
        type: "array",
        description:
          "Сегменти профілю отримувача: наприклад, 'tech', 'sport', 'books'.",
        items: { type: "string" }
      },
      budget: {
        type: "object",
        description:
          "Діапазон бюджету на подарунок у валюті користувача (min/max).",
        properties: {
          min: { type: "number", minimum: 0 },
          max: { type: "number", exclusiveMinimum: 0 },
          currency: {
            type: "string",
            minLength: 3,
            maxLength: 3,
            description: "Код валюти ISO 4217, наприклад 'USD' або 'UAH'."
          }
        },
        required: ["min", "max", "currency"]
      },
      locale: {
        type: "string",
        description: "Локаль користувача, наприклад 'uk-UA' або 'en-US'."
      },
      occasion: {
        type: "string",
        description:
          "Привід для подарунка: 'birthday', 'anniversary', 'new_year' тощо."
      }
    },
    required: ["segments", "budget", "locale", "occasion"]
  }
};

Тут є кілька нюансів.

По‑перше, ми прямо повʼязуємо поведінку інструмента з system‑prompt. Фраза «дотримуйся інструкцій system‑prompt» нагадує моделі: «порожній результат = чесна розмова, а не креатив».

По‑друге, ми задаємо негативні умови («не використовуй…», «не вигадуй…»). Як показує практика, це не менш важливо, ніж позитивний опис.

По‑третє, ми робимо inputSchema семантично насиченою: нормальні описи й обмеження допомагають моделі правильно зіставляти запити з полями та рідше «помилятися» ще до виклику інструмента.

Патерни follow‑up‑ів у коді віджета та у форматі відповіді

Окрім текстових інструкцій, у нас є ще один важіль — формат відповіді інструмента. Через нього ми теж можемо підказати моделі, що сталося, і звузити поле для фантазії.

Формально follow‑up‑и задаються текстом у system‑prompt. Але у вашому Next.js‑віджеті ви можете додатково нормалізувати ToolOutput, щоб полегшити життя моделі й зменшити простір для домислів.

Наприклад, домовмося, що бекенд для recommend_gifts завжди повертає:

// тип відповіді інструмента на бекенді
export type RecommendGiftsResult = {
  items: Array<{
    id: string;
    title: string;
    price: number;
    currency: "USD" | "EUR" | "UAH";
    tags: ("digital" | "physical" | "education" | "fitness" | "tech")[];
  }>;
  // поле, яке backend заповнює, щоб явно сказати моделі, що сталося
  status: "ok" | "empty" | "error";
  errorMessage?: string;
};

Віджет може відображати це «красиво», а модель — спиратися на status під час формування відповіді. В Apps SDK ви часто повертаєте ToolOutput моделі як JSON‑обʼєкт, і вона бачить це поле.

У system‑prompt можна додати невеликий блок:

# Інтерпретація статусу інструмента

- Якщо status = "empty": дивись розділ "Діалог після роботи з інструментами" і
  не вигадуй подарунки.
- Якщо status = "error": повідом про технічну помилку і не намагайся вгадувати
  вміст каталогу.

Так, модель і без цього могла б здогадатися. Але явна інструкція знижує шанс «вгадувань» на основі припущень.

7. Практика: допрацьовуємо свій App

Щоб не залишалося відчуття «це гарно виглядає на слайдах», зафіксуймо конкретну вправу, яку ви можете виконати зі своїм поточним застосунком (у нашому випадку — GiftGenius). Зробіть невеликий рефакторинг за трьома рівнями захисту: system‑prompt, описи інструментів і обробка результатів.

По‑перше, на рівні system‑prompt візьміть ваш system‑prompt з першої лекції. Знайдіть у ньому місце, де описано зону відповідальності й роботу з інструментами, і додайте туди:

  • заборону вигадувати сутності поза каталогом або базою (подарунки, SKU, ціни);
  • правила на випадок порожнього результату та помилки інструмента;
  • розділ «Діалог після роботи з інструментами» з 2–3 сценаріями (порожньо, багато, помилка).

По‑друге, на рівні описів tools відкрийте опис ключового інструмента (у вас це може бути recommend_gifts, search_gifts, search_tariffs, calculate_quote — неважливо). Перепишіть description так, щоб він:

  • прямо вказував, що інструмент працює лише з вашим джерелом даних (каталог подарунків, тарифів тощо);
  • пояснював, коли він потрібен, а коли — ні;
  • містив явні негативні обмеження: «не вигадуй…», «не використовуй для…».

По‑третє, на рівні структури відповіді інструмента: якщо у відповіді ще немає поля, яке явно описує статус (status, resultType, hasMore), додайте його в тип на бекенді та в ToolOutput. Після цього в system‑prompt пропишіть, як модель має інтерпретувати цей статус у діалозі.

Насамкінець проганяйте кілька запитів у Dev Mode — зокрема такі, де результати наперед порожні або «граничні». Подивіться, чи перестала модель вигадувати сутності й наскільки чесно вона пояснює користувачу обмеження.

У наступній лекції ви формалізуєте такі запити в так званий golden prompt set і перетворите це на відтворюваний тестовий артефакт. А поки для нас важливо, щоб ви власноруч відчули різницю.

8. Типові помилки під час боротьби з галюцинаціями через промпти та інструменти

Помилка №1: одна «чарівна фраза» «не галюцинуй» у system‑prompt.
Розробник пише наприкінці промпта: «Не вигадуй інформацію» — і вважає завдання розвʼязаним. На практиці модель продовжує вигадувати, бо описи інструментів і follow‑up‑и не дають їй альтернативної поведінки. Без конкретних правил «що робити замість вигадування» (визнати порожній результат, запропонувати змінити фільтри, повідомити про помилку) така фраза майже не допомагає.

Помилка №2: суперечність між system‑prompt і description інструмента.
У system‑prompt ви кажете: «Не вигадуй подарунки, яких немає в каталозі», а в описі інструмента — «Підбирає відповідні подарунки, а якщо не знайшов — може запропонувати схожі варіанти на свій розсуд». У підсумку модель метається між двома джерелами правди, і перемагає (на жаль) конкретніше — зазвичай description інструмента. Потрібно, щоб обидва шари говорили одне й те саме. Якщо «схожі варіанти» допустимі, це теж варто формалізувати — і обовʼязково пояснювати користувачу, що це не точний збіг.

Помилка №3: надто розпливчасті описи інструментів.
Опис на кшталт «Інструмент, який допомагає користувачу розвʼязувати завдання» майже нічого не говорить моделі про межі інструмента. У такому разі вона або взагалі не використовуватиме його, або викликатиме з будь‑якого приводу. А потім «домислюватиме» дані, коли інструмент повернув мало або нічого. Хороший description має бути дискримінативним: прямо говорити, що робить інструмент і коли його не треба викликати.

Помилка №4: відсутність стратегії для порожніх і помилкових результатів.
Розробник дбайливо пише бекенд, який повертає { items: [], status: "empty" }, але ніде не пояснює моделі, що це означає. У результаті модель бачить порожній масив і вирішує: «мабуть, треба запропонувати щось із загальних знань». У system‑prompt бракує розділу, який пояснює, як інтерпретувати такі статуси і що говорити користувачу. Водночас кілька чітких правил для порожнього або помилкового результату дають дуже помітний приріст якості.

Помилка №5: спроба «лікувати» галюцинації лише на рівні коду віджета.
Іноді хочеться перекласти все на фронтенд: «якщо список порожній — покажу заглушку й не дам користувачу побачити текстову відповідь моделі». Це може трохи помʼякшити UX, але сама модель при цьому й далі «вірить» у вигадані сутності та так само поводиться в наступних репліках. Правильний підхід — спершу змінювати інструкції (system‑prompt, описи інструментів, follow‑up‑и), а вже потім доповнювати це захистами в UI.

Помилка №6: ігнорування впливу метаданих і схем на поведінку моделі.
Дехто сприймає JSON Schema та описи полів як «суто для форми й валідації». Насправді для ChatGPT це важлива частина промпта: за цими описами модель розуміє, які параметри потрібно витягнути із запиту і як виглядає коректна відповідь. Слабкі або неузгоджені описи полів (description, enum) підвищують шанс помилок і опосередковано провокують галюцинації.

Помилка №7: надто жорсткі заборони без альтернатив.
Буває, що промпт перетворюється на суцільний список «не роби того, не роби цього», але ніде не сказано, що робити у складних випадках. Наприклад, ми заборонили вигадувати подарунки й обмежилися лише каталогом, але нічого не сказали про теоретичні питання. У результаті модель інколи відповідає «я не знаю», хоча могла б корисно пояснити загальні принципи вибору подарунків. Намагайтеся не лише забороняти, а й відкривати дозволені шляхи: «якщо не можеш знайти подарунок у каталозі — чесно скажи про це і запропонуй, як можна змінити запит» або «якщо запит теоретичний — відповідай сам, без інструментів».

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ