Авторская колонка

Узкий ИИ-агент против универсального комбайна: как мы срезали задержку ответа с 17 до 7,7 секунды

Замена универсального профиля инструментов на узкий специализированный плагин в сочетании с отключением проб окружения и лишнего шага рассуждений сжала системный префикс с 15 266 до 1 424 токенов (в 10,7 раза) и ускорила ответ с 17 до 7,7 секунды. Все вычисления, где языковая модель склонна ошибаться или поддаваться на уговоры пользователя — серии дней обучения, начисление опыта, рубрикатор оценок и легальность шахматных ходов, — выносятся в детерминированный Python-плагин поверх SQLite. Стабильность пользовательского прогресса требует явной нормализации идентификатора сессии, иначе ротация служебного ключа при перезапуске шлюза молча обнуляет историю ученика.

Узкий ИИ-агент против универсального комбайна: как мы срезали задержку ответа с 17 до 7,7 секунды
Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
Главный редактор
Снижение задержки ответамедиана сократилась с ~17 с (13,3–20,6 с) до 7,7 с (7,25–7,93 с)
Сжатие входного префиксас 15 266 до 1 424 токенов на запрос (экономия в 10,7 раза без изменения бизнес-логики)
Объём детерминированного ядра766 строк Python-плагина геймификации поверх SQLite и 342 строки верификатора нотации
Практический потолок файла личностиоколо 20 000 байт для `SOUL.md` без потери внимания модели к середине инструкции
  • Снижение задержки ответа: медиана сократилась с ~17 с (13,3–20,6 с) до 7,7 с (7,25–7,93 с)
  • Сжатие входного префикса: с 15 266 до 1 424 токенов на запрос (экономия в 10,7 раза без изменения бизнес-логики)
  • Объём детерминированного ядра: 766 строк Python-плагина геймификации поверх SQLite и 342 строки верификатора нотации
  • Практический потолок файла личности: около 20 000 байт для `SOUL.md` без потери внимания модели к середине инструкции

Первый соблазн при сборке ИИ-агента — дать ему доступ ко всему сразу: терминалу, браузеру, поиску по вебу, файлам и MCP-серверам. Отрезвление пришло на детском шахматном тренажёре, поднятом через локальный эндпоинт `/v1/chat/completions`. Ребёнок двигал фигуру на доске, а комментарий тренера прилетал через 17 секунд — когда юный игрок уже сделал ещё два хода.

Разбор показал, что из 15 266 токенов входного префикса почти 14 000 занимали JSON-схемы инструментов, которые в шахматной партии не вызывались ни разу, плюс автосбор сведений об ОС на старте. Более того, агент с доступом к `execute_code` при малейшем затруднении начинал писать и запускать скрипты в песочнице, превращая один ход в двадцать вызовов API.

Как три строки в конфиге сжимают промпт в 10,7 раза и убирают латентность?

Чтобы превратить задумчивого универсала в быстрый сервис, не пришлось переписывать код плагина. Мы зажали три параметра в конфигурации рантайма:

1. Оставили платформе `api_server` только один доменный набор инструментов (`[chess]`), убрав файловые и шелл-тулсеты. 2. Выключили `environment_probe`, который на каждом старте опрашивал хост и складывал слепок среды в системный промпт. 3. Поставили `reasoning_effort: none` — поскольку тактические факты уже вычислены движком Stockfish, модели не нужно строить цепочку рассуждений перед ответом, её задача — живо озвучить готовый вердикт.

На контрольных замерах с прогретым кэшем время ответа сдвинулось с `13,3 / 17,3 / 20,6 с` до `7,25 / 7,74 / 7,93 с` (медиана 7,7 с), а расход входных токенов упал в 10,7 раза — с 15 266 до 1 424. Урезание тулсета экономит токены и защищает контур от самодеятельности в терминале, а отключение лишнего reasoning-шага даёт основной выигрыш по секундам. Важная деталь: профили инструментов для мессенджера и для планировщика (`cron`) задаются раздельно — если забыть прописать плагин в секцию `cron`, утренняя рассылка молча полезет искать данные через чтение файлов.

Как разделить личность на два слоя и вынести расчёт стрейков в SQLite?

Личность узкого агента проектируется в два яруса: короткий триггерный блок в `config.yaml` (10–15 строк) задаёт диспетчеризацию (`tutor_state` в начале диалога, `tutor_record_lesson` после упражнения), а регламент тона и педагогики живёт в `SOUL.md`. Рабочий потолок этого файла — около 20 000 байт (у моих ботов 6,7–19,9 КБ): если раздуть сильнее, модель теряет правила из середины.

Языковая модель прекрасно отыгрывает эмоции, но плохо считает даты, очки опыта и оценки по рубрикам. В языковом тьюторе вся математика геймификации (10 уровней от 0 до 8000 XP, рубежи стрейков от 3 до 365 дней, 15 бейджей и кристаллы) вынесена в Python-плагин на 766 строк поверх SQLite:

