
На связи Сергей Смирнов, AI-инженер и основатель LLMStart.ru. Мы делаем AI-системы для бизнеса. И сегодня я расскажу, откуда мы точно знаем, что наш production-агент для компании «Айтон» (консультирует по 1С:УНФ) реально умнеет, а не делает вид.
В прошлой статье мы разбирали контекст-инжиниринг. А сейчас поговорим о самом сокровенном — подсистеме оценки. Спойлер: именно на ней держится любое осознанное развитие продукта.
Когда ваш агент уже работает в проде, главный вопрос команды звучит так: «Как доказать, что он становится лучше?». На пяти-десяти тестовых кейсах это понять невозможно. Можно строить догадки, опираться на интуицию. Но знать наверняка — нельзя.
Что у нас под капотом?
Фреймворк: Langchain.
Среда обитания: Telegram-бот для клиентов «Айтона» (компания больше 20 лет внедряет 1С:УНФ).
Что спрашивают пользователи: Раньше они мучали живых менеджеров вопросами вроде: «Как настроить склад с учетом резерва?» или «Можно ли вести производство по серийникам?».
Типы вопросов: Половина — это конкретное «как сделать», другая половина — разбор сложных терминов и проверка, есть ли вообще такая функция в системе.
Ниже я покажу изнанку: четыре области оценки, две уникальные метрики, Венгерский алгоритм (да-да, тот самый, ради честного F1) и разбор боевого цикла. А еще расскажу про тот неловкий момент, когда метрика рухнула просто потому, что наш ИИ оказался умнее старого эталона!
Проверка «глазами»: почему интуиция больше не работает
Обычно разговоры про evaluation (оценку) начинаются с фразы: «Давайте просто посмотрим пару ответов». Команда лениво листает 10-15 примеров. Один говорит: «О, тут круто ответил!», другой морщится: «А вот тут чушь какая-то». И на основе этих эмоций принимается решение — катить новый промпт в прод или нет.
Так вот, ручная проверка — это не начало пути. Это глухой потолок. Выше вы не прыгнете, пока не построите нормальную систему оценки. Я сам долго этого не понимал, пока просто не взял калькулятор.
Смотрите, на одном из боевых датасетов проекта у нас сейчас 33 кейса. Они разбиты на четыре функциональные области. Мы выжали их из Excel-файла заказчика до последней капли. Но 33 кейса для статистики — это просто слезы. Представьте: у вас 15 кейсов в одной области. Если агент стал отвечать лучше всего на один вопрос, метрика прыгает сразу на ≈7%. Ого, рост на 7%! Но что это значит? Может, мы реально починили логику. А может, просто случайно угадали, и на следующем вопросе агент эпично провалится.
И тут кроется главная мысль, о которой почему-то все молчат: Системная оценка нужна не ради красивых отчетов для QA. Она нужна, чтобы у вас был железный аргумент.
Пока у вас есть только «ощущение» команды, красивые скриншоты и демо — у вас нет ничего. Настоящий аргумент появится только вместе с инструментом, который измеряет качество в цифрах. Эмоции и десяток ручных проверок — это ваш предел.
Чтобы пробить этот потолок, мы создали инструмент замера. Для нашего агента понадобилось целых четыре области оценки, и стандартными метриками RAG тут было не обойтись.
Анатомия оценки: на какие четыре части мы распилили агента
Признаюсь, в начале пути я был наивен. Думал: «Возьму RAGAS из коробки, и всё взлетит!». На второй неделе розовые очки разбились.
Казалось бы, всё просто: подключаем RAGAS к Langfuse, прогоняем сотню вопросов и любуемся графиками. Да, это сработало бы, будь наш агент простой искалкой по базе знаний (чистый RAG). Но в реальном проде всё гораздо хитрее.
Мы разбили систему оценки на четыре функциональные области. Каждая проверяет свой аспект работы:
1. RAG (Поиск по базе). Агент тут — черный ящик. Дали вопрос, получили ответ и куски найденного текста. Проверяем всё стандартными метриками RAGAS (
faithfulness,answer_correctness,answer_relevancy). Это фундамент для любого бота-поисковика.2. Agent (Работа с инструментами). Здесь нас волнует не красивый текст ответа, а механика: тот ли инструмент взял агент? Правильные ли данные в него передал? Спойлер: тут RAGAS работает по принципу «всё или ничего», поэтому нам пришлось засучить рукава и переписать парочку метрик.
3. Clarifying (Уточняющие вопросы). Если пользователь пишет что-то непонятное, агент может либо пальнуть наугад, либо переспросить. В 1С:УНФ это боль! Например, слово «резерв» может быть товарным, финансовым или оценочным. Мы измеряем, умеет ли ИИ вовремя остановиться и задать уточняющий вопрос по делу.
4. No-feature (Работа с отсутствующим функционалом). Клиент просит фичу, которой нет. У агента три пути: сказать «есть», сказать «нет» или честно поднять лапки — «не знаю». Последнее — суперважный исход для случаев, когда инфы нет вообще. Самое страшное — когда агент начинает галлюцинировать и придумывать функционал. Эта область бьет его по рукам за такие фантазии.
Как это всё живет вместе?
База — фреймворк RAGAS (поверх которого мы пишем свою магию).
Хранилище — Langfuse (держит датасеты и логи трейсов).
Запуск происходит из одной точки: скрипт сам раскидывает вопросы по областям и натравливает на них нужные метрики.
Если RAG и Agent — это классика, для которой есть готовые решения, то Clarifying и No-feature — наши авторские разработки. Эталоны для них мы не придумывали за кофе. Мы вытащили их из 10 000 реальных переписок менеджеров!

Как 10 000 сообщений подарили нам свои метрики
Наши авторские метрики не родились в вакууме. Мы не придумывали формулы, чтобы потом искать под них данные. Всё было ровно наоборот: сначала фактура, потом классификация, и только в конце — метрика.
Заказчик выгрузил нам 10 317 сообщений из Telegram. Это реальные переписки менеджеров с клиентами за несколько месяцев. Именно этих живых людей наш ИИ-агент должен был заменить или хотя бы подстраховать.
Мы скормили эти чаты в Gemini 3 Pro и запустили два промпта:
Ищи паттерны, где менеджер задает уточняющие вопросы.
Ищи вопросы от клиентов в духе «А есть ли у вас такая-то фича?».
С эталонами для RAG всё понятно: бьешь базу знаний на куски, генерируешь синтетику. С эталонами для инструментов тоже: пишешь правильные сценарии руками. А вот выдумывать «правильные уточнения» из головы было бы фатальной ошибкой. Мы бы создали сферического коня в вакууме. К счастью, все идеальные эталоны уже лежали в логах переписок менеджеров.
В итоге мы получили девять категорий контекста, которого вечно не хватает клиентам (девятую, к слову, добавили уже позже из боевого опыта):
technical_env— где сидим: Браузер или Тонкий клиент? Какая версия?process_state— что делаем: закрываем месяц или проводим документы?object_identification— дайте ID: ссылка, номер документа, артикул.terminology_ambiguity— боль терминов: «резерв», «аванс», «база» (все это значит разное в разных местах).true_goal— чего хотим на самом деле (классика: клиент спрашивает про X, а проблема в Y).data_source— откуда дровишки: источник данных.business_logic— как считаем: бизнес-логика.visual_context— покажи скриншот, иначе не пойму.configuration_dependency— зависит от конфигурации (та самая девятая категория из реальной боли).
Для фич, которых в системе может и не быть, мы выделили три железных вердикта:
«Есть» — нашли подтверждение в базе.
«Нет» — точно нет, пруфы на месте.
«Не знаю» — инфы нет вообще. И это важнейший исход! Раньше без него агент либо врал, что фича есть, либо лил воду в стиле «это возможно при правильных настройках». Теперь у него есть официальное право поднять лапки и честно признаться в неведении.
И вот из всего этого богатства родились наши звезды:
1. Clarifying Accuracy (Метрика Уточнений) Оценивает, как ловко агент распутывает неоднозначности. Оценка идет по трем ступеням: 0.0, 0.5 и 1.0. LLM-судья смотрит, должен ли был агент задать вопрос, и совпал ли он с нужной категорией из списка выше.
1.0 — Красавчик! Спросил и попал в нужную категорию.
0.5 — Молодец, что спросил, но промахнулся с темой (например, спросил про версию браузера, а проблема была в терминах).
0.0 — Провал. Надо было уточнять, а он промолчал.
Половинчатый балл тут критически важен. Сам факт того, что ИИ понял необходимость вопроса — это уже половина успеха. Бинарная система (0 или 1) убила бы этот нюанс.

