Всички проекти

AI шлюз

pacod-gw

Един шлюз пред всички модели — с ключовете, цените, квотите и използването, които не е нужно приложенията ви да държат.

pacod-gw стои между вашите приложения и LLM доставчиците. Ядро на Rust препраща или преобразува всяко извикване, държи ключовете на доставчиците извън приложенията, налага квоти, остойностява всяка заявка и подава данните за използването към анализи в ClickHouse — всичко управлявано от конзола на SvelteKit.

  • Apache-2.0
  • Версия 0.1.0
  • Предварителна

Възможности

  • Proxy или managed

    Препращайте API-то на доставчика байт по байт или оставете шлюза да разрешава шаблони, да обединява параметри и да превежда между диалекти.

  • Много диалекти, един договор

    OpenAI, Anthropic, Gemini и собствен диалект; проверени на живо срещу DeepSeek и GLM, а Kimi и Ollama се емулират от симулатора.

  • Ключовете остават в шлюза

    Съхранени идентификационни данни на доставчици и ключове на шлюза за всяко работно пространство. Приложенията никога не виждат ключ на доставчик.

  • Квоти и лимити

    Лимити за токени и заявки по организация, работно пространство и ключ, налагани преди извикването да напусне шлюза.

  • Всяко извикване с цена

    Регистър на използването с разхода в отговора, така че екипите виждат колко струва всяка заявка още в момента.

  • Анализи в ClickHouse

    Събитията постъпват в отделна услуга за анализи с отчети и планирани задачи; Prometheus, Grafana и OpenTelemetry за експлоатацията.

  • Маршрутизиране и намерение

    Схеми и правила за маршрутизиране, плюс плъгин за намерение с механизми LLM, Jev и каскаден, който избира правилния модел за всяка заявка.

  • Режим lite

    Същият data plane в един контейнер — без база данни, без конзола — конфигуриран с един .env файл и с журнал на всяко извикване.

Мястото в системата

Хора и услугиLLM доставчициAPpacod-apCMpacod-cmsKBpacod-kbGWpacod-gwIDpacod-id
Хора и услугиLLM доставчициAPpacod-apCMpacod-cmsKBpacod-kbGWpacod-gwIDpacod-id
Диаграма: как се свързват проектите на pacod Извиквания към LLM Докоснете проект, за да видите с какво е свързан.

Защо шлюз

Всеки продукт, който работи с езиков модел, в крайна сметка преоткрива едни и същи неща: съхранение на ключове на доставчици, преобразуване между API-та, броене на токени, налагане на лимити и обясняване на сметката. pacod-gw изважда всичко това от приложението. Приложението извиква една крайна точка с ключ на шлюза; шлюзът решава кой модел обслужва извикването, колко може да струва и кой плаща за него.

Първата цел е конкретна: да замени LiteLLM прокси пред дадено приложение, като се сменят само неговият базов URL и ключ.

Два режима, едно ядро

Ядрото е един двоичен файл на Rust с два слушателя: data plane за приложенията и управляващото API за конзолата и скриптовете. Режимът се избира по префикса на URL и се разрешава за всеки ключ.

  • Режим proxy (/proxy/{provider}/…) препраща собственото API на доставчика байт по байт и добавя удостоверяване, лимити и отчитане. Шаблон все пак може да зададе модела и неговите параметри.
  • Режим managed обслужва /v1/chat/completions на OpenAI, /v1/messages на Anthropic, generateContent на Gemini и собствения /gw/v1/chat, както и embeddings и синтез на реч.

В режим managed диалектът на извикващия и доставчикът на модела определят маршрута:

Извикващият говори Моделът е при Какво се случва
Диалект на OpenAI OpenAI-съвместим доставчик (OpenAI, DeepSeek, GLM, Kimi, Ollama, …) Байтовете на извикващия се коригират; цената се добавя в usage.
Диалект на Anthropic Anthropic Разговорът стига до Anthropic така, както е изпратен; цената се връща в заглавка.
Всяка друга комбинация и собственият интерфейс Всеки доставчик Превежда се през неутрален към доставчиците модел и обратно, така че извикването може да премине към резервен модел и през диалекти.

