Инженерия

Прозрачный прокси для управления языковыми моделями: архитектура, совместимость и режимы отказа

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

Автор Krasper Engineering 01 Май 2026 8 мин чтения
Drop-in Proxy Pattern — hero

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

Содержание

  1. Почему прямая интеграция ломается на первом аудите
  2. Шаблон прозрачного прокси управления
  3. Совместимость API — проектное ограничение
  4. Потоковая передача и окно применения политик
  5. Где на самом деле работает политика
  6. Аудиторский след, который теперь спрашивает каждый регулятор
  7. Уроки продуктива и компромиссы
  8. Когда этот подход вам не подходит

1. Почему прямая интеграция ломается на первом аудите

Большинство компаний внедряло доступ к языковым моделям так же, как любой новый SaaS API: команда берёт ключ, встраивает SDK провайдера прямо в приложение и выкатывает. Это работает ровно до первого аудита, первого инцидента с персональными данными или первого ревью безопасности системы, связанной с ИИ. Потом кто-то из комплаенса задаёт четыре вопроса, и в инженерной команде ни на один нет ответа:

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

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

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

2. Шаблон прозрачного прокси управления

Архитектуру легко нарисовать и неожиданно тонко построить:

Сторона клиента
Приложение
Использует SDK вендора как есть. Меняется только базовый URL.
Слой управления
Прокси управления Krasper
  • Передача аутентификации
  • Политика до потока
  • Проверка фрагментов в потоке
  • Запись в аудит
Вышестоящая система
Провайдер языковой модели
Любая совместимая точка инференса.
Слой соответствия
Аудит и приёмник SIEM
Только на добавление, с цепочкой хешей, с выявлением подмены.

Приложение продолжает использовать свой SDK. Импорты не меняются. Клиентская библиотека не заменяется. Меняется единственная настройка — базовый URL: вместо публичной точки вендора он указывает на прокси. Прокси говорит на том же протоколе, которого ждёт SDK, применяет политику по пути и пропускает или блокирует запрос.

Концептуально это похоже на корпоративный веб-прокси или API-шлюз. Две вещи делают управление языковыми моделями сложнее обычной фильтрации HTTP. Промпт несёт намерение, а не только полезную нагрузку, поэтому прокси приходится рассуждать о семантике запроса. И ответы приходят потоком в течение многих секунд, что ломает аккуратную модель «запрос — ответ», на которую рассчитано большинство движков политик.

3. Совместимость API — проектное ограничение

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

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

На практике это значит, что достаточно смены базового URL:

До: прямая интеграция

bash
# Application talks directly to the upstream provider
export LLM_API_BASE="https://api.upstream-provider.example.com"
export LLM_API_KEY="sk-***"

curl "$LLM_API_BASE/v1/messages" \
  -H "Authorization: Bearer $LLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-3-class-large",
    "messages": [{"role": "user", "content": "Summarize Q3 results."}]
  }'
Прямая интеграция с вышестоящим провайдером

После: через прокси управления

bash
# Same request, only the base URL changed
export LLM_API_BASE="https://governance.internal.example.org"
export LLM_API_KEY="sk-***"   # unchanged

curl "$LLM_API_BASE/v1/messages" \
  -H "Authorization: Bearer $LLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic-3-class-large",
    "messages": [{"role": "user", "content": "Summarize Q3 results."}]
  }'
Тот же запрос: изменился только базовый URL

Код приложения не меняется. SDK не должен знать о существовании прокси. Формат запроса провайдера сохраняется сквозным образом. Меняется то, что происходит между двумя запросами в сети.

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

4. Потоковая передача и окно применения политик

Большинство современных эндпоинтов языковых моделей поддерживают потоковую передачу через Server-Sent Events (SSE). Клиент открывает HTTP-соединение, сервер держит его открытым, и токены приходят именованными событиями в течение многих секунд. Именно это делает приложения отзывчивыми и одновременно делает наивное применение политик невозможным.

Традиционная модель API-шлюза предполагает: принять запрос целиком, решить, передать, принять ответ целиком, решить, вернуть. Поток ломает обе половины. Тело запроса можно принять целиком в начале (политика по промпту тривиальна), но ответ приходит токен за токеном по соединению, которое может жить 30 секунд и дольше. К моменту, когда вы увидели весь ответ, пользователь уже увидел его бóльшую часть.

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

На уровне протокола это выглядит так:

CLIENT GOVERNANCE PROXY LLM PROVIDER POST /messages pre-stream policy · PII scan · intent match · policy decide (allow) POST /messages event: message_start message_start event: content_delta in-stream chunk policy · redact PII · rewrite / pass content_delta … stream repeats per content_delta … event: message_stop post-stream audit · record full event · extend hash chain message_stop

Два проектных замечания. Проверка фрагментов в потоке ограничена задержкой: работа на каждый фрагмент должна укладываться в миллисекунды, иначе она разрушает тот самый потоковый опыт, ради защиты которого архитектура и существует. И прокси не просто проверяет поток — он его формирует для клиента. Поэтому он может вставлять собственные события (например, синтетическое событие policy перед первым content_delta), чтобы сообщать решения клиентам, умеющим их читать.