2. No Feature Accuracy (Метрика Фантазий) Тут всё жестко: либо 1, либо 0. LLM-судья берет ответ агента про какую-то фичу, раскидывает его по корзинам («есть» / «нет» / «не знаю») и сверяет с эталоном. Совпало — молодец. Нет — ноль баллов. Без пощады.

Прелесть таких эталонов в том, что мы не требуем от агента отвечать слово в слово. Нам важна логика. Ситуация категоризирована правильно? Получи балл.
Это отличный пример того, как система оценки сама эволюционирует на проде. Мы не высекали категории в камне, а вырастили их из реальных болей пользователей.
С логикой разобрались. Но чтобы оценивать техническую работу агента (вызов инструментов), нам пришлось залезть в высшую математику.
Бунт против RAGAS: зачем нам понадобился Венгерский алгоритм
Признаюсь честно: я переписывал базовые метрики RAGAS не от любви к математике, а потому что они жестоко сливали нашего агента. ИИ делал всё правильно, а система оценки лепила ему гордый «ноль».
В стандартном RAGAS есть две метрики: ToolCallAccuracy и ToolCallF1. Звучит логично: берем эталонный список вызовов инструментов, сравниваем с тем, что сделал агент, и ставим оценку. Но в суровой реальности это развалилось.
И вот почему:
Первый провал: дословное сравнение. ToolCallAccuracy сверяет данные байт в байт. Допустим, в эталоне написано: query="как настроить склад с резервом". Агент проявил смекалку и переформулировал: query="настройка склада, резерв". И всё! Метрика кричит: «Ошибка!» и ставит ноль. Хотя по смыслу агент всё сделал идеально. Наказывать ИИ за то, что он умнее скрипта — путь в никуда. Поэтому я переписал эту штуку, создав RouterToolCallAccuracy.
Теперь мы сами указываем, как сравнивать данные:
Для запросов (
query) мы включилиSemanticSimilarity— система смотрит на смысл, а не на буквы.Для строгих вещей вроде
idилиphoneоставили строгое совпадение (ExactMatch).
Никакой магии, просто жесткие правила для каждого параметра:
metric = RouterToolCallAccuracy( argument_metrics={ # Смысл важнее букв "query": SemanticSimilarity(embeddings=..., threshold=0.7), # Только точное совпадение "document_id": ExactMatch(), "phone": ExactMatch(), }, default_metric=ExactMatch(), )
Второй провал: потеря кратности. Метрика ToolCallF1 сжимала одинаковые вызовы. Если агент умно вызывал поиск три раза подряд с разными словами, а в эталоне было два вызова, RAGAS тупо сплющивал их, теряя количество.
Так родилась метрика FuzzyToolCallF1. И вот тут на сцену выходит Венгерский алгоритм (привет, дискретная математика 1955 года!).
Как это работает:
Считаем «матрицу сходства» между тем, что сделал агент, и эталоном.
Ищем идеальные пары (тут-то алгоритм и находит самое дешевое и точное совпадение).
Оставляем только те совпадения, которые пробили нужный порог уверенности.
Высчитываем итоговую метрику (precision, recall, F1).
async def ascore(self, references, predictions, callbacks=None): n_refs, n_preds = len(references), len(predictions) # 1. Строим матрицу сходства cost_matrix = np.zeros((n_refs, n_preds)) for i, ref in enumerate(references): for j, pred in enumerate(predictions): cost_matrix[i, j] = await self._compare_tool_calls(pred, ref, callbacks) # 2. Вызываем магию Венгерского алгоритма row_ind, col_ind = linear_sum_assignment(-cost_matrix) # 3. Отсекаем мусор по порогу tp = sum(1 for r, c in zip(row_ind, col_ind) if cost_matrix[r, c] >= self.match_threshold) # 4. Считаем итоговые баллы precision = tp / n_preds recall = tp / n_refs return 2 * precision * recall / (precision + recall)
Обычно в инфраструктуре агентов слова «задача о назначениях» звучат дико. Но именно Венгерский алгоритм дал нам честный результат там, где стандартные эвристики пасовали.

Но одно дело — собрать красивые формулы на бумаге. Совсем другое — выкатить это в бой.
Боевое крещение: как метрика заставила агента поумнеть
Любая система мертва, пока не столкнется с реальностью. Давайте разберем один суровый боевой цикл: датасет из 33 сложных кейсов и четыре мощных прогона.
Заказчик принес нам пачку «провалов» агента — те самые диалоги, где клиент Айтона ушел ни с чем или получил неверный ответ. Мы разобрали эту боль, разложили кейсы по нашим любимым областям (RAG / Clarifying / No-feature) и загнали в систему оценки. Схема простая: я запускаю тест -> смотрю метрики -> иду в Langfuse раскапывать трейсы (где агент споткнулся, что вытянул из базы) -> правлю промпты и логику -> запускаю заново.
Вот как развивались события:
Прогон 1 → Прогон 2. Мы перевели системный промпт в XML (модели так лучше соображают) и жестко запретили агенту фантазировать про несуществующий функционал. Ввели кучу фильтров. И… бац! Метрика честности (
faithfulness) рухнула с 0.468 до 0.273. Почему? Потому что требования стали строже, и старые халтурные ответы перестали прокатывать. Это правильная боль роста.Прогон 2 → Прогон 3. Тут мы поняли, что сломался сам датасет! Четыре кейса лежали в разделе RAG, но на деле клиенты писали настолько размыто, что агенту нужно было задавать уточняющие вопросы, а не искать инфу вслепую. Мы перекинули их в Clarifying. То есть система помогла нам вылечить собственные данные!
Прогон 3 → Прогон 4. Допилили логику до идеальных «трех исходов»: нашел пруфы / точно нет / честно не знаю. А еще увеличили агенту лимит на вызов инструментов, чтобы он успевал раскопать сложные цепочки до окончательного ответа. И добавили ту самую девятую категорию уточнений (
configuration_dependency), потому что реальность подкинула новых сюрпризов.
А теперь посмотрите на цифры. Главный триллер здесь — это второй прогон, когда из-за новых жестких правил всё покраснело. Зато потом начался стабильный рост.
Метрика |
Run 1 |
Run 2 |
Run 3 |
Run 4 (Gemini) |
Run 4 (Claude) |
|---|---|---|---|---|---|
|
0.468 |
0.273 |
0.633 |
0.509 |
0.693 |
|
0.437 |
0.405 |
0.481 |
0.478 |
0.478 |
|
0.870 |
0.391 |
0.528 |
0.877 |
0.894 |
Clarifying Accuracy |
0.273 |
0.182 |
0.367 |
0.400 |
0.467 |
No Feature Accuracy |
0.615 |
0.538 |
0.538 |
0.769 |
0.615 |

И вот тут начинается самое интересное. Иногда метрика ставит ноль не потому, что агент тупой, а потому, что он слишком умный!
И вот тут логика сломалась. Разбираю трейсы в Langfuse. Вижу кейс: в эталоне написано «такой функции в УНФ нет». А агент расписывает клиенту: «Есть такая функция! Зайдите в раздел X, настройте Y…». И что вы думаете? В свежем обновлении 1С:УНФ эту фичу реально добавили! А наш эталон был собран полгода назад. Агент оказался прав, прочитал свежую доку, а жесткая метрика влепила ему жирный ноль.
Или другой случай с уточнениями: по эталону агент должен был переспросить термин, а он копнул глубже и спросил клиента про бизнес-логику расчетов. Система поставила ему 0.5 балла («не та категория»). Но по здравому смыслу агент заслужил 10 из 10.
Какой из этого вывод? Эталоны на проде протухают. Низкая метрика — это не всегда диагноз агенту. Иногда это сигнал, что пора обновить ваши же правила.
Именно поэтому я всегда говорю: оценка ИИ — это не бездушная автоматизация QA. Если тест покраснел, это не приговор, а повод засучить рукава и разобраться ручками.
Цифры вместо гаданий на кофейной гуще
Повторюсь: на 15 случайных тестах вы никогда не поймёте, реально ли поумнел ваш бот или ему просто повезло с вопросами.
Системная оценка превращает размытое «вроде стало лучше» в железобетонное число. Вы можете показать его бизнесу, сравнить с прошлой неделей и точно знать: ваши правки в промпте сработали. А рядом с этим числом всегда лежит подробный лог трейсов, в который можно провалиться в любой момент.
Но сказок не бывает:
Эталоны придётся собирать руками (или выуживать из терабайтов реальной переписки, как это сделали мы).
Метрики часто придется переписывать под себя (даже если придется вспомнить Венгерский алгоритм), потому что готовые фреймворки слишком грубые.
И да, всё равно иногда придется садиться и разбирать провалы глазками, чтобы понять — ИИ сломался или просто мир изменился.
У нашей системы оценки есть ещё крутые фишки, о которых я обязательно напишу позже: и хитрая синтетика для датасетов, и автоматические циклы оценки трейсов, и миграция от судейства LLM к строгим компонентным метрикам. Но это уже совсем другая история.
Главная мысль: если ваш агент работает, и вам кажется, что он хорош — вам только кажется. Чтобы это стало знанием, нужна инфраструктура: свои метрики, реальные эталоны и жесткий цикл проверки. Иначе вы так и останетесь заложниками слепой веры в собственный код.
А теперь ваша очередь! Расскажите в комментариях: как вы сейчас измеряете качество своих ИИ-агентов? На какой выборке тестируете промпты? Какие костыли лезут из коробочных решений? Очень жду ваших историй!
Мы разобрали реальный кейс того, как системная оценка превращает размытое «вроде стало лучше» в железобетонное число. Качество агента держится не на слепой вере, а на собственных метриках, реальных эталонах и жестком цикле проверки.
В LLMStart.ru мы помогаем бизнесу решать такие задачи и получать реальный эффект от ИИ — от прототипа до промышленной эксплуатации. Если вы устали гадать на кофейной гуще и хотите выстроить нормальную оценку, обращайтесь, будем рады помочь консультацией или разработкой под ключ.
Если хотите перенять опыт и научиться делать подобные системы самостоятельно, у нас есть онлайн-курсы, а ближайший живой поток курса Deep Agents, где evaluation и red teaming — один из четырёх ключевых блоков, стартует уже в четверг, 28 мая.
По любым вопросам пишите мне в личку: Telegram или ВК. Приглашаем также в наши соцсети про ИИ-кодинг ИИ-агентов: в ТГ-канал и ВК-сообщество