Начало работы

Как расширять возможности Meridian собственными плагинами, которые перехватывают и изменяют запросы и ответы.

Стандартные образы и сборки Meridian собраны статически и не загружают динамические плагины (.so): это упрощает установку. Для in-process плагинов нужна сборка Meridian с динамической линковкой; готовые образы такой сборки публикуются с суффиксом -dyn. HTTP-плагины работают с любой сборкой.

Что такое плагины Meridian

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

Meridian поддерживает два вида плагинов:

  • In-process плагины — разделяемые библиотеки Go (.so), которые загружаются в процесс шлюза и вызываются напрямую, без накладных расходов на межпроцессное взаимодействие.
  • HTTP-плагины — отдельные процессы на любом языке, реализующие Meridian Plugin API. Шлюз подключается к ним по сети; в кластере к одному плагину подключается каждый узел.

Оба вида плагинов управляются на одной странице Settings → Plugins и получают одни и те же хуки.

Страница Plugins: in-process и HTTP-плагины в одной таблице

Сценарии использования

Собственные плагины позволяют:

  • Преобразовывать запросы и ответы — изменять данные до отправки провайдеру и после получения ответа.
  • Добавлять собственные проверки — применять бизнес-правила к входящим запросам, например блокировать или маскировать конфиденциальные данные.
  • Маршрутизировать по содержимому — выбирать провайдера, модель и fallback'и по содержанию запроса.
  • Реализовывать собственное кэширование — кэшировать ответы по своей логике.
  • Интегрироваться с внешними системами — передавать данные в системы журналирования, мониторинга и аналитики.
  • Обрабатывать ответы моделей — разбирать, фильтровать и обогащать ответы LLM, в том числе потоковые.

Архитектура плагинов

Архитектура динамических плагинов: исходный код собирается в plugin.so и загружается загрузчиком плагинов

Meridian использует встроенный механизм плагинов Go. Плагин собирается в разделяемую библиотеку (.so), которую шлюз загружает во время работы.

Как работают Go-плагины

Плагины Go используют пакет plugin стандартной библиотеки, который позволяет программе на Go загружать код во время выполнения. Преимущества этого подхода:

  • Нативная интеграция — плагин пишется на Go и имеет полный доступ к типам и интерфейсам Meridian.
  • Динамическая загрузка — плагин можно загрузить, отключить и перезагрузить без перезапуска шлюза.
  • Типобезопасность — система типов Go гарантирует, что сигнатуры методов плагина соответствуют ожидаемым.
  • Производительность — плагин выполняется в процессе шлюза, без межпроцессного взаимодействия.

Сборка разделяемой библиотеки

Плагин компилируется с флагом -buildmode=plugin:

go build -buildmode=plugin -o myplugin.so .

Полученный файл .so экспортирует функции интерфейса плагина Meridian. Обязательны только GetName и Cleanup, остальные хуки реализуются по необходимости:

  • Init(config any) error — инициализация плагина конфигурацией из его записи.
  • GetName() string — имя плагина.
  • HTTPTransportPreHook() — перехват HTTP-запроса до входа в ядро Meridian (только HTTP-транспорт).
  • HTTPTransportPostHook() — перехват HTTP-ответа после выхода из ядра (только HTTP-транспорт).
  • HTTPTransportStreamChunkHook() — обработка каждого фрагмента потокового ответа (только HTTP-транспорт).
  • PreRequestHook() — фаза маршрутизации, один раз на запрос: выбор провайдера, модели и fallback'ов.
  • PreLLMHook() — перехват запроса перед обращением к провайдеру (выполняется для каждой попытки).
  • PostLLMHook() — обработка ответа провайдера (выполняется для каждой попытки).
  • PreMCPHook() / PostMCPHook() — перехват вызовов инструментов MCP до и после выполнения.
  • PreMCPConnectionHook() / PostMCPConnectionHook() — перехват подключения к MCP-серверу.
  • Cleanup() error — освобождение ресурсов при остановке.