```python if last_date == today: streak = max(1, prev_streak) elif last_date == yesterday or not last_date: streak = (prev_streak + 1) if last_date == yesterday else 1 else: gap_days = (parse_date(today) - parse_date(last_date)).days if freezes > 0 and gap_days == 2: freezes -= 1 streak = prev_streak + 1 events.append({"type": "freeze_used", "msg": "Заморозка спасла серию дней!"}) else: if prev_streak > 1: events.append({"type": "streak_reset", "old": prev_streak}) streak = 1 ```

Инструмент возвращает массив `events`, а в поле `description` самой JSON-схемы функции зашита директива: эмоционально поздравить ученика с каждым событием из `events` и ничего не придумывать про баланс от себя. Аналогично в тренажёре закупочных переговоров рубрикатор из 4 модулей по 40-балльной шкале проверяет стем-маркеры (риски, сверка фактов, торг) кодом, чтобы участник не мог «уговорить» нейросеть повысить оценку.

Почему прогресс молча обнулялся после рестарта и как лечить фреймворк?

В первых сборках движок передавал в обработчик инструмента параметр `task_id`, равный ID текущей сессии, и я использовал его как первичный ключ ученика. При нажатии `/new` или рестарте контейнера генерировался новый `task_id`, и человек видел чистый лист вместо 30 дней учёбы. Проблему решил двухуровневый резолвер ключа, который регуляркой вытаскивает постоянный ID аккаунта из `telegram:dm:<user_id>` или сверяется с `sessions.json`, гарантируя стабильный ключ `tg:<id>`.

Чтобы не пересобирать гигабайтный образ ради каждой библиотеки, деплой ставит пакеты через `pip install --target` в том `data/pylibs`, выставляет `chown -R` под не-рутового пользователя и чистит `__pycache__`. А там, где базовому транспорту не хватало нижней клавиатуры или он глотал `/start`, самолечащиеся патчи из `bootstrap.sh` на старте проверяют якоря в коде адаптера, вшивают блок и верифицируют файл через `py_compile`.

Паттерн «детерминированный плагин считает — узкая модель отыгрывает» встроен в основу [Nomad AI](https://nomadnet.ai) и облачной среды [agent.nomadnet.ai](https://agent.nomadnet.ai). Лабы по сборке таких агентов доступны в [Hamidun Academy](https://academy.hamidun.com) (72 часа триала бесплатно), а готовые плагины и 370+ навыков мы разбираем в [Vibe Club](https://hamidun.com/club).

Сюжет

Вопросы и ответы по материалу

Как три строки в конфиге сжимают промпт в 10,7 раза и убирают латентность?

Чтобы превратить задумчивого универсала в быстрый сервис, не пришлось переписывать код плагина. Мы зажали три параметра в конфигурации рантайма: 1. Оставили платформе `api_server` только один доменный набор инструментов (`[chess]`), убрав файловые и шелл-тулсеты. 2. Выключили `environment_probe`, который на каждом старте опрашивал хост и складывал слепок среды в системный промпт. 3. Поставили `reasoning_effort: none` — поскольку тактические факты уже вычислены движком Stockfish, модели не нужно строить цепочку рассуждений перед ответом, её задача — живо озвучить готовый вер

Как разделить личность на два слоя и вынести расчёт стрейков в SQLite?

Личность узкого агента проектируется в два яруса: короткий триггерный блок в `config.yaml` (10–15 строк) задаёт диспетчеризацию (`tutor_state` в начале диалога, `tutor_record_lesson` после упражнения), а регламент тона и педагогики живёт в `SOUL.md`. Рабочий потолок этого файла — около 20 000 байт (у моих ботов 6,7–19,9 КБ): если раздуть сильнее, модель теряет правила из середины. Языковая модель прекрасно отыгрывает эмоции, но плохо считает даты, очки опыта и оценки по рубрикам. В языковом тьюторе вся математика геймификации (10 уровней от 0 до 8000 XP, рубежи стрейков от

Почему прогресс молча обнулялся после рестарта и как лечить фреймворк?

В первых сборках движок передавал в обработчик инструмента параметр `task_id`, равный ID текущей сессии, и я использовал его как первичный ключ ученика. При нажатии `/new` или рестарте контейнера генерировался новый `task_id`, и человек видел чистый лист вместо 30 дней учёбы. Проблему решил двухуровневый резолвер ключа, который регуляркой вытаскивает постоянный ID аккаунта из `telegram:dm:<user_id>` или сверяется с `sessions.json`, гарантируя стабильный ключ `tg:<id>`. Чтобы не пересобирать гигабайтный образ ради каждой библиотеки, деплой ставит пакеты через `pip install --

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ ИИ-агенты на практике · Академия & Nomad

От чтения про ИИ-агентов — к запуску своего агента за вечер

Пошаговая сборка автономных агентов и MCP-связок в Hamidun Academy (academy.hamidun.com) (72 часа бесплатно) или мгновенный запуск готовых мультишаговых агентов в облаке Nomad.

Попробовать Академию (72ч бесплатно) →Запустить Nomad Agent
Что вы думаете?
Загружаем комментарии…