Привет, Хабр! Меня зовут Дмитрий Титов, я DevOps-инженер в команде интеграционных сервисов Platform V Synapse в СберТехе. Наша команда работает над продуктом Platform V Streaming Event Processing — программным решением для фильтрации и трансформации форматов событий, агрегирования и выявления аномалий и закономерностей. Это enterprise‑решение, которое обрабатывает миллионы событий в секунду в режиме реального времени. Чтение входящего потока и запись результата обработки происходит из топиков сервиса передачи событий, а правила обработки задаются с помощью собственного декларативного DSL.

Представьте типичную ситуацию: вам нужно настроить очередной обработчик потоковых данных. Вы открываете документацию на 200 с лишним страниц, где описаны десятки типов источников, трансформаций, фильтров и политик обработки ошибок. Ищете нужные параметры в разделах про Kafka, RabbitMQ/ArtemisMQ, GRPC, PostgreSQL и так далее. Вспоминаете синтаксис DSL — а он различается для разных типов операций. Копируете похожую конфигурацию из прошлого проекта, найденную в корпоративном Git‑репозитории, и правите её под новые требования. Переключаетесь между вкладками браузера с документацией и IDE.

На это уходит от 30 минут до нескольких часов, а в итоге всё равно можно допустить ошибку в синтаксисе, неправильно сконфигурировать источник данных или пропустить важный параметр безопасности.

А что, если сократить этот процесс до 30 секунд? Просто описать задачу на естественном языке — «Настрой обработчик для фильтрации событий от Kafka, оставь только записи с user_id больше 1000 и приоритетом high, результат отправь в новый топик» — и получить готовую конфигурацию, адаптированную под специфику нашего продукта. Не абстрактную YAML или CONF-заготовку, которую ещё нужно подгонять под продукт, а конфигурацию с правильными параметрами, корректным синтаксисом DSL для трансформаций и с соблюдением архитектурных паттернов продукта, готовую к проверке и применению в промышленной среде.

В этой статье я расскажу, как мы создали систему автоматического генерирования конфигураций для одного из компонентов нашего продукта, используя RAG (Retrieval-Augmented Generation), векторные базы данных и межагентное взаимодействие по протоколу A2A.

Немного о проблематике

Инженеры, работающие с системами потоковой обработки данных, ежедневно сталкиваются с необходимостью создавать конфигурации для различных систем. Это обработчики данных, сложные многошаговые трансформации, политики обработки ошибок, правила маршрутизации событий между сервисами. При этом приходится изучать объёмную документацию на сотни страниц, где каждый компонент системы описан в отдельном разделе.

Разработчик должен помнить синтаксис множества форматов: YAML/JSON для основных конфигураций, специфичные форматы для описания политик безопасности. Но самое сложное — работа с проприетарным DSL для описания трансформаций данных. Создание одной конфигурации средней сложности занимает от 30 минут до нескольких часов. За это время инженер переключается между задачами, теряет контекст, отвлекается на поиск информации.

Классический подход — копипаст из предыдущих проектов с ручными правками — не только медленный, но и чреват ошибками. Каждая опечатка в имени параметра, неверный отступ в YAML, забытый обязательный параметр или устаревшая версия синтаксиса из старой конфигурации превращается в потерянное время на отладку. А если речь идёт об эксплуатационной среде, то цена ошибки может быть очень высокой.

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

Специфика DSL для трансформаций

В Platform V Synapse Streaming Event Processing используется проприетарный DSL для описания трансформаций потоковых данных — tr-файлы. Это декларативный язык, специально разработанный для наглядного описания трансформаций без необходимости писать императивный код на Java или Python.

DSL позволяет описывать маппинг полей — преобразование структуры входящего события в требуемую структуру выходного, с переименованием полей, извлечением вложенных значений из JSON, объединением нескольких полей в одно. Фильтрация событий реализована через выражения с поддержкой сложных условий, логических операторов, функций для работы с датами, строками, числами, регулярными выражениями. Есть обогащение данными из внешних источников. Система поддерживает работу с окнами агрегации, группировку по ключам и применение агрегирующих функций.

Вот пример простой трансформации на этом DSL:

define isFirst = true
for ($data: in) {
    if ($isFirst) {
        out[>] = $data
        headers[>].TargetKey = generateId()
        define isFirst = false
    } else {
        out[+>] = $data
        headers[+>].TargetKey = generateId()
    }
    INFO("RESULT", out, "TEST.OUT", "-")
}

Для LLM этот DSL нестандартный, его не было в обучающей выборке GigaChat или других публичных моделей. Модель не может просто «вспомнить» синтаксис, как это было бы с Python или SQL. Попытка сгенерировать tr-файл без дополнительного контекста приводит к галлюцинациям: модель может выдумать несуществующие функции, использовать синтаксис от других похожих языков, перепутать порядок секций.

Именно поэтому RAG становится не просто улучшением, а критически необходимым компонентом системы. Без доступа к актуальной документации и примерам невозможно корректно сгенерировать конфигурации на проприетарном DSL.

От идеи до готовой конфигурации за 30 секунд

Мы создали систему, которая за считанные секунды превращает естественно-языковое описание требований в корректную конфигурацию. Ключевая идея — использовать саму документацию продукта как источник знаний для искусственного интеллекта, а не пытаться обучить модель с нуля на специфичном DSL.

Процесс начинается с подготовительного этапа: загрузки всей документации по продукту в векторную базу данных. Мы берём официальную документацию в формате Markdown, специальный сервис разбивает документы на логические фрагменты (чанки) и превращает их в векторные представления — эмбеддинги. Этот процесс нужно выполнить только один раз при первоначальной настройке системы, далее векторная база обновляется только при изменении документации.

Инженер описывает требования к конфигурации на естественном языке, и магия начинается.

Запрос может быть сформулирован просто и понятно: «Создай обработчик, который читает события из топика user-actions, фильтрует только события типа purchase с суммой больше 1000 рублей, обогащает данными о пользователе из дополнительного топика и отправляет результат в топик high-value-purchases». Система не требует знания точного синтаксиса или имён параметров — она сама найдёт нужную информацию в документации.

Система анализирует запрос и через механизм RAG находит в документации релевантный контекст. Это не простой полнотекстовый поиск по ключевым словам, а семантический поиск по смыслу. Система понимает, что «читает события из топика» связано с разделом документации про источники Kafka, «фильтрует только события типа purchase» требует конфигурации фильтров, а «отправляет результат в топик» — настройку destination.

LLM получает найденные фрагменты документации и генерирует готовую конфигурацию с учётом контекста. Модель не просто генерирует текст наугад — она опирается на конкретные примеры из документации, использует правильные имена параметров, соблюдает синтаксис.

В результате получается конфигурация, которую можно сразу применить без дополнительной доработки, все обязательные параметры заполнены корректными значениями, соблюдены требования к структуре конфигурационных файлов продукта согласно текущей версии, применён корректный синтаксис DSL для трансформаций (если требуется).

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

Но генерирование это только половина дела.

Во время создания конфигурации агент-генератор по протоколу A2A вызывает агент-валидатор. Тот получает сгенерированную конфигурацию и исходный запрос пользователя, после чего проверяет, действительно ли конфигурация решает поставленную задачу? Все ли обязательные параметры указаны? Нет ли логических ошибок или потенциальных проблем с производительностью? Валидатор может ответить «конфигурация корректна» или запросить исправления: «в секции filters пропущен обязательный параметр field_name» или «для production-среды рекомендую добавить SSL-подключение».

Агенты итеративно взаимодействуют до получения валидной конфигурации. Это может занять несколько циклов: генератор создаёт первую версию, валидатор находит проблемы, генератор исправляет с учётом замечаний, валидатор проверяет снова. Обычно требуется от одной до трёх итераций. Этот процесс полностью автоматический и занимает секунды, а не часы ручной отладки.

После того как конфигурация прошла ИИ-проверку, её можно дополнительно проверить статическими методами. Config Validator проверяет, что YAML синтаксически корректен, JSON-схемы корректны, а если конфигурация предназначена для развёртывания в Kubernetes — проверяет соответствие спецификации манифеста.

Можно настроить кастомные проверки через регулярные выражения: например, убедиться, что имена топиков соответствуют корпоративному соглашению об именовании (naming convention). Готовый результат можно сразу применить в кластере через встроенный механизм развёртывания или скопировать и использовать в существующем CI/CD pipeline.

Векторные базы данных: как ИИ понимает документацию

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

Что такое эмбеддинг

Эмбеддинг — это способ представить текст в виде числового вектора фиксированной длины, обычно от 384 до 1536 измерений в зависимости от модели.

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

Например, рассмотрим три фразы из документации: «источник Kafka» может быть представлен вектором [0.82, -0.33, 0.15, 0.67, ...], «Kafka input» — вектором [0.81, -0.35, 0.14, 0.65, ...], а «читать из очереди сообщений» — [0.77, -0.33, 0.14, 0.63, ...].

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

Важно понимать, что эмбеддинги не просто считают количество общих слов. Модель, создающая эмбеддинги, обучена на огромных объёмах текстов и понимает контекст, синонимы, связи между концепциями. Поэтому «Kafka source» и «читать из топика» будут иметь близкие эмбеддинги, даже если у них нет общих слов.

Индексация документации

При загрузке документа в систему происходит несколько важных этапов обработки.

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

Размер чанка мы настраиваем в зависимости от специфики документации. Для справочной документации с короткими описаниями параметров оптимальный размер — 256-512 токенов. Мы используем перекрытие (overlap) между чанками размером 10-20% от размера чанка. Это означает, что последние несколько предложений одного чанка повторяются в начале следующего. Зачем? Чтобы сохранить контекст на границах. Если описание какой-то концепции попадает на границу между чанками, то перекрытие гарантирует, что в одном из чанков описание будет представлено целиком.

Каждый чанк превращаем в вектор с помощью модели Embeddings от Сбера. Мы выбрали её, потому что она специально обучена на русском языке и создаёт качественные семантические представления русскоязычных технических текстов. Модель понимает специфичную терминологию, аббревиатуры, технический жаргон.

Векторные представления сохраняются в Platform V Vector DB — специализированной векторной базе данных, предназначенной для высокопроизводительного семантического поиска. Вместе с векторами мы храним исходный текст фрагмента и метаданные: источник документа, раздел, дату обновления, теги (например, kafka, filters, security). Это позволяет точно искать с фильтрами — например, только по материалам для Kafka или только по разделам, связанным с безопасностью.

Скажем, документ с правилами конфигурирования сетевых политик можно разбить так: чанк «Запретить весь входящий трафик по умолчанию» получит вектор [0.76, -0.21, 0.94, ...] и метаданные {source: "network-policy.yaml", section: "ingress-rules", tags: ["security", "network"]}, а следующий чанк «Разрешить порт 80 только из namespace frontend» получит свой вектор [0.68, -0.19, 0.91, ...] и похожие метаданные. При поиске по запросу «настроить доступ к сервису только для фронтенда» система найдёт оба этих чанка как релевантные, причём второй получит больше баллов.

RAG: Retrieve-Augment-Generate

Давайте разберёмся, почему простого использования LLM недостаточно для нашей задачи. Современные языковые модели, такие как GigaChat, GPT или Claude, обладают впечатляющими способностями к генерированию текста и пониманию контекста. Но у них есть фундаментальные ограничения.

Во-первых, модель может не знать специфики вашей документации. GigaChat обучен на публичных данных из интернета, но нашей внутренней документации по Platform V Synapse Streaming Event Processing, проприетарного DSL и корпоративных стандартов в обучающей выборке не было.

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

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

RAG (Retrieval-Augmented Generation) — это архитектурный паттерн, где модель не полагается только на знания, полученные при обучении, а сначала получает актуальный контекст из внешнего источника — в нашем случае из векторной базы с документацией. Это принципиально меняет подход: модель становится не источником знаний, а интерпретатором документации, который умеет понимать запрос пользователя и правильно применять информацию из найденных фрагментов.

Три этапа RAG

