Сначала агент был слишком уверенным
Пятница, конец дня. В почте у логиста висит письмо: «Перенесите, пожалуйста, отгрузку, как договаривались». Кто договаривался, какая именно отгрузка — непонятно. Опытный человек позвонит и уточнит. Новичок может угадать и ошибиться. А ИИ-агент, если его не ограничивать, выдаст ответ уверенно и быстро.
Я делал агента для разбора входящих заявок. Задача казалась простой: прочитать письмо, найти заказ в PostgreSQL, понять просьбу и либо выполнить, либо подготовить действие. На тестовых письмах всё работало. На реальных — нет. Половина писем ссылалась на разговоры по телефону, которых агент не слышал. Клиенты называли заказы своими словами. Иногда в одном письме было сразу три просьбы.
Агент на всё это отвечал. Иногда правильно, иногда нет. Операторы перестали ему доверять и начали перепроверять каждое предложение. Работы прибавилось.
Агент обязан знать, когда остановиться
Для меня теперь определение простое: агент — это система, которая делает сама там, где уверена, и честно отдаёт человеку там, где нет. Без второй части это просто стажёр, который боится задать вопрос и делает наугад.
Самооценка модели не работает
Сначала я пробовал просить модель поставить оценку уверенности. Получалось бесполезно. Модель оценивает, насколько гладко звучит ответ, а не насколько он верен. Проверял на GigaChat, Qwen и YandexGPT — везде одинаково.
Пришлось искать сигналы снаружи.
Что я проверяю вместо самооценки
Структурные правила
Самое надёжное. Код на FastAPI сверяет извлечённые поля с базой:
- найден ровно один заказ;
- отправитель привязан к контрагенту;
- новая дата в будущем и не противоречит статусу.
Если что-то не сходится — эскалация.
Два прогона с разными промптами
Если результаты совпали — хорошо. Разошлись — значит, в письме есть неоднозначность.
Категория «не могу определить»
Добавил её в классификатор и прямо в инструкции разрешил моделью пользоваться. Без этой опции она всегда впихивает письмо в ближайшую категорию.
Проверка найденных документов
Если агент ссылается на договорённость, проверяю, нашёл ли он её через pgvector. Слабое совпадение — эскалация.
Грабли: сначала агент сдавался слишком часто
Первая версия была параноидальной — отдавал почти каждое второе письмо. Операторы получили почти ту же почту, только с лишним шагом. Ослабил пороги — появились уверенные ошибки.
Решение нашлось не в порогах, а в том, чтобы у каждой эскалации была конкретная причина: «найдено два заказа», «отправитель не привязан», «ссылка на телефонный разговор». Статистика по причинам помогла быстро доработать две-три самые частые.
Что получает человек
В интерфейсе на Angular оператор видит:
- исходное письмо;
- что агент понял;
- причину остановки;
- варианты, которые он рассматривал;
- черновик действия, если есть.
Часто остаётся только выбрать один вариант и нажать «подтвердить».
Что изменилось
Простые письма агент закрывает сам. Сложные приходят уже разобранными. Утреннюю почту стали разбирать за час вместо до обеда. Главное — вернулось доверие. Операторы знают: если агент сомневается, он скажет.
Как я теперь подхожу к таким проектам
- Эскалацию проектирую с самого начала.
- Уверенность проверяю снаружи, а не через самооценку модели.
- Каждую передачу человеку фиксирую с причиной.
- Человек получает почти готовое решение с вариантами.
Когда меня спрашивают, как сделать агента, который реально разгрузит людей, я начинаю разговор не с того, что он будет делать, а с того, где он должен остановиться.