Едно извикване, стъпка по стъпка

  1. Удостоверяване. Ключът се търси чрез HMAC в моментна снимка на конфигурацията в паметта.
  2. Четене. Скенер намира модела и флаговете за поточно предаване, без да разбира цялото тяло; плъгините на работното пространство виждат разговора.
  3. Разрешаване. Шаблон (@name или x-gw-template) или идентификатор на разрешен модел определя модела и неговите параметри.
  4. Допускане. Ограничението на паралелните извиквания на ключа и всеки приложим лимит трябва да бъдат спазени.
  5. Изпращане. Съхранените идентификационни данни на доставчика заменят ключа на шлюза. В режим managed отговор 429, 5xx или изгубена връзка се опитват отново или се пренасочват към следващия модел, преди извикващият да получи и един байт.
  6. Препращане и отчитане. Отговорът се връща поточно, докато отклонител чете използването от копие; след това цената и броячите се обновяват, а събитие за използване отива в спул на диска.

Отговорът съдържа x-gw-request-id, x-gw-delay-ms (времето, добавено от самия шлюз), x-gw-model-served и, при извиквания в режим managed без поточно предаване, x-gw-cost.

Конфигурацията живее в PostgreSQL, но пътят на заявката не я чака: промяната подменя моментната снимка за около две секунди, а ако някое хранилище не работи, трафикът продължава с последната.

Организации, работни пространства и ключове

Организацията е клиент или голямо звено. Работното пространство е едно приложение, проект, среда или екип и притежава своите ключове, шаблони, лимити, настройки и използване. Две правила покриват всяко ограничение: списъците с разрешения се пресичат и числовите тавани вземат минимума.

Ключовете на доставчиците принадлежат на инсталацията, на организация или на работно пространство, а извикването използва най-близкия: собствения на работното пространство, после този на организацията му, после общия ключ на инсталацията. Ключ, който шлюзът вече съхранява, може да бъде предаден надолу към организация или работно пространство, без да се въвежда отново; тайната никога не напуска шлюза.

Ролите са един файл, authz/gw.yaml, от който се генерират проверките както на ядрото, така и на конзолата:

Роля Какво обхваща
Администратор на платформата Доставчици, идентификационни данни, модели, цени, организации, хора
Администратор на организация Нейните настройки, работни пространства, членове и разрешения за модели
Администратор на работно пространство Шаблони, ключове, лимити, настройки и одитен режим на едно работно пространство
Одитор Чете конфигурация, използване и записи от одитния режим
Наблюдател Чете конфигурация и използване; без тайни, без записи от одитния режим

Извикванията носят атрибуция — end_user, session_id, trace_id, декларирани тагове, agent_id, task, complexity — която отчетите, лимитите и маршрутизирането използват. Хората влизат в конзолата с локални акаунти или, с PGW_AUTH=oidc, през pacod-id.

Лимити и цена

Лимитът се прилага към организация, работно пространство, ключ или краен потребител. Той брои токени, заявки или разходи за минута, час, ден, седмица, месец или за целия период и или отказва извиквания (429, 402), или само брои и докладва. Приложенията могат да прочетат състоянието на квотата на потребител чрез GET /gw/v1/quota. Броячите се обединяват между инстанциите през PostgreSQL приблизително веднъж в секунда, така че лимит може да бъде надвишен с около секунда трафик.

