Инженерный дневник

Как я собрал бота, который отвечает по документации

Я дизайнер и спроектировал RAG-систему для документации UserGate. За полтора месяца она прошла путь от 30 % полезных ответов и 52 секунд ожидания до 80 % и 12 секунд. Ниже — что именно сработало, с цифрами всех провалов по дороге.

80 %
полезных ответов на вопросы, покрытые документацией
0
выдуманных фактов на контрольных замерах: порты и команды не фабрикуются
12 с
на ответ — в первой версии было 52 секунды

Стартовые значения: 30 % полезных ответов, 52 секунды. Дальше — как закрылась эта разница.

01Зачем дизайнеру свой бот

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

Гипотеза выглядела просто: пусть документация отвечает на вопрос сама — коротко, своими словами и со ссылкой на источник. Для этого существует RAG, retrieval-augmented generation: базу режут на фрагменты, под вопрос находят подходящие и отдают модели с инструкцией отвечать только по ним.

Первую версию — телеграм-бота — я собрал за несколько вечеров. Она думала 52 секунды и была полезна в трёх случаях из десяти.

30 %
полезных ответов в первой версии. Остальное — промахи и уверенные выдумки. Выдуманный порт хуже отсутствия ответа: по нему кто-то пойдёт настраивать реальную систему.

02Кто писал код

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

У ассистента обнаружилась та же болезнь, что у моего бота: он уверенно писал код под версии библиотек из своей обучающей выборки — например, методы aiogram двухлетней давности, которых больше нет. Лечение оказалось тем же: заземление. Через протокол MCP (Model Context Protocol) сервер Context7 подтягивает актуальную документацию библиотеки прямо в контекст, и код пишется под сегодняшний API.

Бот и инструмент, которым он собран, держатся на одном принципе: не доверять памяти модели — давать ей настоящие документы.

03Данные: 48 % базы оказались мусором

Разбираться я начал не с моделей, а с базы. Выяснилось, что скрипт сбора отработал дважды, а часть статей сохранилась пустыми: у них другой HTML-шаблон, который парсер не понимал.

48 %
базы — дубликаты и пустышки. Бот искал ответы среди сорока тысяч фрагментов, из которых полезны были двадцать. После чистки доля полезных ответов выросла с 30 до 48 % — больше, чем позже дала любая замена модели.

04Скорость против честности

52 секунды на ответ уходили из-за режима рассуждений: модель сначала проверяла себя, потом отвечала. Я отключил рассуждения — стало 8 секунд, в пять раз быстрее. Доля ошибок выросла с 8 до 32 %.

8 → 32 %
ошибок после «ускорения». Рассуждения были не тормозом, а дисциплиной: они удерживали модель в рамках документации. Каждый третий быстрый ответ оказался неверным.

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

0
выдуманных фактов на контрольных замерах при 10–12 секундах на ответ. Тогда же появился измерительный стенд — набор реальных вопросов, на котором с этого момента проверялось каждое изменение.

05«А можно не в телеграме?»

Коллегам бот пригодился, но первый же практический вопрос развернул проект: рабочий мессенджер у команды другой, а доступа для интеграции в него пока нет. Телеграм был удобен мне — не команде.

Так появился второй интерфейс — веб-страница с полем вопроса. Ядро общее: тот же поиск, та же проверка ответа; интерфейсы сменные. Корпоративный мессенджер станет третьим входом к тому же ядру, когда появится доступ.

06Что не сработало

Есть метрика качества поиска: попал ли нужный документ в топ выдачи. Интуиция подсказывает, что лучший поиск даёт лучшие ответы. На стенде эта связь несколько раз подряд не подтвердилась:

Переранжирование выдачи отдельной моделью. Прироста нет, плюс десять секунд к ответу.
Переписывание вопроса нейросетью перед поиском. Качество упало: формулировка «улучшалась» до потери сути.
Обогащение фрагментов контекстом — техника из публикации крупной ИИ-лаборатории, обещала минус 35–49 % промахов. На моих данных — статистический шум: заголовки, которые я и так вшивал в каждый фрагмент, уже давали тот же эффект.
Замена поисковой модели на более сильную по бенчмарку. Метрика поиска выросла, качество ответов упало: находилось похожее по смыслу, но не то, и генератор на это опирался.

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

07Что в итоге

Бот отвечает на 80 % вопросов, покрытых документацией, за 10–15 секунд, со ссылками на источники. На заведомо сложных вопросах — около половины, и это потолок данных, а не модели: второй половины ответов в документации просто нет.

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

  1. Мерить, а не верить. Интуиция в этой области ошибается систематически — см. раздел 06.
  2. Отрицательный результат — тоже результат. Подтверждённый цифрами список тупиков экономит недели.
  3. Данные важнее моделей. Чистка корпуса дала +18 пунктов; замены моделей — ноль или минус.
  4. Честное «не знаю» дороже правдоподобного ответа. Одна выдумка обесценивает все верные ответы рядом.
  5. Ограничения улучшают архитектуру. Вопрос «а можно не в телеграме?» разделил систему на ядро и сменные интерфейсы.

08Что дальше

Аналитика вопросов. Не «сколько спросили», а что спрашивают чаще всего и где повторяются одни и те же боли. Это готовая карта того, что в продукте и документации непонятно людям, — материал и для меня, и для авторов доков.

Обратная связь в ответе. Отметка «помог / не помог» одним касанием и комментарий, если ответ неточен. Каждая отметка — сигнал, где подкрутить; каждый комментарий — конкретная задача.

Главный вывод — не про ИИ. Продукт получается, когда решаешь собственную регулярную боль и честно измеряешь, стало ли легче. Технология здесь — исполнитель, а не идея.