5. Где на самом деле работает политика

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

  • До потока. Пока ничего не передано, у прокси есть полный промпт, системное сообщение, параметры модели и личность вызывающего, поэтому он может заблокировать, потребовать согласования или пропустить с маскированием. Бюджет задержки здесь щедрый: пользователь всё равно ждёт ответа.
  • В потоке. Здесь прокси видит по одному фрагменту на фоне накапливающегося контекста и может маскировать, переписывать или прерывать поток. Бюджет жёсткий: работа на фрагмент не должна тормозить доставку.
  • После потока. С полным ответом и полным контекстом аудита прокси может писать аудиторские записи, ретроспективно заводить инциденты или запускать оценки. Эта работа асинхронна и не влияет на видимую пользователю задержку.

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

Разделение, которое выдерживает продуктив, формулируется просто: блокировать до потока, изменять содержимое в потоке, оставлять аудит и ретроспективный анализ на после потока. Движок политик один и тот же на всех трёх стадиях; меняется то, что ему разрешено делать.

6. Аудиторский след, который теперь спрашивает каждый регулятор

Как только прокси на месте, аудиторский след получается почти бесплатно — но только если спроектировать его правильно с самого начала. Свойства, которые важны регуляторам (и вам самим, когда через восемь месяцев вы восстанавливаете картину инцидента):

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

Набросок схемы:

json
{
  "event_id": "01HF7K3M5N8Q2R9V0W3X4Y5Z6A",
  "ts": "2026-05-06T12:14:08.331Z",
  "tenant": "tenant-a",
  "actor": {
    "principal": "service-account/data-platform",
    "ip_redacted": "10.x.x.x"
  },
  "request": {
    "endpoint": "/v1/messages",
    "model": "anthropic-3-class-large",
    "input_hash": "sha256:e3b0c4...",
    "input_redacted_preview": "Summarize [PII_REDACTED] results."
  },
  "policy": {
    "bundle_version": "v2026.05.04-r3",
    "decision": "allow_with_redaction",
    "matched_rules": ["pii.financial.summary"]
  },
  "response": {
    "output_hash": "sha256:7d865e...",
    "redactions_applied": 2,
    "duration_ms": 3417
  },
  "previous_event_hash": "sha256:6f9b1a...",
  "event_hash": "sha256:a4c8d2..."
}
Схема аудиторского события: только на добавление, с цепочкой хешей

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

7. Уроки продуктива и компромиссы

Несколько вещей, которые узнаёшь, только поэксплуатировав такой прокси какое-то время.

Задержка не бесплатна

Каждая стадия применения политик добавляет миллисекунды. Для фазы до потока пользовательский опыт это поглощает: обращение к размещённой модели и так измеряется секундами. Для проверки фрагментов в потоке каждая миллисекунда обработки на фрагмент превращается в ощущение более медленного ответа. Профилируйте и жёстко нормируйте бюджет. Соблазн добавить «ещё одну проверку» на фрагмент — самая частая причина жалоб «из-за прокси приложение стало тормозить».

Отказ в закрытое состояние — единственное верное умолчание

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

Написание политик — отдельная задача

Прокси применяет политику. Он не решает, какую политику применять. Относитесь к политике как к коду: под контролем версий, с ревью двух независимых утверждающих, подписанная и выкатываемая тем же конвейером, что и любое другое продуктивное изменение. Движок политик без управления авторами политик — театр.

Мультиарендность поднимает планку изоляции

Если прокси обслуживает больше одного подразделения, цепочка аудита, набор политик и токены маскирования должны быть привязаны к арендатору. Фильтра на уровне строк мало: нужна изоляция на уровне схемы, подкреплённая построчным контролем, чтобы даже честная ошибка в запросе не смогла прочитать данные соседнего арендатора.

8. Когда этот подход вам не подходит

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

  • Агентные сценарии, оркестрирующие много инструментов. Агенту, который обращается к десяти инструментам у нескольких провайдеров, управление нужно на уровне агента, а не на каждом отдельном вызове провайдера. Прокси здесь необходим, но недостаточен.
  • Использование ИИ в браузере. Если пользователи вставляют текст в веб-интерфейс вендора, никакой прокси уровня API этих взаимодействий не увидит. Нужна другая поверхность контроля, обычно инструментирование на уровне сессии или политика браузера.
  • Собственные модели внутри периметра. Когда модель не покидает вашу сеть, задача утечки данных меняет форму; прозрачный прокси по-прежнему полезен для управления и аудита, но проблемы конфиденциальности, которую он решал бы, больше нет.
  • Жёсткий реальный масштаб времени. Если у приложения требования по задержке ниже 100 мс, применение политик в потоке принципиально противоречит вашему дизайну. Фазы до и после потока ещё могут работать; в потоке — обычно нет.

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

Готовы защитить
корпоративную инфраструктуру?

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