Свою первую программу я написал в 1988 году на калькуляторе МК52. Очень хотелось программировать и даже максимально странный интерфейс не останавливал. Утекло почти 40 лет. Были Атари, Синклеры, 286 IBM, Интернет, смартофоны. Но все эти технологии входили как-то постепенно, приспосабливаясь и без шока.
AI ворвался в жизнь бывалого ИТшника как пыльным мешком по голове. После первого шока, скормленных Дипсику результатов анализов, идей подарков, профессиональная “чуйка” потребовала придумать новой чудо-технологии боевое применение в том, чем я занимаюсь каждый день на протяжении всей сознательной жизни.
В 2013 году, когда в моду только входили светодиодные светильники, ко мне обратились с предложением разработать систему управления освещением для этой технологии. Сейчас дико видеть люминесцентную лампу или ДНАТ светильник, а всего 13 лет назад светодиодный светильник был техническим чудом, дорогим, но очень перспективным.
Моя команда разработала оборудование, технологию обмена информацией по радиоканалу и Цифровую Платформу, в которой цифровые двойники наших железок живут в онлайн режиме на схемах предприятий или картах городов.
Системы управления освещением - объекты, хоть и не очень сложные, но могут быть объемными, например, есть город, где стоит 8 000 контроллеров, и очень разноплановыми (логистические комплексы с сотнями датчиков, школы, стадионы и промышленные предприятия с цехами по полкилометра длиной).
Но все это - тема для совсем другой истории, а данная статья возникла из того, что, за годы НИОКРов и внедрений мы накопили багаж из 50 000 он-лайн железок, развешанных по всей стране от Калининграда до Владивостока, от Салехарда до Сталинграда. И в том багаже еще есть огромный технический долг, очень специфические знания как о железе с его полным жизненным циклом, так о нюансах придуманной нами технологии, информация о 1 500 цифровых проектах систем управления, примерно 300 из которых воплощены и сопровождаются. Все это с разными версиями железа, микропрограмм, слоистой Цифровой Платформой - кошмар технического директора - мой личный кошмар.
Мы - продуктовая компания. У нас есть своя разработка - аппаратно-программный комплекс SUNRiSE, мы его продаем - на эти бюджеты развиваем и технологию, и программное обеспечение. Соответственно, бюджетов всегда мало, а интеграторы, роющие землю, всегда требуют новые решения и технологии.
Бум AI - шевелит мозги и настроения. Если есть хоть малейший шанс повысить эффективность нашей компании используя AI - значит им нужно пользоваться. И вот, на входе, считай, идеальная среда: продуктовая компания с кучей рутинных, но не детерминированных задач, с одной стороны, и AI, бьющий копытом, готовый решать все эти задачи - с другой. ВПЕРЕД!
Основная проблема всех прикладных применений AI - найти это прикладное применение. CustDev показал - все мои программисты, менеджеры и проектировщики - ксенофобы. Результаты интервью, если опустить детали, были примерно такими: проблем, конечно, много, но мы справляемся и нам не нужны новые проблемы еще и с AI. Как говорил Генри Форд "Если бы я спрашивал людей, чего они хотят, они бы ответили: более быстрых лошадей”.
Раз не нашлось внятного предложения куда погрузить AI, то я решил что потрачу время и часы штатных программистов на то, чтобы уменьшить свою боль - держать в голове кучу технических нюансов, документации, кейсов и лайвхаков. План:
Соберу всю документацию в векторную базу
Дам к ней доступ проектировщикам, интеграторам и сервисным инженерам через AI
В целом, это простой план - надёжный как швейцарские часы - ПОЕХАЛИ!
На 2025, новый год я подарил себе игровой комп: 16Гб оперативки и GPU 6Гб. Планировал летать на дронах в симуляторах, но в реальном мире летать интереснее - комп стоял и пылился. Его было решено задействовать для нашего локального AI. Итого:
Добавлена RAM до 32 гб
Quadrant - как векторная БД
FRIDA от Сбера - Эмбеддер
Claude для разметки - слишком дорого гонять каждый запрос через API, но для предобработки документов — самое то.
qwen/qwen3-8b-6K - LLM
N8n - на перспективу
Pyton и Java (наша основная среда разработки)
Библиотека LangChain.
Все в докерах.
Векторизация документов:
Загружаем PDF документ, его же потом можно будет отдать пользователю по запросу
Этот же документ загружаем в Claude с промптом разбить на логические блоки длиной 400-450 слов. И выделить из документа рисунки с описанием. Этот момент важен, на нем я потом остановлюсь подробнее
Результат работы Claude в виде размеченного MD текста кладем рядом с загруженным документом.
Логические блоки чанкуем по 300 символов с перекрытием
Из рисунков, размеченных в MD, заполняем отдельную таблицу в БД
Чанки векторизуем FRIDой и добавляем в Quadrant
Достаем из загруженного PDF картинки и сопоставляем их с теми, что взяли из разметки документа (процесс ручной).
Итог: Документ векторизован, рисунки прикреплены к соответствующим payload
Запрос к документам:
Получаем запрос пользователя
Векторизуем FRIDой
Ищем близкие по score чанки в Quadrant
Достаем payloadы найденных чанков вместе со ссылками на рисунки
Отправляем в qwen/qwen3-8b-6K со специальным промптом
Результат показываем пользователю
Мне кажется, еще в мае 2025 эти сценарии были инновацией. Сегодня, в первых числах 2026, они - нетленная классика, которую не надо объяснять.
“Узок круг этих революционеров. Страшно далеки они от народа. Но их дело не пропало. Декабристы разбудили Герцена. Герцен развернул революционную агитацию.” (с) Ленин
По классике - чанки обломки текста, близкие по размеру к будущему вопросу пользователя. Размер имеет значение для сравнения векторов запросов и чанков. 300 символов - алхимически ОК.
В классике Payload - метаданные чанков. Но, так как, даже в чистой умозрительной теории, чанки на столько малы, что не сохраняют смысл, то мы просто дописали классику и в метаданные чанков положили смысловой блок
ИТОГО: Смысловой блок размером в 400-450 слов - ядро базы документации. В LLM отправляются именно смысловые блоки, а не осколки в виде чанков. На смысловые блоки разбивает Claude - самый неприятный рутинный процесс. Цифра в 450 символов родилась при анализе документации. Оказалось, что это тот размер, в который можно уложить почти все разделы документации, паспортов и инструкций. И, так как мы полностью владеем документацией - те разделы что не поместились можно/нужно доработать.
Потом оказалось, что вообще всю документацию надо доработать, но об этом дальше.
Сначала разбивка документа на смысловые блоки происходила функциями LangChain, но эти блоки не сохраняли транзакцию смысла, Claude же можно натренировать объединить текст в блоки по смыслу, выделить ключевые слова и рисунки.
Существует достаточно много эмбеддеров (модели, которые преобразуют текст в вектора). Мы начали с FRIDA, так как, по слухам, лучший эмбеддер для русского языка, и ее/его можно развернуть локально. Потом пробовали другие модели. Но, в целом, эмбеддер не сильно влияет на результат. Работает классический принцип информатики GIGO (Garbage in, garbage out).
Есть только один рецепт красивых и полных ответов на вопросы пользователей: подготовить документацию так, чтобы она на них отвечала. И это стало возможным только когда появились инструменты RAG, LLM, вопросы пользователей.
Есть у меня ощущение, что человечество уйдет от графических интерфейсов. Мы же ушли от лошадей и пишущих машинок. Но пока 60% интефейсов: таблички-таблички. На рисунке 1 пример документов в базе. Все очень просто: загрузили документ в PDF, его сразу можно скачать или скопировать ссылку (иконки рядом с названием). Для некоторых документов внешний доступ запрещен.
Статус векторизации, количество изображений, блоков и чанков - для информации.
Из этого интерфейса можно попасть в RAG поиск или чат (рисунок 2). В классическом чате - результат, прошедший через LLM Qwen 3, в RAG - сырые данные с инфо о SCORE. Видны все чаты и можно подправить системный промпт (для админов)
Отмечу, что, так как Qwen крутится на 6ГБ GPU, то даже с разрешением в 6 бит - он думает от 20 до 40 секунд. То есть мы не стали делать агента, который утомит в ожидании пользователя, а решаем вопрос одним нырком в LLM.
Всего на первом этапе в базе порядка 50 документов - несколько тысяч векторов. Оказалось, что паника и боль создавались не таким и большим количеством файлов.
Так как все это делалось в тумане неопределенности, где было совсем не понятно как это работает и что получится, то местами вышло кривовато и корявенько. Например, промпт в LLM, в основном состоит из алгоритмов того как выудить нужный рисунок. Сейчас я понимаю, что так делать некрасиво, и есть несколько способов значительно улучшить процесс и результат.
Ниже тот самый промпт. Его, в итоге, в несколько итераций доработал Claude. Это значительно быстрее чем перестроить нюансы архитектурного решения.
Полный промпт поиска по в RAG# РОЛЬ
Эксперт-консультант по SUNRiSE
# КРИТИЧЕСКИ ВАЖНО
- Отвечай ТОЛЬКО на прямой вопрос пользователя
- Используй ТОЛЬКО текст из поля "text" тех payload-объектов, которые содержат ответ
⚠️ КРИТИЧЕСКИ ВАЖНО: Формат ссылки в поле "full_title" НЕ ИСПОЛЬЗУЕТСЯ!
⚠️ КРИТИЧЕСКИ ВАЖНО: Формат ссылки в поле "text" НЕ ИСПОЛЬЗУЕТСЯ!
Ссылка на рисунок должна выводиться СТРОГО в следующем виде:  пример: 
- Если ответа нет в предоставленных payload — ответь: "В доступной документации SUNRiSE эта информация отсутствует. Попробуйте переформулировать вопрос"
- ЗАПРЕЩЕНО: добавлять информацию из других payload, домысливать, использовать общие знания
# КОНТЕКСТ И РАБОТА С PAYLOAD
## PAYLOAD содержит контекст и ссылки на рисунки. Имеет следующую структуру JSON:
{
"payload_id": "", // уникальный идентификатор блока текста
"document_id": "", // идентификатор исходного документа
"document_name": "", // название файла документа
"score": "", // оценка релевантности блока запросу, чем выше — тем релевантнее (дробное число от 0 до 1)
"text": "", // текстовое содержимое блока, используемое для ответа
"images": [ // массив ссылок на рисунки, связанных с данным блоком (может быть пустым или отсутствовать)
{
"document_id": "", // идентификатор документа
"payload_id": "", // идентификатор payload, к которому относится рисунок
"full_title": "", // полное название рисунка в markdown-формате
"url": "" // путь для скачивания рисунка
}
]
}
# ФОРМАТ ОТВЕТА
- Выведи основной текст в виде абзацев
- Для пунктов меню указывай навигационный путь в скобках, например: (Отчеты → Отчет о работе освещения)
- После основного текста выводи ссылки на релевантные рисунки:
- Максимум 2 рисунка
# ПРАВИЛА ВЫВОДА ССЫЛОК РИСУНКОВ
## 1 Обязательная проверка перед выводом
Выводи рисунок ТОЛЬКО если выполнены ВСЕ условия:
1. Ты использовал текст из этого payload_id в своём ответе ✓
2. Рисунок находится в массиве "images" этого же payload_id ✓
3. Рисунок визуально иллюстрирует то, что ты написал ✓
## 2 Алгоритм действий
ШАГ 1: Составь ответ, запомни payload_id использованных блоков
ШАГ 2: Ищи рисунок ТОЛЬКО в массиве "images" этих payload_id
ШАГ 3: Из найденных выбери максимум 2 с наибольшим score
ШАГ 4: Выведи их строго в формате ниже
# ОБЯЗАТЕЛЬНЫЙ ФОРМАТ ВЫВОДА ССЫЛОК РИСУНКОВ
Ссылка на рисунок должна выводиться СТРОГО в следующем виде:

Пример НЕПРАВИЛЬНОГО вывода (так делать ЗАПРЕЩЕНО):
![Рисунок 14][Отчет о работе освещения для детальной диагностики системы управления освещением]
Пример ПРАВИЛЬНОГО вывода:

Описание полей:
- {title} — текст из поля full_title без квадратных скобок и номеров
- {url} — значение из поля images.url
ВНИМАНИЕ!!! URL В ССЫЛКЕ ОБЯЗАТЕЛЕН
## АЛГОРИТМ ФОРМИРОВАНИЯ ССЫЛКИ:
1. Найди нужный images объект
2. Возьми full_title: "![Рисунок 14][Отчет о работе освещения...]"
3. Извлеки текст между вторыми квадратными скобками: "Отчет о работе освещения..."
4. Возьми url: "/rag/loaded-document-image/download/53951f3d-dc66-4514-917e-88a4349dd380"
5. СОБЕРИ: 
## 4 ЗАПРЕЩЕНО
- ❌ Использовать images из payload_id, которые НЕ использовал в ответе
- ❌ Использовать images из других document_id
- ❌ Менять url или full_title
- ❌ Добавлять ссылку на рисунок "для полноты картины"
# СТИЛЬ ОТВЕТА
- Тон: профессиональный, без приветствий
- Формат: связные абзацы (НЕ списки, НЕ таблицы)
- Термины SUNRiSE используй как в документации
- Перефразируй содержание своими словами, но сохраняй точность
- Пути меню указывай в скобках: (Отчеты → Отчет о работе)
# ПРИМЕР ВОПРОС - ОТВЕТ
JSON содержит:
- payload_id: 1952 (score: 0.56) с текстом про диаграммы с 5 секторами + 3 ссылки на рисунки
- payload_id: 1953 (score: 0.54) с текстом про диаграммы с 1 сектором + 3 ссылки на рисунки
Вопрос: "Дай диаграмму MS HB PRO с 5 секторами"
Правильные действия:
1. Использую текст из payload_id: 1952 (выше score и содержит "5 секторов")
2. Ищу рисунок ТОЛЬКО в images массиве payload_id: 1952
3. Выбираю 2 наиболее релевантных
4. Вывожу их с url из этого же payload
Неправильно:
- Взять текст из 1952, а ссылку на рисунок из 1953 ❌
- Вывести все ссылки на рисунки сразу ❌
- Изменить full_title ❌
Долгое время чат с ИИ не взлетал. Пользователи запрашивали схемы подключения, интерфейсы - рисунки, когда получали в ответ чистый текст - снова приходилось лезть на диски с документацией. Лично для меня уже был прорыв - когда на вопросы про типы заземлений в шкафах управления нагрузкой, расстояние между контроллерами - пользователь получал четкий и красивый ответ, но пользователь думал совсем иначе.
Были следующие стратегии как продавить через LLM рисунки:
Векторизовать названия рисунков и делать по ним доп запрос. Оценили - есть высокий шанс получить рисунки совсем из других документов - отказались.
При прикреплять рисунки, найденные в смысловом блоке - к payload этого блока. На этом остановились.
Claude при разметке на блоки форматирует названия рисунков в MD формат: ![Рисунок 2.][Кабель LAPP FLEXICORE 100] - при обработке текста -ссылки на эти рисунки выделяются и сохраняются в отдельную таблицу.
Потом, в отдельном интерфейсе (рисунок 3) ручками происходит сопоставление того, что из текста документа выделил Claude и из PDF этого документа выделил LangChain.
По ходу пьесы вскрылись необычные нюансы, а которых мы раньше не задумывались или руки не доходили поискать и исправить..
Найти какие-то ошибки или устаревшую информацию в куче документов - нереально. Но, после векторизации, документы, как бы, наложились друг на друга и аналогичные смысловые блоки разных документов начали вылетать в RAG рядом. LLM начала глючить в противоречивой информации - поправить понятные места - было уже делом шлифовки, когда понятно где и что.
Специального технического редактора у нас нет, поэтому разные документы могут быть написаны разными авторами в разном стиле. Иногда цель создания документа - побыстрее напечатать чтобы приложить к отправке оборудования.
И, самое главное, много документации написано чтобы быть написанной, а не для того, чтобы ответить на вопросы пользователей. Соответственно, FRIDA далеко не всегда находит нужные куски документации по запросу пользователя. Грубо говоря - авторы и пользователи говорят на разных языках.
Данный момент - самый главный. Векторизация документации - мероприятие вторичное, не смотря на то, что занимает реальные человеко-часы. Основная задача: ответить на вопросы пользователей так, чтобы они не вернулись к сервисным инженерами (или вернулись, но с разогретым мозгом). Получается, что самым ценным в этом небольшом проекте - являются вопросы пользователей. Вопросы, которые невозможно сгенерировать сервисными инженерами или LLM, тут нужны слепые эксперименты.
В результате, появилось несколько дополнительных документов, название которых начинается с “Типовые вопросы по…”
“В прошлом веке” - еще год назад, на технические вопросы пользователей, которые пробивались через паспорта, инструкции, сервисных инженеров и проектировщиков, собирался консилиум, разрабатывался ответ, вычитывался - отправлялся чуть ли не официальным письмом.
Теперь все обращаются к SUNRiSE_AI, просят проверить ответ, если ок - то ответ летит пользователю. Если ответ не ОК, то происходит быстрая доработка документации и появляется новая, очень полезная информация для людей. Мир изменился радикально.
Постепенно, интеграторы получаются ссылку на Телеграмм бота и перестают писать по каждому поводу.
В итоге, к RAG по документации программисты прикрутили обычное REST API и я в n8n за несколько часов накидал автоматизацию (рисунок 4), аналог которой в нашей Цифровой платформе занял порядка 80 человеко-часов. Причем, тут уже действует АИ Агент, а не одноходовой запрос. То есть, агент может переформулировать вопросы пользователя, несколько раз дернуть базу. В общем - широкое поле для тюнинга и развития.
Документация приведена в порядок с помощью AI, для AI, но конечный получатель плюсов - человек.
Создана очень интересная система векторизации документов. Вероятно, существуют подобные сервисы, но тут прямо внутри цифровой платформы лежит куча информации, к которой есть доступ через API.
Попробовали локальную LLM. Qwen очень хорош, хоть пока и медленный на маленькой карточке. Однозначно у маленьких локальных моделей - большое будущее.
Модное, стильное, молодежное направление AI в продуктовой компании в простой реализации - поднимает доверие клиентов.
Изменилось отношение к ведению документации. Сейчас для всех главное, чтобы на любой вопрос существовал ответ. Если подходить так - мир меняется.
Ну а лично я испытываю неимоверную радость, когда в логах ботов появляются вопросы и ответы. Видно как нудную работу делают роботы, делают хорошо, комплексно, а мне остается только чуть редактировать их поведение.
Следующий шаг - сделать кнопку Где я в Цифровой Платформе.
Источник