Retrieve (Поиск). Когда пользователь вводит запрос, система не сразу отправляет его в LLM. Сначала запрос векторизируется — превращается в эмбеддинг той же моделью Embeddings, которая использовалась для индексации документации. Получается вектор запроса. Затем система ищет в векторной базе данных чанки с наиболее похожими векторами, вычисляя косинусное сходство между вектором запроса и векторами всех чанков в базе.

Это семантический поиск: мы ищем не по точным совпадениям слов, а по смыслу. Например, запрос «настроить фильтрацию событий по полю timestamp больше вчерашней даты» найдёт релевантные фрагменты, даже если в документации используются другие формулировки вроде «временная фильтрация», «отсечение по времени», «filter by time field» или примеры с другими названиями полей. Модель понимает, что все эти фразы семантически близки.

Система возвращает топ-K наиболее релевантных чанков, обычно K=3-5. Больше не всегда лучше: слишком много контекста может запутать модель, увеличивает токены в промпте (а значит, стоимость и время обработки), может включить менее релевантную информацию. Мы экспериментально подобрали оптимальное значение для нашей системы.

Augment (Обогащение). Найденные чанки не просто конкатенируются, они структурируются и форматируются. Формируется промпт, состоящий из нескольких секций. System_prompt задаёт роль агента и правила поведения, вот часть системного промта:

Ты — генератор конфигурационных файлов и DSL-трансформаций для Cloud Event Processing, действующий строго по спецификации и переданному контексту.

Основные требования:

Используй только информацию из этого промпта.

Генерируй только синтаксически и семантически валидные конфигурации и DSL-файлы по спецификации или переданному контексту.

Все обязательные поля должны быть заполнены. Если невозможно корректно заполнить обязательное поле — не генерируй файл.

Не используй конструкции, блоки, параметры, функции или синтаксис, не описанные в спецификации или переданном контексте. Любое отклонение — ОШИБКА.

Не добавляй пояснений, описаний, комментариев или вымышленных элементов ни в одном из файлов.

Если необходимы несколько файлов (например, config и transform), выводи каждый с указанием имени и расширения отдельным блоком.

Для улучшения качества генерирования используй информацию, переданную в поле контекст.

Имя и расширение файла — первой строкой блока. Дубли имён не допускаются.

Context включает в себя релевантные фрагменты из документации, отформатированные специальным образом. Каждый фрагмент предваряется заголовком, указывающим источник: «Из раздела "Конфигурация источников Kafka":», «Пример из документации:», «Best practice:». Это помогает модели понять, какая информация откуда взята и как её следует интерпретировать. Если найдены примеры кода, то они включаются целиком с комментариями.

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

Generate (Генерирование). Полностью сформированный промпт отправляется в GigaChat. Важный нюанс: мы используем специфичные параметры генерирования. Temperature (температура) установлена на относительно низкое значение около 0,5, это делает генерирование более детерминированным и предсказуемым, что критично для генерирования кода и конфигураций. High temperature (0,8-1,0) хороша для творческих задач, но в нашем случае может привести к «творческим интерпретациям» синтаксиса.

LLM генерирует ответ, опираясь как на свои базовые знания о форматах YAML/JSON и общих принципах конфигурирования, так и на предоставленный контекст из документации. Это гарантирует, что конфигурация будет соответствовать актуальной спецификации продукта, использовать правильные имена параметров, соблюдать версию API, следовать лучшим корпоративным практикам.

Микросервисная архитектура решения

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

Сервис

Функция

UI Service

Веб-интерфейс для взаимодействия с системой

DB Service

REST API для работы с реляционной БД

Vector Generator

Создание и наполнение векторных баз

Vector Loader

Семантический поиск контекста в векторных БД

Config Generator

Генерирование конфигураций через GigaChat с RAG

AI Validation Agent

ИИ-проверка через межагентное взаимодействие

Config Validator

Статическая проверка форматов и синтаксиса

Config Deployer

Применение конфигураций в Kubernetes

Каждый сервис — это отдельный Docker-контейнер с собственной конфигурацией ресурсов, политиками restart, health check endpoints. Взаимодействие между сервисами происходит по REST.

UI Service

