TGViewer
DeepSchool / underthehood DeepSchool / underthehood @deepschool_underthehood · 1.13K subscribers
Post #540 586
Агенту нельзя просто дать backend API и ждать магии

Делали простой сценарий:
— есть LLM-агент
— есть API сервиса поиска круизов
— есть клиент, который пишет: “хочу круиз из Казани в июле на 5 дней”

Задача агента — вызвать поиск и вернуть подходящие варианты.

Казалось бы, всё просто: берем метод API, заворачиваем в MCP tool, описываем параметры и даем агенту.

Формально работает. Но на практике быстро выяснилось, что tool получился не “LLM-friendly”, а “backend-friendly”.

То есть удобный для кода, но хрупкий для модели.

И в какой-то момент стало понятно: проблема не в агенте, а в интерфейсе, который мы ему дали.

Антипаттерн 1 — цепочка вызовов вместо одного

Проблема: инструмент поиска принимал не человеческие сущности, а внутренние id: города, теплоходы, направления, стоянки.

Поэтому агенту приходилось сначала вызывать tool-маппинг “название → id”, а потом уже search_cruises.

Что ломалось:
— модель забывала вызвать маппинг
— вызывала его не для всех сущностей
— путала полученные id между параметрами: cityStart, cityEnd, cities

Короткий вывод: если пользователь говорит названиями, а инструмент требует id, мы заставляем LLM быть не ассистентом, а glue-code между UI и базой данных.

Фикс: принимать в LLM-facing tool названия:
— город отправления: Москва
— теплоход: Беда
— направление: Волга

А id-резолвинг делать внутри инструмента.

Антипаттерн 2 — непопулярные типы аргументов

Проблема: некоторые параметры API были типизированы странно. Например, одиночное значение передавалось как массив: не durationFrom = 7, а durationFrom = [7].

Что ломалось:
— модель передавала скаляр вместо массива
— массив не там
— не тот shape
— параметр вообще пропускался

Короткий вывод: LLM лучше работает с boring-типами: string, number, boolean, простые объекты вроде min/max.

Необычная форма данных — это не нейтральная backend-деталь, а дополнительная когнитивная нагрузка.

Фикс:

Было:
— durationFrom: [7]
— durationTo: [10]

Стало:
— duration_days_min: 7
— duration_days_max: 10

Или один понятный объект: duration_days: от 7 до 10

Антипаттерн 3 — плохие имена параметров

Проблема: параметры назывались как поля backend API, а не как понятия из пользовательского запроса: cities, dateTo, costFrom, category_id, motorships.

Что ломалось: модель путала семантику.

Например, cities может значить город отправления, город прибытия, стоянки, города маршрута или просто направление.

dateTo тоже неочевиден: это дата отправления “до” или дата прибытия “до”?

Короткий вывод: имя параметра — это часть prompt’а.

Если имя требует знания внутренней модели данных, LLM начинает угадывать.

Фикс:
Было: cities, dateTo, costFrom
Стало: must_visit_cities_or_landmarks, departure_before, price_min_rub

Да, имена становятся длиннее. Но для LLM это плюс: название параметра одновременно работает как мини-инструкция.

Главный вывод

Хороший tool для агента — это не thin wrapper над backend API.

Backend API проектируется под код: id, внутренние типы, короткие поля, цепочки методов.

LLM-facing tool лучше проектировать под модель и пользовательскую задачу:
— одно пользовательское действие = один tool
— человеческие названия вместо внутренних id
— простые boring-типы вместо legacy-форматов
— говорящие имена параметров
— минимум промежуточного состояния

Иначе получается странная ситуация: модель вроде умная, MCP вроде подключили, API вроде рабочий — а агент всё равно хрупкий.

Потому что для LLM tool — это не endpoint.

Это UX.
  • 👍 19
  • ❤ 9
  • 🤩 5
  • 🤷‍♂ 4
More from @deepschool_underthehood
  1. May 13, 2026На этом моя неделя заканчивается Пытался показать агентскую разработку не со стороны хайпа…
  2. May 12, 2026Tool call — это просто текст. Его можно модифицировать Когда LLM вызывает инструмент, это…
  3. May 10, 2026Пока писал пост про перегрузку LLM-промпта, понял, что упустил важное ограничение: ответ а…
  4. May 9, 2026ReAct-промпт стал монолитом Это был узел в агенте, который искал круизы и вел пользователя…
  5. May 6, 2026Всем привет! Меня зовут Егор, на этой неделе канал веду я Я эдакий фулстак мл - начинал с…
  6. May 6, 2026Неделя авторства тут пересеклась с организацией хакатона, поэтому не успел написать поболь…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →