Руководство администратора ИС "Платформа ИИ"
ООО "ГК "Иннотех", домен Искусственный интеллект, 2026 г.
Глоссарий
| Термин / Аббревиатура | Расшифровка / Описание |
|---|---|
| A2A | Agent-to-Agent протокол (версия 1.0) |
| Agent Registry | Каталог агентов: REST API, поиск, авторизация, мониторинг рабочих нагрузок в Kubernetes |
| Kubernetes Reconciler | Сервис Agent Registry, автоматически обнаруживающий и наблюдающий за рабочими нагрузками |
| Outbox Relay | Компонент Agent Registry, публикующий зафиксированные события в Redpanda |
| Search Indexer | Компонент Agent Registry, обновляющий разрешения SpiceDB и документы OpenSearch |
| Search Reindex | Задание Agent Registry для построения нового поколения поискового индекса |
| Retention | Задание Agent Registry, применяющее сроки хранения данных |
| Поток (Flow) | Визуальный граф (набор связанных узлов/компонентов), который описывает логику агента |
| Low-code Конструктор (Low-code IDE) | Среда визуального редактирования Потока (Flow) на основе адаптированной версии LangFlow (источник исходного кода) |
| Low-code Runtime | Среда выполнения агентов с низкой кодовой базой; исполняет одну версию одного агента |
| Garden | Единый инструмент сборки и деплоя компонентов платформы |
| Helm | Система управления пакетами Kubernetes, используемая через Garden |
| PostgreSQL | Каноническое хранилище метаданных каталога и рабочих версий Flow |
| Alembic | Система миграций базы данных PostgreSQL |
| SpiceDB | Хранилище разрешений и проверок доступа |
| Redpanda | Канал изменений событий (Outbox), отключён по умолчанию |
| OpenSearch | Поисковая проекция, отключена по умолчанию |
| OpenTelemetry Collector | Сбор метрик, трассировок и журналов |
| Keycloak | Временный издатель OpenID Connect для разработки |
| AI Gateway | Платформенная служба маршрутизации запросов |
| MCP | Model Context Protocol |
| SSE | Server-Sent Events |
| SSO | Single Sign-On |
| OIDC | OpenID Connect |
| REST API | Application Programming Interface на основе HTTP |
| SBOM | Software Bill of Materials — перечень компонентов образа |
| FileRef | Ссылка на файл в объектном хранилище |
| lfx | Внутренний интерфейс LangFlow, не публикуется наружу |
| PlatformRAG | Платформенный сервис retrieval-augmented generation: реестр коллекций, приём нормализованных документов, гибридный поиск с фильтрацией по правам доступа |
| PlatformMemory | Управляемый сервис памяти агентов: персистентная память, поиск и дедупликация фактов |
| Principal | Пользователь или сервис в каталоге |
| Workspace | Рабочая область — контейнер агентов и участников |
| Team | Команда-владелец агента |
| traceId | Безопасный идентификатор события для связи логов и трассировок |
| Коллекция | Управляемый индекс знаний: профиль эмбеддинга, модель ACL, стратегия чанкинга, параметры поиска |
| Ingest | Асинхронный приём: регистрация задания → чанкинг → эмбеддинг → индексация |
| Retrieval | Синхронный поиск: гибридный kNN+BM25, слияние RRF, фильтр tenant+ACL, цитаты |
| RAG API | Stateless HTTP-сервис (platform-rag-api), порт 8090 |
| RAG Worker | Процесс platform-rag-worker, обрабатывающий задания ingest из RabbitMQ |
| Job store | Таблица platform_rag.ingest_job в PostgreSQL — источник истины по заданиям приёма |
| ACL | Список групп и субъектов на документе; перепроверяется в момент запроса |
| Act-цепочка | Делегированная идентичность пользователя (JWT / заголовки), по которой строится фильтр выдачи |
| Fail-closed | При недоступности AuthZ сервис отвечает 503 и не выдаёт данные |
| RRF | Reciprocal Rank Fusion — слияние ранжированных списков vector/BM25 |
| KEDA | Автомасштабирование воркеров по числу заданий PENDING в PostgreSQL |
| RabbitMQ | Брокер уведомлений ingest (exchange: rag.ingest, quorum-очередь rag.ingest.jobs) |
| Guardrails | Система проверки текста (запросов и ответов модели) на запрещённое содержимое: отказ, маскирование или пропуск |
| Guardrails Runtime | Отдельный процесс проверки текста: загружает неизменяемый набор политик при старте, выдаёт решение pass/deny/mask |
| Политика Guardrails | Версионируемый набор правил проверки на двух стадиях — request (вход) и response (выход) |
Общие сведения
Платформа ИИ обеспечивает создание, регистрацию, каталогизацию и вызов AI-агентов в среде Kubernetes. Платформа состоит из основных компонентов, каждый из которых имеет собственную границу данных и зону ответственности.
Low-code IDE (Low-code Конструктор) — среда визуального редактирования Flow на основе адаптированной версии LangFlow (LangFlow — источник исходного кода; платформенное наименование компонента — Low-code Конструктор). Она обеспечивает вход пользователей через платформенный SSO, отображение разрешённой палитры компонентов, серверную проверку схем, сохранение рабочих версий и публикацию проверенных версий Flow как агентов в каталоге Платформы ИИ через Control Plane. Low-code IDE не занимается исполнением запросов, развёртыванием среды выполнения или управлением записями каталога.
Low-code Runtime — неизменяемая среда выполнения, в которой один экземпляр выполняет одну версию одного агента. Runtime принимает Flow и манифест по токену, проверяет контрольные суммы, загружает Flow и публикует согласованные A2A и MCP интерфейсы. Внутренний административный API LangFlow и интерфейс lfx не публикуются наружу. Runtime не подключается к базе Low-code IDE и не загружает изменяемые рабочие копии.
Agent Registry — каталог агентов с REST API, поиском и авторизацией. Он автоматически обнаруживает рабочие нагрузки в Kubernetes через Reconciler (по Service и EndpointSlice), загружает карточки агентов, проверяет соответствие заявленных возможностей, управляет разрешениями через SpiceDB и обеспечивает транзакционную доставку событий через Redpanda. Поиск проекцируется в OpenSearch. Agent Registry не создаёт записи вручную — регистрация происходит автоматически.
Platform RAG — платформенный сервис уровня COMMON, предоставляющий управляемое извлечение знаний (retrieval-augmented generation): реестр коллекций, приём нормализованных документов, гибридный поиск с обязательной фильтрацией по правам доступа и выдачу фрагментов с цитатами. Потребители обращаются к сервису через санкционированные пути: платформенный SDK (platform-rag) или кастом-компонент low-code. Построение собственного retrieval внутри Flow (generic HTTP, ключи моделей во Flow, захардкоженные URL) не допускается. Platform RAG использует PostgreSQL (реестр коллекций и job store), RabbitMQ (очередь ingest), OpenSearch (индекс чанков: knn_vector + BM25), AI Gateway (эмбеддинг и реранк), SpiceDB (права на коллекцию) и S3/MinIO (staging документов).
Platform Memory — единый управляемый слой памяти платформы. Агент получает персистентную память: search перед ответом, add после ответа. Извлечение фактов, дедупликация, гибридный поиск, изоляция по скоупам и история изменений выполняются сервисом, а не каждым агентом отдельно. Память не заменяет RAG. Platform RAG отвечает за корпус документов; Platform Memory — за знания о пользователе, агенте и сессии. Сборка промпта комбинирует оба источника. Публичный контракт совместим с mem0 (add / search / get_all / history / delete). Сервис использует PostgreSQL (event store и история), RabbitMQ (уведомления о заданиях add), OpenSearch (индекс фактов: kNN + BM25) и AI Gateway (эмбеддинг и LLM-извлечение).
Guardrails — система проверки текста (запросов и ответов модели) на запрещённое содержимое: отказ, маскирование или пропуск. Control Plane хранит версии политик и привязывает их к модели; отдельный процесс Guardrails Runtime загружает неизменяемый набор правил при старте и выдаёт решение. Детали — в разделе «Guardrails».
Все компоненты развёртываются через Garden — единый инструмент сборки и деплоя. Ручные helm upgrade, kubectl apply или docker-compose не образуют воспроизводимый путь поставки.
Архитектура
Компоненты платформы
| Компонент | Назначение | Основные сигналы |
|---|---|---|
| Agent Registry API | Каталог, получение записи и поиск с учётом прав доступа | Работоспособность, готовность, время ответа, коды 401/403/404/503 |
| Kubernetes Reconciler | Мониторинг Service, EndpointSlice и разрешённых HTTPRoute | Свежесть покрытия, ошибки наблюдения, повторный список, задержка согласования |
| Outbox Relay | Публикация зафиксированных событий в Redpanda | Возраст неопубликованной записи, попытки, срок владения, ошибки брокера |
| Search Indexer | Обновление разрешений SpiceDB и документов OpenSearch | Отставание группы потребителя, повторные события, ошибки проекции |
| Search Reindex | Построение нового поколения поискового индекса | Состояние задания, смещения разделов, количество документов, контрольный набор |
| Retention | Применение сроков хранения | Время завершения, ошибки удаления, сохранность неопубликованной очереди |
| Low-code IDE | Визуальное редактирование Flow, SSO, политика компонентов, серверная проверка и экспорт | Идентификаторы образов, версия LangFlow, версия политики, доступность БД рабочих версий |
| Low-code Runtime | Среда выполнения агентов с низкой кодовой базой | Готовность, карточка A2A/MCP, отсутствие перезапусков и ошибок AI Gateway |
| Platform RAG | Сервис retrieval-augmented generation: коллекции, приём документов, гибридный поиск с ACL | Работоспособность, готовность, статус заданий ingest, глубина очереди, латентность query |
| Platform Memory | Управляемый сервис памяти агентов: async add, search, list, history, delete | Работоспособность, готовность, статус событий add, глубина DLQ, латентность search, отставание извлечения |
| Guardrails Runtime | Проверка текста запросов и ответов по политикам: pass / deny / mask | Готовность (/readyz), счётчики проверок и ошибок, 503 policy_unavailable/overloaded, таймауты стадии |
Границы компонентов
Low-code IDE владеет:
- визуальным редактированием Flow;
- рабочими версиями Flow в своей базе;
- SSO входом пользователя;
- отображением разрешённой палитры компонентов;
- серверной проверкой и экспортом;
- публикацией проверенных версий Flow как агентов в каталоге Платформы ИИ через Control Plane.
Low-code IDE не владеет:
- исполнением промышленного запроса;
- развёртыванием Low-code Runtime;
- записями Agent Registry и разрешениями SpiceDB;
- прямой загрузкой артефакта в обход Control Plane и Publisher;
- открытыми секретами поставщиков моделей.
Low-code Runtime: один Deployment исполняет одну версию одного агента. Все экземпляры используют одинаковые исходные данные, манифест, образ и настройки. Наружу предоставляются только согласованные A2A и MCP интерфейсы.
Agent Registry: PostgreSQL хранит метаданные. Redpanda, SpiceDB и OpenSearch являются производными или внешними проекциями и восстанавливаются из метаданных и событий.
Platform RAG: PostgreSQL хранит реестр коллекций и job store (platform_rag). OpenSearch — производная проекция чанков (индекс rag-kb-{env}). RabbitMQ и S3 — вспомогательные каналы ingest. AI Gateway и SpiceDB — внешние зависимости. Helm-чарт устанавливает только прикладные нагрузки api и worker; зависимости чартом не устанавливаются.
Platform Memory: PostgreSQL хранит event store и историю записей (схема platform_memory). OpenSearch — индекс фактов (kNN + BM25, алиас mem-facts-{env}). RabbitMQ — очередь уведомлений add. AI Gateway — эмбеддинг и LLM-извлечение. Helm-чарт устанавливает только прикладную нагрузку api; worker запускается отдельно. Зависимости чартом не устанавливаются.
Агент принадлежит команде. Владелец (owner) получает права view и diagnose, но не invoke. Агент привязан к рабочей области. Явные права на использование (invoke) агента могут быть выданы пользователю (principal) и сервису (service). Пользователь является членом команды-владельца. Пользователь имеет роль в рабочей области: member даёт право view к агентам в этом workspace; admin даёт право manage и diagnose.
Неизменяемые входные данные Low-code Runtime
Перед развёртыванием фиксируются:
| Данные | Требование |
|---|---|
| Образ | Неизменяемый идентификатор, полный SBOM и файл блокировки зависимостей |
source.json | JSON Flow и SHA-256 |
manifest.json | platform.low-code.publish-manifest/v1, SHA-256 и ссылка на исходные данные |
| Политика компонентов | Версия, соответствующая разрешённому набору поставки |
| Карточка A2A или описание MCP | Совпадает с манифестом и фактическими возможностями |
| Настройки выпуска | Версия манифестов Kubernetes, ресурсов и регистрационных меток |
Исправление любого байта создаёт новую версию и новую контрольную сумму. Изменять файл внутри работающего контейнера запрещено.
Последовательность запуска Low-code Runtime
- Получить исходный Flow и манифест по токену либо ограниченному полномочию.
- Ограничить тип содержимого, размер и время получения.
- Проверить SHA-256 обоих файлов.
- Проверить Flow, идентичность агента, политику и совместимость с
lfx. - Повторно проверить компоненты, исполняемый код и отсутствие секретов.
- Загрузить Flow через поддерживаемый интерфейс.
- Выполнить проверку эндпоинта без вызова модели.
- Сформировать карточку либо описание и сравнить с разрешёнными возможностями.
- Перейти в состояние готовности.
Регистрационный контракт
Одна сущность Service Kubernetes объявляет один протокол. Если один Deployment агента предоставляет A2A и MCP интерфейсы, создаются две сущности Service с разными логическими именами. Обязательные метки включают регистрацию, протокол, рабочую область, имя, версию, владельца и тип low-code. Аннотация версии контракта равна agent-platform.agent-registry.registration/v1.
Имя агента соответствует виду <domain>-<function>-v<major>, а основная версия имени совпадает с SemVer версии рабочей нагрузки.
Технический стек
Платформенные зависимости
| Зависимость | Назначение | По умолчанию |
|---|---|---|
| PostgreSQL 18 | Каноническое хранилище каталога | Включено |
| SpiceDB | Хранение разрешений и проверок доступа | Включено |
| OpenTelemetry Collector | Сбор метрик, трассировок и журналов | Включено |
| Redpanda | Канал изменений событий (Outbox) | Включено |
| OpenSearch | Поисковая проекция | Включено |
Примечание: В окружении ST Redpanda и OpenSearch развёрнуты. Компоненты Outbox Relay и Search Indexer в базовом развёртывании отключены, так как зависят от этих служб и включаются отдельным решением.
Зафиксированные версии
| Зависимость | Версия поставки |
|---|---|
| Kubernetes | 1.36.x (исходная точная версия 1.36.2) |
| PostgreSQL | 18.4.0; базовый образ и chart 18.8.4 |
| SpiceDB | 1.54.0 |
| Redpanda Community | сервер 26.1.13, chart 26.1.9 |
| OpenSearch | 3.7.0 |
| OpenTelemetry Collector | образ 0.156.0, chart 0.165.0 |
LangFlow / lfx | 1.11.1 |
Основное обновление PostgreSQL на существующем постоянном томе требует отдельной проверки pg_upgrade. В одноразовой среде разработки том можно пересоздать после удаления выпуска Garden; данные промышленной среды так обрабатывать нельзя.
Среда развёртывания
Garden — единственный поддерживаемый инструмент сборки и развёртывания компонентов. Ручные helm upgrade, kubectl apply не образуют воспроизводимый путь поставки.
Образы платформы публикуются в корпоративный реестр артефактов nexus.inno.tech:19108, доступный из узлов кластера ai-dev.
Среды
В настоящее время Платформа ИИ развёрнута только в окружении ST.
| Среда | Назначение | Способ доступа | Ограничения |
|---|---|---|---|
st | Интеграционная проверка | Статические адреса среды | Требует собственных зависимостей и подтверждающих материалов |
prod | Не реализована | — | Нужны внешние зависимости, секреты, TLS, масштабирование и порядок отката |
ST использует одно пространство имён ap-st и один управляемый Keycloak. Все релизы агентов разворачиваются в этом же пространстве имён. Изменять чужое пространство имён и кластерные ресурсы запрещено.
Параметры окружения ST
| Параметр | Значение |
|---|---|
| Контекст Kubernetes | ai-dev |
| Пространство имён | ap-st |
| kubeconfig | ~/.kube/ai-dev |
| StorageClass | longhorn |
| Реестр образов | nexus.inno.tech:19108/ap |
| Режим сборки | local-docker с кросс-сборкой linux/amd64 |
| OIDC-издатель | https://api-gw.ai-dev.inno.tech/keycloak/realms/ap-dev |
| Keycloak Realm | ap-dev |
Внешняя шлюзовая инфраструктура ST
TLS, DNS, шлюзы и сертификаты принадлежат DevOps. Развёртывание создаёт только HTTPRoutes в пространстве имён ap-st.
Наблюдаемые внешние родители (ListenerSets) в пространстве имён agentgateway-system, секция https:
api-gw.ai-dev.inno.tech-listeners— API, Keycloak, low-code runtime;ide.ai-dev.inno.tech-listeners— Low-code Конструктор;docs.ai-dev.inno.tech-listeners— Team Docs.
Важно: наличие и условия внешних родителей нужно заново подтвердить перед каждым развёртыванием. Внешняя инфраструктура может измениться независимо от поставки.
Включённые и отключённые компоненты в st
| Компонент | Статус | Причина |
|---|---|---|
| Agent Registry API | Включено | Основной сервис |
| Kubernetes Reconciler | Отключено | Наблюдение рабочих нагрузок включается отдельно |
| Outbox Relay | Отключено | Зависит от Redpanda |
| Search Indexer | Отключено | Зависит от OpenSearch |
| Control Plane | Отключено | Активируется отдельным решением вместе с LLM Gateway |
| LLM Gateway | Отключено | Активируется вместе с Control Plane |
| PostgreSQL | Включено | Каноническое хранилище |
| SpiceDB | Включено | Хранение разрешений |
| Redpanda | Включено | Канал изменений событий (Outbox) |
| OpenSearch | Включено | Поисковая проекция |
| OpenTelemetry Collector | Включено | Наблюдаемость |
| Документация поставки | Включено | Документация поставки |
| Low-code Конструктор | Отключено | Поставляется отдельным контуром |
| Platform RAG | Отключено | Поставляется отдельным компонентом |
| Platform RAG API | Отключено | Поставляется отдельным компонентом |
| Platform RAG Worker | Отключено | Поставляется отдельным компонентом |
| Platform Memory | Отключено | Поставляется отдельным компонентом |
| Platform Memory API | Отключено | Поставляется отдельным компонентом |
| Platform Memory Worker | Отключено | Поставляется отдельным компонентом |
| Guardrails Runtime | Отключено | Поставляется отдельным контуром; активация в ST — отдельное решение |
Развертывание
Примечание: Инструкция приведена для кластера
ai-dev(ST). Для других сред порядок аналогичен с учётом соответствующего профиля Garden.
Предварительные условия
- Kubernetes: кластер с контекстом
ai-devи доступом к записи в пространство имёнap-st. - StorageClass
longhornсуществует в кластере. - Docker доступен текущему пользователю (локальная сборка и кросс-сборка образов).
- Garden версии
0.14.20установлен. - Helm версии 3.x или новее.
- kubectl — для диагностики; curl и jq — для проверок; Python 3 — для вспомогательных скриптов.
- Файл
kubeconfigдля кластераai-devдоступен по пути~/.kube/ai-devи содержит контекстai-dev. - Команды выполняются из корня репозитория
agent-platform.
Важно: Команды Garden используют
${local.usernameLowerCase}для формирования пространства имёнap-dev-${local.usernameLowerCase}. Убедитесь, что вы работаете под своей учётной записью.
RBAC-проверки
Перед развёртыванием убедитесь, что учётная запись имеет необходимые права:
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create deployments -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create serviceaccounts -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create secrets -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create httproutes.gateway.networking.k8s.io -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i patch httproutes.gateway.networking.k8s.io -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i delete httproutes.gateway.networking.k8s.io -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create roles.rbac.authorization.k8s.io -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev auth can-i create rolebindings.rbac.authorization.k8s.io -n ap-st
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev \
-n agentgateway-system get listenersets.gateway.networking.k8s.ioПроверка внешних родителей
Перед каждым развёртыванием подтвердите наличие, hostnames и условия внешних ListenerSets:
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev \
-n agentgateway-system get listenerset \
api-gw.ai-dev.inno.tech-listeners \
ide.ai-dev.inno.tech-listeners \
docs.ai-dev.inno.tech-listeners -o yamlОстановитесь, если любой родитель отсутствует, не имеет условий Accepted=True и Programmed=True, не принимает маршруты из ap-st или обслуживает другой hostname.
Шаг 1. Проверка конфигурации
Из корня репозитория выполните валидацию:
garden validate --env stПроверка должна завершиться до сборки образов. Если ошибка не исправлена, развёртывание будет прервано. Возможные причины ошибок:
- неверное пространство имён;
- занят один из фиксированных портов
18080–18083; - отсутствует файл
kubeconfig; - недоступен реестр образов.
Шаг 2. Аутентификация в реестре образов
Garden автоматически выполняет действие run.image-registry-auth перед сборкой. Он:
- Выполняет вход в реестр.
- Создаёт или обновляет секрет
ap-image-pull-secretв целевом пространстве имён для возможности загрузки образов.
Ручная аутентификация не требуется. Учётные данные реестра не выводятся в журналы.
Шаг 3. Развёртывание
Запустите развёртывание среды выполнения:
garden deploy all --env st --yesКоманда последовательно поднимает:
- Образы приложений (сборка и публикация в реестре).
- Общий поставщик идентичности (Keycloak) и базовые настройки realm.
- Идентификацию Платформы ИИ (clients, роли, пользователи).
- Идентификацию Low-code Конструктора.
- Runtime Платформы ИИ, включая Control Plane, если он включён.
- Low-code Runtime.
- Low-code Конструктор.
Повторный запуск является штатным способом восстановления после частичного сбоя.
Примечание: Control Plane отключён по умолчанию (
controlPlane.enabled=false). Для его активации необходимо явное включение в Helm-значениях; он активируется совместно с LLM Gateway. Подробности — в разделе «Control Plane».
Развёртывание тестовых данных
Тестовые агенты и пользователи создаются отдельными целями; обычный garden deploy тестовые данные не создаёт:
# Только Платформа ИИ с тестовыми данными
garden deploy agent-platform-fixtures --env st --yes
# Полное развёртывание тестового стенда (рекомендуется)
garden deploy all-fixtures --env st --yesЦель all-fixtures выполняет все зависимости all и дополнительно согласует тестовых пользователей, тестовых агентов, разрешения Low-code Конструктора и явные разрешения agent#invoker для lowcode-linguist-v1 (субъекты workspace-admin и agent-invoker).
Шаг 4. Проверка развёртывания
Проверка подов
kubectl --kubeconfig ~/.kube/ai-dev --context ai-dev -n ap-st \
get pods,deploy,statefulset,job,svc,pvc,httprouteОжидаемые поды:
| Под | Статус |
|---|---|
ap-agent-registry-api | Running |
ap-team-docs-web | Running |
ap-agent-registry-keycloak | Running |
ap-agent-registry-postgresql | Running |
ap-agent-registry-spicedb | Running |
ap-agent-registry-opensearch | Running |
ap-agent-registry-redpanda | Running |
ap-agent-registry-opentelemetry-collector | Running |
ap-agent-registry-embeddings | Running |
Проверка готовности компонентов
kubectl -n ap-st rollout status statefulset/ap-agent-registry-keycloak --timeout=10m
kubectl -n ap-st rollout status statefulset/ap-agent-registry-postgresql --timeout=10m
kubectl -n ap-st rollout status statefulset/ap-agent-registry-spicedb --timeout=10m
kubectl -n ap-st rollout status statefulset/ap-agent-registry-opensearch --timeout=10m
kubectl -n ap-st rollout status statefulset/ap-agent-registry-redpanda --timeout=10m
kubectl -n ap-st rollout status deployment/ap-agent-registry-api --timeout=10m
kubectl -n ap-st rollout status deployment/langflow-backend --timeout=10m
kubectl -n ap-st rollout status deployment/langflow-frontend --timeout=10mПроверка маршрутов
kubectl -n ap-st \
get httproute ap-agent-registry-api ap-agent-registry-keycloak \
ap-agent-linguist ap-team-docs-web langflow-frontend -o yamlУ всех HTTPRoutes должны быть условия Accepted=True и ResolvedRefs=True; у каждого внешнего ListenerSet — Accepted=True и Programmed=True. Статус маршрута должен ссылаться на ожидаемого родителя: API/Keycloak/low-code — на api-gw...-listeners, Low-code Конструктор — на ide...-listeners, Team Docs — на docs...-listeners.
Проверка Swagger UI
- Откройте браузером
https://api-gw.ai-dev.inno.tech/agent-registry/docs. - Нажмите кнопку Authorize.
- Выберите тип аутентификации
oauth2Password. - Укажите имя пользователя
workspace-adminи парольworkspace-admin. - Укажите
client_id=agent-registry-dev, секрет клиента оставьте пустым. - Выполните запрос
GET /api/v1/agents?workspaceId=ap-st.
Ожидаемый результат — как минимум два агента:
st-smoke-v1с типом реализацииsdk;lowcode-linguist-v1с типом реализацииlow-code.
Обнаружение агентов выполняется асинхронно. Первый пустой ответ допустимо повторить через несколько секунд.
Проверка Low-code Runtime
Подтвердите работоспособность среды выполнения:
- Неразрушающая проверка (
/health/live) возвращает200. - Проверка готовности (
/health/ready) возвращает200. - Карточка агента A2A содержит регистрационные метки.
- Версия агента автоматически появляется в каталоге Agent Registry.
Примечание: Проверка вызова модели требует действительного ключа AI Gateway. Без ключа допустима только проверка обнаружения и связности.
Публичные проверки HTTP
curl -fsS https://api-gw.ai-dev.inno.tech/agent-registry/health/ready | jq
curl -fsS \
https://api-gw.ai-dev.inno.tech/keycloak/realms/ap-dev/.well-known/openid-configuration |
jq -e '.issuer == "https://api-gw.ai-dev.inno.tech/keycloak/realms/ap-dev"'
curl -fsS \
https://api-gw.ai-dev.inno.tech/a2a/lowcode-linguist-v1/health/ready |
jq -e '.status == "ready"'
curl -fsS \
https://api-gw.ai-dev.inno.tech/a2a/lowcode-linguist-v1/.well-known/agent-card.json |
jq -e '.supportedInterfaces[0].url == "https://api-gw.ai-dev.inno.tech/a2a/lowcode-linguist-v1"'
curl -fsS https://ide.ai-dev.inno.tech/config.js >/dev/null
curl -fsS https://docs.ai-dev.inno.tech/health/readyДоступные адреса
| Компонент | URL |
|---|---|
| Платформа ИИ | https://api-gw.ai-dev.inno.tech/agent-registry |
| Control Plane | https://api-gw.ai-dev.inno.tech/control-plane |
| Keycloak | https://api-gw.ai-dev.inno.tech/keycloak |
| Low-code fixture | https://api-gw.ai-dev.inno.tech/a2a/lowcode-linguist-v1 |
| Low-code Конструктор | https://ide.ai-dev.inno.tech |
| Team Docs | https://docs.ai-dev.inno.tech |
Правила работы в среде
- Писать только в пространство имён
ap-st. - Запрещено изменять GatewayClass, Gateway, IngressClass, cluster-операторы и чужие пространства имён.
- Cluster-scoped RBAC выключен в Helm-значениях.
- Создание и ротация секретов требуют отдельного подтверждения человека.
- Garden system-метаданные направляются в целевое пространство имён, а не в общий
garden-system.
Устранение неполадок
Поды не переходят в состояние Running
- Проверьте статус подов:
kubectl -n ap-st get pods --sort-by=.metadata.creationTimestamp - Просмотрите журналы проблемного пода:
kubectl -n ap-st logs <pod-name> --tail=200 - Проверьте события:
kubectl -n ap-st get events --sort-by=.lastTimestamp - Наиболее частая причина — pods не готовы, а не сбой Helm. Повторите
garden deployпосле устранения причины.
Занятые порты
Garden использует фиксированные локальные порты 18080–18083. Если один из них занят, развёртывание завершается ошибкой до начала rollout. Освободите порт или завершите процесс, использующий его.
Ошибка аутентификации реестра
Если действие run.image-registry-auth завершается ошибкой:
- Проверьте доступность
nexus. - Убедитесь, что учётные данные реестра корректны.
- Проверьте, что kubeconfig содержит контекст
ai-dev.
Ошибка миграции базы данных
- Остановите развёртывание.
- Сохраните журнал миграции Alembic.
- Восстановите совместимый образ приложения.
- Убедитесь, что
alembic checkне выдаёт ошибок перед повторной попыткой.
Фикстуры пользователей
При развёртывании создаются ролеориентированные пользователи Keycloak:
| Пользователь | Роль | Пароль |
|---|---|---|
workspace-admin | Администратор рабочей области | workspace-admin |
agent-invoker | Вызывающий агент | agent-invoker |
unauthorized-user | Запрещённый пользователь (тест) | unauthorized-user |
Пароль каждого фикстурного пользователя совпадает с именем. Эти учётные записи создаются только в non-production средах и не переносятся в промышленную эксплуатацию.
Фикстуры агентов
По умолчанию создаются два тестовых агента:
| Агент | Тип реализации | Описание |
|---|---|---|
st-smoke-v1 | sdk | Дымовой тест агента |
lowcode-linguist-v1 | low-code | Агент Low-code Runtime |
Завершение работы
Для полного удаления развёртывания:
garden deploy --env st --uninstallИли удалите пространство имён вручную:
kubectl delete namespace ap-stПримечание: При удалении пространства имён все данные PostgreSQL, SpiceDB, OpenSearch и Redpanda будут безвозвратно удалены.
Откат
Процесс обновления и отката не является атомарным. Для регрессии конфигурации или образа:
- возьмите предыдущий проверенный коммит композиции;
- повторите тот же target — reconcilers и релизы Helm идемпотентны.
Откат по Git/Garden не откатывает автоматически миграции базы данных, изменения realm или содержимое PVC.
Деструктивная очистка
Порядок деструктивной очистки, если она явно разрешена:
фикстуры → приложения → идентификация приложения → realm-base → Keycloak/PVC- Автоматических точек очистки тестовых данных нет;
- Удаление данных ST выполняется только версионированной миграцией с точным селектором владения и подтверждением человека;
- Не удаляйте
ap-st, Keycloak PVC или тестовые данные как «откат».
Сводная таблица команд
| Действие | Команда |
|---|---|
| Валидация конфигурации | garden validate --env st |
| Развёртывание (ST) | garden deploy all --env st --yes |
| Фикстуры Платформы ИИ | garden deploy agent-platform-fixtures --env st --yes |
| Полный тестовый стенд | garden deploy all-fixtures --env st --yes |
| Проверка подов | kubectl -n ap-st get pods |
| Проверка служб | kubectl -n ap-st get svc |
| Удаление развёртывания | garden deploy --env st --uninstall |
Материалы для фиксации результата
При развёртывании сохраните:
- точную команду, среду и время выполнения;
- версии Garden, Docker и Kubernetes;
- пространство имён и версии действий Garden;
- идентификаторы собранных образов;
- результаты миграций базы данных;
- проверки работоспособности подов;
- результаты тестирования API;
- ограничения среды (отключённые компоненты, внутрикластерные DNS).
Не сохраняйте в журнале учётные данные, токены и пользовательские запросы.
Развертывание SDK агента
Как работает регистрация
В Agent Registry нет отдельной операции создания агента. Регистрация выполняется автоматически после развёртывания рабочей нагрузки и k8s сущности Service с регистрационными метками в доверенном пространстве имён Kubernetes.
Agent Registry:
- обнаруживает
Service; - проверяет метки, аннотации и привязку пространства имён к рабочему пространству;
- дожидается готового адреса из принадлежащей службе
EndpointSlice; - загружает карточку агента по внутреннему адресу службы;
- проверяет A2A 1.0, имя, версию, навыки и заявленные возможности;
- добавляет разрешённую проекцию агента в каталог.
Объектом регистрации является Service, а не Deployment или отдельный Pod. Перезапуск экземпляра не создаёт новую запись, пока служба и логическая версия агента остаются прежними.
Что подготовить заранее
До развёртывания запросите у владельца среды:
- точное пространство имён, включённое в состав доверенных в Agent Registry;
- идентификатор рабочего пространства для регистрационной метки;
- идентификатор команды из доверенного каталога владельцев;
- разрешённый способ доставки через Garden и Helm;
- требования среды к внутреннему TLS и публичному маршруту;
- права на просмотр и, при необходимости, вызов зарегистрированного агента.
Имя агента имеет форму <domain>-<function>-v<major> и должно быть допустимым DNS именем длиной не более 63 символов. Суффикс имени должен совпадать с основной частью SemVer: версии 1.0.0 соответствует суффикс -v1.
Подготовка карточки агента
Агент должен возвращать карточку по адресу /.well-known/agent-card.json, если в аннотации службы не указан другой безопасный абсолютный путь.
Минимальный пример для A2A 1.0 HTTP+JSON:
{
"name": "finance-invoice-v1",
"description": "Проверяет счет и извлекает структурированные поля.",
"supportedInterfaces": [
{
"url": "https://agent.example/a2a/finance-invoice-v1",
"protocolBinding": "HTTP+JSON",
"protocolVersion": "1.0"
}
],
"version": "1.2.0",
"capabilities": {
"streaming": true,
"pushNotifications": false,
"extendedAgentCard": false
},
"defaultInputModes": ["application/json", "text/plain"],
"defaultOutputModes": ["application/json"],
"skills": [
{
"id": "invoice_parsing",
"name": "Разбор счета",
"description": "Извлекает нормализованные поля из счета.",
"tags": ["invoice", "finance"],
"examples": ["Извлеки поставщика, сумму и НДС из этого счета"]
}
]
}Значения name и version должны точно совпадать с метками службы. В поставке 2026.3.5 для HTTP+JSON подтверждена возможность streaming. Не объявляйте неподдерживаемую возможность: Agent Registry не запускает агент для пробного вызова во время регистрации и полагается на правдивую неизменяемую карточку и проверку совместимости до развёртывания.
Публикация Service
Рабочая нагрузка должна иметь именованный порт и проверку готовности. Рядом с ней опубликуйте службу с селектором:
apiVersion: v1
kind: Service
metadata:
name: finance-invoice-v1
namespace: finance
labels:
agent-platform.inno.tech/registrable: "true"
agent-platform.inno.tech/protocol: a2a
agent-platform.inno.tech/workspace: finance
agent-platform.inno.tech/agent-name: finance-invoice-v1
agent-platform.inno.tech/version: "1.2.0"
agent-platform.inno.tech/owner: team-finance-ai
agent-platform.inno.tech/implementation-type: sdk
annotations:
agent-platform.inno.tech/registration-contract: agent-platform.agent-registry.registration/v1
agent-platform.inno.tech/card-path: /.well-known/agent-card.json
agent-platform.inno.tech/service-port: a2a
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: finance-invoice-v1
ports:
- name: a2a
protocol: TCP
port: 8443
targetPort: a2aОбязательные значения:
| Поле | Требование |
|---|---|
registrable | Только строка true |
protocol | a2a |
workspace | Совпадает с доверенной привязкой пространства имён |
agent-name | Совпадает с карточкой и основной частью версии |
version | SemVer без метаданных сборки |
owner | Существующий идентификатор команды |
implementation-type | sdk |
registration-contract | Точная ревизия agent-platform.agent-registry.registration/v1 |
service-port | Имя единственного порта A2A |
Поддерживается служба ClusterIP с селектором. Не используйте ExternalName, службу без селектора, созданный вручную EndpointSlice или publishNotReadyAddresses: true.
Проверка регистрации
Сначала проверьте готовность рабочей нагрузки и принадлежность адреса службе:
kubectl --namespace finance get service/finance-invoice-v1 --output=wide
kubectl --namespace finance get endpointslice \
--selector kubernetes.io/service-name=finance-invoice-v1 \
--output=wideДля диагностики в непроизводственной среде получите у владельца среды разрешённый тестовый адрес и проверьте карточку:
curl --fail --silent --show-error \
"${AGENT_TEST_URL}/.well-known/agent-card.json" \
| jq '{name, version, supportedInterfaces, capabilities, skills}'Схему внутреннего соединения и доверенный сертификат выбирает среда. Не отключайте проверку TLS ради диагностики.
После асинхронного обнаружения запросите каталог с пользовательским токеном:
curl --fail --silent --show-error \
"${REGISTRY_URL}/api/v1/agents?workspaceId=finance&protocol=a2a&implementationType=sdk&limit=20" \
--header "Authorization: Bearer [REDACTED]" \
| jq '.items[] | select(.name == "finance-invoice-v1") | {
id,
name,
implementationType,
lifecycleStatus,
selectedVersion
}'Успешная запись имеет состояние active, тип реализации sdk и выбранную версию, совпадающую с карточкой. Отсутствие публичного интерфейса при этом означает, что доверенный маршрут ещё не готов; это не ошибка регистрации.
Проверка потоковой передачи A2A
Если карточка содержит streaming: true, до публикации версии проверьте фактический HTTP+JSON SSE-путь. Для контролируемой непроизводственной среды:
message_id="$(python3 -c 'import uuid; print(uuid.uuid4())')"
curl --no-buffer --fail-with-body --show-error \
--request POST "${AGENT_TEST_URL}/message:stream" \
--header 'A2A-Version: 1.0' \
--header 'Accept: text/event-stream' \
--header 'Content-Type: application/a2a+json' \
--data-binary @- <<JSON
{
"message": {
"messageId": "${message_id}",
"role": "ROLE_USER",
"parts": [
{
"text": "Проверь тестовый документ",
"mediaType": "text/plain"
}
]
}
}
JSONПоток должен начинаться отправленной задачей, содержать рабочее состояние и последовательные обновления результата, а завершаться терминальным состоянием. Разрыв соединения, повторная подписка и получение завершенной задачи должны соответствовать A2A 1.0. Agent Registry сохраняет возможность потоковой передачи в каталоге, но не выполняет этот тест вместо разработчика.
Разбор ошибки регистрации
| Наблюдение | Возможная причина | Действие |
|---|---|---|
| Агент отсутствует в каталоге | Пространство имён не входит в состав доверенных или нет прав наблюдения | Обратиться к владельцу Agent Registry; не добавлять обходную ручную запись |
Состояние rejected | Метки, имя, версия, путь или карточка не прошли проверку | Сверить службу и карточку, затем опубликовать исправленную неизменяемую версию |
Состояние degraded | Нет пригодного готового адреса или карточка временно недоступна | Проверить готовность экземпляров, EndpointSlice, порт и внутренний TLS |
Запись active, но интерфейса нет | Не принят маршрут Platform Agent Gateway или нет права вызова | Проверить маршрут и отношение agent#invoke у владельца среды |
| Карточка доступна напрямую, но Registry её не принимает | Имя или версия карточки расходятся с метками либо заявлена неподтверждённая возможность | Исправить контракт и повторить поставку |
Важно: При обращении в поддержку передавайте имя агента, версию, пространство имён, время развёртывания и безопасный
traceId. Не передавайте токен, секрет модели, внутренние учётные данные и полный закрытый запрос.
Обновление зарегистрированного агента
Карточка и возможности опубликованной версии неизменяемы. При изменении поведения, навыков, входных данных или возможностей:
- назначьте новую SemVer;
- согласованно обновите карточку, образ и метку версии службы;
- повторите проверки A2A и готовности;
- дождитесь появления новой выбранной версии в Agent Registry;
- сохраняйте предыдущую версию как явную точку отката на принятый срок.
При переходе с 1.x на 2.x измените суффикс логического имени с -v1 на -v2. Не меняйте содержимое уже опубликованной версии без изменения SemVer.
Граница безопасности
- Не помещайте ключи, токены и внутренние адреса в метки или описание карточки.
- Не публикуйте сырой адрес
Serviceкак пользовательский интерфейс. - Не считайте регистрацию разрешением на просмотр или вызов.
- Не передавайте исходный пользовательский токен непосредственно SDK-агенту.
- В производственной среде вызывайте агент только через интерфейс Platform Agent Gateway, возвращенный Agent Registry после проверки прав.
Обновление и откат
Поддерживаемая граница
Для версии 2026.3.5 подтверждается установка в непромышленных средах. Порядок промышленного обновления не считается принятым до появления всех неизменяемых артефактов, проверки внешних зависимостей и испытанного отката.
Обновление рассматривается как согласованное изменение трёх компонентов, даже если они поставляются разными проектами. Нельзя обновлять Low-code IDE, Low-code Runtime без проверки уже сохраненных и пригодных для отката Flow.
Подготовка
Зафиксируйте текущее и целевое состояние:
| Область | Что записать |
|---|---|
| Agent Registry | Идентификаторы образов, версию OpenAPI, Alembic, схему SpiceDB, поколение OpenSearch и версию chart |
| Low-code Runtime | Идентификатор образа, политику компонентов, Flow A2A/MCP/FileRef |
| Low-code IDE | Идентификаторы клиентского и серверного образов, версию LangFlow, базу рабочих версий, политику и проверяющий модуль |
| Артефакт агента | Версию, SHA-256 исходных данных и манифеста, список пригодных для отката версий |
| Среда | Kubernetes, внешние зависимости, значения Garden и пространство имен |
Проверьте резервное копирование и фактическую возможность восстановления PostgreSQL Agent Registry и базы Low-code IDE. Для OpenSearch достаточно пересоздания из метаданных.
Проверка совместимости Flow Low-code
Для каждого активного и пригодного для отката Flow:
- экспортируйте исходные данные прежней версией Low-code IDE;
- проверьте их целевым проверяющим модулем и политикой;
- загрузите и выполните путь целевой версией Low-code Runtime;
- сравните входы, выходы, карточку A2A, описание MCP и контрольные примеры;
- зафиксируйте необходимость миграции либо заблокируйте обновление;
- не изменяйте сохранённый источник автоматически при запуске.
Если PlatformRAG или PlatformMemory появляются в новой политике, это отдельное изменение возможностей с собственными контрактами и не может включаться только обновлением версии.
Проверка Agent Registry
До обновления:
- выполните сравнение OpenAPI и машинных схем;
- проверьте применение и понижение версии Alembic на одноразовой базе;
- подтвердите совместимость схемы SpiceDB и читателей/писателей;
- проверьте повторную доставку Redpanda и пересоздание OpenSearch;
- выполните разрешённые, запрещённые, межпространственные запросы и отказ SpiceDB;
- проверьте регистрацию службы Low-code Runtime целевой формы.
Порядок обновления
- Остановите развёртывание новых версий Flow пользователями.
- Создайте резервные копии метаданных и зафиксируйте текущее состояние.
- Выполните все проверки совместимости Flow Low-code.
- Обновите репозиторий до новой версии поставки.
- Запустите
garden validate --env TARGET. - Запустите
garden deploy --env TARGET --yesдля компонентов этого репозитория. - Дождитесь миграции PostgreSQL, схемы SpiceDB, топиков Redpanda и поисковой схемы.
- Дождитесь готовности всех процессов Agent Registry, Low-code IDE и проверочного Low-code Runtime.
- Выполните вход, создание, сохранение, проверку и повторяемый экспорт.
- Воспроизведите общий путь от создания Flow агента до автоматического обнаружения и вызова.
- Разрешите создание новых рабочих версий Flow только после успешной проверки.
Условия немедленной остановки
Остановите обновление, если:
- миграция данных завершилась ошибкой;
- прежний Flow Low-code не проходит целевую проверку;
- карточка или описание агента объявляет отсутствующую возможность;
- Low-code IDE может передать непроверенный или содержащий секрет источник;
- Agent Registry возвращает недоступный объект;
- новый экземпляр Reconciler не получил свежее полное наблюдение;
- поисковая проекция не сходится с метаданными.
Критерии завершения
Обновление завершено только когда:
- образы, настройки, схемы данных и внешние зависимости совместимы;
- активные и откатные Flow Low-code прошли проверку;
- Low-code IDE создаёт повторяемый Flow;
- Low-code Runtime готов и исполняет принятый профиль;
- Agent Registry автоматически обнаруживает его и соблюдает отрицательные проверки доступа;
- сохранены контрольные суммы и очищенные результаты проверки;
- подтверждён применимый путь отката.
Откат
Принцип: Откат возвращает всю систему к заранее проверенной комбинации образов, настроек, схем данных, артефактов агента и внешних зависимостей. Возврат одного образа без проверки совместимости данных и Flow Low-code не считается безопасным.
Исходный файл Flow не исправляется во время отката. Выбирается предыдущая версия с известной контрольной суммой и подтверждённой совместимостью.
Ограничение текущего релиза: Ввиду того, что текущий релиз является первым, процедура отката к предыдущей версии не предусмотрена.
Мониторинг состояния и обслуживание
Ежедневная проверка состояния
Agent Registry
Проверьте:
- работоспособность и готовность API;
- актуальность данных мониторинга Service и EndpointSlice в Kubernetes;
- лидера сервиса Kubernetes Reconciler;
- возраст самой старой неопубликованной записи транзакционной очереди;
- отставание обработчика Redpanda;
- состояние SpiceDB и OpenSearch;
- завершение задания хранения и удаления устаревших данных.
Low-code Runtime
Для каждой поставленной версии проверьте:
- идентификатор образа;
- SHA-256 исходного Flow и манифеста;
- ответ эндпоинта проверки работоспособности процесса;
- ответ эндпоинта проверки готовности Flow;
- соответствие карточки A2A и описания MCP фактическим возможностям агента;
- отсутствие перезапусков, таймаутов и ошибок AI Gateway;
- отсутствие секретов и содержимого запросов в журналах.
Low-code IDE
Проверьте:
- идентификаторы клиентского и серверного образов;
- доступность входа через платформенный SSO;
- запрет доступа для пользователя без нужной роли;
- согласованную версию клиентской и серверной частей;
- доступность хранилища рабочих версий;
- версию политики компонентов и проверяющего модуля;
- отсутствие внешних поставщиков и открытых секретов в экспортируемой схеме;
- доступность Control Plane и
api-gw, через которые выполняется публикация агентов.
Значение проверок состояния
- Проверка работоспособности сообщает только о живом процессе. Она не должна выполнять дорогой вызов модели.
- Готовность Agent Registry требует исправной БД с метаданными, настройки удостоверений и функционирующего процесса мониторинга развёрнутых в Kubernetes агентов.
- Готовность Low-code Runtime требует успешно загруженной Flow, манифеста, рабочего эндпоинта, карточки и критической конфигурации.
- Доступность клиентской части Low-code IDE не доказывает готовность серверной проверки, хранилища и входа.
- Отказ SpiceDB запрещает защищённые операции. Отказ AI Gateway или OpenSearch отключает поиск, но не обязан останавливать просмотр списка.
Безопасный сбор сведений
После явного выбора контекста и пространства имён допустимы команды чтения:
kubectl -n "$REGISTRY_NAMESPACE" get deploy,pod,svc,endpointslice,job,lease
kubectl -n "$REGISTRY_NAMESPACE" get events --sort-by=.lastTimestamp
kubectl -n "$REGISTRY_NAMESPACE" logs \
deploy/ap-agent-registry-kubernetes-reconciler --all-pods --tail=200
kubectl -n "$REGISTRY_NAMESPACE" logs \
deploy/ap-agent-registry-api --all-pods --tail=200Важно: Не помещайте значение токена, текст карточки, запрос поиска, вектор и внутренний адрес в запрос.
Диагностика Agent Registry
Устаревшие данные мониторинга Kubernetes
Признак: алерт AgentRegistryObservationCoverageStale, потеря готовности Reconciler или исчезновение доступных интерфейсов.
- Проверьте возраст покрытия, ошибки данных мониторинга, ответы
410, ограничение запросов Kubernetes и лидера сервисов Reconciler.
| Возраст покрытия | Поведение |
|---|---|
| ≤ 30 с | Покрытие свежее, ресурсы доступны |
| > 30 с | Покрытие устарело |
| > 300 с ±20 % | Периодический full resync — полное подтверждение наличия/отсутствия |
- Убедитесь, что потоки Service и EndpointSlice свежие для каждого явно сопоставленного пространства имён.
- Проверьте только права
get/list/watchчерез RoleBinding. Чтение Secret, Pod, Deployment и всего кластера не требуется. - При
410 Goneдождитесь полного повторного списка. - При перезапуске лидера сервисов Reconciler новый владелец должен сначала выполнить полную синхронизацию и только потом считать покрытие свежим.
Потеря готовности агента
Проверьте все EndpointSlice, принадлежащие сервису агента: управляющий контроллер, тип адреса, порт и признаки ready, serving, terminating.
При отсутствии доступного EndpointSlice:
- агент не доступен из обычной выдачи для вызова;
- удаляется публичный интерфейс;
- инициируется отзыв разрешений доступа (SpiceDB) и поисковой проекции.
Восстанавливайте исходный агентский сервис или Low-code Runtime. Пересозданный сервис получает новый UID и проходит полную проверку.
Ошибка разрешений SpiceDB
Признак: AgentRegistryPermissionCleanupFailing или ответы authorization_unavailable.
- Считайте затронутый агент недоступным до завершения восстановления.
- Проверьте состояние SpiceDB и код ошибки авторизационного запроса.
- После восстановления дождитесь повторной операции Reconciler.
- Убедитесь, что разрешения владельца и рабочей области удалены либо созданы в соответствии с текущим состоянием.
Откат БД SpiceDB не приведёт к восстановлению.
Отказ поиска
- При отказе AI Gateway поиск возвращает
503. - При отказе OpenSearch поиск возвращает
503. - Просмотр списка и одной записи продолжается, если PostgreSQL и SpiceDB исправны.
- После восстановления создайте новое поколение индекса.
- Переключайте псевдоним только после проверки количества, контрольного набора и догонки потока событий.
- Храните прежнее поколение не менее семи дней для быстрого возврата.
Не редактируйте отдельные документы OpenSearch вручную.
Задержка транзакционной очереди
Признак: AgentRegistryOutboxPublishFailing или рост возраста самой старой неопубликованной записи.
- Проверьте Redpanda, права на топик, срок хранения и владельца блокировки.
- Не меняйте
published_atвручную. - После истечения периода блокировки запись должна стать доступной повторной попытки.
- Повторная доставка допустима: Search Indexer устраняет повторы по идентификатору события и версии агрегата.
- После восстановления убедитесь, что очередь сокращается, а группа потребителя продвигается.
Миграции и восстановление
Задание миграции и проверка при запуске используют транзакционную блокировку PostgreSQL. При ошибке:
- остановите развёртывание версии;
- сохраните номер Alembic и ошибку базы;
- верните совместимый образ приложения;
- выполняйте понижение версии схемы только после проверки сохранности данных;
- не запускайте разрушительный SQL из интерактивного контейнера.
Цели восстановления: Agent Registry — RTO 60 минут и RPO 5 минут; SpiceDB — RTO 30 минут и RPO 5 минут.
OpenSearch восстанавливается из метаданных и не имеет внутреннего механизма, гарантирующего сохранность.
Диагностика Low-code Runtime
Проверки состояния
| Маршрут | Значение | Не доказывает |
|---|---|---|
/health/live | Процесс работает | Исправность Flow, модели и доступа |
/health/ready | Артефакт, манифест, точка входа и критическая настройка приняты | Качество ответа модели и право конкретного пользователя |
/.well-known/agent-card.json | Карточка A2A выбранной версии | Право вызова; публичный клиент получает маршрут через Agent Registry |
Проверка готовности не должна выполнять тяжёлый запрос к модели. Фактическая готовность AI Gateway подтверждается отдельной сквозной проверкой.
Типичные причины неготовности
| Признак | Проверка | Безопасное действие |
|---|---|---|
| Несовпадение SHA-256 | Сравнить байты файла, путь и ожидаемый SHA-256 | Повторно разместить файл Flow как новую версию |
component_not_allowed | Найти узел и версию политики в результате проверки | Исправить Flow в Low-code IDE; не отключать проверку |
| Несовместимость среды исполнения | Сверить версию lfx и набор совместимости | Заблокировать обновление либо создать совместимый Flow |
advertised_capability_unavailable | Сравнить манифест, карточку и исполняемый путь | Убрать неподдерживаемую возможность и создать новую версию |
| Ошибка AI Gateway | Проверить целевой профиль, срок полномочия, ограничение времени | Исправить настройку платформенной службы; не передавать пользовательский токен |
| Ошибка FileRef | Проверить цель, операцию, срок, размер, тип и SHA-256 | Получить новый FileRef; не передавать прямой URL |
| Превышение нагрузки | Проверить параллельность, очередь и сроки | Вернуть 429, применить ограниченную повторную попытку только для безопасного чтения |
Наблюдаемость
Для диагностики достаточно идентификатора агента и версии, версии Flow, хеш-префикса, traceId, кода ошибки.
Условие успешной эксплуатации
Версия считается исправной, когда готовность агента устойчива, карточка соответствует поведению, A2A и MCP проходят согласованный набор проверок, неверные FileRef и права отклоняются до выполнения, а Agent Registry автоматически обнаруживает рабочую нагрузку развёрнутого агента.
Диагностика Low-code IDE
Предварительные проверки
Перед открытием доступа пользователям зафиксируйте:
- идентификаторы клиентского и серверного образов;
- полный SBOM обоих образов и отчёт чистой сборки;
- версию LangFlow, версию адаптации и совместимую версию схемы данных;
- версию политики компонентов;
- версию проверяющего модуля и JSON Schema Flow и манифеста;
- адрес и конфигурацию платформенного поставщика токенов доступа;
- карту ролей Low-code IDE к рабочим областям;
- доступность базы рабочих версий;
- доступность Control Plane и
api-gw, через которые выполняется публикация агентов.
Вход и доступ
Проверьте четыре состояния:
| Состояние | Ожидаемое поведение |
|---|---|
| Пользователь не вошёл | Перенаправление к платформенному поставщику токенов без показа закрытых схем |
| Токен не действителен | Отказ с понятным сообщением и без создания локального сеанса |
| Пользователь вошёл, но не имеет права | Отказ без раскрытия схем и состава чужой рабочей области |
| Пользователь имеет право | Доступ только к разрешённой рабочей области и операциям роли |
Идентификатор пользователя, рабочая область и роли из формы, URL или неподписанного заголовка не являются источником полномочий.
Политика компонентов
Запрет должен действовать на двух уровнях:
- клиентская палитра не показывает недоступный компонент;
- серверная проверка отклоняет вручную добавленный или изменённый JSON.
| Platform RAG | Платформенный сервис retrieval-augmented generation: реестр коллекций, приём нормализованных документов, гибридный поиск с фильтрацией по правам доступа |
После изменения политики повторно проверьте все активные и пригодные для отката версии Flow. Нельзя автоматически изменять уже зафиксированные исходные данные.
Сохранение
Серверная часть должна:
- сохранять рабочую версию в правильной рабочей области;
- предотвращать перезапись зафиксированной версии;
- формировать устойчивую SHA-256;
- возвращать версию проверяющего модуля и политики;
- отделять предупреждение от блокирующей ошибки;
- не включать секрет в исходные данные и сообщение об ошибке.
Повторный экспорт одной неизменённой версии должен давать те же байты и контрольную сумму.
Первичная диагностика
Клиент открывается, но данные не загружаются. Проверьте совместимость клиентской и серверной версий, состояние API, срок сеанса и права рабочей области.
Сохранение не работает. Проверьте доступность базы, миграцию, ограничение размера и конфликт версии. Сохраните рабочую копию пользователя безопасным способом; не записывайте JSON в произвольную таблицу вручную.
Публикация недоступна. Сохраните проверенную версию и контрольные суммы. Не выполняйте прямую загрузку артефакта. Проверьте доступность Control Plane и api-gw, срок токена доступа и права рабочей области; при повторном сбое передайте идентификатор операции публикации администратору Платформы ИИ.
Первичная диагностика происшествия
- Зафиксируйте среду, контекст, пространство имён, версию выпуска и время.
- Определите затронутый пользовательский шаг: вход, редактирование, проверка, запуск среды исполнения, обнаружение, поиск или вызов.
- Зафиксируйте идентификаторы образов, версии схемы и манифеста без их чувствительного содержимого.
- Проверьте компонент-владелец, затем его непосредственные зависимости.
- Сохраните события, показатели и очищенные журналы с
traceId. - Убедитесь, что отказ доступа, устаревшие данные мониторинга или неверный маршрут не обходятся временной настройкой.
- Остановите развёртывание версии, если нарушены граница доступа, контрольная сумма, регистрационный контракт или соответствие заявленных возможностей.
- Откатывайте только заранее проверенную совместимую комбинацию образов, конфигурации, схем данных и внешних зависимостей.
Данные, которые нельзя сохранять
Не включайте в журналы, трассировки и материалы проверки:
- исходный пользовательский токен и короткоживущие полномочия;
- ключи, пароли и значения Vault;
- текст пользовательского запроса и ответа модели;
- содержимое файлов и подписанный FileRef;
- полный экспорт схемы, если в нём могут быть закрытые данные;
- вектор запроса и закрытые внутренние адреса;
- карточки и описания протокола без очистки чувствительных полей.
Для связи событий используйте безопасные идентификаторы агента, версии, Flow, хеш-префикс, traceId и время.
Безопасное восстановление
- Исправляйте исходную рабочую нагрузку или конфигурацию и дожидайтесь согласования состояния.
- После ответа Kubernetes
410 Goneразрешите Reconciler выполнить полную повторную синхронизацию. - Не помечайте запись транзакционной очереди опубликованной вручную.
- Повреждённый поисковый индекс заменяйте новым поколением и переключайте псевдоним только после проверки количества и контрольного набора.
- При несовпадении артефакта Low-code Runtime создавайте новую версию; не исправляйте файл внутри контейнера.
- При ошибке Low-code IDE сохраняйте рабочую версию и результат проверки; не передавайте непроверенный JSON оператору.
- При ошибке миграции остановите развёртывание и следуйте плану миграции.
Control Plane
Control Plane — центральный управляющий компонент Платформы ИИ. Он предоставляет управление политиками моделей, виртуальными ключами LLM и публикацией low-code агентов. Компонент владеет желаемым состоянием и длительными операциями, но не участвует в путях инференса LLM и вызова агентов (A2A): каталог агентов и их вызов — это Agent Registry и Platform Agent Gateway.
Control Plane отключён по умолчанию (controlPlane.enabled=false) и активируется отдельным решением вместе с LLM Gateway. Platform API Gateway (api-gw) монтирует компонент по пути /control-plane: публичное API — /control-plane/api/v1, документация — /control-plane/docs.
Важно: Все изменяющие состояние операции асинхронные. Запрос возвращает
202 Acceptedсо ссылкой на Operation — это подтверждение принятия намерения, а не факта выполнения. Фактическое применение отслеживается через полеverifiedStateресурса иGET /api/v1/operations/{operationId}.
Назначение и состав
Control Plane состоит из прикладного API, фоновых воркеров оркестрации и транзакционной базы данных. Управление внешними ресурсами (Kubernetes, LLM Gateway, Agent Registry) выполняется асинхронно через фоновые согласующие воркеры.
| Компонент | Назначение |
|---|---|
| Control Plane API | Аутентификация, авторизация, проверка запросов, идемпотентность, контроль ревизий. Stateless, масштабируется горизонтально; не владеет учётными данными Kubernetes и не проксирует инференс |
| Воркер моделей | Применяет уровни, провайдеров и модели; материализует зашифрованные учётные данные провайдера в неизменяемый Kubernetes Secret |
| Воркер ключей | Применяет виртуальные ключи, верифицирует их через Gateway, управляет жизненным циклом |
| Воркер публикации | Проверяет low-code источник, создаёт агента, версию и публикацию, разворачивает рабочую нагрузку, дожидается фидбэка Agent Registry |
| PostgreSQL | Желаемое состояние, идентичности, операции, неизменяемый журнал аудита (схема control_plane) |
| Temporal | Порядок длительных операций, таймеры, повторные попытки и отмена |
| SpiceDB | Ресурсно-ориентированная авторизация; при недоступности — отказ (fail-closed) |
Права доступа
| Право | Назначение |
|---|---|
control_plane#observe | Чтение безопасного статуса, дрейфа и аудита |
control_plane#administer | Управление уровнями, провайдерами, моделями, ключами и политиками |
control_plane#operate | Операции, согласование и восстановление |
control_plane#author_publication | Публикация low-code агентов |
agent_publication#manage | Управление публикацией конкретного агента |
agent#diagnose | Диагностика и статус публикации |
api_key#view / api_key#manage | Самообслуживание ключами текущего субъекта |
Проверка выполняется прямо на целевом ресурсе. Недоступность или неопределённый результат SpiceDB приводит к отказу (fail-closed), а не к частичному доступу.
Управление моделями
Управление моделями строится на трёх связанных сущностях: Tier (профиль скорости и квот), Provider (внешний LLM-провайдер) и Model (конкретная модель, привязанная к провайдеру). Все операции, изменяющие состояние, возвращают 202 Accepted. Чтение ресурса возвращает заголовок ETag вида "r<revision>", который обязателен в If-Match для PATCH и DELETE.
Tier (Уровень)
Профиль обслуживания ключа: лимит запросов в минуту и квота токенов в минуту. Tier не имеет членов, владельцев или унаследованных прав.
| Поле | Описание |
|---|---|
name | Уникальное имя, ^[a-z][a-z0-9._-]{0,127}$; неизменяемо |
displayName | Отображаемое имя (необязательно, 1–128 символов) |
requestsPerMinute | Лимит запросов в минуту (≥1) |
tokensPerMinute | Квота токенов в минуту (≥1) |
desiredState | enabled / disabled |
Удаление выполняется только для неиспользуемого уровня; при наличии зависимостей возвращается 409 Conflict. Рекомендуемые примеры: standard (100 запросов/мин, 50K токенов/мин) и premium (500 запросов/мин, 200K токенов/мин).
Provider (Поставщик)
Конфигурация внешнего LLM-провайдера. Создание выполняется в отключённом состоянии: POST /api/v1/providers принимает name, kind (единственное значение openai_compatible), endpoint (только https://) и desiredState: "disabled".
| Поле | Описание |
|---|---|
kind | openai_compatible |
endpoint | HTTPS-адрес; неизменяемо после создания |
credentialStatus | missing, pending, verified, invalid |
credentialFingerprint | sha256:…, если учётные данные установлены |
Учётные данные задаются отдельным ресурсом PUT /api/v1/providers/{providerId}/credential. Значение поля credential (16–8192 символов) не возвращается API. Провайдер можно включить только после проверки учётных данных. Удаление возможно, только когда на провайдера не ссылаются модели. Учётные данные провайдера удалить нельзя — их можно только установить или заменить.
Model (Модель)
Конкретная модель с именем для шлюза, привязкой к провайдеру и профилем. Наличие модели не создаёт права доступа — доступ выдаётся только явными привязками моделей к ключам.
| Поле | Описание |
|---|---|
gatewayName | Имя для Gateway, ^[a-z][a-z0-9._-]{0,127}$; неизменяемо |
providerId | Привязанный провайдер; неизменяемо |
upstreamModel | Имя модели у внешнего провайдера (например, gpt-4o) |
profile | internal — внутренняя модель платформы, external — модель внешнего провайдера |
desiredState | enabled / disabled |
В PATCH входят только upstreamModel, profile и desiredState: сменить gatewayName или провайдера нельзя — можно только сменить модель, на которую указывает upstreamModel. Удаление возможно, только когда модель не требуется активными ключами или маршрутами, иначе 409 Conflict. Массовая смена состояния — через пакетные операции set_model_state.
Управление ключами
Ключи доступа к моделям управляются двумя сущностями: KeyIssuancePolicy (политика выдачи) и ApiKey (виртуальный ключ). Все операции, изменяющие состояние, асинхронные и возвращают 202 Accepted; фактическое применение отслеживается через verifiedState ресурса и статус операции.
KeyIssuancePolicy (Политика выдачи ключей)
Настройка самообслуживающейся выдачи ключей людям и сервисам. Это синглтон — единичный объект на всю установку. Изменение политики влияет только на будущие выдачи и не изменяет ранее выданные ключи.
| Поле | Описание |
|---|---|
enabled | Включена ли выдача ключей |
allowedTierIds | Список разрешённых уровней обслуживания |
allowedModelIds | Список разрешённых моделей |
maxActiveKeysPerPrincipal | Максимум активных ключей на одного субъекта |
Управление через GET /api/v1/key-issuance-policy (получение) и PATCH /api/v1/key-issuance-policy (обновление). При enabled=true требуются не менее одного уровня и одной модели, иначе обновление отклоняется.
ApiKey (Ключ API)
Виртуальный ключ доступа к моделям: один владелец (человек, сервис или агент), один уровень и непустой набор разрешённых моделей.
| Поле | Описание |
|---|---|
owner | Владелец: principal (человек), service (сервис) или agent (агент) |
tierId | Привязанный уровень обслуживания |
modelIds | Набор разрешённых моделей (1–256, уникальные) |
label | Читаемое название (необязательно, 1–128 символов) |
status | pending — ожидает проверки Gateway, active, revoking, revoked, degraded |
generation | Номер генерации; увеличивается при каждой ротации |
fingerprint | Хэш ключа sha256:<64 hex> — позволяет проверить ключ без раскрытия значения |
Особенности жизненного цикла:
- секретный материал ключа (
oneTimeSecret, форматcpk_<base64url>) возвращается только один раз при создании или ротации; повторный запрос по тому жеIdempotency-Keyвозвращает лишь метаданные; - ключи с владельцем-агентом (
owner.type = "agent") не управляются через административные методы — их жизненный цикл принадлежит публикации агента; попытка завершается409 Conflict; - при отзыве ключ верифицируется через LLM Gateway; если Gateway не отвечает в пределах таймаута, возвращается
504 VerificationTimeout.
Типовые сценарии администратора
Настройка провайдера и моделей. Администратор последовательно создаёт Provider (адаптер, HTTPS-адрес, зашифрованные учётные данные), Tier (имя, лимиты requestsPerMinute/tokensPerMinute, состояние enabled) и Model (уникальное gatewayName, привязка к провайдеру, профиль). Для дополнительных уровней и моделей шаги повторяются; каждая модель привязывается к одному провайдеру. После этого платформа готова обслуживать подключённых поставщиков.
Настройка политики выдачи ключей. Администратор обновляет синглтон PATCH /api/v1/key-issuance-policy: включает выдачу (enabled: true), выбирает разрешённые уровни и модели, задаёт лимит активных ключей на субъекта. После сохранения пользователи и сервисы самостоятельно выпускают ключи через POST /api/v1/me/keys в рамках заданных ограничений.
Выдача ключа администратором. По запросу субъекта администратор создаёт ключ через POST /api/v1/keys, указав владельца, уровень и разрешённые модели, затем передаёт секретный материал субъекту по защищённому каналу. Полный аудит-трейл выдачи доступен администратору.
Управление ключами. Администратор может:
| Действие | Метод |
|---|---|
| Просмотр списка | GET /api/v1/keys (фильтрация по владельцу) |
| Получение ключа | GET /api/v1/keys/{keyId} (метаданные без секрета) |
| Обновление политики | PATCH /api/v1/keys/{keyId} (tierId, modelIds, label) |
| Ротация ключа | POST /api/v1/keys/{keyId}:rotate (новый секрет возвращается один раз) |
| Отзыв ключа | POST /api/v1/keys/{keyId}:revoke (перевод в revoked с проверкой через Gateway) |
Публикация low-code агента. В этом релизе low-code агент публикуется прямо из интерфейса Low-code Конструктора: пользователь инициирует публикацию проверенной версии Потока (Flow) в самом Конструкторе, без обращения к Control Plane напрямую. Провайдер agent-platform экспортирует версию Потока в канонический формат и вызывает Control Plane через api-gw от имени пользователя.
| Шаг | Метод | Результат |
|---|---|---|
| Создание агента с начальной версией | POST /api/v1/agents | 202 Accepted → Operation |
| Создание новой версии | POST /api/v1/agents/{agentId}/versions | 202 Accepted → Operation |
| Проверка статуса публикации | GET /api/v1/agents/{agentId}/status | 200 OK → состояние, гейты, наблюдения Registry |
| Откат / скрытие / повторная валидация | POST /api/v1/agents/{agentId}:rollback / :unpublish / :revalidate | 202 Accepted → Operation |
| Обновление метаданных | PATCH /api/v1/agents/{agentId} | 202 Accepted → Operation |
Признаки успешной публикации: 202 Accepted означает принятую операцию, а не завершение; конечная готовность — publicationState = active в статусе публикации и статус операции succeeded в GET /api/v1/operations/{operationId}. Ограничения: изменяемые Flow.data не публикуются; неизвестный или изменённый вручную компонент отклоняется; прямая загрузка схемы в OCI, Kubernetes или Agent Registry запрещена.
Настройка политики публикации. Администратор задаёт синглтон PATCH /api/v1/agent-publication-policy — допустимый уровень и набор моделей для новых версий агентов. Версия замораживает разрешённые модели, уровень и ревизию политики; изменения политики не действуют задним числом.
Platform RAG — платформенный сервис уровня COMMON, предоставляющий управляемое извлечение знаний (retrieval-augmented generation): реестр коллекций, приём нормализованных документов, гибридный поиск с обязательной фильтрацией по правам доступа и выдачу фрагментов с цитатами.
Архитектура
Сервис состоит из двух прикладных нагрузок без локального состояния: API и воркер ingest. Всё состояние хранится во внешних сервисах данных. Модели вызываются только через AI Gateway. Авторизация коллекций — SpiceDB; видимость чанков — ACL документа, выведенный из act-цепочки вызывающего.
| Компонент | Назначение | Примечание |
|---|---|---|
platform-rag-api | HTTP API: коллекции, приём документов, статус заданий, поиск, /health | Stateless, горизонтально масштабируется. Порт 8090 |
platform-rag-worker | Обработка ingest: staging → chunk → embed → index | Масштабируется независимо, в т.ч. через KEDA |
| PostgreSQL | Реестр коллекций и источник истины по заданиям ingest | Схема platform_rag |
| RabbitMQ | Уведомления о заданиях (exchange: rag.ingest, quorum-очередь rag.ingest.jobs, DLX/DLQ) | Не хранит состояние задания |
| OpenSearch | Индекс чанков: embedding (kNN), текст BM25, tenant_id, acl, version | Алиас вида rag-kb-{env} |
| S3 / MinIO | Staging канонического JSON на время задания (payload_uri) | В локальном Compose допускается s3.dry_run: true |
| AI Gateway | Эмбеддинг и реранк | Идентификаторы моделей задаются профилями, не хардкодом в коде |
| SpiceDB | Права на коллекцию: owner / reader / writer | Fail-closed при недоступности |
| Keycloak | Проверка JWT при auth.enabled: true | В dev идентичность задаётся заголовками |
Helm-чарт helm/platform-rag создаёт Deployment *-api, Deployment *-worker, Service (ClusterIP, порт 8090), ConfigMap, ServiceAccount и опционально Ingress и KEDA ScaledObject. Зависимости чартом не устанавливаются.
Потоки данных
Приём документа. Клиент вызывает POST /v1/documents:submit. API проверяет право записи в коллекцию, регистрирует задание в PostgreSQL (PENDING), сохраняет канонический JSON в S3 и публикует уведомление в RabbitMQ. Воркер захватывает задание (RUNNING), выполняет чанкинг, эмбеддинг через AI Gateway и bulk-индексацию в OpenSearch, затем переводит задание в DONE или FAILED. Повторная отправка с тем же (tenant, collection, doc_id, content_hash, idempotency_key) возвращает DEDUPLICATED.
Поиск. Клиент вызывает POST /v1/query. API авторизует доступ к коллекции (SEC prior), строит эмбеддинг запроса через AI Gateway, выполняет гибридный поиск (kNN + BM25) со слиянием RRF, обязательно фильтрует выдачу по tenant_id и ACL вызывающего (SEC posterior) и возвращает цитаты (doc_id, chunk_id, фрагмент, оценка).
Идемпотентность и надёжность очереди. Источник истины — PostgreSQL. RabbitMQ доставляет уведомление; при потере сообщения фоновая сверка выбирает зависшие PENDING и публикует повторно. Воркеры идемпотентны.
Минимальные ресурсы
| Ресурс | Минимум (пилот) | Рекомендуется (пром) |
|---|---|---|
| Процессор (API + worker) | 2 ядра | 4–8 ядер |
| Оперативная память | 4 ГБ | 8–16 ГБ |
| OpenSearch | 2 ГБ heap | отдельный кластер, реплики индекса |
| PostgreSQL | 1 ГБ | внешний отказоустойчивый кластер |
| Диск | 20 ГБ (индекс + WAL) | по объёму коллекций |
| ОС | Linux x86-64, Docker Compose v2 или Kubernetes 1.27+ | — |
Запросы чарта по умолчанию: API — 100m CPU / 256Mi RAM (лимит 1Gi); worker — 250m CPU / 512Mi RAM (лимит 2Gi).
Развёртывание
Предварительные требования
- Linux x86-64; Docker Engine и Docker Compose v2 или кластер Kubernetes с Helm 3.
- Доступ к реестру образов либо возможность собрать образ из исходного кода.
- Для полного цикла ingest/query: доступные PostgreSQL 16, RabbitMQ 3, OpenSearch 2.x, объектное хранилище S3-совместимое, AI Gateway, SpiceDB.
Проверка Docker:
docker --version
docker compose versionПроверка Kubernetes / Helm:
kubectl version --client
helm versionПолучение дистрибутива
Исходный код и чарт поставляются репозиторием сервиса. Сборка образа:
docker build -t platform-rag:<tag> .В контуре заказчика используется согласованный реестр. После сборки образ публикуется в реестр, доступный узлам кластера.
Настройка конфигурации
Образец — config/config_template.yaml. Рабочий файл — config/config.yaml (путь задаётся RAG_CONFIG). Секреты (DSN, пароли, ключи) не хранятся в Git.
Обязательные группы параметров до запуска:
| Группа | Назначение | Действие |
|---|---|---|
postgres.dsn | Подключение к БД (postgresql+asyncpg://…) | Задать устойчивый пароль; схема platform_rag |
rabbitmq.* | Брокер ingest | Хост, пользователь, пароль, exchange/queue/dlx/dlq |
opensearch.hosts | Индекс чанков | URL кластера; index_alias вида rag-kb-<env> |
s3.* | Staging документов | Endpoint, bucket, ключи; для пилота без MinIO — dry_run: true |
ai_gateway.url / api_key | Эмбеддинг и реранк | URL шлюза; ключ только в Secret |
embedding_profiles | Профиль модели и размерность | Закрепляется за коллекцией; смена — через переиндексацию |
spicedb.* | Авторизация коллекций | В проде enabled: true, TLS, не insecure |
auth.* | Проверка JWT | В проде enabled: true и параметры Keycloak |
Переопределение из окружения (примеры):
export RAG_CONFIG=/app/config/config.yaml
export RAG__POSTGRES__DSN='postgresql+asyncpg://[REDACTED]@postgres:5432/platform_rag'
export RAG__RABBITMQ__PASSWORD='[REDACTED]'
export RAG__S3__ACCESS_KEY_ID='<key>'
export RAG__S3__SECRET_ACCESS_KEY='<secret>'
export RAG__OPENSEARCH__USERNAME='<user>'
export RAG__OPENSEARCH__PASSWORD='[REDACTED]'
export RAG__AI_GATEWAY__API_KEY='[REDACTED]'
export RAG__SPICEDB__ENABLED=true
export RAG__AUTH__ENABLED=trueПри app.create_schema_on_startup: true API при старте создаёт схему PostgreSQL. Для промышленного контура порядок миграций согласовывается отдельно; откат Helm не откатывает схему БД.
Внимание. Профиль эмбеддинга (
model+dimension) закрепляется за коллекцией. Смена профиля без версионируемой переиндексации сделает векторный поиск несовместимым.
Развёртывание в Docker Compose
Файл docker-compose.yml поднимает прикладные сервисы и зависимости: PostgreSQL, RabbitMQ, OpenSearch, SpiceDB (с отдельной БД и миграцией схемы). MinIO и AI Gateway в Compose не входят: для пилота без объектного хранилища используется s3.dry_run: true.
Публикуемые порты Compose:
| Сервис | Порт на хосте | Назначение |
|---|---|---|
| API | 8095 → 8090 | HTTP API |
| PostgreSQL | 5433 → 5432 | БД сервиса |
| RabbitMQ | 5672, 15672 | AMQP и management UI |
| OpenSearch | 9201 → 9200 | Поиск / индекс |
| SpiceDB | 50051, 8443 | gRPC / HTTP |
Вариант A. Инфраструктура в Docker, приложение на хосте:
docker compose up -d postgres rabbitmq opensearch spicedb-postgres
docker compose up spicedb-migrate
docker compose up -d spicedb
# из корня репозитория, Python 3.11+
pip install -e .
export RAG_CONFIG=config/config.yaml
platform-rag-api
# во втором терминале:
platform-rag-workerПроверка:
curl -fsS http://127.0.0.1:8090/healthОжидается "status": "ok" по компонентам postgres, rabbitmq, s3, opensearch. При s3.dry_run: true проверка S3 считается успешной без реального бакета.
Вариант B. Полный стек в Compose:
docker compose up -d --build
docker compose ps
docker compose logs -f api worker
curl -fsS http://127.0.0.1:8095/healthОстановка:
docker compose down
# с удалением томов данных:
docker compose down -vРазвёртывание в Kubernetes (Helm)
Чарт: helm/platform-rag. Канонические команды также приведены в helm/platform-rag/README.md и docs/helm-deployment.md.
Подготовка
- Собрать и опубликовать образ.
- Проверить сетевую доступность PostgreSQL, RabbitMQ, S3, OpenSearch, AI Gateway и SpiceDB из целевого пространства имён.
- Создать Secret с учётными данными (не помещать их в values):
kubectl -n <namespace> create secret generic platform-rag-secrets \
--from-literal=postgres-dsn='postgresql+asyncpg://[REDACTED]@host:5432/platform_rag' \
--from-literal=postgres-dsn-sync='postgresql://[REDACTED]@host:5432/platform_rag' \
--from-literal=rabbitmq-password='[REDACTED]' \
--from-literal=s3-access-key-id='<access-key>' \
--from-literal=s3-secret-access-key='<secret-key>' \
--from-literal=opensearch-username='<username>' \
--from-literal=opensearch-password='[REDACTED]' \
--from-literal=ai-gateway-api-key='[REDACTED]'- Подготовить values окружения (образцы:
helm/platform-rag/values.yaml,values-dev.yaml,values-prod.example.yaml).
Установка
helm lint helm/platform-rag
helm template platform-rag helm/platform-rag -n <namespace> -f values-<env>.yaml
helm upgrade --install platform-rag helm/platform-rag \
-n <namespace> --create-namespace \
-f values-<env>.yaml \
--atomic --wait --timeout 10m
kubectl -n <namespace> rollout status deployment/platform-rag-api --timeout=5m
kubectl -n <namespace> rollout status deployment/platform-rag-worker --timeout=5m
kubectl -n <namespace> get pods,svcПроверка с порта кластера:
kubectl -n <namespace> port-forward svc/platform-rag 8090:8090
curl -fsS http://127.0.0.1:8090/healthПри включённом Ingress (ingress.enabled: true) задайте ingress.hosts[].host и при необходимости TLS. Снаружи публикуется только API; воркер наружу не выставляется.
Особенности промышленного контура
- Образы запускаются от UID/GID
10001,runAsNonRoot, без привилегий, read-only root filesystem,/tmp—emptyDir. - Конфиг монтируется ConfigMap по пути
/app/config/config.yaml. - Probes API: startup/liveness/readiness на
GET /health. terminationGracePeriodSeconds: 60— чтобы воркер успел завершить текущее задание.- При полной замене блока
configсохраните секцииapi,embedding_profiles,rerank_profiles,chunking,paths,logиз значений чарта, если не меняете их намеренно.
Автомасштабирование воркеров (KEDA)
Источник истины backlog — SQL, не глубина очереди RabbitMQ:
SELECT COUNT(*) FROM platform_rag.ingest_job WHERE status = 'PENDING'Включение в values (см. values-prod.example.yaml):
worker:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 10
targetQueryValue: "4"
authentication:
existingSecret: [REDACTED]
connectionKey: postgres-dsn-syncТребования: KEDA в кластере; ключ Secret с libpq-строкой postgresql://… (SQLAlchemy postgresql+asyncpg://… скейлер не принимает). При включённом autoscaling поле replicas у Deployment воркера не задаётся — число реплик принадлежит KEDA.
Подключение моделей
Сервис не содержит собственной языковой модели. Все вызовы эмбеддинга и реранка идут через AI Gateway. Ключи инференса хранятся у шлюза; в конфигурации RAG задаётся только URL шлюза и ключ доступа к нему.
Профили задаются в конфигурации:
embedding_profiles:
text-default-v1:
profile_id: text-default-v1
model: bge-m3
dimension: 1024
normalize: true
rerank_profiles:
rerank-default-v1:
profile_id: rerank-default-v1
model: bge-m3
candidates: 20| Назначение | Где задаётся | Примечание |
|---|---|---|
| Эмбеддинг | embedding_profile_id коллекции | Изменение требует новой версии индекса |
| Реранк | retrieval_defaults.rerank_profile_id и флаг rerank в запросе | Только из числа одобренных профилей |
| Размерность вектора | embedding_profiles.*.dimension | Должна совпадать с mapping OpenSearch (knn_vector) |
Для закрытого контура используется шлюз в контуре заказчика. Передача содержимого документов во внешние сетевые сервисы без правовых оснований недопустима.
ai_gateway.dry_run: true возвращает нулевые векторы фиксированной размерности — только для проверки конвейера без модели. Для приёмки качества поиска dry-run не используется.
Авторизация и доступ
Две плоскости идентичности
Каждый вызов несёт тенант и идентичность вызывающего. В режиме разработки (auth.enabled: false) идентичность передаётся заголовками. В промышленном режиме (auth.enabled: true) обязателен Authorization: Bearer [REDACTED].
| Заголовок | Назначение |
|---|---|
X-Tenant-Id | Тенант (обязателен всегда) |
X-User-Id | Пользователь (dev; в проде — из JWT sub / user_id) |
X-Groups | Группы через запятую (dev; в проде — claim groups) |
X-Principals | Дополнительные principals (dev) |
X-Agent-Id | Идентификатор агента (dev; в проде — claim agent_id) |
Authorization | Bearer JWT при auth.enabled: true |
X-Trace-Id | Корреляция (поиск прокидывает в meta.trace_id) |
Фильтр выдачи строится по правам пользователя, а не агента: один и тот же агент для разных пользователей возвращает разный набор чанков.
SpiceDB
Модель прав:
collection.owner— пользователь-владелец;collection.reader— пользователь, группа или агент (чтение / поиск);collection.writer— интеграционный сервис (запись /submit_documents);document.view— членviewer_groupилиparent->read.
При недоступности SpiceDB сервис отвечает 503 authz_unavailable (fail-closed), а не «пропускает» запрос.
ACL документа
В приватной коллекции пустой ACL при upsert недопустим: документ отклоняется (empty_acl_policy: reject) либо индексируется с самой строгой видимостью (strictest). Политика задаётся на коллекции и значением app.empty_acl_policy.
Отзыв прав действует на следующем запросе: ACL перепроверяются в момент retrieval, переиндексация для отзыва не требуется.
Безопасность
Секреты
В Secret / защищённом хранилище: DSN PostgreSQL, пароль RabbitMQ, ключи S3, учётные данные OpenSearch, ключ AI Gateway, preshared key SpiceDB. Файл values и ConfigMap не содержат паролей.
Права на локальный config.yaml с секретами:
chmod 600 config/config.yamlСетевые ограничения
Наружу публикуется только API (ClusterIP + Ingress, порт 8090 / TLS). Воркер, PostgreSQL, RabbitMQ, OpenSearch, SpiceDB во внешнюю сеть не публикуются.
| Источник | Порт | Протокол | Назначение |
|---|---|---|---|
| Потребители (SDK, low-code, интеграции) | 8090 / 443 | HTTP/HTTPS | RAG API |
| API / worker | 5432 | PostgreSQL | Реестр и job store |
| API / worker | 5672 | AMQP | Очередь ingest |
| API / worker | 9200 | HTTPS | OpenSearch |
| API / worker | 50051 | gRPC | SpiceDB |
| Worker / API | 443 | HTTPS | AI Gateway, S3 |
Хранение данных
Документы и чанки хранятся в контуре: PostgreSQL (метаданные, jobs), OpenSearch (текст и векторы), S3 (staging). Каждая операция ingest и query подлежит аудиту (минимум: trace_id, операция, идентичность обеих плоскостей, тенант, коллекция).
Резервное копирование
Объекты копирования: PostgreSQL (реестр и job store), индексы OpenSearch, при необходимости бакет staging, файл/Secret конфигурации. RabbitMQ некритичен как SoT.
Логическая выгрузка БД (Compose):
docker compose exec -T postgres \
pg_dump -U postgres platform_rag > platform_rag_db_$(date +%F).sqlВ Kubernetes:
kubectl -n <namespace> exec -T <под_postgresql> -- \
pg_dump -U <user> platform_rag > platform_rag_db_$(date +%F).sqlСнимки OpenSearch выполняются штатными средствами кластера (snapshot repository). Копии хранятся отдельно от контура приложения; периодически проверяется восстановление.
Восстановление
- Развернуть ту же версию сервиса с прежними секретами и профилями эмбеддинга.
- Восстановить PostgreSQL (схема
platform_rag). - Восстановить снимки OpenSearch (алиас
rag-kb-<env>). - Запустить API и worker; проверить
/health, список коллекций и контрольныйquery.
Обновление сервиса
Перед обновлением — резервное копирование и окно обслуживания.
Docker Compose
docker compose down
# обновить код / тег образа
docker compose build
docker compose up -d
docker compose logs -f api workerСверить config_template.yaml с рабочим конфигом на предмет новых параметров.
Kubernetes (Helm)
helm upgrade --install platform-rag helm/platform-rag \
-n <namespace> \
-f values-<env>.yaml \
--atomic --wait --timeout 10mСхема базы данных
При app.create_schema_on_startup: true API создаёт/догоняет объекты схемы при старте. Эксплуатация начинается после успешного /health и отсутствия ошибок создания схемы в журнале API.
Откат Helm не отменяет изменения схемы и данных внешних хранилищ.
Откат
helm -n <namespace> history platform-rag
helm -n <namespace> rollback platform-rag <REVISION> --wait --timeout 10m
kubectl -n <namespace> rollout status deployment/platform-rag-api --timeout=5m
kubectl -n <namespace> rollout status deployment/platform-rag-worker --timeout=5mПри несовместимых миграциях откат версии выполняется вместе с восстановлением БД из копии, снятой до обновления.
Мониторинг
Состояние сервисов
Docker Compose
docker compose ps
docker compose logs -f api
docker compose logs -f worker
curl -fsS http://127.0.0.1:8095/healthKubernetes
kubectl -n <namespace> get pods -l app.kubernetes.io/instance=platform-rag
kubectl -n <namespace> logs deploy/platform-rag-api --tail=200
kubectl -n <namespace> logs deploy/platform-rag-worker --tail=200
kubectl -n <namespace> top podsGET /health возвращает status: ok | degraded и статусы postgres, rabbitmq, s3, opensearch. Probes Kubernetes используют этот путь.
Дополнительно контролируются: число PENDING/FAILED в ingest_job, глубина DLQ rag.ingest.dlq, латентность query, ошибки AI Gateway.
Журналы
Уровень задаётся log.level (по умолчанию INFO). Воркер пишет о старте listener, захвате job, ошибках эмбеддинга и индексации. Корреляция — trace_id.
Типовые нарушения
| Признак | Источник | Вероятная причина и действие |
|---|---|---|
/health → degraded | Тело ответа details | Недоступен Postgres, RabbitMQ, S3 или OpenSearch |
401 Missing X-Tenant-Id | Журнал API | Нет заголовка тенанта |
401 Missing bearer token | Журнал API | Включён auth.enabled, нет JWT |
403 на коллекции | SpiceDB | Нет read/write/owner |
503 authz_unavailable | SpiceDB | Шлюз авторизации недоступен — не «обходить» |
Submit 202, job завис в PENDING | Worker, RabbitMQ | Воркер не запущен; нет потребителя; сбой публикации |
Job FAILED | Журнал worker, поле error | Ошибка AI Gateway, OpenSearch, S3; неверный профиль |
| Query пустой при наличии документов | ACL, группы | Вызывающий не в acl.groups; неверный тенант |
| Индексация медленная | KEDA, PENDING count | Нехватка воркеров; лимит AI Gateway |
Производительность и масштабирование
Воркеры ingest
Основной потребитель ресурсов при загрузке знаний. Число реплик — worker.replicaCount или KEDA по PENDING (целевое значение targetQueryValue, по умолчанию 4 задания на реплику). Параллелизм внутри процесса — app.worker_concurrency (по умолчанию 4). Prefetch RabbitMQ — rabbitmq.prefetch (16).
API
Stateless: увеличивайте api.replicaCount. Пул БД — postgres.pool_size. Эмбеддинг запроса на каждый query идёт в AI Gateway — фактический предел латентности часто определяется шлюзом, а не API.
OpenSearch
Индексу выделяются CPU/RAM; mapping knn_vector требователен к памяти. Смена размерности эмбеддинга требует нового шаблона и переиндексации.
Аварийные ситуации
Недоступность сервиса
- Проверить
/healthи Ingress/Service. - По
detailsопределить отказавший компонент (БД, очередь, S3, OpenSearch). - Проверить поды API и worker, события Kubernetes, журналы.
- Перезапуск:
# Compose
docker compose restart api worker
# Kubernetes
kubectl -n <namespace> rollout restart deploy/platform-rag-api
kubectl -n <namespace> rollout restart deploy/platform-rag-worker- При переполнении диска — очистка журналов/образов, расширение PVC OpenSearch/PostgreSQL.
- При повреждении данных — восстановление из копии.
- Зафиксировать время, признаки,
trace_id, выдержки журналов, выполненные действия.
Эскалация
| Категория | Признаки | Ответственный |
|---|---|---|
| Функциональное | Некорректная выдача, ACL, качество поиска | Владелец знаний / функциональная команда |
| Инфраструктурное | Поды, сеть, диски, Helm, зависимости | Администратор контура |
| Платформенное | Дефект API/worker, контракт, SpiceDB-схема | Команда Platform RAG |
Перед эскалацией: версия образа/чарта, описание, затронутые коллекции, trace_id, журналы, время, уже выполненные действия.
Platform Memory
Назначение и область применения
Platform Memory — единый управляемый слой памяти платформы. Агент получает персистентную память: search перед ответом, add после ответа. Извлечение фактов, дедупликация, гибридный поиск, изоляция по скоупам и история изменений выполняются сервисом, а не каждым агентом отдельно.
Память не заменяет RAG. Platform RAG отвечает за корпус документов; Platform Memory — за знания о пользователе, агенте и сессии. Сборка промпта комбинирует оба источника.
Публичный контракт совместим с mem0 (add / search / get_all / history / delete). Пути платформы — /v1/*. Платформенные отличия: идентичность вызывающего не берётся из тела запроса, запись асинхронна, инференс и эмбеддинг идут только через AI Gateway.
Архитектура сервиса
Сервис состоит из двух прикладных нагрузок без локального состояния: API (синхронное чтение и приём записи) и воркер извлечения (асинхронный write-path). Состояние хранится во внешних сервисах данных. Модели вызываются только через AI Gateway.
| Компонент | Назначение | Примечание |
|---|---|---|
platform-memory-api | HTTP API: add, search, list, history, events, /health | Stateless. Контейнерный порт 8091; в Compose публикуется как 8093 |
platform-memory-worker | Обработка add: claim события → mem0 Memory.add → индекс и история | Масштабируется независимо (worker.concurrency) |
| PostgreSQL | Event store, история записей, служебные сообщения mem0 | Схема platform_memory |
| RabbitMQ | Уведомления о заданиях (memory.add / memory.add.jobs / DLX memory.add.dlx / DLQ memory.add.dlq) | Не хранит состояние задания; источник истины — PostgreSQL |
| OpenSearch | Индекс фактов: kNN + BM25 | Алиас вида mem-facts-dev / mem-facts-prod |
| AI Gateway | Эмбеддинг запросов/фактов и LLM-извлечение (infer: true) | Ключ шлюза — только в Secret |
Потоки данных
Запись (POST /v1/memories). Клиент передаёт messages и минимум один скоуп (agent_id или run_id). Идентичность (workspace_id, user_id) берётся из заголовков, не из тела. API создаёт событие PENDING в PostgreSQL, публикует уведомление в RabbitMQ и сразу отвечает 202 с event_id. Если публикация в очередь не удалась, событие помечается FAILED, клиент получает 503 queue_unavailable.
Воркер захватывает событие (RUNNING), вызывает Flow mem0: при infer: true — LLM через AI Gateway с дедупликацией; при infer: false — сохранение сообщений без LLM. Результат пишется в OpenSearch и историю PostgreSQL; статус события — SUCCEEDED или FAILED.
Поиск (POST /v1/memories/search). Синхронно: эмбеддинг запроса через AI Gateway, гибридный поиск в OpenSearch (семантика + BM25), упаковка результатов в token_budget. Обязательны фильтры со скоупом.
Список и забвение. GET /v1/memories возвращает факты по agent_id / run_id в рамках workspace и пользователя. DELETE /v1/memories удаляет записи по фильтру (право на забвение); user_id в запросе не может отличаться от идентичности вызывающего.
История. GET /v1/memories/{memory_id}/history отдаёт журнал ADD / UPDATE / DELETE из PostgreSQL.
Минимальные ресурсы
Значения ориентировочные и уточняются по нагрузке. Для пилотного стенда (проверка API и одного агента):
| Ресурс | Минимум (пилот) | Рекомендуется (пром) |
|---|---|---|
| Процессор (API + worker) | 2 ядра | 4–8 ядер |
| Оперативная память | 4 ГБ | 8–16 ГБ |
| OpenSearch | 512 МБ heap (Compose) | отдельный кластер, реплики индекса |
| PostgreSQL | 1 ГБ | внешний отказоустойчивый кластер |
| Диск | 20 ГБ (индекс + WAL) | по объёму фактов |
| ОС | Linux x86-64, Docker Compose v2 или Kubernetes 1.27+ | — |
Языковые модели и эмбеддинги размещаются за AI Gateway, вне сервиса. Требования к GPU определяются выбранной моделью, а не Platform Memory.
Установка и развёртывание
Основной способ пилотных и локальных стендов — Docker Compose. Для промышленных сред — Kubernetes + Helm.
Предварительные требования
- Linux x86-64.
- Docker Engine и Docker Compose версии 2 или кластер Kubernetes с Helm 3.
- Доступ к реестру образов либо возможность собрать образ из исходного кода.
- Для полного цикла add/search: доступные PostgreSQL 16, RabbitMQ 3, OpenSearch 2.x, AI Gateway.
Получение дистрибутива
Сборка образа:
docker build -t platform-memory:<tag> .Образ запускается от UID/GID 10001 (non-root), корневая ФС в Kubernetes — read-only. В контуре заказчика используется согласованный реестр. После сборки образ публикуется в реестр, доступный узлам кластера.
Настройка конфигурации
Образец — config/config_template.yaml. Рабочий файл задаётся MEMORY_CONFIG. Секреты (DSN, пароли, ключ AI Gateway) не хранятся в Git; для локального стенда допустимы dev-значения только во внутреннем контуре.
Обязательные группы параметров до запуска:
| Группа | Назначение | Действие |
|---|---|---|
postgres.dsn | Подключение к БД (postgresql+asyncpg://…) | Задать устойчивый пароль; схема platform_memory |
rabbitmq.* | Брокер write-path | Хост, пользователь, пароль, exchange/queue/dlx/dlq |
opensearch.hosts | Индекс фактов | URL кластера; index_alias вида mem-facts-<env> |
embedding.model / dimension | Модель и размерность вектора | Должны совпадать с mapping OpenSearch (по умолчанию 1024) |
ai_gateway.url / api_key / llm_model | Эмбеддинг и LLM-извлечение | URL шлюза; ключ только в Secret |
Переопределение из окружения (примеры):
export MEMORY_CONFIG=/app/config/config.yaml
export MEMORY__POSTGRES__DSN='postgresql+asyncpg://[REDACTED]@postgres:5432/platform_memory'
export MEMORY__RABBITMQ__HOST=rabbitmq
export MEMORY__RABBITMQ__PASSWORD='[REDACTED]'
export MEMORY__OPENSEARCH__USERNAME='<user>'
export MEMORY__OPENSEARCH__PASSWORD='[REDACTED]'
export MEMORY__AI_GATEWAY__URL='https://<ai-gateway>/v1'
export MEMORY__AI_GATEWAY__API_KEY='[REDACTED]'При app.create_schema_on_startup: true API при старте создаёт схему PostgreSQL. Для промышленного контура порядок миграций согласовывается отдельно; откат Helm не откатывает схему БД.
Внимание. Размерность эмбеддинга (embedding.dimension и opensearch.embedding_dimension) закрепляется за индексом. Смена модели/размерности без переиндексации сделает векторный поиск несовместимым.
Развёртывание в Docker Compose
Файл docker-compose.yml поднимает API, worker и зависимости: PostgreSQL, RabbitMQ, OpenSearch. AI Gateway в Compose не входит.
Публикуемые порты Compose:
| Сервис | Порт на хосте | Назначение |
|---|---|---|
| API | 8093 → 8091 | HTTP API |
| PostgreSQL | 5435 → 5432 | БД сервиса |
| RabbitMQ AMQP | 5674 → 5672 | Очередь add |
| RabbitMQ management | 15674 → 15672 | UI брокера |
| OpenSearch | 9202 → 9200 | Поиск / индекс |
Проверка:
curl -fsS http://127.0.0.1:8091/healthОжидается "status": "ok" по компонентам postgres, opensearch, rabbitmq.
Развёртывание в Kubernetes (Helm)
Чарт: helm/platform-memory.
Подготовка
- Собрать и опубликовать образ.
- Проверить сетевую доступность PostgreSQL, RabbitMQ, OpenSearch и AI Gateway из целевого пространства имён.
- Создать Secret с учётными данными:
kubectl -n <namespace> create secret generic platform-memory-secrets \
--from-literal=postgres-dsn='postgresql+asyncpg://[REDACTED]@host:5432/platform_memory' \
--from-literal=opensearch-username='<username>' \
--from-literal=opensearch-password='[REDACTED]' \
--from-literal=ai-gateway-api-key='[REDACTED]'- Подготовить values окружения (образцы:
values.yaml,values-dev.yaml,values-prod.example.yaml).
Секция rabbitmq в values.yaml чарта по умолчанию может отсутствовать — её необходимо задать в values окружения, иначе API возьмёт значения по умолчанию (127.0.0.1), непригодные в кластере.
Установка
helm lint helm/platform-memory
helm template platform-memory helm/platform-memory -n <namespace> -f values-<env>.yaml
helm upgrade --install platform-memory helm/platform-memory \
-n <namespace> --create-namespace \
-f values-<env>.yaml \
--atomic --wait --timeout 10m
kubectl -n <namespace> rollout status deployment/platform-memory --timeout=5mПроверка с порта кластера:
kubectl -n <namespace> port-forward svc/platform-memory 8091:8091
curl -fsS http://127.0.0.1:8091/healthВоркер в Kubernetes
Без platform-memory-worker запросы POST /v1/memories принимаются (202), но события остаются в PENDING. До появления Deployment воркера в чарте воркер запускают тем же образом с командой platform-memory-worker и тем же ConfigMap/Secret, что и API (уточняется при внедрении). В Docker Compose воркер уже описан сервисом worker.
Особенности промышленного контура
- Образы запускаются от UID/GID
10001,runAsNonRoot, без привилегий, read-only root filesystem,/tmp—emptyDir. - Конфиг монтируется ConfigMap по пути
/app/config/config.yaml(MEMORY_CONFIG). - Probes: startup/liveness/readiness на
GET /health. terminationGracePeriodSeconds: 30.
Подключение моделей
Сервис не содержит собственной языковой модели. Все вызовы эмбеддинга и LLM-извлечения идут через AI Gateway. Для закрытого контура используется шлюз в контуре заказчика. Передача фактов о пользователях во внешние сетевые сервисы без правовых оснований недопустима.
infer: false позволяет записать готовый факт без вызова LLM (миграция, системные факты, явное «запомни это») — дешевле и предсказуемее для нагрузочных проверок записи.
Доступ и изоляция памяти
Идентичность вызывающего
На текущем релизе идентичность передаётся заголовками. Поля workspace_id / user_id в теле запроса не доверяются.
| Заголовок | Назначение |
|---|---|
X-Workspace-Id | Рабочая область (обязателен) |
X-User-Id | Пользователь (обязателен; скоуп user_id для фактов) |
Без заголовков API отвечает 422. Целевой контракт (JWT платформы + SpiceDB check на memory_collection, fail-closed) описан в PRD и в текущем API не включён.
Скоупы
Факты изолируются по комбинации workspace, user_id, agent_id, run_id. Для add и list обязателен минимум один из agent_id / run_id. Поиск требует filters со скоупом. Удаление по фильтру не позволяет указать чужой user_id (403 Wrong user ID).
Право на забвение
DELETE /v1/memories с фильтром удаляет релевантные факты в OpenSearch и пишет события DELETE в историю. В ответе — deleted_count и confirmation_id для журнала операций.
Безопасность
Секреты
В Secret / защищённом хранилище: DSN PostgreSQL, пароль RabbitMQ, учётные данные OpenSearch, ключ AI Gateway. Файл values и ConfigMap не содержат паролей.
Права на локальный конфиг с секретами:
chmod 600 config/config.yamlКлючи выдаются по принципу наименьших полномочий; при компрометации отзываются и перевыпускаются.
Сетевые ограничения
Наружу публикуется только API (ClusterIP + Ingress, порт 8091 / TLS). Воркер, PostgreSQL, RabbitMQ, OpenSearch во внешнюю сеть не публикуются.
| Источник | Порт | Протокол | Назначение |
|---|---|---|---|
| Потребители (SDK, low-code, интеграции) | 8091 / 443 | HTTP/HTTPS | Memory API |
| API / worker | 5432 | PostgreSQL | Event store и история |
| API / worker | 5672 | AMQP | Очередь add |
| API / worker | 9200 | HTTP/HTTPS | OpenSearch |
| API / worker | 443 | HTTPS | AI Gateway |
| Администраторы | 22 / API Kubernetes | SSH / kubectl | Сопровождение |
Management-порт RabbitMQ (15672) на промышленных контурах наружу не публикуется.
Хранение данных
Факты хранятся в контуре: PostgreSQL (события, история), OpenSearch (текст и векторы). Персональные факты в долговременной памяти обрабатываются в контуре заказчика. Передача во внешние LLM без шлюза и правовых оснований недопустима.
Резервное копирование
Объекты копирования: PostgreSQL (event store и история), индексы OpenSearch, файл/Secret конфигурации. RabbitMQ некритичен как источник истины.
Логическая выгрузка БД (Compose):
docker compose exec -T postgres \
pg_dump -U postgres platform_memory > platform_memory_db_$(date +%F).sqlВ Kubernetes (внешний кластер PostgreSQL — штатными средствами кластера):
kubectl -n <namespace> exec -T <под_postgresql> -- \
pg_dump -U <user> platform_memory > platform_memory_db_$(date +%F).sqlСнимки OpenSearch выполняются штатными средствами кластера (snapshot repository) для алиаса mem-facts-<env>.
Восстановление
- Развернуть ту же версию сервиса с прежними секретами и той же размерностью эмбеддинга.
- Восстановить PostgreSQL (схема
platform_memory). - Восстановить снимки OpenSearch (алиас
mem-facts-<env>). - Запустить API и worker; проверить
/health, контрольныйadd/search.
Обновление сервиса
Перед обновлением — резервное копирование (п. 5.4) и окно обслуживания.
Docker Compose
docker compose down
# обновить код / тег образа
docker compose build
docker compose up -d
docker compose logs -f api workerСверить config_template.yaml с рабочим конфигом на предмет новых параметров.
Kubernetes (Helm)
helm upgrade --install platform-memory helm/platform-memory \
-n <namespace> \
-f values-<env>.yaml \
--atomic --wait --timeout 10mОткат
helm -n <namespace> history platform-memory
helm -n <namespace> rollback platform-memory <REVISION> --wait --timeout 10m
kubectl -n <namespace> rollout status deployment/platform-memory --timeout=5mПри несовместимых миграциях откат версии выполняется вместе с восстановлением БД и индекса из копии, снятой до обновления.
Мониторинг и журналы
Состояние сервисов
Docker Compose
docker compose ps
docker compose logs -f api
docker compose logs -f worker
curl -fsS http://127.0.0.1:8093/healthKubernetes
kubectl -n <namespace> get pods -l app.kubernetes.io/instance=platform-memory
kubectl -n <namespace> logs deploy/platform-memory --tail=200
kubectl -n <namespace> top podsGET /health возвращает status: ok | degraded и статусы postgres, opensearch, rabbitmq. Probes Kubernetes используют этот путь.
Дополнительно контролируются: число событий PENDING/FAILED в memory_event, глубина DLQ memory.add.dlq, латентность search, отставание извлечения (время PENDING → SUCCEEDED).
Журналы
Уровень задаётся log.level (по умолчанию INFO). API пишет о приёме add (event_id, infer) и ошибках публикации в очередь. Воркер пишет о старте listener, захвате события (RUNNING), ошибках mem0/AI Gateway/индексации.
Типовые нарушения
| Признак | Источник | Вероятная причина и действие |
|---|---|---|
/health → degraded | Тело ответа details | Недоступен Postgres, OpenSearch или RabbitMQ |
422 / missing header | Журнал API | Нет X-Workspace-Id или X-User-Id |
400 «At least one of agent_id or run_id» | Тело запроса | Нет скоупа |
503 queue_unavailable | Журнал API, RabbitMQ | Брокер недоступен; событие помечено FAILED |
Add 202, событие зависло в PENDING | Worker, RabbitMQ | Воркер не запущен; нет потребителя очереди |
Событие FAILED | Журнал worker, поле error | Ошибка AI Gateway, OpenSearch, Flow mem0 |
| Search пустой при наличии фактов | Скоупы, workspace | Другой agent_id/user_id/X-Workspace-Id; событие ещё не SUCCEEDED |
| Search медленный | AI Gateway, OpenSearch | Эмбеддинг запроса; нехватка heap у индекса |
403 на DELETE | user_id в query | Попытка удалить память другого пользователя |
Производительность и масштабирование
Воркеры извлечения
Основной потребитель ресурсов при infer: true (LLM на каждый add). Параллелизм внутри процесса — worker.concurrency (по умолчанию 4). Prefetch RabbitMQ — rabbitmq.prefetch (16). После rabbitmq.delivery_limit (5) неуспешных доставок сообщение уходит в DLQ.
Горизонтальное масштабирование в Compose:
docker compose up -d --scale worker=3В Kubernetes число экземпляров воркера задаётся отдельно от API (уточняется при внедрении). API при росте search масштабируется увеличением replicaCount.
API
Stateless: увеличивайте число реплик Deployment. Пул БД — postgres.pool_size. Эмбеддинг запроса на каждый search идёт в AI Gateway — фактический предел латентности часто определяется шлюзом, а не API.
Ограничения
| Параметр | Назначение |
|---|---|
top_k | Search: 1–200 (по умолчанию 20); list: до 1000 |
token_budget | Лимит токенов в выдаче search |
threshold | Порог релевантности (по умолчанию 0.1) |
ai_gateway.timeout / batch_size | Таймаут и пачки эмбеддинга |
rabbitmq.delivery_limit | После 5 неуспешных доставок — DLQ |
| Пропускная способность AI Gateway | Фактический предел add (infer) и search |
Аварийные ситуации
Недоступность сервиса
- Проверить
/healthи Ingress/Service. - По
detailsопределить отказавший компонент (БД, очередь, OpenSearch). - Проверить поды API и worker, события Kubernetes, журналы.
- Перезапуск:
# Compose
docker compose restart api worker
# Kubernetes
kubectl -n <namespace> rollout restart deploy/platform-memory- При переполнении диска — очистка журналов/образов, расширение томов OpenSearch/PostgreSQL.
- При повреждении данных — восстановление из копии (п. 5.5).
- Зафиксировать время, признаки,
event_id, выдержки журналов, выполненные действия.
Эскалация
| Категория | Признаки | Ответственный |
|---|---|---|
| Функциональное | Некорректные факты, скоупы, качество поиска | Владелец агентов / функциональная команда |
| Инфраструктурное | Поды, сеть, диски, Helm, зависимости | Администратор контура |
| Платформенное | Дефект API/worker, контракт mem0, Flow извлечения | Команда Platform Memory |
Перед эскалацией: версия образа/чарта, описание, затронутые workspace/agent_id, event_id, журналы, время, уже выполненные действия.
Примеры запросов для проверки системы
Базовый URL локального Compose: http://127.0.0.1:8093. При запуске API на хосте с портом из конфига: http://127.0.0.1:8091. При port-forward Helm: http://127.0.0.1:8091. Ниже $BASE — выбранный URL.
export BASE=http://127.0.0.1:8093
export WS=ws-admin-check
export USER=user-admin-check
export AGENT=procurement-assistant-v1Все вызовы кроме /health требуют заголовков X-Workspace-Id и X-User-Id.
Живучесть
curl -fsS "$BASE/health"Ожидается HTTP 200 и JSON вида:
{
"status": "ok",
"components": {
"postgres": "ok",
"opensearch": "ok",
"rabbitmq": "ok"
},
"details": {}
}Запись памяти (async add, infer)
curl -sS -X POST "$BASE/v1/memories" \
-H "Content-Type: application/json" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER" \
-d '{
"messages": [
{"role": "user", "content": "Я работаю в отделе закупок, отчёты нужны в xlsx"},
{"role": "assistant", "content": "Понял, буду присылать xlsx"}
],
"agent_id": "'"$AGENT"'",
"run_id": "run-admin-check-1",
"infer": true,
"metadata": {"source": "admin-check"}
}'Ожидается 202:
{
"event_id": "<uuid>",
"status": "PENDING"
}Без agent_id и run_id — 400. Без заголовков идентичности — 422. При недоступном RabbitMQ — 503 с error: queue_unavailable.
Статус события
export EVENT_ID='<uuid из ответа>'
curl -sS "$BASE/v1/events/$EVENT_ID" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER"Ожидается 200. Цепочка: PENDING → SUCCEEDED | FAILED.
Список фактов
curl -sS "$BASE/v1/memories?agent_id=$AGENT&page_size=20" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER"Ожидается 200, объект с count и массивом results (id, memory, скоупы, created_at).
Поиск
curl -sS -X POST "$BASE/v1/memories/search" \
-H "Content-Type: application/json" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER" \
-d '{
"query": "в каком формате присылать отчёт",
"filters": {"agent_id": "'"$AGENT"'"},
"top_k": 5,
"token_budget": 400,
"threshold": 0.1,
"explain": true
}'Ожидается 200: массив results с фактами, score и tokens_returned.
История записи
export MEMORY_ID='<uuid из list или search>'
curl -sS "$BASE/v1/memories/$MEMORY_ID/history" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER"Ожидается 200 и массив записей с event: ADD / UPDATE / DELETE.
Удаление по скоупу (право на забвение)
curl -sS -X DELETE "$BASE/v1/memories?agent_id=$AGENT" \
-H "X-Workspace-Id: $WS" \
-H "X-User-Id: $USER"Ожидается 200: deleted_count и confirmation_id.
Попытка ?user_id=other-user при заголовке X-User-Id: $USER — 403.
Негативные проверки
| Проверка | Запрос | Ожидание |
|---|---|---|
| Нет workspace | любой /v1/* без X-Workspace-Id | 422 |
| Нет user | без X-User-Id | 422 |
| Add без скоупа | POST /v1/memories только с messages | 400 |
| List без скоупа | GET /v1/memories | 400 |
| Delete без фильтра | DELETE /v1/memories | 400 |
| Чужой user при delete | DELETE /v1/memories?user_id=other | 403 |
| Несуществующее событие | GET /v1/events/{uuid} | 404 |
| Очередь недоступна | POST /v1/memories при остановленном RabbitMQ | 503 queue_unavailable |
Ключевые параметры конфигурации
| Параметр | Назначение |
|---|---|
MEMORY_CONFIG | Путь к YAML (в контейнере /app/config/config.yaml) |
api.host / api.port | Слушатель API (0.0.0.0:8091) |
app.environment | Метка среды (dev / prod) |
app.create_schema_on_startup | Создание схемы PostgreSQL при старте API |
worker.concurrency | Параллелизм обработки событий в процессе worker (4) |
postgres.dsn | postgresql+asyncpg://… |
postgres.schema_name | По умолчанию platform_memory |
postgres.pool_size | Пул соединений (5) |
rabbitmq.host / port / username / password | Брокер |
rabbitmq.exchange / queue / dlx / dlq | memory.add / memory.add.jobs / memory.add.dlx / memory.add.dlq |
rabbitmq.prefetch / delivery_limit / heartbeat | 16 / 5 / 60 |
opensearch.hosts / index_alias | Кластер и алиас (mem-facts-dev, mem-facts-prod) |
opensearch.embedding_dimension | Размерность kNN (1024) |
embedding.model / dimension | Модель эмбеддинга у AI Gateway |
ai_gateway.url / api_key / llm_model | Шлюз моделей |
ai_gateway.timeout / batch_size / dry_run | 120 / 32 / false |
log.level | Подробность журналов |
replicaCount | Реплики API в чарте |
Guardrails
Назначение и область применения
Guardrails — система проверки текста (запросов и ответов модели) на запрещённое содержимое. Она отклоняет запрос или ответ либо маскирует чувствительные данные (например, email) до того, как текст попадёт в модель или вернётся клиенту.
Функционал разделён на два слоя с чёткой границей ответственности:
- Control Plane — хранение версий политик, проверка структуры, компиляция в «generation», доставка в Kubernetes и привязка политики к модели.
- Guardrails Runtime — отдельный процесс. Загружает неизменяемый набор правил при старте, выполняет
/requestи/responseи выдаёт вердиктpass/deny/mask.
Ключевой принцип: Control Plane не вызывается на каждый запрос. Он один раз доставляет неизменяемый набор правил в отдельный процесс Runtime, который уже на лету проверяет текст. Недоступность управления не останавливает уже работающие проверки.
Два способа применения
- Через шлюз (Agentgateway). Политика привязывается к модели в Control Plane. Шлюз сам вызывает Runtime (
promptGuardкак webhook сfailureMode: FailClosed). Защищает текстовые вызовы/v1/chat/completions. - Прямой HTTP-вызов из сервиса. Адаптер RAG/Memory сам вызывает Runtime перед индексацией, записью или выдачей. Этот путь можно проверить локально без Kubernetes; для общей среды нужно отдельно согласовать адрес, доступ и версии.
Автоматических привязок вида «политика → коллекция RAG / память агента» в Control Plane нет. Для первого подключения команда платформы и команда сервиса фиксируют параметры среды и явное соответствие операций политикам.
Виды правил
| Тип | Назначение | Механика |
|---|---|---|
regex | Регулярные выражения | Движок RE2, линейное время, без ReDoS; замена на replacement. Обратные ссылки и lookbehind не поддерживаются |
stop_list | Стоп-список терминов | До 512 терминов; совпадение substring либо token; чувствительность к регистру задаётся явно |
external_pipeline | Внешний детектор | HTTPS-вызов проверенного провайдера, протокол detector/v1, вердикт allow/deny, без маскирования |
llm_classifier | Проверка моделью | Классификатор по версионируемой инструкции, вердикт allow/deny/uncertain. uncertain ведёт к блокировке |
Параметры правила: mode (enforce/observe), onMatch (deny/redact), timeoutMs (1–5000 мс). Базовые правила (baseline) всегда enforce; дополнительные (additional) допускают enforce или observe. Наблюдаемое правило не блокирует и не меняет текст — его срабатывание фиксируется в метриках.
Структура политики
Политика состоит из двух стадий — request (проверка входа) и response (проверка выхода). Каждая стадия включает:
deadlineMs— общий бюджет стадии (максимум 5000 мс);baseline— обязательные правила (всегдаenforce), до 64;additional— дополнительные правила, до 64.
Модель сущностей: Policy → Stage → Rule[] плюс список providers (до 32). Идентификаторы и ревизии правил/провайдеров — строки вида [a-zA-Z0-9][a-zA-Z0-9._-]* (до 128 символов).
Логика проверки в Runtime
Движок последовательно прогоняет текст через правила выбранной стадии, соблюдая общий бюджет времени стадии. Для каждого правила:
- правило сработало в режиме
enforceс действиемdeny— проверка останавливается, возвращаетсяdeny; - правило в режиме
enforceс действиемredact— замена накапливается, в конце текст возвращается уже замаскированным (mask); - правило в режиме
observe— срабатывание только фиксируется, решение не меняется.
Если после всех правил замены не накоплены, результат pass.
Надёжность (FailClosed). Таймаут правила или стадии, недоступность внешнего провайдера и неопределённый ответ классификатора трактуются как запрет, а не как пропуск. Ответ формируется только после успешного завершения всей проверки; маска применяется атомарно (пересечение замен или выход за границы — техническая ошибка).
Входные проверки. Прежде чем текст попадёт в движок, Runtime проверяет: один сервисный токен в заголовке Authorization: Bearer; четыре обязательных заголовка контекста; тип application/json без сжатия; конкурентность и размер тела.
Важно про маскирование. Все правила одной проверки видят исходный текст, а не результат предыдущего маскирования. Поэтому маска email первым правилом не скрывает email от следующего LLM-классификатора. Если классификатор не должен получать исходные данные, нужны две отдельные проверки: сначала локальное маскирование, затем вызов классификатора с уже обработанным текстом. Это решение адаптера, а не режим внутри одной политики.
API проверки текста (Guardrails Runtime)
| Метод и путь | Назначение | Аутентификация |
|---|---|---|
POST /request | Выполнить секцию request выбранной политики | Сервисный токен и четыре заголовка контекста |
POST /response | Выполнить секцию response выбранной политики | Те же заголовки |
GET /readyz | Проверить загрузку набора политик | Не требуется |
GET /metrics | Метрики Prometheus текущего процесса | Сервисный токен |
Универсальных маршрутов /v1/check, /evaluate, /batch нет. Guardrails принимает только нормализованные текстовые сообщения; PDF, URL документов, изображения и потоки SSE не поддерживаются. Извлечение текста и обратное сопоставление полей выполняет вызывающий сервис.
Политика не указывается в теле запроса — она задаётся заголовками:
| Заголовок | Значение |
|---|---|
Authorization | Bearer <service-token>; отдельный секрет Guardrails, не пользовательский JWT и не ключ LLM |
x-ap-gr-policy-id | Точный идентификатор политики в загруженном наборе |
x-ap-gr-policy-revision | Точная строковая ревизия, например 1 |
x-ap-gr-bundle-digest | 64 шестнадцатеричных символа SHA-256 канонического набора (RFC 8785), без префикса sha256: |
x-ap-gr-content-profile | Точное значение contentProfile загруженного набора, например agentgateway-1.5.0-text-webhook-v1 |
Каждый заголовок должен встречаться ровно один раз; дублирование и пустые значения отклоняются (403 untrusted_context).
Три результата проверки — все возвращаются с HTTP 200:
| Результат | Поле action | Действие вызывающего |
|---|---|---|
| Разрешить | {"reason": "policy_pass"} | Продолжить операцию с исходными полями |
| Заблокировать | {"status_code": 403, "reason": "policy_denied", ...} | Остановить защищаемое действие; повтор того же содержимого недопустим |
| Маскировать | {"body": <заменённый текст>, "reason": "content_redacted"} | Подставить возвращённые строки вместо исходных; сохранять исходник после mask запрещено |
Проверять только HTTP-статус недостаточно. Техническая ошибка (401, 403, 413, 415, 422, 503, таймаут) трактуется как запрет: защищаемое действие не выполняется до успешной проверки.
Управление политиками (API Control Plane)
Control Plane хранит определения политик и историю их изменений. Сохранение политики создаёт новую версию, но само по себе не включает проверку запросов. Применение к модели — отдельная операция.
Все методы, включая чтение, требуют действующей аутентификации Control Plane и разрешения control_plane:control-plane#administer. Используется токен платформы; сервисный токен проверки текста здесь не подходит.
| Метод и путь | Результат |
|---|---|
GET /api/v1/guardrail-policies | Список политик; limit 1–50, пагинация по cursor |
POST /api/v1/guardrail-policies | Создать политику и первую версию |
GET /api/v1/guardrail-policies/{policyId} | Последняя версия с определением и заголовком ETag |
PUT /api/v1/guardrail-policies/{policyId} | Сохранить новую полную версию, в том числе сменить статус |
GET /api/v1/guardrail-policies/{policyId}/revisions | История ревизий |
GET /api/v1/guardrail-policies/{policyId}/revisions/{revision} | Конкретная неизменяемая версия |
GET /api/v1/guardrail-providers | Одобренные конфигурации внешних проверок в среде |
GET /api/v1/models/{modelId}/guardrail-binding | Выбранная для модели политика, состояние применения и ETag |
PUT /api/v1/models/{modelId}/guardrail-binding | Применить версию политики или снять привязку |
Для POST и PUT обязателен Idempotency-Key (16–128 символов). Для PUT также обязателен If-Match из последнего чтения изменяемого ресурса. Обновление выполняется полным телом, а не частичным PATCH. Команды возвращают 202; до завершения операции (GET /api/v1/operations/{operationId}) ресурс перечитывают.
Архивирование создаёт новую версию и сохраняет историю, но не снимает ранее применённую защиту. Метода безвозвратного удаления политики нет.
Применение политики к модели
- Прочитать
GET /api/v1/models/{modelId}/guardrail-bindingи сохранитьETag. - Выполнить
PUTтого же адреса с этимIf-Matchи новымIdempotency-Key. - Передать точную пару идентификатора и ревизии вместе с
contentProfile. - Дождаться завершения операции и перечитать привязку. Состояние
appliedпоявляется только после подтверждения конфигурации на экземплярах Gateway.
state | Значение |
|---|---|
pending | Применение ещё не подтверждено |
applied | Конфигурация подтверждена для работающей модели |
failed | Ошибка применения или неподдержанная версия профиля |
disabled | Модель или её провайдер выключены |
unbound | У работающей модели нет привязки Guardrails |
Для отката применяют ранее сохранённую ревизию тем же методом. Для снятия защиты передают policyId: null и policyRevision: null, сохранив contentProfile. Редактирование политики после применения не меняет уже работающую версию — привязка действует на модель целиком.
Настройки процесса Runtime
| Переменная окружения | Назначение |
|---|---|
AP_GUARDRAIL_RUNTIME_BUNDLE_FILE | Путь к файлу набора политик |
AP_GUARDRAIL_RUNTIME_BUNDLE_DIGEST | Ожидаемая контрольная сумма набора |
AP_GUARDRAIL_RUNTIME_TOKEN_FILE | Путь к файлу входящего сервисного токена |
AP_GUARDRAIL_RUNTIME_PROVIDER_ORIGINS | JSON-массив разрешённых HTTPS-источников; по умолчанию [] |
AP_GUARDRAIL_RUNTIME_CREDENTIAL_FILES | JSON-объект «ссылка на учётные данные → путь к файлу»; по умолчанию {} |
AP_GUARDRAIL_RUNTIME_CLASSIFIER_TARGETS | JSON-массив точных сочетаний url, model, modelRevision; по умолчанию [] |
Токен содержит от 32 до 4096 печатных ASCII-символов без пробелов. Секреты не хранятся внутри политики, примера запроса или Git; правило содержит только credentialRef. Ограничения сети и TLS обеспечивает среда: сам HTTP-процесс запускается на заданном адресе/порту и не настраивает сертификаты. Разрешены только нужные источники вызовов и назначения провайдеров.
HTTP-клиент Guardrails проверяет TLS, не следует редиректам и не использует прокси из переменных окружения. Вызов собственной защищённой модели через Gateway создаст рекурсию: проверка снова вызовет саму себя. Текст уходит внешнему провайдеру только для правил, которые его вызывают; локальные стоп-листы и регулярные выражения внешнюю модель не используют.
Обновление набора политик
Набор политик имеет schemaVersion: agent-platform.guardrail-runtime.bundle/v1 и содержит обе стадии, список провайдеров и общие ограничения. Guardrails читает и проверяет его при старте. Изменение файла на диске не приводит к перечитыванию; управляющего метода перезагрузки нет.
Для обновления нужны новый проверенный набор, его контрольная сумма и новый процесс (поколение). Клиент переключает связку «адрес, политика, ревизия, контрольная сумма, профиль» как единое целое. Пока один Service распределяет запросы между старыми и новыми наборами, часть вызовов с новой контрольной суммой получит 503. Старое поколение сохраняют, пока завершаются его запросы и пока нужен откат. В управляемой доставке через Control Plane есть предел 32 поколения и нет автоматического удаления по возрасту.
Ограничения нагрузки
| Ограничение | Диапазон контракта |
|---|---|
JSON тела запроса и ответа (maxBodyBytes) | 256–131072 байт |
Сообщения / варианты ответа (maxMessages) | 1–64 |
Совпадения детектора (maxMatches) | 1–1024 |
Одновременные проверки процесса (maxConcurrency) | 1–256 |
Очередь внутри Guardrails (queueSize) | 0 — без очереди |
Общий бюджет стадии (deadlineMs) | 1–5000 мс |
Таймаут правила (timeoutMs) | 1–5000 мс, не больше бюджета стадии |
| Файл набора политик | До 700 КиБ до и после канонизации |
У Guardrails нет внутренней очереди: при заполнении лимита одновременных проверок возвращается 503 overloaded. Число параллельных вызовов ограничивают со стороны обработчиков RAG/Memory; суммарная нагрузка всех процессов и повторов важнее ограничения одного обработчика.
Наблюдение и диагностика
GET /readyz возвращает {"ready":true}, если набор загружен. Это не проверка качества правил, доступности внешней модели или применения конфигурации Gateway. После запуска выполняют синтетические проверки разрешения, маскирования и запрета.
GET /metrics требует сервисного токена и содержит ограниченные счётчики проверок, ошибок, наблюдаемых срабатываний и длительности. Метки не содержат текст, ключи, адреса провайдеров или имена политик. Это показатели процесса, сбрасываемые при перезапуске; хранилища результатов или журнальных записей каждого решения Guardrails не предоставляет.
| Симптом | Что проверить первым |
|---|---|
401 | Адрес, файл токена, точность Bearer, отсутствие дублированного заголовка |
403 untrusted_context | Все четыре заголовка контекста, пустые значения и дублирование |
503 policy_unavailable | Точную ревизию, контрольную сумму, профиль и попадание в нужное поколение |
503 overloaded | Конкурентность всех клиентов и массовые повторы |
| Таймауты | Бюджет стадии, время передачи документа, задержку провайдера |
| Маска в ответе, но исходник в БД | Обратное сопоставление полей и все места записи в адаптере |
| Политика сохранена, результат не изменился | Применённую ревизию (модель) или доставленный набор (прямой клиент) |
Не включают запись тел запросов в прокси и журналы ради диагностики. Используют код ошибки, идентификатор задания, ревизию политики и длительность.
Развёртывание
Важно: Развёртывание Guardrails реализовано только для локального контура разработки (Kind). Активация в среде ST и в промышленном контуре — отдельное решение. В текущем развёртывании ST Guardrails не поставляется: его включение, адрес и учётные данные согласуются отдельно.
Guardrails поставляется не отдельным Helm-чартом, а связкой действий Garden:
- Сборка образа — нативный образ
guardrail-runtimeсобирается изsrc/guardrail-runtime/Dockerfileи публикуется в реестр по неизменяющему digest. - Доставка конфигурации — сценарий доставки управляет неизменяемой TLS-идентичностью транспорта (Secret + неизменяемый ConfigMap CA) с именем сервера
guardrails.agent-platform.internal, проверяет срок действия сертификата и доставляет одобренный каталог классификаторов в Control Plane. - Патч шлюза — контроллер Agentgateway (Helm-релиз
agentgatewayвagentgateway-system) патчится проверенным по SHA-256 источником, чтобы inline-webhookpromptGuardмодели получал политики TLS, аутентификации и таймаутов.
Профиль текущего контура — v1.5.0-ap-gr1. Роллаут выполняется garden run agentgateway-controller --env dev-local (атомарный Helm-upgrade; CRD, Secret и PVC не удаляются).
Для прямого вызова из RAG/Memory (без Kubernetes) достаточно запустить процесс guardrail-runtime serve с согласованными переменными окружения (см. «Настройки процесса Runtime») и файлом набора политик.
Ввод в работу
- Обе команды согласуют точки записи/чтения и поля, которые нужно проверять.
- Владелец политики готовит правила и синтетический корпус; платформа — конфигурацию и доступ.
- Команда сервиса проверяет локальные примеры и обработку всех трёх решений (разрешить, заблокировать, маскировать).
- На общей тестовой среде выполняются сквозные сценарии, включая недоступность Guardrails и повтор задания.
- Проверяются новое поколение, переключение и откат, затем согласуется включение для реальных данных.
Готовность интеграции в сервисе подтверждается только испытанием его реальной записи и выдачи вместе с хранилищами, очередями и проверками доступа.