Всяко извикване се остойностява при приключването си по версионирана цена, която покрива четене и запис в кеша, разсъждения, пакетни варианти, нива според размера на входа и извънпикови прозорци. Цена по подразбиране няма: модел се активира само с цена или изрично „безплатно“. Откриването на модели пита всеки доставчик за списъка му с модели, по подразбиране веднъж дневно, и предлага моделите, които шлюзът няма; модел, добавен от предложение, остава чернова, докато не получи цена. Планиран проследяващ цени чете ценовия списък на LiteLLM или страницата с цени на доставчика и прилага промени в зададена граница или ги предлага за одобрение. Докато няма източници, конзолата предлага списъка на LiteLLM за OpenAI, Anthropic, Gemini, DeepSeek и z.ai.

Маршрутизиране и намерение

Шаблонът може да съдържа пул от модели с нива, тегла и приоритети. Без допълнителна настройка първият модел обслужва, а следващият поема при 429, 5xx или изгубена връзка. Схема за маршрутизиране добавя правила според това, което извикващият заявява (complexity, task, тагове, размер на входа или CEL израз), и алгоритми: по приоритет, претеглен, round robin, най-ниска латентност и най-евтин, с незадължителен афинитет към сесията, за да остават кешовете на промптовете „топли“. Прекъсвач (circuit breaker) отстранява временно модел, който се проваля, а всеки отговор посочва в x-gw-route правилото, което го е маршрутизирало.

Плъгинът за намерение отговаря на въпроса „за какво е това извикване?“ спрямо каталог, който организацията или работното пространство пише, чрез LLM, двигателя Jev или каскада от двата. Решението му може да блокира извикване, да го маршрутизира, да го отчете към лимити за намерение или да го маркира за преглед; може първо да работи в режим shadow и никога не променя разговора.

Нов каталог започва от вграден шаблон, starter, с намеренията на общ асистент и правила, които маркират и блокират. Нова връзка (binding) започва от шаблон, който шлюзът попълва за своя обхват: режим shadow, този каталог и най-евтиният разрешен модел, който отговаря по JSON схема, или Jev, ако няма такъв. Панелите за проба и оценка в конзолата пускат двигателите върху примерни текстове, първо върху демонстрационни данни, създадени за каталога, така че двигателите да се сравнят, преди връзката да започне да налага решенията си. Вижте ръководството за маршрутизиране и концепцията за плъгините.

Наблюдаемост и одит

Събитията за използване стигат до услугата за анализи на пакети от спула на всяка инстанция; доставката е поне веднъж, а ClickHouse премахва дубликатите. Услугата изгражда отчети за използване, грешки, забавяне от шлюза, класации и крайни потребители, с експорт в CSV, и изпълнява планираните задачи. Конзолата стига до нея само през ядрото, което проверява ролята на извикващия и налага обхвата.

Prometheus, табла в Grafana, правила за Alertmanager и трасировки с OpenTelemetry покриват експлоатацията; конзолата показва текущи показатели, състоянието на доставчиците и отворените аларми.

Одитният режим пази пълни извиквания за отстраняване на грешки: заявката, всеки опит към доставчика и отговорите. По подразбиране е изключен, организацията може да го изисква или забрани, идентификационните данни се премахват преди съхранение, а записите изтичат по подразбиране след 14 дни.

Модел на сигурност

  • Ключовете на доставчиците се запечатват поотделно с AES-256-GCM под ключ за криптиране на ключове, който идва от средата или от файл, никога от базата данни. API-то показва само отпечатък.
  • Ключовете на шлюза (pgw_…) съдържат 32 случайни байта, съхраняват се като HMAC-SHA256 с pepper и се показват веднъж.
  • Разделяне на наемателите. Работното пространство идва от ключа, никога от заявката, а ядрото ограничава отчетите до това, което ролите на извикващия позволяват.
  • Изходящите връзки към доставчици и източници на цени се проверяват след разрешаването на имената: частни и link-local адреси се отказват, освен ако операторът изрично не ги разреши.
  • Промптовете остават извън логовете, метриките и трасировките, които носят само метаданни; телата се съхраняват само в одитен режим.

