Эфир 18.11 · Поток 318 ноября в 19:00 МСК — бесплатный практический эфир по ИИ-агентам · Живой Поток 3 стартует 23.11Эфир 18 ноября →Поток 3 (23.11)
РелизРазбор · На радарHabr AI→ оригинал

Claude Code на GLM-5.3 и Qwen: пять граблей при подмене модели через LiteLLM

Claude Code можно направить на любую модель через ANTHROPIC_BASE_URL, но на практике всё ломается в мелочах. Команда ZuBrIQ поставила между агентами и моделями шлюз на LiteLLM и собрала пять граблей. Самые неприятные из них молчаливые: запрос тихо уходит в резерв, расход показывает ноль, а картинка исчезает без ошибки.

AI-обработка оригинала Habr AI; редакция Hamidun News
Claude Code на GLM-5.3 и Qwen: пять граблей при подмене модели через LiteLLM
Источник: Habr AI. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникHabr AI ↗
Главный редактор
Ключевой факт #1Смотрите заголовок x-litellm-attempted-fallbacks, а не только коды ответов
Ключевой факт #2Цены модели прописывайте в litellm_params, иначе spend будет нулевым
Ключевой факт #3Для Claude Code задайте модели Haiku, Sonnet и Opus, иначе будут 403

Подменить модель под Claude Code проще простого: ANTHROPIC_BASE_URL, токен — и агент шлёт запросы по протоколу Anthropic Messages куда угодно. Проблемы начинаются на второй день. Команда белорусского шлюза ZuBrIQ, где Claude Code официально не работает и платить Anthropic нечем, описала пять граблей, на которые наступила сама.

Схема и главное правило

Между клиентами (Claude Code, Codex, OpenCode, Zed, Cursor) и моделями стоит LiteLLM на двух подах. Клиенты знают только стабильные имена: zubr, zubr-flash, zubr-coder. За каждым — список маршрутов с порядком и резервом: GLM-5.3 у провайдера, DeepSeek V4 Pro как запасной вариант и собственный Qwen3.8-27B на четырёх V100. Сменились веса или упал провайдер — интеграции не замечают. Это удобно, но именно здесь и прячутся тихие поломки.

Три молчаливые поломки

Первая: тихий уход в резерв. GLM-5.3 завели как обычный openai/-бэкенд. Чат работал, а Claude Code и Codex получали ответы от резервной модели. LiteLLM переводит /v1/messages и /v1/responses в Responses API, провайдер отвечает 404, роутер молча идёт дальше. В логах ошибки нет, выдаёт только заголовок x-litellm-attempted-fallbacks: 1. Лечится нативным провайдером LiteLLM для этого вендора, который переводит всё в chat/completions.

Вторая: нулевые расходы. С нативным провайдером LiteLLM не берёт цену из model_info, spend равен нулю, бюджеты ключей не срабатывают, отчёт по марже врёт. Цены нужно продублировать прямо в litellm_params: input_cost_per_token, output_cost_per_token, cache_read_input_token_cost. Ещё нюанс: правка через PATCH /model/{id}/update доезжает до второго пода минуту-две, так что не спешите считать, что не сработало.

Третья: картинки. GLM-5.3 силён в коде, но изображения не принимает. Чат-эндпоинт провайдера отвечает 400, а Anthropic-совместимый эндпоинт молча выбрасывает картинку, и модель уверенно угадывает по тексту. Пользователь кидает скриншот ошибки, а получает рассуждения о том, чего модель не видела. В ZubrCode это обошли: если в каталоге у модели нет зрения, картинку заменяет текстовое описание от GLM-5.3 Flash, а результат кешируется по sha256 картинки, потому что агент переигрывает всю историю на каждом ходе. И отдельный баг каталога: supports_vision: null трактовался как false, и зрение пропало у модели, которая видит.

Конфиг Claude Code и свои GPU