Это единая точка входа для инженеров. Функциональность включает в себя управление полным циклом работы с конфигурациями. Это лишь один из вариантов реализации, система спроектирована так, что к остальным сервисам можно обращаться напрямую через REST API, интегрировав их в существующие процессы CI/CD.

Например, можно настроить Jenkins pipeline, который вызывает Config Generator API для автоматического генерирования конфигураций на основе параметров из Git-репозитория, проверяет результат через Config Validator и применяет через Config Deployer. Интерфейс — это уровень представления для интерактивной работы, но не обязательное звено.

DB Service

Это центральное хранилище метаданных системы и REST API для работы с СУБД. База хранит в себе системные промпты для различных типов конфигураций. Каждый тип конфигурации имеет свой оптимизированный промпт с инструкциями для модели, примерами желаемого формата вывода, списком обязательных и опциональных параметров.

Правила проверки хранятся в структурированном виде: регулярные выражения шаблонов для проверки имён, диапазоны для числовых параметров, списки допустимых значений для полей с перечислениями. Шаблоны для развёртывания — это шаблоны Jinja2 для Kubernetes-манифестов с заглушками для подстановки сгенерированных конфигураций.

Метаданные векторных баз включают в себя название базы, описание, дату создания, количество чанков, используемую модель embeddings, параметры чанкинга (размер, перекрытие), статус (активна/неактивна), теги для фильтрации.

История генерирований журналируется полностью: timestamp запроса, user_id, текст запроса, тип конфигурации, использованные векторные базы, найденный контекст, сгенерированная конфигурация, результаты проверки, статус развёртывания (если применялся). Эти данные бесценны для анализа качества работы системы и её совершенствования.

Vector Generator

Это ETL-pipeline для документации. Он отвечает за создание и наполнение векторных баз знаний, трансформируя неструктурированные тексты в векторные представления, по которым можно искать (searchable embeddings).

Процесс начинается с создания векторных баз: инициализации новой базы (коллекции) в Platform V Vector DB с заданными параметрами. Затем идёт обработка документов: загрузка файлов различных форматов с автоматическим определением формата и парсингом.

Далее происходит разбиение на чанки, размер которых настраивается для каждой векторной базы индивидуально — 256 или 512 токена. Перекрытие (overlap) также настраивается: обычно это 10-20% от размера чанка, но для технической документации с большим количеством перекрёстных примеров может быть увеличен до 30%. После этого генерируются эмбеддинги.

Синхронизация метаданных — финальный этап, на котором информация о векторной базе регистрируется в DB Service для дальнейшего использования другими компонентами. Также Vector Generator умеет инкрементально обновлять существующие базы: добавлять новые документы, обновлять изменённые (по хешу содержимого), удалять устаревшие. Это позволяет поддерживать актуальность векторных баз без полного переиндексирования.

Vector Loader

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

Работа начинается с запроса активных векторных баз из DB Service. Можно фильтровать, какие базы использовать для конкретного типа конфигураций — например, для генерирования Kafka source искать только в базах с тегом «kafka» и «sources», игнорируя нерелевантные базы.

Формирование контекста — это топ-5 чанков по коэффициенту сходства (similarity score) с исходным запросом.

Результат — упорядоченный список чанков с метаданными, готовый для подстановки в промпт.

Config Generator

Сердце системы, оркестратор всего процесса генерирования. Это асинхронный сервис для работы с GigaChat API. Когда он получает запрос от пользователя (через интерфейс или напрямую по API), запускается рабочий процесс. Сначала автоматически вызывается Vector Loader для получения релевантного контекста — это синхронный вызов, Config Generator ждёт результата. Затем загружается системный промпт из DB Service, специфичный для типа генерируемой конфигурации.

Формируется полный запрос, объединяющий системный промпт, контекст и пользовательский запрос. Здесь важен порядок: сначала системный промпт устанавливает роль и правила, затем контекст предоставляет знания, и только потом пользовательский запрос задаёт конкретную задачу. Это помогает модели правильно приоритизировать информацию.

Запрос отправляется в GigaChat с конфигурацией параметров генерирования.