Моделът на заплахите изброява и какво остава открито: например портът за метрики няма удостоверяване и носи етикети на наематели, а в общата мрежа всеки контейнер на pacod може да достигне управляващото API, което тогава разчита само на собственото си удостоверяване.

Внедряване и експлоатация

Ядрото работи като all или е разделено на инстанции gateway и една инстанция admin. Инстанциите споделят един PostgreSQL и нищо друго.

Подредба Файлове
Едно ядро deploy/docker-compose.yml с docker-compose.standalone.yml
Няколко шлюза на един хост плюс docker-compose.scale.yml
Шлюзове на други машини docker-compose.hub.yml централно, deploy/node/ на всяка машина
Kubernetes deploy/helm/pacod-gw
Минимален шлюз deploy/lite/docker-compose.yml

Както всеки проект на pacod, шлюзът се включва в общата Docker мрежа pacod-net, където всяка услуга има собствено име: ядрото е pacod-gw, останалите услуги са gw-*. docker-compose.yml съдържа собствените услуги на шлюза; docker-compose.standalone.yml добавя неговите копия на общите компоненти: PostgreSQL, pacod-id, Caddy и мониторинга. pacod-demo пуска шлюза заедно с останалите проекти на pacod на demo.pacod.io. pacod-demo зарежда само първия файл и пуска всеки общ компонент веднъж; ClickHouse остава при шлюза.

Caddy терминира TLS и изпраща всяко извикване към готовия шлюз с най-малко текущи извиквания. Наръчникът за експлоатация покрива тайните, архивирането и възстановяването, ротацията на ключове, надграждането и отстраняването на проблеми; вграден тестер изпълнява тестови случаи и натоварващи тестове от конзолата.

pacod-gw-lite запазва превода, поточното предаване, повторните опити и превключването към резервен модел, с лимити за ключ в паметта и един ред в лога за всяко извикване с неговата цена. Клиентите му споделят ключовете на доставчиците и не са разделени един от друг при доставчика. В общата мрежа минималният шлюз също е pacod-gw, затова на един хост работи или той, или пълният шлюз (подробности).

Какво е тествано

  • OpenAI, Anthropic, Gemini, DeepSeek и GLM са проверени с реални извиквания; Kimi, Ollama, xAI и Vertex AI — само спрямо документацията си и имитиращия доставчик.
  • Целта от дизайна — 10 000 едновременни потока в режим proxy и 5 000 в режим managed на инстанция (2 CPU, 1 GB) — все още не е потвърдена с натоварващ тест.
  • Все още не са изпробвани: сертификати от Let's Encrypt, Linux хост, надграждане между версии и Helm чартът в реален клъстер.
  • Не са част от първата версия: управление на MCP и инструменти, предпазни механизми за съдържанието и кеширане на отговори.

Страницата за архитектурата показва как е подреден кодът и къде се различава от концепцията на дизайна.

Технологии

Написан на
  • Rust
  • TypeScript
  • Python
Технологии
  • Rust
  • PostgreSQL
  • ClickHouse
  • SvelteKit
  • Caddy
  • Docker
  • Helm
  • Prometheus
  • OpenTelemetry

Бърз старт

Пълният стек със симулиран доставчик
make test-servicesmake verifymake dev-upmake smoke-mockopen http://localhost:13000
Минималният шлюз
make lite-dev-upmake lite-smoke

Работи с

  • pacod-id

    С PGW_AUTH=oidc хората влизат в конзолата през pacod-id; ролите и работните пространства идват от неговия поток за оторизация.

  • pacod-ap

    Всяко LLM извикване на агентите минава през шлюза, който управлява моделите, цените, ключовете и използването.

  • pacod-cms

    AI преводът в студиото извиква шлюза, така че CMS никога не държи ключ на доставчик.

  • pacod-kb

    Незадължителното LLM почистване в базата знания се маршрутизира, остойностява и отчита от шлюза.

Лиценз

Apache-2.0