Нарисуйте схему компании не деревом сотрудников, а набором работ. Менеджер в Казани пишет клиенту ответ и просит модель поправить тон. Ночью, когда в офисах темно, отдельный сервис собирает сводку по обращениям за день и кладёт её в общую папку. У филиала есть общий бюджет на всё это, и его хочется видеть одной цифрой. Три совершенно разных «кто-то» ходят в один и тот же ИИ-шлюз, и если выдать им одинаковый ключ, начнутся странности: расходы не разложить по причинам, увольнение человека сломает чужую автоматизацию, а утечку одного секрета придётся расследовать по всему филиалу.
Вопрос, с которого стоит начинать, звучит так: какие права выдавать человеку, а какие программе, работающей без него? Ответ не в том, что программе нужно «больше» или «меньше». Ответ в том, что у них разные хозяева, разные причины существовать и разные поводы перестать существовать. Дальше разберём это на трёх субъектах: сотруднике, филиале и ночном процессе.
Филиал платит, сотрудник отвечает, процесс работает
Первая путаница возникает из-за того, что в голове всё сливается в слово «пользователь». Но у филиала и у сотрудника разные роли в учёте.
Филиал — это центр расходов. Он не нажимает кнопок, не вводит запросов и не может ошибиться в промпте. Зато у него есть бюджет, руководитель и вопрос «сколько мы потратили в этом месяце». Сотрудник — владелец личного доступа: он отвечает за то, что делается под его ключом, и этот ключ существует, пока он работает в компании. Ночной процесс — третий тип: у него нет ни зарплаты, ни отпуска, он существует, потому что компании нужна сводка, а не потому что кто-то лично этого хочет.
Если смоделировать это в шлюзе честно, получаются три разные сущности. Личные ключи привязаны к людям. Командная (или проектная) сущность соответствует филиалу или рабочей группе и несёт общий лимит. Сервисный ключ привязан к самому проекту. В документации LiteLLM это различие записано прямо: сервисный ключ предназначен для проекта, а не для отдельного пользователя. Для нашей темы это ключевая мысль: «проект» в этой формулировке — как раз то, что я назвал работой.
Заметьте, чего здесь не сказано. Никто не обещает, что всё устроится само. Разделение делает не шлюз, а вы: когда решаете, что ночная сводка — это проект, а не «скрипт Миши».
Карта трёх субъектов
Прежде чем выдавать любые ключи, полезно заполнить таблицу из трёх строк. Она заставляет назвать владельца и событие отзыва до того, как ключ окажется в чьём-то конфиге. Ниже условный пример для филиала; названия моделей и цифры — иллюстрация, подставьте свои.
| Субъект | Владелец | Допустимая модель | Бюджет | Событие отзыва |
|---|---|---|---|---|
| Сотрудник филиала | Он сам; руководитель филиала отвечает за состав группы | Универсальная недорогая модель для переписки и черновиков; дорогие модели только по заявке | Личный лимит внутри общего лимита филиала | Увольнение, перевод в другое подразделение, подозрение на утечку ключа |
| Филиал | Руководитель филиала как владелец расходов | Список моделей, разрешённых для команды целиком | Общий месячный лимит команды | Закрытие или реорганизация филиала, пересмотр бюджета |
| Ночной процесс | Назначенная команда или должность, а не конкретный разработчик | Одна фиксированная модель, подходящая для сводки | Отдельный лимит проекта, видимый отдельно от людей | Решение компании остановить сводку или передача сервиса другой команде |
Обратите внимание на столбец «владелец» у третьей строки. Это самая частая точка поломки: в пустой ячейке чаще всего стоит имя человека, написавшего скрипт. Пока он в штате, всё работает. Что происходит, когда он уходит, — следующий раздел.
Чтобы пустая ячейка не оставалась пустой, полезно к каждой строке таблицы дописать два вопроса: «кто узнает, что событие отзыва наступило» и «что остановится первым». У сотрудника на первый вопрос отвечает кадровый процесс: увольнение или перевод попадают к тому, кто управляет группой в шлюзе. У филиала ответ даёт руководитель, потому что закрытие подразделения само по себе до шлюза не дойдёт. У ночного процесса такого автоматического сигнала нет вообще: никто не увольняется, никто не переводится. Поэтому его событием отзыва становится письменное решение компании, и записать его стоит в той же таблице, рядом с названием команды-владельца.
Второй вопрос показывает последствия. Если отозвать личный ключ сотрудника, остановится одна переписка с клиентами, и человек сразу заметит это сам. Если исчерпан или закрыт командный бюджет филиала, остановятся все его люди одновременно, и это уже разговор с руководителем. Если же упадёт ночной процесс, первым это заметят не те, кто им владеет, а шесть читателей сводки, и только утром. Чем позже и чем дальше от владельца обнаруживается остановка, тем важнее заранее назвать ответственного и дать ему отдельную строку расходов: по ней видно, что ночью запросы прошли.
Что происходит с ночной сводкой, когда автор уходит
Разберём сценарий, который рано или поздно случается в любой компании. Разработчик Антон написал сервис, который каждую ночь обращается к шлюзу, собирает сводку и выкладывает её. Ключ он выпустил на себя: так было быстрее. Через год Антон уходит, кадровая служба закрывает его учётную запись, а вместе с ней — всё, что на ней висело, включая ключ. Следующей ночью сводки нет. Утром выясняется, что её читали шесть руководителей.
Здесь легко сделать неверный вывод: «значит, сотрудников нельзя удалять» или «значит, ключи надо выдавать в обход людей». Правильный вывод другой: ключ автоматизации не должен принадлежать человеку, потому что у ключа и у человека разные жизненные циклы. Человек уходит по причинам, не имеющим отношения к сводке. Сводка должна остановиться только по причинам, касающимся сводки.
Документация LiteLLM описывает именно такое свойство сервисного ключа: он сохраняется после удаления пользователя и использует ограничения команды. Практическое следствие простое. Если ночной процесс работает на сервисном ключе, увольнение автора не гасит его автоматически, а лимиты берутся командные, а не личные. Удаление человека перестаёт быть событием отзыва для проекта.
Тут нужна оговорка в обратную сторону, чтобы не получить новую проблему. Если проектный ключ переживает удаление человека, значит, никто не отзовёт его «заодно». Ключ, который не умирает вместе с автором, должен иметь живого хозяина, иначе вы получите вечный доступ без ответственного. Поэтому в карте выше у ночного процесса владелец — команда или должность. Увольнение автора в этом случае запускает не отзыв ключа, а короткую проверку: кто теперь отвечает за сервис и знает ли он, где хранится секрет.
Разберём на примере с Антоном, что именно должна выяснить эта проверка. Во-первых, где физически лежит секрет проектного ключа и кто из оставшихся сотрудников имеет к нему доступ: если только сам Антон, ключ формально жив, но в реальности ничей. Во-вторых, к какой команде в шлюзе привязан проект. Раз сервисный ключ использует командные ограничения, именно эта команда определяет, какой лимит и какие правила будут действовать на ночной прогон. Если команда разработки расформирована вместе с уходом автора, сводка может оказаться привязанной к группе, за которой никто не следит.
В-третьих, стоит выяснить, что сервис делает при отказе. Если ночной прогон упрётся в лимит или недоступную модель, пишет ли он об этом куда-то, где его прочтёт новый владелец, или просто молчит до утра? Эти три ответа занимают четверть часа, а без них «ключ пережил увольнение» превращается из достоинства в скрытый долг: работа идёт, но отвечающего за неё нет.
Что менять в самом сервисе
Перевод автоматизации с личного ключа на сервисный — обычно мелкая правка: меняется значение секрета в конфигурации, остальной код остаётся прежним. Неприятность в другом: старый личный ключ, который вы заменили, нужно именно отозвать, а не оставить «на всякий случай». Иначе у вас два рабочих пути в шлюз, и расходы по ночной сводке продолжат записываться на человека, которого уже нет. Порядок такой: сначала выпустить проектный ключ и убедиться, что очередной прогон проходит на нём, потом отозвать личный.
Секрет проектного ключа держите там, где сервис его получает при запуске, а не в репозитории и не в чате. Об общих принципах выдачи доступов сотрудникам к рабочим системам мы писали отдельно: как оформить доступ сотрудников к продакшену. Здесь важна только одна мысль из той темы: доступ человека и доступ программы оформляются разными решениями.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.
Общий лимит филиала и личные ограничения
Теперь про деньги. Филиалу выделен бюджет, внутри филиала двадцать человек и пара автоматизаций. Как разложить расходы, чтобы один активный сотрудник не съел месяц целой команды, а ночная сводка не зависела от настроения коллег?
В документации по бюджетам LiteLLM сказано, что существуют индивидуальные, командные и внутригрупповые бюджеты. Это три уровня, на которых можно задать потолок: для человека, для команды и для группы внутри команды. Из этого можно построить понятную систему, но тут важно не приписывать шлюзу лишнего. Документация перечисляет виды бюджетов; она не обещает, что все они автоматически вложены друг в друга по каким-то особым правилам наследования. Поэтому логику «личный лимит не может превысить командный» не стоит считать данностью: проверьте на своём стенде, как ведёт себя ваша версия, когда у ключа и у команды разные потолки.
Практичная схема, которая не требует угадывать правила наследования, выглядит так:
- Командный бюджет филиала задаёт общий потолок, ради которого вообще заводится команда.
- Личные лимиты ставятся заведомо ниже общего, чтобы один человек физически не мог исчерпать месячный запас за неделю.
- Сумма личных лимитов может быть больше общего: не все тратят максимум одновременно. Но тогда последний в очереди рискует упереться в общий потолок, и об этом стоит предупредить людей заранее.
- Ночной процесс получает свой отдельный лимит проекта, и его расход читается отдельной строкой, а не растворяется в расходах людей.
Последний пункт важнее, чем кажется. Когда сводка тратит деньги «через сотрудника», вы не отличаете её расход от ручной работы. Отдельная сущность даёт простой разговор: сводка стоит столько-то в месяц, и руководителю филиала решать, нужна ли она за эти деньги.
Условный расчёт
Возьмём числа для иллюстрации, не из реального проекта. Допустим, у филиала общий месячный лимит 100 условных единиц. Двадцать сотрудников, личный лимит каждого — 8 единиц. Сумма личных — 160, то есть больше общего потолка. Если все выберут лимит целиком, команда упрётся в сто на двенадцатом-тринадцатом человеке. Это не ошибка, а осознанный выбор: либо вы принимаете, что часть людей не дойдёт до личного максимума, либо опускаете личный лимит до 5, чтобы сумма совпала с общей. Ночную сводку при этом можно отделить: у неё свой лимит, скажем 15 единиц, и её работа не зависит от того, как потратили месяц люди.
Тот же расчёт полезно прочитать с другой стороны. Сто единиц минус пятнадцать на сводку — если считать, что лимит сводки выделен отдельно от людей, — оставляют людям восемьдесят пять, а не сто. Тогда при личном лимите 8 команда упрётся в потолок уже примерно на одиннадцатом человеке, а при лимите 5 сумма личных (100) всё равно превысит оставшиеся 85. Значит, вопрос не только в том, какой личный лимит поставить, а из какой доли общего бюджета резервируется работа процесса. Это решение руководителя филиала, и принимать его лучше до первого месяца, а не после первого скандала о том, кто «съел» бюджет.
Есть и вторая сторона. Отдельный лимит проекта защищает людей от сводки так же, как сводку от людей: если в ночном скрипте зациклится вызов, он упрётся в собственный потолок и не заберёт то, что выделено сотрудникам. Но это работает только при подключённой базе, о чём ниже, и только после проверки на тестовом ключе, что потолок действительно срабатывает именно для проектного ключа, а не только для личных.
Обратите внимание на выбор: система из трёх уровней не решает за вас, что важнее — гибкость или предсказуемость. Она лишь даёт рычаги.
Без базы данных лимиты не работают
Есть деталь, о которой легко забыть на этапе проектирования. Согласно той же документации, бюджетные проверки требуют базы данных, а без неё глобальный бюджет не ограничивает запросы. Это значит, что красивая схема лимитов на бумаге превращается в декорацию, если шлюз запущен без подключённой базы. Для филиалов это не абстракция: пробный стенд, который «просто запустили», часто работает без базы, и люди привыкают, что всё идёт. А потом тот же конфиг переезжает в рабочий режим, и обнаруживается, что лимиты никогда не включались.
Поэтому первая проверка после развёртывания звучит приземлённо: создайте тестовый ключ с крошечным бюджетом и убедитесь, что при превышении шлюз действительно отказывает. Не тот ключ, на котором работает сводка, а отдельный пробный. Если запросы идут бесконечно, значит, ограничения не действуют, и дальше обсуждать схему бессмысленно.
Где разместить шлюз и что для него нужно
Шлюз — это обычный сервис, которому нужны процессор, память, диск под базу и стабильный адрес. Для небольшого филиала или пилота на пару команд его можно развернуть на виртуальном сервере. На VPS MAATRIX используются NVMe-диски и процессоры AMD EPYC, есть root-доступ, а предложение включает локации UK, US, RU и FR. Для базы лимитов и журнала расходов именно диск и root-доступ полезны на практике: вы сами решаете, как поставить базу и где хранить конфигурацию шлюза.
Линейка тарифов начинается с Ba (1 vCPU, 2 ГБ RAM, 40 ГБ NVMe) и идёт через Uab (2 vCPU, 4 ГБ, 80 ГБ), Heka (4 vCPU, 8 ГБ, 160 ГБ) и Maat (8 vCPU, 16 ГБ, 240 ГБ) до Djed (16 vCPU, 32 ГБ, 320 ГБ). Для пилота с несколькими командами логично начинать с малого и смотреть на реальную нагрузку: заявленные ресурсы не равны обещанию ёмкости, сколько запросов выдержит шлюз, покажет только замер на вашем трафике. Для самих ключей и бюджетов размер сервера почти не влияет; он станет вопросом, когда вырастет поток запросов.
Если рядом со шлюзом нужны сервисы автоматизации, в каталоге MAATRIX предлагаются n8n и Nextcloud с установкой, а точное наличие и операционная система уточняются в форме заказа. Это удобно, когда ночной процесс собирается не кодом, а сценарием в n8n: тогда и у сценария должен быть проектный ключ, а не ключ того, кто его собрал.
Передача сервиса между командами
Теперь последний поворот. Сводка прожила год, и компания решила, что ей должна заниматься не команда разработки, а аналитики. Формально ничего не ломается: ключ проектный, живёт сам. Но именно в такие моменты доступ превращается в «ничей».
Передача ответственности — это не передача секрета. Секрет может остаться тем же, а вот ответственность нужно перенести явно. Что для этого меняется:
- Запись о владельце. В карте из трёх субъектов меняется ячейка «владелец» у ночного процесса: теперь там команда аналитиков, а не разработчиков.
- Привязка к команде в шлюзе. Если лимиты проекта берутся из команды, нужно решить, какой командой считается сводка после передачи. От этого зависит, чей бюджет она тратит. Проверьте на тестовом ключе, что расход действительно пошёл в новую строку, а не остался на старой.
- Ротация секрета. Старые владельцы знали значение ключа. Если они не должны иметь доступ, выпустите новый проектный ключ, переведите сервис на него и отзовите прежний. Здесь отзыв — полноценное событие, а не побочный эффект чьего-то увольнения.
- Подтверждение работы. Дождитесь очередной ночи и убедитесь, что сводка пришла. Только потом закрывайте передачу.
Одна тонкость. Пока старый и новый ключи оба активны, сервис может случайно продолжить работать на старом: например, в одном из окружений остался прежний конфиг. Поэтому порядок «сначала новый, потом отзыв старого» работает, лишь если вы убедились, что именно новый ключ используется. Расход по ключам в шлюзе — самое простое доказательство.
Полезно заранее решить, как выглядит «достаточное доказательство» в шлюзе. Простой критерий: после переключения расход по новому ключу растёт в ночь прогона, а по старому остаётся неизменным. Если обе строки растут, значит, где-то работают два экземпляра сервиса или осталась копия конфигурации, и отзывать старый ключ рано. Если не растёт ни одна, сервис вообще не дошёл до шлюза, и причина не в ключах, а в самом запуске.
Отдельно проверьте сценарии, где ключ вставлен вручную: сценарий в n8n, планировщик на другом сервере, чья-то локальная копия для отладки. Такие места не видны в карте владельцев, но именно они чаще всего удерживают старый секрет живым. Перед отзывом спросите у новой команды, откуда ещё может приходить трафик, и после отзыва в первую же ночь смотрите на сообщения об отказе: так вы найдёте забытый путь, пока его потеря стоит одной пропущенной сводки, а не нескольких.
Что получает каждый из трёх субъектов
Если собрать описанное в одну картину, получается простое разделение. Сотруднику — личный ключ, привязанный к его роли и к лимиту, с отзывом по кадровому событию. Филиалу — командный бюджет, под которым живут люди, и руководитель, отвечающий за расходы. Ночному процессу — проектный ключ с собственным лимитом, моделью, которая нужна именно ему, и назначенным владельцем-командой.
Не нужно выдавать один секрет на весь филиал, даже если так проще в первую неделю. Общий секрет лишает вас возможности ответить на два самых практичных вопроса: кто это сделал и кого отключать, если ключ утёк. Личный ключ отвечает на первый, проектный — на второй, и отзыв затрагивает ровно тот круг, который должен быть затронут.
Ещё одно предостережение: возможности вроде сервисных ключей и командных бюджетов описаны в документации LiteLLM, но не нужно переносить их на любой другой шлюз. Если вы выбираете или уже используете другой продукт или конкретную редакцию, наличие и поведение таких функций нужно проверять отдельно, не по аналогии.
Возвращаясь к ночной сводке
Сводка, которую читают шесть руководителей, не должна зависеть от того, остался ли в компании её автор. Она существует по решению компании: кто-то счёл её нужной, выделил на неё бюджет и назначил ответственных. Остановить её тоже должно решение компании, а не удаление чужой учётной записи в кадровой системе.
Поэтому в итоге всё сводится к простому разделению: человек приходит и уходит, филиал расходует и пересматривает бюджет, а работа продолжается, пока в ней есть смысл. Ключи в шлюзе стоит выдавать именно по этому порядку: сначала решить, чья это работа, и только потом — кто её исполняет.