Получив сгенерированную конфигурацию, Config Generator не сразу возвращает её пользователю. Вместо этого автоматически запускается проверка. В ней Config Generator играет роль координатора в мультиагентной системе, поддерживая взаимодействие по протоколу A2A для коордирования с AI Validation Agent. Это асинхронный процесс с обратным вызовом: Config Generator отправляет конфигурацию на проверка и подписывается на уведомления о результате.

AI Validation Agent

Это второй ИИ-агент в системе, специализирующийся на проверке. Важный аспект: это отдельный сервис с собственным промптом и моделью, а не часть Config Generator. Почему? Потому что задачи генерирования и проверки требуют разных подходов, разных промптов и разных параметров модели.

Агент получает по протоколу A2A запрос на проврек, содержащий сгенерированную конфигурацию, исходный запрос пользователя и контекст из документации (те же чанки, что использовались при генерировании). Это критично: валидатор должен видеть тот же контекст, чтобы оценивать корректность относительно актуальной документации, а не абстрактных представлений о «правильности».

Выполняется несколько типов анализа. Анализ корректности проверяет, действительно ли конфигурация решает поставленную задачу — если пользователь просил «фильтровать по user_id > 1000», то есть ли в конфигурации соответствующий фильтр? Правильно ли указаны параметры? Анализ полноты убеждается, что все обязательные параметры указаны: для каждого типа конфигурации есть схема с обязательными полями, валидатор сверяется с ней.

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

Анализ безопасности — один из самых важных — выявляет потенциальные проблемы: используется ли TLS для передачи данных, нет ли жёстко заданных секретов в конфигурации. Валидатор обучен распознавать паттерны небезопасных конфигураций.

Агент возвращает структурированный ответ: общий вердикт (valid, invalid, warning), показатель уверенности (насколько агент уверен в оценке, от 0 до 100), список проблем (каждая с указанием приоритета: error, warning, info, местоположение в конфигурации, описание проблемы) и общие рекомендации по улучшению. Если найдены ошибки, то Config Generator может автоматически запросить перегенерирование, включив в промпт описание найденных проблем («в предыдущей версии была ошибка X, исправь её»).

Config Validator

Это уровень защиты от синтаксических ошибок и нарушений схемы, который работает параллельно с AI Validation Agent. Классический валидатор без ИИ, но не менее важный.

Проверка YAML-/JSON-форматов использует yamllint и встроенные Python-парсеры с детальными сообщениями об ошибках — не просто «invalid YAML», а «line 15, column 3: expected indentation of 2 spaces but found 4». Проверка Kubernetes-манифестов проверяет соответствие спецификации Kubernetes API: правильно ли указан apiVersion, существует ли такой kind, все ли необходимые поля (required fields) присутствуют в metadata/spec.

Regex-проверка для специфичных паттернов: можно задать правила вроде «имена топиков должны соответствовать паттерну ^[a-z0-9-]+$», «порты должны быть в диапазоне 1024-65535», «namespace не может быть 'default' для production». Dry-run в Kubernetes — финальная проверка перед реальным применением: отправляем манифест в Kubernetes API с флагом dryRun=true, API проверяет корректность без реального создания ресурсов.

Результаты всех проверок объединяются в единый отчёт с категоризацией по типам замечаний и рекомендациями по исправлению.

Config Deployer

Финальное звено цепочки, отвечающее за безопасное развёртывание конфигураций в Kubernetes.

Система поддерживает два режима работы. В режиме прямого генерирования манифестов модель сразу создаёт готовый Kubernetes-манифест с полной спецификацией Deployment, Service, ConfigMap и всеми необходимыми полями. Это быстрее, но менее гибко. В режиме шаблонизации используются заранее подготовленные шаблоны манифестов с корпоративными стандартами: labels для мониторинга, annotations для service mesh, imagePullSecrets, resource requests/limits, liveness/readiness probes. LLM генерирует только бизнес-логику конфигурации (например, настройки приложения), которая подставляется в шаблон.

Второй подход гарантирует согласованность развёртываний, соблюдение корпоративных политик, интеграцию с существующей инфраструктурой. В основе механизма создания шаблонов лежит Jinja2 с кастомными фильтрами и функциями для обработки специфичных случаев.

Полный цикл работы системы

Давайте на реальном примере проследим детальный путь от запроса до применённой конфигурации.

Пользователь — инженер Алексей — получил задачу: нужно настроить обработчик для фильтрации событий от источника Kafka, оставить только события от пользователей с user_id больше 1000 и приоритетом high, результат отправить в новый топик для дальнейшей обработки. Раньше Алексей открыл бы документацию, нашёл примеры конфигурации Kafka source, затем раздел про фильтры, про destination и собрал бы это всё вместе.

Теперь Алексей просто открывает интерфейс нашей системы, выбирает тип конфигурации Cloud Event Processing, вводит в текстовое поле: «Настрой обработчик для фильтрации событий от источника Kafka топик user-events, оставь только события с user_id > 1000 и priority == 'high', результат отправь в топик high-priority-users». Нажимает «Запустить генерацию».

Vector Loader получает запрос, векторизирует его через Embeddings, ищет в векторных базах. Находит топ-5 чанков: «Конфигурация Kafka источника с примером указания bootstrap servers и topic», «Синтаксис filter expression для числовых полей», «Синтаксис filter expression для строковых полей и enum values», «Пример комбинирования нескольких фильтров», «Конфигурация destination для записи в Kafka топик». Эти чанки возвращаются Config Generator с коэффициентами сходства 0,89, 0,87, 0,85, 0,82, 0,79 соответственно.

Config Generator получает системный промпт из DB Service, который содержит инструкцию: «Генерируй конфигурацию в формате CONF. Структура: source, aggregationStep, transformStep, destination. Используй точный синтаксис из примеров. Не выдумывай несуществующие параметры». Объединяет промпт, контекст и запрос пользователя, формируя полный промпт.

Отправляет в GigaChat API с тщательно подобранными параметрами генерирования. Temperature=0.5, почему выбрано именно такое значение, мы обсудили выше. Однако мы передаём модели ещё один параметр — max_tokens со значением 1500, что ограничивает длину ответа. Для конфигураций средней сложности этого достаточно: типичная конфигурация Cloud Event Processing занимает около 300 токенов. Запас нужен для комментариев и возможных пояснений от модели. Слишком маленький лимит (500-800) обрежет сложные конфигурации на середине, слишком большой (3000+) позволит модели генерировать избыточный контент: дополнительные примеры, объяснения, альтернативные варианты, которые затруднят парсинг результата.

Config Generator по протоколу A2A автоматически отправляет эту конфигурацию AI Validation Agent. Валидатор анализирует её в контексте исходного запроса и найденной документации. Проверяет: есть ли фильтр по user_id > 1000? Да. По priority == 'high'? Да. Destination указан на правильный топик? Да. Все обязательные поля присутствуют? Проверяет source (type, config.bootstrap_servers и config.topic есть), transformStep (структура корректна), destination (type и config есть) — всё на месте.

Валидатор обращает внимание на то, что используется заглушку ${KAFKA_BOOTSTRAP} вместо фиксированного адреса — это соответствует стандартам компании, отмечает как положительное. Проверяет безопасность: нет ли учётных данных в открытом виде? Нет. Используется ли group_id для избежания дублирования обработки? Да. Показатель уверенности вычисляется как 0,94 (очень уверен).

Валидатор возвращает вердикт: {status: "valid", confidence: 0.94, issues: [], recommendations: ["Рассмотрите возможность добавления политики обработки ошибок для сообщений о сбоях"]}.

Config Generator получает положительный вердикт, запускает Config Validator для статической проверки. Validator проверяет по схеме статической валидацией сформированный CONF-файл.

В интерфейсе Алексей видит сгенерированную конфигурацию с зелёной галочкой«Validated» и рекомендациями в виде информационных подсказок. Конфигурация выглядит правильно. Алексей нажимает «Установить конфигурацию в пространство имён».

Config Deployer получает запрос, загружает из DB Service шаблон Kubernetes-манифеста для компонента Cloud Event Processing, подставляет сгенерированную конфигурацию в шаблон для развёртывания. Выполняет dry-run через Kubernetes API. API возвращает success — манифест корректен и будет принят. Deployer применяет конфигурацию. Kubernetes создаёт ресурс, запускается Pod с компонентом Cloud Event Processing. Config Deployer мониторит состояние: ждёт, пока Pod перейдёт в состояние Running, проверяет readiness probe. Через 15 секунд Pod готов, health check зелёный. Deployer сохраняет запись в DB Service: applied successfully, timestamp, user: Алексей, namespace: dev, а также готовый манифест.

В интерфейсеАлексей видит «Deployed successfully to dev namespace», зелёный индикатор, ссылку на Pod в Kubernetes dashboard. От запроса до рабочей конфигурации в кластере прошло 30 секунд. Алексей с улыбкой смотрит в монитор.

Как система работает с проприетарным DSL

Вернёмся к вопросу работы с tr-файлами — проприетарным DSL для трансформаций, который мы упоминали в начале статьи. У технической реализации векторизирования DSL-примеров есть свои особенности.

В векторной базе мы храним не просто текст документации, а специально структурированные примеры: полные рабочие tr-файлы, разбитые на смысловые блоки с аннотациями (скажем, «пример агрегации с временным окном»), комментарии с объяснением неочевидных конструкций и типичные паттерны использования с вариациями. Каждый пример векторизируется целиком, без разбиения на мелкие чанки — это критично для сохранения синтаксической целостности кода.

Когда пользователь запрашивает генерирование трансформации, Vector Loader по семантическому сходству задачи находит несколько наиболее релевантных примеров tr-файлов. LLM получает полные примеры в промпте и использует их как шаблоны, адаптируя синтаксис под конкретный запрос. Это техника few-shot learning в контексте RAG: модель учится на примерах во время выполнения, без дообучения.

В результате получаем высокую точность генерирования tr-файлов для проприетарного языка, которого нет в обучающей выборке модели.

Безопасность и приватность

Работа с корпоративной документацией и production-конфигурациями накладывает строгие требования к безопасности. Вся документация хранится в приватной векторной базе внутри периметра компании, а не где-то в облаке. Мы не отправляем во внешние API конфиденциальные данные. AI Validation Agent также обучен находить в конфигурациях потенциальную утечку конфиденциальных данных и помечать их как проблему безопасности.

Выводы

Мы создали сквозное решение для автоматического генерирования конфигураций потоковой обработки данных, которое сокращает время создания конфигурации с часов до секунд, благодаря автоматической проверке исключает ошибки copy-paste и опечатки. Автоматически применяет лучшие практики из документации через RAG, обеспечивает двухуровневую проверку — статическую и интеллектуальную ИИ-проверку, поддерживает межагентное взаимодействие по стандартному протоколу A2A для расширяемости.

RAG оказался идеальным решением для генерирования конфигураций на проприетарном DSL. Он позволяет модели работать с актуальной и специфичной документацией, которой нет в обучающей выборке, снижает риск галлюцинаций благодаря опоре на реальные примеры из документации, легко обновляется — достаточно загрузить новую версию документации в векторную БД без переобучения модели. Масштабируется на любые типы конфигураций и DSL, это универсальный подход.

Ключевые технологии проекта: RAG для контекстуализации генерирования, векторные базы данных Platform V Vector DB для семантического поиска по смыслу, Embeddings для создания качественных эмбеддингов русскоязычных технических текстов, GigaChat как основная LLM для генерирования и проверки, протокол A2A для межагентного взаимодействия и расширяемости, микросервисная архитектура для гибкости и масштабируемости.

Это решение можно адаптировать не только для Platform V Synapse, но и для любых enterprise-систем с объёмной документацией и конфигурациями. Архитектура универсальна — меняется только контент векторных баз и системные промпты.

Дополнительные материалы

Если у вас есть опыт внедрения RAG или генерирования кода или конфигураций с помощью LLM, то поделитесь в комментариях! Интересно сравнить подходы и вызовы, с которыми сталкиваются другие команды. Особенно интересны примеры с проприетарными DSL, техники борьбы с галлюцинациями, стратегии промпт-инжиниринга для генерирования кода.