1. Інструмент агента: що це таке насправді
У попередніх модулях ви вже бачили інструменти з боку Apps SDK — як «бекенд-функції», до яких ChatGPT звертається через ваш застосунок. Тепер змінимо ракурс: подивімося на інструменти з погляду агента в Agents SDK і розберімося, як він обирає, що викликати, та як поводитися з помилками.
У звичайному бекенді ви звикли мислити категоріями «endpoint», «метод контролера», «функція сервісу». У світі агентів базовою одиницею дії стає інструмент (tool). Водночас tools агента й MCP-tools — різні, хоч і споріднені, речі.
Якщо говорити точно, інструмент у контексті ChatGPT Agents SDK — це опис функції, яку модель може попросити виконати. Сама модель код не запускає: вона генерує структурований запит (зазвичай JSON), а рантайм (ваш код, MCP‑сервер або Agents SDK) уже виконує операцію та повертає результат.
В екосистемі ChatGPT Agents SDK інструмент описують конфігурацією: він має name, description і parameters (JSON Schema аргументів). Агент бачить цей набір інструментів, тримає його у своєму контексті й у процесі міркувань (reasoning) вирішує, який tool викликати та з якими аргументами.
Агент (або ChatGPT як хост) отримує цей список, «запамʼятовує» його у своєму контексті й під час міркувань визначає, який інструмент викликати для конкретного запиту користувача та які аргументи сформувати. Саме тому в специфікаціях постійно повторюють мантру «tools are a contract»: інструменти — це контракт між моделлю й вашим кодом, а не просто «функція в Python/TS».
Можна провести аналогію з класичним API. Маршрут /api/gifts/search — це суто синтаксис: URL, метод, формат тіла. А tool search_gifts — це семантика: «пошук подарунків за профілем і бюджетом». Опис інструмента — це, по суті, такий самий промпт, лише структурований і розрахований на LLM, а не на людину.
2. Типи інструментів: чим саме може займатися LLM‑агент
Щоб не потонути в хаосі «функцій, які вміють усе», корисно дивитися на інструменти як на кілька типових категорій. Це не формальна типізація SDK, а архітектурний підхід, який вам дуже допоможе.
У нашому бекенді LLM‑агенти зазвичай мають три джерела інструментів.
- Локальні бізнес‑інструменти. Це те, що живе у вашому бекенді: робота з БД, доменна логіка (фільтрація, рекомендації, скоринг). Наприклад, для GiftGenius у нас можуть бути інструменти, які дістають товари зі своєї таблиці PostgreSQL або рахують персональний скоринг «наскільки подарунок зайде цій людині».
- MCP‑інструменти. Тут MCP‑сервер виступає постачальником інструментів (tools): він реєструє функції, ресурси й промпти та віддає їх клієнту (ChatGPT, LLM‑агенту). Інструменти через MCP можуть викликати зовнішні API, працювати з файлами або надавати шаблони промптів.
- Інтеграційні інструменти. Це все, що повʼязує вас із рештою світу: ACP/commerce (створення замовлення і checkout), надсилання листів, вебхуки, запис у CRM. Такі інструменти (tools) часто небезпечніші, бо змінюють стан зовнішніх систем. Тож до них потрібно ставитися особливо суворо — з погляду безпеки та ідемпотентності.
Є й інша корисна класифікація — за характером дії. У дослідженнях про LLM‑інструменти зазвичай виокремлюють: інструменти отримання даних (пошук, RAG, get_*), інструменти дій із побічними ефектами (create_order, send_email), суто обчислювальні (calculate_loan) і системні/керувальні (handoff_to_human, finish_task).
Щоб це зафіксувати, зручно подивитися невелику таблицю.
| Категорія | Приклад у GiftGenius | Побічний ефект | Ризик |
|---|---|---|---|
| Data Retrieval | |
Ні | Низький |
| Action / Mutating | |
Так | Високий |
| Computation | |
Ні | Середній |
| System / Control | |
Ні | Логічний |
З архітектурного погляду найважливіше таке: інструментів лише для читання має бути багато — і вони мають бути «дешевими», а ті, що змінюють стан, — рідкісними, максимально обережними, із журналюванням, ідемпотентністю й часто з підтвердженням від користувача.
Далі ми говоритимемо переважно про інструменти отримання даних та Action‑інструменти, тому що саме на них тримається логіка GiftGenius.
3. JSON Schema як контракт між моделлю і вашим кодом
Тепер давайте заглибимося в те, як описують інструмент. У ChatGPT Agents SDK (як і в Apps SDK) стандартний формат опису параметрів інструмента — JSON Schema: ви описуєте тип object, його properties, типи полів, обовʼязкові поля, обмеження тощо.
Важливо розуміти: JSON Schema тут не лише й не стільки про валідацію. Це частина промпта для моделі. В офіційних настановах OpenAI щодо проєктування інструментів (tools) прямо сказано: якість роботи агента дуже залежить від того, наскільки докладно й однозначно описані поля, їхні назви та коментарі.
Подивімося на приклад для GiftGenius, який уже траплявся в планах курсу.
{
"name": "search_gifts",
"description": "Знаходить подарунки за типом отримувача, інтересами та бюджетом.",
"parameters": {
"type": "object",
"properties": {
"recipient_type": {
"type": "string",
"description": "Хто отримувач подарунка (наприклад, 'чоловік', 'жінка', 'дитина')."
},
"interests": {
"type": "array",
"items": { "type": "string" },
"description": "Ключові інтереси (спорт, книги, технології тощо)."
},
"budget": {
"type": "number",
"description": "Максимальний бюджет у валюті користувача."
}
},
"required": ["recipient_type", "budget"]
}
}
Тут є кілька важливих моментів.
- По‑перше, name і description. Для моделі це головний сигнал: чи варто взагалі використовувати цей інструмент. Документація про семантичну маршрутизацію підкреслює, що опис інструмента — це фактично API для моделі. Якщо ви назвете його func1 і підпишете «робить щось корисне», модель просто не зрозуміє, коли його викликати. А якщо написати search_gifts і додати зрозумілий опис, вибір стає значно простішим.
- По‑друге, parameters. Назви полів і їхні описи вкрай важливі. Для LLM recipient_type набагато зрозуміліше, ніж type. Вдалий description на кшталт «Хто отримувач подарунка…» підказує моделі, що сюди потрібно підставити саме тип отримувача, а не, скажімо, формат пакування.
- По‑третє, required. Це не лише валідація на вашому боці, а й підказка моделі: вона намагатиметься заповнити обовʼязкові поля, а необовʼязкові пропустить, якщо з контексту неясно, що туди ставити. Це зменшує кількість «порожніх» або некоректних tool‑викликів.
Офіційні настанови щодо Apps SDK прямо рекомендують: робіть інструменти вузькими, з однією відповідальністю, з чіткими іменами та описами й уникайте інструментів «зроби все для подарунків», які намагаються обʼєднати різні завдання.
4. Проєктуємо інструменти GiftGenius: від схеми до коду
Візьмімо наш GiftGenius і додамо туди два ключові інструменти LLM‑агента, які знадобляться майже в усіх сценаріях:
- suggest_gifts(profile, budget) — видає список кандидатів;
- get_gift_details(gift_id) — показує подробиці про конкретний подарунок.
Наші suggest_gifts і get_gift_details — типовий приклад локальних бізнес‑інструментів із попередньої класифікації, здебільшого з категорії Data Retrieval.
Схема для suggest_gifts
Почнемо з чистого JSON Schema, а потім покажемо, як це може виглядати в TypeScript‑коді бекенду або агентного рантайму.
{
"name": "suggest_gifts",
"description": "Підбирає список подарунків на основі профілю отримувача та бюджету.",
"parameters": {
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 0,
"maximum": 120,
"description": "Вік отримувача у роках."
},
"relationship": {
"type": "string",
"enum": ["friend", "coworker", "partner", "family"],
"description": "Стосунки з отримувачем: друг, колега, партнер, сімʼя."
},
"interests": {
"type": "array",
"items": { "type": "string" },
"description": "Інтереси отримувача (спорт, книги, технології тощо)."
},
"budget": {
"type": "number",
"minimum": 1,
"description": "Максимальний бюджет у валюті користувача."
}
},
"required": ["budget"]
}
}
Тут ми використовуємо enum для relationship, щоб модель не вигадувала довільні рядки на кшталт "поганий колега" і не передавала їх далі в код. Такий охайний дизайн схеми допомагає і моделі (вона бачить допустимі варіанти), і розробнику (менше несподіванок у рантаймі).
Тепер уявімо, що в нас є MCP‑сервер на Node.js з якимось умовним McpServer. Реєстрація інструмента може виглядати так:
// Спрощений приклад реєстрації інструмента в MCP‑сервері
server.registerTool(
{
name: "suggest_gifts",
description: "Підбирає подарунки за профілем і бюджетом.",
inputSchema: suggestGiftsSchema
},
async (input, ctx) => {
const gifts = await findGiftsInDb(input, ctx.userLocale);
return { items: gifts }; // JSON, який потім побачить агент
}
);
Код дуже спрощено, але логіка зрозуміла: в одному місці — опис контракту (імʼя, опис, схема), в іншому — реалізація.
Схема для get_gift_details
Другий інструмент, який потрібен майже на будь‑якій вітрині:
{
"name": "get_gift_details",
"description": "Отримує повні відомості про подарунок за його ідентифікатором.",
"parameters": {
"type": "object",
"properties": {
"gift_id": {
"type": "string",
"description": "UUID подарунка в базі GiftGenius."
}
},
"required": ["gift_id"]
}
}
І аналогічна реєстрація:
server.registerTool(
{
name: "get_gift_details",
description: "Повертає детальну інформацію про подарунок.",
inputSchema: getGiftDetailsSchema
},
async ({ gift_id }) => {
const gift = await db.gifts.findById(gift_id);
if (!gift) return { notFound: true };
return { gift };
}
);
Зверніть увагу: ми тут одразу показуємо, що інструмент може повернути notFound: true. Це перші кроки до семантичних помилок (бізнес‑помилок), про які поговоримо нижче. Агент побачить «подарунок не знайдено» й ухвалить рішення: наприклад, спробує інший ID або запропонує користувачу вибрати інший товар.
5. Як агент обирає, який інструмент викликати
Тепер найцікавіше: маршрутизація. У традиційному веб‑застосунку роутинг жорсткий: URL → конкретний контролер. У світі ChatGPT Apps і агентів вибір інструмента відбувається семантично та ймовірнісно.
Високорівневий цикл можна зобразити так:
flowchart TD
U[User message] --> M["Модель (агент)"]
M -->|аналіз запиту| C{Потрібен tool?}
C -->|ні| T[Текстова відповідь]
C -->|так| S[Вибір інструмента]
S --> K[Формування аргументів JSON]
K --> R[Виконання інструмента]
R --> M2[Модель бачить результат]
M2 --> T2[Фінальна відповідь або наступний крок]
На кожному кроці агент бачить кілька речей:
- По‑перше, system‑інструкції (роль агента, обмеження);
- По‑друге, історію діалогу;
- І нарешті, список інструментів (tools) з їхніми name, description, inputSchema.
Коли надходить чергове повідомлення користувача, модель порівнює зміст запиту з описами інструментів (семантичне зіставлення). Якщо запит «підібрати подарунок другу до 50 доларів», опис suggest_gifts звучить значно релевантніше, ніж get_gift_details, і агент із високою ймовірністю обере саме його.
Офіційні настанови підкреслюють дві речі, які сильно впливають на якість маршрутизації.
- По‑перше, потрібно уникати інструментів, що перетинаються за змістом: якщо у вас є search_gifts і find_gifts, описані приблизно однаково, модель плутатиметься.
- По‑друге, варто дотримуватися принципу єдиної відповідальності для інструмента: один tool — одне чітке завдання, а не «підібрати подарунки, створити замовлення та надіслати лист».
Усередині різних LLM‑агентів є механізми керування режимом вибору інструментів: наприклад, «auto» (модель сама вирішує, чи потрібен інструмент), «required» (інструмент потрібно викликати обовʼязково), «none» (tools вимкнено). Це допомагає в складних workflow (багатокрокових сценаріях), коли, скажімо, на певному кроці ви хочете примусово викликати suggest_gifts, а не дозволяти моделі просто «розмовляти».
Приклад семантичної маршрутизації в GiftGenius
Нехай у нашого агента є щонайменше два інструменти: suggest_gifts і get_gift_details.
- Користувач пише: «Підбери подарунок колезі до 30 доларів, він любить настільні ігри».
- Агент бачить, що запит містить мету «підібрати подарунок» і дані про бюджет та інтереси. Опис suggest_gifts підходить ідеально — викликаємо цей інструмент.
- Інструмент повертає список із пʼяти подарунків з їхніми ID, назвами та коротким описом.
- Користувач далі пише: «Розкажи докладніше про третій варіант». Агент зіставляє «третій варіант» з ID із попереднього результату — і тепер за змістом підходить інструмент get_gift_details. Тож викликаємо його.
Важливо помітити: ніде в коді ви явно не писали «якщо в запиті є слово „підбери“, то виклич suggest_gifts». Цим займається сама модель — на основі ваших описів та історії діалогу. Ваша відповідальність як розробника — зробити так, щоб вибір був очевидним і для моделі, і для людини.
6. Помилки інструментів: не 500, а сигнал для моделі
Памʼятаєте, у get_gift_details ми вже показували notFound: true? Це якраз приклад бізнес‑помилки, яку агент має побачити й осмислено обробити, а не отримувати «голий» 500.
Тепер перейдемо до найболючішого. У звичайному REST‑API щось упало в глибинах бекенду — повернули 500 Internal Server Error, записали стек-трейс у журнал — і далі користувач уже якось упорається. У випадку агента такий підхід працює погано.
Практичні настанови та матеріали про Agents SDK рекомендують ставитися до помилок інструментів як до спостережуваних подій, а не просто до падінь. Це часто називають патерном «Error as Observation».
Грубо кажучи, вам не варто «падати» без пояснення. Натомість краще повертати моделі структуровану відповідь, яка пояснює, що пішло не так, — щоб вона могла адаптувати поведінку: переформулювати запит, перепитати користувача, спробувати інший інструмент тощо.
Типи помилок зазвичай ділять на три групи.
- Помилки валідації аргументів. Модель може згенерувати некоректні параметри: пропустити обовʼязкове поле, підставити рядок замість числа, вийти за межі допустимих значень. Тут схему й валідацію потрібно використовувати не лише для того, щоб кидати винятки, а й для осмисленої відповіді: наприклад, повернути, яке поле некоректне й чому.
- Бізнес‑помилки. Це цілком очікувані ситуації на кшталт «товар не знайдено», «регіон недоступний», «бюджет надто малий для цього типу подарунків». З погляду API це теж помилки, але їх потрібно повертати в межах звичайної відповіді — зі зрозумілим кодом і повідомленням, а не як креш.
- Системні помилки. Тайм-аути зовнішнього сервісу, проблеми мережі, збої бази. Тут агенту зазвичай достатньо акуратного, узагальненого повідомлення на кшталт «служба тимчасово недоступна, спробуйте пізніше». Жодних стек-трейсів, назв таблиць та інших подробиць, які моделі не потрібні й можуть бути небезпечними з погляду безпеки.
Офіційні матеріали про Agents SDK навіть пропонують спеціальний механізм failure_error_function, який дає змогу акуратно сформувати текст помилки, що його побачить модель, замість того щоб просто кидати виняток угору стеком.
Структура «дружньої» помилки
В інструменті агента (у вашому бекенді) ви можете домовитися, що будь‑яка помилка повертається, наприклад, у вигляді обʼєкта:
type ToolError = {
code: string; // 'VALIDATION_ERROR', 'OUT_OF_STOCK', ...
message: string; // для моделі
retryable: boolean;
};
А результат роботи інструмента — як обʼєднання:
type SuggestGiftsResult =
| {
ok: true;
items: GiftSummary[];
}
| {
ok: false;
error: ToolError;
};
Модель (або агентний рантайм) побачить такий JSON і зможе вирішити: якщо retryable: true, можна спробувати ще раз із невеликими змінами; якщо помилка бізнес‑рівня й вона неповторювана, краще повернутися до користувача та пояснити, що саме не так.
7. Приклади: валідація, бізнес‑помилка і системна помилка
Повернімося до нашого бекенду та інструментів агента й подивімося, як реалізувати ті самі ідеї в коді.
Помилка валідації
Уявімо, що до вас надійшов виклик інструмента suggest_gifts, але модель чомусь вирішила передати відʼємний бюджет.
async function handleSuggestGifts(input: SuggestGiftsInput)
: Promise<SuggestGiftsResult> {
if (input.budget <= 0) {
return {
ok: false,
error: {
code: "VALIDATION_ERROR",
message: "budget має бути додатним числом.",
retryable: false
}
};
}
const items = await findGiftsInDb(input);
return { ok: true, items };
}
Тут ми свідомо не кидаємо виняток, а повертаємо структуровану помилку. Агент може переосмислити запит: можливо, він вирішить, що переплутав валюту, і перепитає користувача. Або просто визнає, що не може підібрати подарунок із таким бюджетом.
Бізнес‑помилка
Тепер приклад із get_gift_details. Подарунка з указаним ID може просто не бути.
async function handleGetGiftDetails(input: { gift_id: string }) {
const gift = await db.gifts.findById(input.gift_id);
if (!gift) {
return {
ok: false,
error: {
code: "GIFT_NOT_FOUND",
message: "Подарунок із таким ідентифікатором не знайдено.",
retryable: false
}
};
}
return { ok: true, gift };
}
У відповіді моделі можна очікувати щось на кшталт: «Здається, обраний подарунок більше недоступний. Можу запропонувати кілька альтернатив із подібної категорії?». Для цього агенту не потрібно бачити SQL‑помилки та стек-трейси — лише зрозумілі code і message.
Системна помилка
Нарешті, приклад системної помилки. Нехай ваш інструмент звертається до зовнішнього API доставки, який інколи «падає».
async function handleEstimateDelivery(input: EstimateDeliveryInput) {
try {
const eta = await callDeliveryApi(input);
return { ok: true, eta_days: eta };
} catch (e) {
return {
ok: false,
error: {
code: "DELIVERY_SERVICE_UNAVAILABLE",
message: "Служба доставки тимчасово недоступна.",
retryable: true
}
};
}
}
Агент може вирішити: «Схоже, служба доставки зараз недоступна. Я все одно покажу вам подарунки, але точний час доставки може відрізнятися. Хочете продовжити?».
8. Безпека та ідемпотентність інструментів (швидкий погляд з боку tools)
Повноцінна розмова про безпеку й дозволи буде в окремій темі, але інструменти агента надто тісно з цим повʼязані, щоб зовсім не торкнутися цього питання.
По‑перше, потрібно розділяти інструменти читання та інструменти запису. В описах, схемах і дозволах явно зазначайте, які tools лише читають дані й абсолютно безпечні, а які вміють списувати гроші, змінювати замовлення тощо. Документація і форуми про агентні сценарії прямо говорять про розділення ReadOnly і Mutating‑інструментів (tools).
По‑друге, для мутуючих інструментів потрібно думати про ідемпотентність. Агент або MCP‑клієнт цілком може повторити виклик (наприклад, через мережеву помилку), і ви не хочете, щоб create_order створив два замовлення замість одного. Типові підходи тут такі:
- idempotency‑key, який передається як аргумент інструмента;
- перевірка існування операції перед виконанням;
- розділення кроків на «створи чернетку замовлення» і «підтвердь замовлення».
Усе це дуже тісно повʼязано з тим, як саме ви проєктуєте контракт інструмента: якщо в JSON Schema немає поля для idempotency‑key, додати ідемпотентність потім буде значно болючіше.
9. Невеликий погляд на Agents SDK: як це виглядає в агентному рантаймі
Цей розділ — короткий огляд для тих, хто працюватиме з TypeScript‑орієнтованим Agents SDK. Хоч основна частина курсу в нас про MCP, корисно розуміти, як подібні інструменти бачить Agents SDK і як виглядає типовий tool у рантаймі.
В офіційній документації зазвичай описують сутність на кшталт «функціонального інструмента»: будь‑яка функція, описана через конфігураційний обʼєкт (або helper на кшталт tool(...)) і забезпечена типами, може бути автоматично перетворена на інструмент, для якого SDK згенерує JSON Schema та опис.
На рівні концепції це те саме, що ми вже обговорювали: імʼя функції, її параметри і коментар/description відіграють роль імені, схеми й опису інструмента. Різниця в тому, що більшу частину «механічної» роботи за вас робить SDK та/або допоміжна бібліотека для схем (наприклад, Zod або JSON Schema).
Умовний приклад (псевдо‑TypeScript, спрощено):
type Gift = {
id: string;
title: string;
// ...
};
const suggestGifts = tool({
name: "suggest_gifts",
description: "Підбирає список подарунків за типом отримувача і бюджетом.",
parameters: {
type: "object",
properties: {
recipient_type: {
type: "string",
description: "Хто отримувач подарунка (наприклад, 'чоловік', 'жінка', 'дитина')."
},
budget: {
type: "number",
description: "Максимальний бюджет у валюті користувача."
}
},
required: ["recipient_type", "budget"]
}
}, async (args: { recipient_type: string; budget: number }): Promise<Gift[]> => {
// Усередині — ваша доменна логіка
return findGifts(args.recipient_type, args.budget);
});
SDK (або ваш helper tool) на основі обʼєкта parameters побудує JSON Schema і передасть його агенту, а рантайм подбає про валідацію та маршалінг аргументів туди й назад. Концептуально це рівно те, що ви вручну робили в MCP‑сервері на TypeScript, тільки тепер інструмент «підʼєднано» прямо в агентний рантайм.
Важливо тут не завчити конкретний синтаксис хелпера tool, а вловити думку: якісна типізація + зрозумілий description/коментарі = якісний інструмент.
Якщо все це підсумувати: хороший інструмент агента — це вузька, чітко описана функція з продуманою JSON Schema, зрозумілим описом для моделі й акуратним опрацюванням помилок. Семантична маршрутизація працюватиме лише тоді, коли інструменти не перетинаються за змістом. А мутуючі операції мають бути безпечні та ідемпотентні — інакше агент у продакшн‑середовищі швидко перетвориться на джерело сюрпризів.
10. Типові помилки під час проєктування інструментів агента
Помилка № 1: Занадто широкі інструменти «do_everything».
Інколи дуже хочеться запхнути все в один інструмент manage_gifts, який і шукає подарунки, і показує деталі, і створює замовлення, і надсилає лист. Після цього моделі складно: опис стає розмитим, семантична маршрутизація деградує, і агент починає викликати цей інструмент «про всяк випадок» навіть там, де потрібен простий пошук. Краще розбивати задачі на окремі інструменти з однією, добре зрозумілою відповідальністю.
Помилка № 2: Інструменти, що перекриваються за змістом.
Якщо у вас є search_gifts і find_gifts, і обидва «шукають подарунки за інтересами», модель випадково обиратиме між ними. У результаті поведінка стає нестабільною: однакові запити іноді йдуть в один tool, іноді — в інший. Намагайтеся, щоб кожне імʼя й опис займали унікальну «нішу» у смисловому просторі.
Помилка № 3: Погані або відсутні описи й поля схеми.
Імʼя func1, опис «Does something» і параметр data: string — класичний спосіб зробити агента «нетямущим». Модель не телепат і не може прочитати ваш вихідний код. Вона спирається на description, properties і їхній description у схемі. Якщо ви не поясните, що таке recipient_type, модель гадатиме й помилятиметься.
Помилка № 4: Орієнтація лише на happy‑path та ігнорування помилок.
Багато реалізацій інструментів припускають: «Ну в нас же завжди будуть коректні аргументи й доступний сервіс». У реальному світі модель легко генерує неправильні параметри, зовнішні сервіси падають, а база інколи каже «timeout». Якщо не продумати формат помилок і не повернути агенту осмислене повідомлення, він не зможе скоригувати поведінку й або мовчки падатиме, або галюцинуватиме.
Помилка № 5: Передавати в LLM «сирий» 500 і стек-трейс.
У REST‑API ми звикли зберігати повний стек-трейс у журналі, щоб швидше налагоджуватися. У контексті агента стек-трейс, переданий моделі, — це водночас і марно (модель не знає, що таке SQLException у вашій конкретній бібліотеці), і потенційно небезпечно (зайві деталі реалізації і, можливо, конфіденційна інформація). Куди корисніше перехопити виняток, записати деталі в журнал, а в модель відправити акуратні code і message.
Помилка № 6: Відсутність ідемпотентності в мутуючих інструментах.
Інструмент create_order без idempotency‑key — це пряме запрошення до подвійних замовлень, особливо в умовах мережевих збоїв та автоматичних ретраїв. Якщо ваш агент працює в комерційному сценарії, інструменти, повʼязані з грошима, мають бути спроєктовані так, щоб повторні виклики не призводили до додаткових списань або дублів.
Помилка № 7: Зберігати секрети й технічні деталі в схемі або описі.
Іноді розробник за звичкою пише в description: «Усередині викликає сервіс X на https://internal-api.example.com». Моделі ця інформація не потрібна, користувачу — тим більше. Схеми й описи — частина промпта, вони живуть у контексті моделі. Тож туди не варто класти URL‑адреси внутрішніх сервісів, назви приватних таблиць і тим паче секрети.
Помилка № 8: Передавати в інструменти все підряд замість продуманого набору полів.
Легко піддатися ідеї «просто передамо всередину весь промпт користувача рядком, а там розберемося». Так ви втрачаєте користь структурування через JSON Schema: модель уже не розуміє, які саме частини запиту важливі для логіки, ви позбуваєтеся валідації та передбачуваності. Краще витягти із запиту явні поля (budget, interests, user_location) і описати їх як частину контракту інструмента.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