Claude Code сам отправляет служебные подзадачи — заголовки, сжатие контекста, субагентов — моделям классов Haiku, Sonnet и Opus. Если подменить только ANTHROPIC_MODEL, эти запросы упадут с 403 посреди работы. Нужно задать ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL и ANTHROPIC_DEFAULT_HAIKU_MODEL. ANTHROPIC_BASE_URL пишите без /v1, иначе получите /v1/v1/messages. Суффикс [1m] сообщает окно в 1M и отрезается до отправки; для моделей без него окно задаёт CLAUDE_CODE_MAX_CONTEXT_TOKENS.

Своя модель на картах 2017 года — отдельная история. На V100 нет bf16 и FP8, поэтому AWQ INT4 с вычислениями в FP16, vLLM с тензорным параллелизмом на 4 карты и форк с поддержкой SM70. Форк не вычитает веса при расчёте бюджета KV-кеша, поэтому --kv-cache-memory-bytes задаётся явно. Два инстанса нельзя стартовать одновременно: пик инициализации больше 16 ГБ, воркер ловит OOM, а основной зависает на NCCL watchdog, хотя systemd показывает active. Теперь второй юнит ждёт health первого. Плотная 27B вместо MoE 35B-A3B умнее и сама видит картинки, но первый токен приходит за ~1,3 с вместо ~0,6 с, поэтому её держат под фоновые задачи и закрытые данные.

Что делать

Ограничения очевидны: это опыт одной команды, цены в примерах условные, а поведение LiteLLM может измениться между версиями. Но принцип общий. Если вы ставите шлюз между агентом и моделями, мониторьте заголовки fallback, сверяйте расход с реальными счетами провайдера, проверяйте, что происходит с картинкой на каждом маршруте, и прописывайте все три слота Haiku, Sonnet и Opus. Самые дорогие баги здесь не падают с ошибкой, они отвечают уверенно и не теми словами. Шлюз — часть коммерческой платформы авторов, так что статья отчасти рекламная, но технические детали легко проверить на своём стенде.

Сюжет

Вопросы и ответы по материалу

Что известно по теме: схема и главное правило?

Между клиентами (Claude Code, Codex, OpenCode, Zed, Cursor) и моделями стоит LiteLLM на двух подах. Клиенты знают только стабильные имена: zubr, zubr-flash, zubr-coder. За каждым — список маршрутов с порядком и резервом: GLM-5.3 у провайдера, DeepSeek V4 Pro как запасной вариант и собственный Qwen3.8-27B на четырёх V100. Сменились веса или упал провайдер — интеграции не замечают. Это удобно, но именно здесь и прячутся тихие поломки.

Что известно по теме: три молчаливые поломки?

Первая: тихий уход в резерв. GLM-5.3 завели как обычный openai/-бэкенд. Чат работал, а Claude Code и Codex получали ответы от резервной модели. LiteLLM переводит /v1/messages и /v1/responses в Responses API, провайдер отвечает 404, роутер молча идёт дальше. В логах ошибки нет, выдаёт только заголовок x-litellm-attempted-fallbacks: 1. Лечится нативным провайдером LiteLLM для этого вендора, который переводит всё в chat/completions. Вторая: нулевые расходы.

Что известно по теме: конфиг Claude Code и свои GPU?

Claude Code сам отправляет служебные подзадачи — заголовки, сжатие контекста, субагентов — моделям классов Haiku, Sonnet и Opus. Если подменить только ANTHROPIC_MODEL, эти запросы упадут с 403 посреди работы. Нужно задать ANTHROPIC_DEFAULT_OPUS_MODEL, ANTHROPIC_DEFAULT_SONNET_MODEL и ANTHROPIC_DEFAULT_HAIKU_MODEL. ANTHROPIC_BASE_URL пишите без /v1, иначе получите /v1/v1/messages. Суффикс [1m] сообщает окно в 1M и отрезается до отправки; для моделей без него окно задаёт CLAUDE_CODE_MAX_CONTEXT_TOKENS.

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Практика · Hamidun Academy

Соберите рабочего ИИ-агента или сервис своими руками без ручного кода

В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.

Открыть 72ч бесплатный доступ →Интенсив по Вайб-кодингу
Что вы думаете?
Загружаем комментарии…