Хуки PreLLMHook, PreMCPHook и PreMCPConnectionHook могут завершить обработку досрочно (short-circuit), вернув готовый ответ или ошибку; PreRequestHook этой возможности не имеет, а его ошибка не блокирует запрос.

Требования к платформе

Механизм плагинов Go накладывает строгие ограничения. Плагин загружается только в тот экземпляр Meridian, с которым он совместим на уровне бинарного кода:

  • Платформы — только Linux и macOS.
  • Без кросс-компиляции — плагин собирается на целевой платформе.
  • Одинаковая архитектура — плагин и Meridian должны быть собраны под одну архитектуру (amd64, arm64).
  • Одинаковая версия Go — плагин должен быть собран той же версией Go, что и Meridian.
  • Одинаковые версии зависимостей и флаги сборки — каждый пакет, общий для плагина и шлюза (в том числе схемы Meridian и их транзитивные зависимости), должен быть собран из той же версии модуля с теми же флагами компиляции. При расхождении загрузка завершается ошибкой plugin was built with a different version of package.

Например, если Meridian работает на Linux AMD64, плагин собирается на Linux AMD64 той же версией Go и с тем же набором зависимостей. Для образов -dyn предусмотрена сборка плагина в среде сборки самого образа, что гарантирует совпадение.

Плагин, собранный на рабочей станции разработчика, не загрузится в контейнерный образ Meridian, а плагин из образа — в локальную сборку: различаются библиотека C, сборка инструментария и граф зависимостей.

Жизненный цикл плагина

  1. Загрузка — Meridian открывает файл .so через plugin.Open().
  2. Инициализация — вызывается Init() с конфигурацией из записи плагина.
  3. Выполнение хуков — для каждого запроса вызываются реализованные плагином хуки.
  4. Очистка — при остановке Meridian вызывается Cleanup().

Хуки выполняются в фиксированном порядке:

  1. HTTPTransportPreHook — перехват HTTP-запроса (только HTTP-транспорт).
  2. PreRequestHook — один раз на запрос, до первого обращения к провайдеру. Здесь принимаются решения о маршрутизации (провайдер, модель, fallback'и), которые действуют для всех последующих попыток.
  3. PreLLMHook / PreMCPHook — для каждой попытки обращения к провайдеру, в порядке регистрации; могут завершить запрос досрочно.
  4. Обращение к провайдеру (если запрос не был завершён досрочно).
  5. PostLLMHook / PostMCPHook — для каждой попытки, в порядке, обратном PreLLMHook.
  6. HTTPTransportPostHook — перехват HTTP-ответа (только HTTP-транспорт, обратный порядок).

Место плагина относительно встроенных плагинов Meridian (журналирование, governance, кэширование) задаётся параметром placement: pre_builtin — до встроенных плагинов, post_builtin — после них; порядок внутри группы определяет order.

HTTP-плагины

HTTP-плагин — это отдельный процесс, который реализует те же хуки через Meridian Plugin API. Шлюз устанавливает с ним постоянное соединение и передаёт вызовы хуков по сети. Этот вариант стоит выбрать, когда:

  • плагин удобнее написать не на Go, либо не хочется соблюдать требования бинарной совместимости;
  • сбой плагина не должен затрагивать процесс шлюза;
  • Meridian работает в кластере — один экземпляр плагина обслуживает все узлы, а состояние его доступности ведётся на каждом узле отдельно;
  • плагин нужно вызывать только для части запросов — условие вызова задаётся CEL-выражением по атрибутам запроса (путь, тип запроса, провайдер, модель, виртуальный ключ, команда, клиент и другие).

Для каждого HTTP-плагина задаётся поведение при недоступности: fail_closed отклоняет запрос с кодом 503, fail_open пропускает запрос дальше без вызова плагина. Ограничения по платформе и версии Go на HTTP-плагины не распространяются.

Что дальше

Готовы создать первый плагин? Выберите подход:

Содержание