ИИ-агент, который не боится сказать «не знаю»

ИИ-агент, который не боится сказать «не знаю»

Сначала агент был слишком уверенным

Пятница, конец дня. В почте у логиста висит письмо: «Перенесите, пожалуйста, отгрузку, как договаривались». Кто договаривался, какая именно отгрузка — непонятно. Опытный человек позвонит и уточнит. Новичок может угадать и ошибиться. А ИИ-агент, если его не ограничивать, выдаст ответ уверенно и быстро.

Я делал агента для разбора входящих заявок. Задача казалась простой: прочитать письмо, найти заказ в PostgreSQL, понять просьбу и либо выполнить, либо подготовить действие. На тестовых письмах всё работало. На реальных — нет. Половина писем ссылалась на разговоры по телефону, которых агент не слышал. Клиенты называли заказы своими словами. Иногда в одном письме было сразу три просьбы.

Агент на всё это отвечал. Иногда правильно, иногда нет. Операторы перестали ему доверять и начали перепроверять каждое предложение. Работы прибавилось.

Агент обязан знать, когда остановиться

Для меня теперь определение простое: агент — это система, которая делает сама там, где уверена, и честно отдаёт человеку там, где нет. Без второй части это просто стажёр, который боится задать вопрос и делает наугад.

Самооценка модели не работает

Сначала я пробовал просить модель поставить оценку уверенности. Получалось бесполезно. Модель оценивает, насколько гладко звучит ответ, а не насколько он верен. Проверял на GigaChat, Qwen и YandexGPT — везде одинаково.

Пришлось искать сигналы снаружи.

Что я проверяю вместо самооценки

Структурные правила

Самое надёжное. Код на FastAPI сверяет извлечённые поля с базой:

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

Если что-то не сходится — эскалация.

Два прогона с разными промптами

Если результаты совпали — хорошо. Разошлись — значит, в письме есть неоднозначность.

Категория «не могу определить»

Добавил её в классификатор и прямо в инструкции разрешил моделью пользоваться. Без этой опции она всегда впихивает письмо в ближайшую категорию.

Проверка найденных документов

Если агент ссылается на договорённость, проверяю, нашёл ли он её через pgvector. Слабое совпадение — эскалация.

Грабли: сначала агент сдавался слишком часто

Первая версия была параноидальной — отдавал почти каждое второе письмо. Операторы получили почти ту же почту, только с лишним шагом. Ослабил пороги — появились уверенные ошибки.

Решение нашлось не в порогах, а в том, чтобы у каждой эскалации была конкретная причина: «найдено два заказа», «отправитель не привязан», «ссылка на телефонный разговор». Статистика по причинам помогла быстро доработать две-три самые частые.

Что получает человек

В интерфейсе на Angular оператор видит:

  • исходное письмо;
  • что агент понял;
  • причину остановки;
  • варианты, которые он рассматривал;
  • черновик действия, если есть.

Часто остаётся только выбрать один вариант и нажать «подтвердить».

Что изменилось

Простые письма агент закрывает сам. Сложные приходят уже разобранными. Утреннюю почту стали разбирать за час вместо до обеда. Главное — вернулось доверие. Операторы знают: если агент сомневается, он скажет.

Как я теперь подхожу к таким проектам

  1. Эскалацию проектирую с самого начала.
  2. Уверенность проверяю снаружи, а не через самооценку модели.
  3. Каждую передачу человеку фиксирую с причиной.
  4. Человек получает почти готовое решение с вариантами.

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