LLM proxy-сервис, через который BloodGPT routes outbound LLM-вызовы (Gemini, GPT, etc.) к cloud-providers. Альтернатива прямому direct-call провайдерам — централизация auth, rate limiting, observability, caching.

Использование в BloodGPT

Statuses unverified — несколько claims ниже Ильдар пометил как “не уверен”. Нужен audit через INFRA / actual deploy configs. Пока — best-known representation.

  • Local development — настройка через Tilt forward’ит запросы к staging Bifrost (не self-hosted Bifrost локально). Главная причина — обойти гeoблокировку Gemini (Google banned local IP); staging-Bifrost в GCP идёт к Gemini напрямую. Это нужно для запуска Gemini на dev machine, иначе LLM calls fail.
  • Staging — Bifrost развёрнут в staging кластере. TBD verify — используется ли для integration testing/E2E (или только как target для local dev forwarding).
  • ProductionTBD verify что Bifrost используется в production. Возможно только часть LLM-вызовов идёт через него (а часть — direct provider). Изначально я писал “all LLM calls через Bifrost” — Ильдар поправил, не уверен.
  • Local-via-staging forwarding — для dev сценариев основной use case: обойти гeoблокировку. Staging-proxy pattern также используется для других heavy services (LOINC normalization service — loinc).

Ключевые свойства

30-second timeout per outbound request — default config, не constraint

Из session 7cc1d514 (BG-1191 V2.5):

Ильдар: «Bifrost сам имеет limit 30 секунд на свой исходящий request. там настраивается..и чуть ли не в ui»

Timeout — легко настраивается через Bifrost UI (графический интерфейс admin-панели), не из application кода. Default 30s, но это не hardcoded constraint — нужно просто поднять для tasks с большими payloads.

Что было видно в проде (с default 30s):

  • Personalizer на больших payloads (Lp(a) Lipoprotein(a) с массивом reference data) падает с TimeoutError. Stdout pattern: [personalizer] Lipoprotein(a) FAIL 270024ms attempt=1 TimeoutError. После 2 attempts — DEAD (540085ms, exhausted).
  • Fix: настроить timeout нормально (вверх) для personalizer flow. Альтернатива — chunking, но это лишний refactor если timeout достаточно поднять.

Cascade fallback through Bifrost

Production model config (например, LOINC pipeline):

Keywords:   Gemini Flash → GPT-5.2 → Gemini Flash → GPT-5.2  (cascade fallback)
Selection:  Gemini Pro   → GPT-5.2 → Gemini Pro   → GPT-5.2  (cascade fallback)

Each step делает через Bifrost — не напрямую к Gemini/OpenAI. Bifrost handles auth (Workload Identity), rate limiting, fallback chains.

См. loinc про конкретный production cascade.

LiteLLM compatibility

Bifrost compatible с LiteLLM API surface — local dev может использовать LiteLLM proxy на :4000 как stand-in (см. сессию 833ec924 про LOINC port). Это даёт Mastra-агентам в TS возможность использовать Gemini локально (Google banned IP block обходится через cloud LiteLLM proxy).

Полное обсуждение LiteLLM как отдельной vendor-страницы — см. litellm. Сравнение прокси (Bifrost / LiteLLM / TensorZero / Cloudflare AI Gateway — почему Bifrost, почему LiteLLM выводится, latency-бенчмарки, compliance-рамка) — llm-proxy-choice (origin: posts/llm-gateway-comparison.md).

Operational gotchas

OOM — двухкомпонентный, требовал двух фиксов

На staging recurrent OOM (BG-1202) имел два независимых источника. Источник #1 (slow leak, часы): SQLite ./logs.db в ephemeral fs с 365-day retention без VACUUM рос монотонно → OOM каждые ~4 часа. Закрыт client.enable_logging: false + logs_store.enabled: false в configmap (2026-05-19). Источник #2 (burst, минуты): concurrent in-flight buffering под algo-hub fanout (30+ параллельных long-running LLM calls × payload буферы + retry state + goroutine stacks) выходило за 512Mi limit под нагрузкой — обнаружено через 20 минут после Phase 1 deploy. Закрыт bumped limits 512Mi/1Gi (с 256Mi/512Mi) в resources секции values.yaml + GOMEMLIMIT=900MiB env var, без которого Go runtime не знал про container limit и accumulate’ил heap до hard cap’а до GC.

LLM observability теперь полностью покрыта langfuse на application-слое. Admin UI на :8080 остаётся для governance/providers, но без per-call dashboard и без /api/logs. Rationale, варианты, Phase 2 (опциональный возврат gateway-audit через OTLP-export в Langfuse или Postgres logs_store) — bifrost-logging.

Bifrost может умереть незаметно

В session 7cc1d514: Bifrost был мёртв 8 часов — никто не заметил, потому что нет отдельного healthcheck в local development workflow.

Ильдар: «но Bifrost уже мёртв (8ч простоя). Если поднимаем — скажи.»

Practical workaround: периодически проверять kubectl get pods -n bifrost или иметь Tilt healthcheck. Если local Bifrost dead — запросы либо timeoutят, либо fall through на других proxies (если cascade настроен).

Staging-forward для local dev — общий pattern

Когда local Bifrost не нужен / не работает — pattern: redirect local app к staging Bifrost (de-facto это default config для Gemini geo-bypass). Это standard в BloodGPT dev workflow для heavy services которые невыгодно поднимать локально. Применимо к нескольким:

  • Bifrost — основной use-case (этот page)
  • LOINC normalization service — staging-forward даёт точные production коды (актуальный словарь, current model state). Local self-hosted имел бы stale codes. См. loinc.
  • Другие heavy services — TBD list.

Причины редиректа на staging могут быть разные: geo-bypass (Gemini), точность данных (LOINC), ресурсы (memory/CPU heavy для local dev), persistence (real DB в staging vs in-memory локально).

Mock LLM плагины (BloodGPT)

Research-направление из FDA digest (2026-04-23) реализовано как пара своих плагинов — upstream maximhq/bifrost/plugins/mocker/ отверга нут потому что он не понимает response_format: json_schema (только canned strings). Подробно в bifrost-mock-plugins: schema-mocker short-circuit’ит запросы, рекурсивно генерирует валидный JSON по schema (с medical biomarker substitution), fhir-postprocessor патчит valueQuantity извлечёнными из prompt’а Parameter_Info значениями.

Реализованы как форк upstream bifrost-http с SyncLoadedPlugin registration вместо .so — обоснование в bifrost-custom-plugin-loading. Toggle через header X-Bifrost-Skip-Mock per-request, через models config-allowlist на уровне модели, через enabled flag на уровне плагина. На 2026-05-07 локально готово, на стейдж не задеплоено.

Связано

  • llm-proxy-choice — решение: Bifrost (self-hosted) как целевой прокси, LiteLLM выводится; сравнение всех вариантов + compliance-рамка
  • bifrost-mock-plugins — наш plugin-stack для mock LLM на стейдже
  • mastra — Mastra-агенты используют Bifrost для outbound LLM вызовов
  • loinc — production model cascade через Bifrost
  • hapi-fhir — local FHIR backend, аналогичный staging-proxy pattern для local dev
  • google-healthcare-api — production FHIR backend (orthogonal к Bifrost — FHIR не идёт через Bifrost)
  • bifrost-custom-plugin-loading — почему наши плагины через SyncLoadedPlugin, не .so
  • bifrost-mock-strategy — почему два плагина (schema-mocker + fhir-postprocessor), не один
  • bifrost-logging — почему internal logging отключён, варианты Phase 2 (OTLP в Langfuse / Postgres logs_store) — draft
  • bifrost-memory-model — техническая карта что аллоцируется в bifrost под нагрузкой, failure modes, диагностика

Источники