Перейти к содержанию

Миграция на 26.1.0 — catalog-owned-model + LLM-prediction option

Этот документ ранее назывался migration_1_8.md и описывал переход с helm chart 1.7.x (релиз 25.4.x) на 1.8.x (25.5.x). С релиза 26.1.0 мы используем сквозную нумерацию — функционально это тот же набор изменений, под унифицированным тегом.

В версии 26.1.0 (исторически — helm chart 1.8.0/1.8.1, релизы 25.5.0/25.5.1) изменена архитектура каталога LLM-провайдеров: каждая запись каталога теперь представляет один валидированный набор (endpoint, ключ, модель). Также администратор может назначить LLM-провайдер для роли Prediction (раньше — только встроенный RL Classifier; после chart 1.7.0 / релиза 25.4.0 — только LLM).

Что изменилось

Архитектура

  • Каталог LLM-провайдеров теперь владеет моделью. Колонка model перенесена с role_provider_assignments на llm_providers (Liquibase 1.8.0/001_provider_owns_model). Каждая строка каталога — один валидированный набор endpoint + API-ключ + модель.
  • Multi-role конфиги авто-разделяются при миграции: если один провайдер использовался и для prediction, и для explanation с разными моделями — Liquibase автоматически клонирует строку каталога и переназначает роли.
  • Test history теперь поддерживает role='catalog' для catalog-level test (Liquibase 1.8.0/002_test_history_catalog_role).
  • Cache invalidation между backend и llm-service: при edit провайдера в UI backend публикует webhook на /admin/cache-invalidate в llm-service, и тот сбрасывает кэш конфига (избегает stale config в течение TTL).

REST API

  • Новые admin-only endpoints для CRUD каталога:
    • GET /api/settings/llm-providers — список
    • POST /api/settings/llm-providers — create с type-aware validation
    • PUT /api/settings/llm-providers/{id} — edit
    • DELETE /api/settings/llm-providers/{id} — delete с защитами
  • Защиты delete:
    • 409 Conflict — если провайдер ассоциирован с ролью (нужно сначала переназначить)
    • 403 Forbidden — для vendor-managed (резервировано)
  • Защиты create/update:
    • 400 Bad Request на protocol=auto для LLM — требуется явный ollama или openai_compatible.
  • Новый probe endpoint: POST /api/settings/providers/test-connection?role=&providerId=
  • Discovery + test credentials: POST /api/settings/providers/llm-providers/{discover-models,test-credentials}

Для администратора

  • В Settings → LLM-провайдеры теперь у каждой строки своя модель (не общая для всех ролей).
  • При редактировании провайдера UI требует пройти "Test connection" перед Save (ensures ключ + endpoint валидны).
  • Per-role health monitor: prediction и explanation имеют независимые state-слоты (warmup одной роли не сбрасывает другую).

Для пользователя

  • Возможность выбрать LLM-провайдер для роли Prediction (через UI Settings → role-card prediction).
  • Качество триажа TP/FP теперь зависит от выбранной LLM-модели (mistral / DeepSeek / GPT-4o и т.п.). Замеры на AILAB-20 holdout (DeepSeek, deepseek-v4-pro): accuracy 86.5%, precision 83.3%, recall 55.6%, F1 66.7%, FP filter 96.4%.

Для feedback loop

  • Approve/reject в Feedback queue → AMQP FeedbackEvent (внутренняя backend очередь appsecsolutions.copilot.feedback) + HTTP forward через FeedbackProxyController в llm-service.
  • На approve строка копируется в few_shot_examples с source='user-feedback' и используется в next predict prompt того же CWE/lang.
  • CWE prefix normalization: входящие CWE в форматах CWE-89, 89, cwe-89 нормализуются в canonical CWE-89.

Шаги миграции с v1.7.0 на v1.8.0

1. Backup

# Дамп БД
sudo docker exec copilot-postgres pg_dumpall -U postgres > /opt/copilot-backups/pre-1.8.0-$(date +%Y%m%d-%H%M%S).sql

# Также сохраним текущий compose-файл и .env (потребуется для отката на v1.7.0)
sudo cp /opt/copilot/docker-compose.yml /opt/copilot-backups/docker-compose-pre-1.8.0-$(date +%Y%m%d-%H%M%S).yml
sudo cp /opt/copilot/.env              /opt/copilot-backups/.env-pre-1.8.0-$(date +%Y%m%d-%H%M%S)

2. Подготовка .env

В /opt/copilot/.env добавить:

# v1.8.0 — обязательный секрет для cache-invalidate webhook между backend и llm-service.
# Сгенерировать random 32+ символов.
APPSECSOLUTIONS_COPILOT_INTERNAL_SECRET=<random-32-chars>

# v1.8.0 — TTL кэша провайдер-конфига в llm-service (по умолчанию 300с).
PROVIDER_CONFIG_TTL_SECONDS=300

# v1.8.0 — toggle feedback loop (по умолчанию true).
FEEDBACK_ENABLED=true

Сгенерировать секрет:

openssl rand -base64 32 | tr -d '\n='

3. Pull новых образов

cd /opt/copilot
sudo docker compose pull

4. Восстановить compose-файл (если нужно)

docker-compose.yml остался без изменений relative to v1.7.0 — те же сервисы. Но backend теперь требует новые env vars (см. §2).

5. Запуск + автомиграция

sudo docker compose up -d

Liquibase автоматически применит:

  • 1.8.0/001_provider_owns_model.sql — переносит model на каталог, авто-сплит multi-role
  • 1.8.0/002_test_history_catalog_role.sql — добавляет role='catalog' в provider_test_history

6. Проверка

После старта:

# Все 6 контейнеров healthy
sudo docker compose ps

# Liquibase changelog содержит миграции 1.8.0/001 и 002
sudo docker exec copilot-postgres psql -U postgres -d copilot -c \
  "SELECT id FROM databasechangelog WHERE filename LIKE '%1.8%';"

# Каталог провайдеров содержит model column
sudo docker exec copilot-postgres psql -U postgres -d copilot -c \
  "SELECT id, name, type, protocol, model FROM checks.llm_providers;"

В UI Settings → LLM-провайдеры — у каждой строки видно поле «Модель». В Settings → role-card prediction теперь можно назначать LLM-провайдера (раньше — только RL).

7. Откат (на крайний случай)

# Restore из backup
sudo docker compose down
sudo docker exec -i copilot-postgres psql -U postgres < /opt/copilot-backups/pre-1.8.0-*.sql
# Откатить .env (убрать новые переменные) и запустить v1.7.0 образы

Известные ограничения

  • На стенде разработки наблюдалась нестабильность Ollama (ошибка unable to create sampling context) — это GPU/model-load issue, не код. Если у клиента похожая ошибка на Ollama — проверить GPU-доступ и memory limit.
  • Cache invalidation webhook требует, чтобы backend мог достучаться до llm-service по HTTP. В docker-compose это автоматически (overlay network), в k8s/helm — через Service DNS llm-service:8000 (см. helm chart values backend.llmServiceUrl).

Поддержка

По вопросам и проблемам обращайтесь в техническую поддержку SwordFish Security через ваш контактный канал support (email или helpdesk-портал, выданные при поставке).