Все outbound LLM-вызовы BloodGPT идут через прокси-слой; целевой прокси — Bifrost (self-hosted в нашем кластере). LiteLLM — первый прокси, который мы поставили, сейчас в режиме phasing-out (остатки в коде на ревизию). Managed-варианты (Cloudflare AI Gateway и т.п.) исключены для PHI-трафика. TensorZero рассматривали как experimentation-gateway — не адоптировали.
Контекст
Зачем вообще прокси-слой между приложением и провайдером
Прямая интеграция с провайдером (OpenAI SDK → api.openai.com) ломается, как только появляется любая из этих ситуаций, и каждая требует переписывания кода:
- провайдер вводит rate limits на твой тариф;
- у провайдера outage (а они случаются);
- у конкурента появилась модель лучше/дешевле;
- нужно логировать все запросы для compliance.
Прокси-слой (LLM Gateway) решает это архитектурно, одним местом:
- Unified API — один интерфейс для всех провайдеров (обычно OpenAI-совместимый);
- Fallback / cascade — автоматическое переключение на другую модель/провайдера при сбое;
- Rate limiting — защита от превышения лимитов;
- Retries — повторные попытки при transient-ошибках;
- Observability — логирование, метрики, трейсинг по всему LLM-трафику в одной точке;
- Cost control — бюджеты, виртуальные ключи, spend tracking;
- Точка для security controls — guardrails / prompt-injection detection, если нужно, ставятся на этом слое.
Proxy vs Gateway
Термины «LLM proxy» и «AI Gateway» часто синонимичны, но различие есть: proxy — лёгкий middleware для роутинга запросов (быстрая итерация важнее governance, ранние стадии); gateway — production-grade инфраструктура для управления всем LLM-трафиком организации (централизованный контроль, безопасность, observability, team-level governance, control plane над моделями/API/storage). Bifrost и LiteLLM — proxy с элементами gateway; TensorZero — полноценный gateway с фокусом на experimentation; Cloudflare AI Gateway — managed-решение, инфру держит вендор.
Compliance-рамка (для нас определяющая)
Промпты BloodGPT содержат PHI (анализы, диагнозы, лекарства пациентов). Это сразу убирает managed-варианты: данные не должны покидать контролируемый периметр. Cloudflare подписывает BAA для Enterprise, но покрывает только CDN/WAF/Bot Management — AI Gateway не упомянут в списке HIPAA-covered сервисов; PHI через managed gateway = нарушение compliance. Единственный допустимый класс для нас — self-hosted gateway (Bifrost / TensorZero / LiteLLM — все self-hostable, данные остаются в кластере, контроль на нас).
Рассматривали
Bifrost — Go, zero-overhead (выбран)
Bifrost от Maxim AI — высокопроизводительный proxy на Go. Ключевое — архитектура почти без overhead.
Почему Go: Python-решения страдают от GIL и async-overhead при тысячах concurrent requests; goroutines — ~2KB памяти (можно миллионы), нет GIL (настоящий параллелизм), предсказуемое потребление памяти, быстрый cold start.
Структура: Core (connection pooling, concurrency control) + Providers (OpenAI, Anthropic, Bedrock, Vertex, Mistral, 15+) + Plugins (pre/post-hooks — custom auth, rate limiting, analytics).
| Параметр | Значение |
|---|---|
| Overhead | ~11 µs при 5K RPS |
| Память | предсказуемая, без leaks |
| Провайдеры | 15+ |
| Semantic caching | через Weaviate (~60ms lookup vs ~2000ms LLM call) |
| Деплой | Docker, single binary, Go package |
Два режима работы: API Server (standalone сервис, приложение делает HTTP-запросы) или Go Package (встраивается в Go-приложение).
Два API endpoint — разные подходы, можно использовать оба:
Bifrost
/v1/chat/completions | /genai
(OpenAI-compatible) | (Native Google GenAI)
|
+ cross-provider | - только Gemini/Vertex
fallback | + GCS URI (gs://...)
+ все провайдеры | + Files API
- файлы только base64 | + нативные Gemini-фичи
+ structured outputs |
/v1/chat/completions — OpenAI-совместимый, все провайдеры, cross-provider fallback, файлы только inline base64. /genai — нативный Google GenAI, поддержка GCS URI (gs://bucket/file.pdf — Gemini читает файл по внутренней сети Google без передачи base64), но только Gemini/Vertex и без fallback на другие провайдеры. Практика: /v1 как основной endpoint с fallback, /genai — для оптимизации Gemini-heavy workloads (например, параллельная обработка одного PDF несколькими вызовами: вместо N × base64 — файл в GCS один раз, N вызовов передают только URI-строку).
Compatible с LiteLLM API surface — переход с LiteLLM на Bifrost = смена URL, клиентский код не меняется.
LiteLLM — Python, максимум фич (выводится)
LiteLLM — самый популярный gateway (15000+ звёзд), Python → максимальная гибкость ценой производительности. Структура: FastAPI Proxy + Router (load balancing, fallbacks, retries) + Features (virtual keys, spend tracking, team management, admin UI, 100+ моделей) → PostgreSQL для логирования.
| Параметр | Значение |
|---|---|
| Overhead | 100+ ms под нагрузкой |
| Память | растёт со временем (memory leaks при streaming) |
| Провайдеры | 100+ (максимальный охват) |
| UI | полноценный admin dashboard |
| Деплой | Docker, pip |
Сильные стороны: самый широкий охват моделей, готовый UI, team management/billing, активное сообщество. Отличный выбор для прототипа (<100 RPS) — memory leaks и деградация не критичны на 10 пользователях с возможностью рестарта.
Проблемы в production (почему выводим):
- Memory leak при streaming: память растёт ~0.4–0.5 MiB на каждом
async for chunk in stream, не освобождается; контейнеры доползают до 12+ GB и падают. Не баг версии — архитектурная особенность Python async + long-lived connections (Issue #6404). - Performance degradation: через 2–3 часа TTFT заметно растёт, помогает только рестарт (Issue #6345).
- Падение под нагрузкой: при 300+ RPS теряет запросы, при 1000 QPS падает полностью.
- Логи в PostgreSQL: при >1M логов тормозит API-запросы (logging и serving на одной базе — архитектурное решение).
- Официальный workaround из их же доков —
--max_requests_before_restart 10000(перезапуск воркеров каждые 10K запросов). Gateway, требующий периодических рестартов, — это workaround, не решение.
TensorZero — Rust, structured inference + experimentation (не адоптирован)
TensorZero — gateway нового поколения на Rust, рассматривает себя не как proxy, а как часть ML-пайплайна: structured inference (схемы для inputs/outputs), встроенный A/B (multi-armed bandits, консистентность варианта в multi-step workflow), сбор данных для fine-tuning, GitOps-конфигурация (TOML). Overhead <1ms P99 при 10K QPS; провайдеров меньше, чем у конкурентов; ClickHouse + собственный UI для observability.
Интересен, если бы experimentation между моделями был первоклассной потребностью. У нас этой потребности на данный момент нет (выбор моделей фиксируется явно — см. gemini-flash-vs-pro-allocation), оверхед адаптации не оправдан. Параковано как «если понадобятся встроенные A/B между моделями».
Cloudflare AI Gateway — managed, edge caching (исключён)
Cloudflare AI Gateway — managed SaaS на edge-сети Cloudflare; интеграция = замена одного URL. Zero ops, edge caching (exact match) снижает стоимость повторов, готовый dashboard, бесплатный core. Vertex AI поддерживается (auto-management access tokens из service-account JSON).
Исключён: данные проходят через третью сторону — несовместимо с HIPAA/healthcare (см. compliance-рамку выше); нет guardrails / prompt-injection detection; нет A/B между моделями; кэширование только exact match (не semantic). Подходит для не-чувствительных данных и команд без DevOps — не наш случай.
Latency overhead — сравнение
| Gateway | Overhead | Условия |
|---|---|---|
| Bifrost | ~11 µs | 5K RPS, t3.xlarge |
| TensorZero | <1 ms P99 | 10K QPS |
| Helicone | ~8 ms P50 | — |
| Cloudflare AI GW | ~15–30 ms | edge routing |
| Portkey | ~20–40 ms | edge workers |
| OpenRouter | ~25–40 ms | production |
| LiteLLM | 100+ ms | под нагрузкой |
11 µs — незаметно. <1 ms — приемлемо везде. 100+ ms — ощутимо в realtime и накапливается в цепочках вызовов (у нас pipeline’ы с десятками LLM-вызовов на анализ).
Compliance — managed vs self-hosted
| Gateway | Хостинг | Данные | HIPAA |
|---|---|---|---|
| Bifrost | self-hosted | в кластере | да (контроль на нас) |
| TensorZero | self-hosted | ClickHouse в нашей инфре | да (контроль на нас) |
| LiteLLM | self-hosted | PostgreSQL в нашей инфре | да (контроль на нас) |
| Cloudflare AI GW | managed (edge) | проходят через Cloudflare | нет (AI GW не в BAA scope) |
Выбрали
Bifrost, self-hosted в нашем кластере — основной прокси для всех outbound LLM-вызовов. LiteLLM ставился первым; сейчас выводится, остатки в коде на ревизию. Managed-варианты исключены compliance-рамкой. TensorZero — паркинг (experimentation), не текущий выбор.
Почему
- Compliance: self-hosted, PHI не покидает кластер. Это hard requirement, отсекает Cloudflare и любые managed-варианты сразу.
- Производительность и стабильность: Go, ~11 µs overhead, предсказуемая память без leaks — в отличие от LiteLLM (memory leaks при streaming, деградация TTFT через пару часов, рекомендация рестартить воркеры). В наших pipeline’ах с многими LLM-вызовами на анализ это разница между «не замечаешь» и «накапливается».
- Минимум зависимостей: один binary, без внешних deps (LiteLLM требует PostgreSQL).
- Drop-in миграция с LiteLLM: API surface совместимый — переход = смена URL, клиентский код не трогаем.
- Два endpoint покрывают и cross-provider fallback (
/v1), и нативные Gemini-оптимизации с GCS URI (/genai) — последнее существенно для recognition-pipeline’а (параллельная обработка одного PDF). - LiteLLM выводим, а не «и то и то»: держать два прокси параллельно — лишний moving part; роль остатков LiteLLM в коде ограничена local-dev stand-in (см. litellm), это убирается.
Следствия
BIFROST_BASE_URL— env-переменная, через которую приложения адресуют прокси. Локально Tilt поднимаетbifrost-proxyкакkubectl port-forwardнаlocalhost:8083к staging-Bifrost (обходит гeоблокировку Gemini на local IP). Port-forward завязан наgcloud auth print-access-token, который протухает раз в день — при протухании forward молча умирает (нет ошибки в логах воркера, толькоConnection errorглубоко внутри pipeline). Pre-flight перед запуском любого LLM-heavy pipeline:gcloud auth print-access-token > /dev/null && curl -s -o /dev/null -w "%{http_code}" localhost:8083/health— см. CLAUDE.md (apps/b2c-dashboard/CLAUDE.md§ Pre-flight).- Model fallback / cascade — через Bifrost, не руками в коде. Production-конфиги вида
Gemini Flash → GPT-5.2 → Gemini Flash → GPT-5.2(cascade fallback) живут в Bifrost-конфиге, не в application-коде. Это та же логика, что и no-self-rolled-queues: ретраи/fallback/очереди — на инфраструктурном слое, не самодельные. Bifrost для model-routing/fallback — аналог inngest для шагов pipeline. - 30s default timeout на исходящий request Bifrost — конфигурируется (вплоть до UI), не constraint. Большие payloads (например, Personalizer на Lp(a) с массивом reference data) на default-е падают с TimeoutError — фикс = поднять timeout для этого flow. См. bifrost.
- Mock LLM на стейдже реализован как Bifrost-плагины (
schema-mocker+fhir-postprocessor, Go) — short-circuit’ят LLM-вызовы, генерируют валидный JSON по schema с medical-substitution. См. bifrost-mock-strategy, bifrost-custom-plugin-loading, bifrost-mock-plugins. - Semantic caching через Weaviate — возможность Bifrost (60ms lookup vs 2000ms LLM call), не включено.
- Operational gotcha: Bifrost не использует нормальную БД для логов — переполняется → service crashes (recurrent). Фикс известен (proper persistent DB / log shipping), Linear-тикет предположительно есть. И умирает незаметно — нет healthcheck в local workflow (был случай 8h простоя). См. bifrost § Operational gotchas.
Открытые вопросы
- Точная роль остатков LiteLLM в коде — TBD verify; похоже только local-dev stand-in (
:4000), но проверить, нет ли production/staging-путей. См. litellm. - Когда полностью decommission LiteLLM — после ревизии путей; есть ли use case, где он реально лучше Bifrost (вряд ли).
- Bifrost в production — какая доля LLM-вызовов реально идёт через него vs direct provider — claim из bifrost помечен «не уверен», нужен audit INFRA / deploy-конфигов.
- Guardrails / prompt-injection detection на gateway-слое — не настроено. Bifrost поддерживает через pre/post-hooks (custom-логика). Стоит ли — отдельный вопрос (defense-in-depth: gateway-валидация недостаточна сама по себе — guardrails обходятся с success rate до 100% через character injection — но как один из слоёв уместна).
- Observability: Bifrost даёт Prometheus metrics + Web UI — насколько используем, что мониторим (latency P50/95/99, TTFT, tokens/request, error rate by provider, cost/request).
- Логи Bifrost — фикс переполнения (proper DB) не сделан; найти тикет, закрыть.
Связано
- bifrost — vendor-страница Bifrost (использование, timeout, cascade, operational gotchas, mock-плагины)
- litellm — vendor-страница LiteLLM (выводится; роль остатков TBD)
- bifrost-mock-plugins —
schema-mocker+fhir-postprocessor - bifrost-mock-strategy — два плагина, не один
- bifrost-custom-plugin-loading — регистрация через SyncLoadedPlugin вместо
.so - gemini-flash-vs-pro-allocation — выбор моделей фиксируется явно (Flash для extraction/OCR/lookup, Pro для reasoning/cross-check), всё через Bifrost
- no-self-rolled-queues — model-fallback/cascade — через прокси, не руками; та же логика, что очереди/ретраи — через Inngest
- llm-call-failure-classes — транспорт + схема (timeout/retry/perturbation/fallback, cleanSchema) — generic, кандидаты уехать на прокси; семантика — остаётся в коде агента
- gemini-doom-loop — конкретный кейс транспорт+схема (Gemini зависает / repetition-loop / MAX_TOKENS) — машинерия обходов, кандидат на прокси-слой
- inngest — Inngest для шагов pipeline ⟷ Bifrost для model-routing/fallback (один паттерн: инфраструктурный слой вместо самодельного)
Источники
Сноски
-
[Bifrost GitHub](, accessed 2026-05-17, https://github.com/maximhq/bifrost — · Bifrost Architecture / 40x faster than LiteLLM · Migration from LiteLLM to Bifrost. ↩
-
[LiteLLM GitHub](, accessed 2026-05-17, https://github.com/BerriAI/litellm — · Memory leak #6404 · Perf degradation #6345 · LiteLLM broke at 300 RPS. ↩
-
[TensorZero GitHub](, accessed 2026-05-17, https://github.com/tensorzero/tensorzero — · Cloudflare AI Gateway Docs · Cloudflare HIPAA scope · Cloudflare AI GW + Vertex. ↩
-
[LLM Proxy vs AI Gateway (Portkey)](, accessed 2026-05-17, https://portkey.ai/blog/llm-proxy-vs-ai-gateway/ — · LLM Guardrails Best Practices (Datadog) · Bypassing LLM Guardrails (arXiv:2504.11168) · Top 5 LLM Gateways for Production 2026. ↩
-
Independent validation overhead claims: [truefoundry: Bifrost vs LiteLLM (independent comparison, те же 8ms vs 11μs)](, accessed 2026-05-17, https://www.truefoundry.com/blog/bifrost-vs-litellm — · Sofian Hamiti: From 429s to 200s with LiteLLM on AWS Fargate (counter-case — successful LiteLLM scaling at small RPS). ↩
-
Industry resilience patterns relevant for mitigation-hierarchy-от-google-rep-7-апреля-2026: [TianPan: LLM API Resilience in Production (почему backoff alone не масштабируется)](, accessed 2026-05-17, https://tianpan.co/blog/2026-03-11-llm-api-resilience-production — · getmaxim.ai: How AI Gateways Tackle Rate Limiting · getmaxim.ai: Retries, Fallbacks, and Circuit Breakers in LLM Apps. ↩