← Все статьи
Новости12 мин чтения

z ai api и совместимость GLM: как изолировать контракт в адаптере

Разобрали, почему за z ai api скрываются три разных base URL и модельно-зависимые поля GLM, и как контрактные тесты показывают, что выносить в адаптер.

Обложка статьи: z ai api и совместимость GLM: как изолировать контракт в адаптере

Ты выяснил, что за строкой z ai api стоит Zhipu и модельная линейка GLM. Это меньше половины работы. Идентифицировать владельца эндпоинта - значит закрыть вопрос «чей это API», но не вопрос «как его особенности не прорастут в мой прикладной код». Именно на втором шаге интеграция ломается тихо: синтаксис совместим с OpenAI, тесты локально зелёные, а поведение на границе поставщика отличается от того, что ты заложил в домен.

Это разбор контракта, а не обзор сервиса. Дальше три вещи по порядку: развести идентификацию поставщика и поведенческий контракт, показать три типа контрактного теста для одного сценария, объяснить, где проходит граница адаптера. Всё ниже опирается на официальную документацию Z.AI на 18 июля 2026 - адаптерного кода и логов прогона у меня пока нет, есть метод и документированная поверхность API.

Умолчание, из-за которого горят сроки, звучит так: «совместимый синтаксис гарантирует одинаковое поведение». Не гарантирует. Ниже - конкретные места, где документация расходится с ожиданиями от OpenAI-совместимого клиента, и метод, который вылавливает их до релиза, а не в проде. Оговорка для тех, кто ещё выбирает поставщика: если возиться с регионами и планами не хочется вовсе, provod.ai (российский аналог OpenRouter) отдаёт один совместимый маршрут сразу к нескольким моделям - но адаптер и тесты всё равно писать тебе, ровно по тем же причинам.

Платите в рублях за AI-модели без наценки на токены через provod.ai

Почему знать владельца z ai api - это только полдела?

Разработчик, который дошёл до этой статьи, обычно уже прошёл этап идентификации. Он видел запросы вроде glm ai api, zhipu ai api и понял, что это один и тот же поставщик под разными именами: Z.AI как международный бренд, Zhipu (BigModel) как исходное имя, GLM как семейство моделей. Знание полезное, но оно отвечает на вопрос «кто», а прикладной риск живёт в вопросе «как».

Скрытая связанность проникает в код незаметно. Ты пишешь обработчик ответа, который читает reasoning_content, потому что видел его в одном ответе. Ты ловишь ошибку и парсишь её как error.message, по привычке от OpenAI. Ты хардкодишь один base URL, потому что первый же запрос прошёл. Каждое из этих решений связывает доменную логику с конкретным поведением GLM-клиента, и ни одно из них не видно из синтаксиса запроса. Через полгода Z.AI меняет умолчание для новой версии модели, и падает не клиент, а бизнес-правило где-то в глубине домена.

Правило, которого я держусь: доменная логика не должна знать имя поставщика. Она формулирует намерение - «дай ответ по этому промпту, обработай отказ» - а перевод намерения в диалект Z.AI живёт в одном изолированном месте. Это не факт из документации, а инженерная ставка. Ставку надо проверять тестами, а не декларировать.

Какой именно endpoint? Три URL для одного аккаунта

Первое, что ломает наивную интеграцию, - предположение, что у z ai api один адрес. Его нет. По документации Z.AI на 18 июля 2026 общий эндпоинт чат-комплишенов - это POST https://api.z.ai/api/paas/v4/chat/completions с заголовком Authorization: Bearer YOUR_API_KEY. Но официальный Python-SDK (zai-org/z-ai-sdk-python) не задаёт единого base URL по умолчанию: разработчик обязан явно выбрать между зарубежным https://api.z.ai/api/paas/v4/ и материковым https://open.bigmodel.cn/api/paas/v4/. То есть «эндпоинт» без указания региона - это не один подтверждённый факт, а два.

Третий адрес появляется отдельно. Подписки GLM Coding Plan используют выделенные base URL, отличные от общего: https://api.z.ai/api/coding/paas/v4 в стиле OpenAI Chat Completions и https://api.z.ai/api/anthropic в стиле Anthropic Messages. Ключи Coding Plan привязаны к своей экосистеме и не работают против общего /api/paas/v4. Все три варианта пришлось собирать с трёх разных официальных страниц: ни одна не сводит их вместе. Сверку делаешь ты сам, до первого теста.

Вопрос «какой url» задают так часто, что он доходит даже в сломанной раскладке - rfrjq url api z ai. Корректный ответ на него один и тот же: зависит от типа аккаунта и региона. Ошибка здесь дорогая не потому, что её трудно найти, а потому, что она всплывает на шаге, где всё уже выглядело готовым к запуску.

Про z ai api free честно: тарифы, пороги квот и бесплатные лимиты проверенные источники этого материала не покрывают. Проверенного числа у меня нет, а выдумывать его я не стану - смотри актуальные условия на день интеграции.

Маршрутная схема: один аккаунт Z.AI и три разных base URL в зависимости от региона и плана.

Три контрактных теста: обычный ответ, ошибка, конфигурация

Метод, который я предлагаю, - контрактный набор по формуле «сценарий - ожидание - адаптер - наблюдение». Берём один GLM-сценарий и пишем для него три теста разной природы: на обычный ответ, на ошибку, на модельную конфигурацию. Смысл не в покрытии всех кейсов, а в том, чтобы закреплённые ожидания показали, какие части клиента переносимы, а какие нужно держать локально.

Тест на ошибку - самый показательный, потому что здесь совместимость с OpenAI обманывает первой. По официальной справке ответ об ошибке у Z.AI - это плоский объект {code, message}, структурно отличный от вложенного error у OpenAI. Плюс проприетарная числовая таксономия кодов, привязанная к HTTP-статусам: 1000/1001/1003 - сбои аутентификации, 1211 - неизвестная модель, 1213 - отсутствует обязательный параметр, 1302 - превышен лимит запросов, 1305 - временная перегрузка. Контрактный тест должен целиться в эти коды явно, а не выводить их из привычек OpenAI. Если у тебя нет теста ошибки - у тебя нет контракта, есть только надежда.

# GLM-клиент: перевод сырого ответа Z.AI в доменную ошибку def map\_error(status: int, body: dict) -> DomainError: code = body.get("code")          # плоский {code, message}, не error.\* message = body.get("message", "") if code in (1000, 1001, 1003): return AuthError(message)     # ключ/аутентификация if code == 1211: return BadModelError(message) # неизвестная модель if code == 1213: return BadRequestError(message) if code in (1302, 1305): return TemporaryError(message)  # лимит или перегрузка -> ретрай return DomainError(message)

Тест на обычный ответ фиксирует не «пришло 200», а форму полезной нагрузки. Здесь важна тонкость: поле reasoning_content документировано как поддерживаемое конкретно серией GLM-4.5. Значит, его присутствие в «нормальном ответе» - свойство модели, а не гарантия общего эндпоинта. Если доменный код рассчитывает на это поле всегда, он привязан к одной серии моделей, и эта привязка не видна из синтаксиса. Тест закрепляет: при модели X поле есть, при модели Y его может не быть, обработчик обязан пережить оба случая.

Сравнительная таблица: вложенный объект error у OpenAI против плоского {code, message} и числовых кодов у Z.AI.

Где проходит граница адаптера?

Дальше решение, ради которого всё затевалось: что именно изолировать. Сразу оговорюсь - деление на «переносимое» и «локальное» Z.AI нигде не публикует, это моя классификация. Документация даёт поверхность, границу проводит инженер. Таблица ниже - гипотеза, которую контрактный тест на твоём сценарии подтвердит или опровергнет, а не универсальная истина.

Логика границы такая. В адаптер уходит всё, что можно выразить как общий контракт: выбор base URL по региону и плану, форма заголовка авторизации, перевод сырой ошибки в доменный тип. В GLM-клиенте остаётся всё, что несёт семантику конкретного поставщика и меняется по версиям: поля рассуждений, модельные умолчания, числовые коды. Домен не должен видеть ни code: 1211, ни reasoning_content - он видит BadModelError и «ответ готов».

ЭлементКуда относитсяПочему
Выбор base URL (регион, Coding Plan)Адаптерконфигурация маршрута, не доменное правило
z ai api key в заголовке BearerАдаптерформа аутентификации переносима
Перевод {code, message} в доменную ошибкуАдаптердомен знает тип, не число
Поля thinking / clear_thinkingGLM-клиентнет эквивалента в схеме OpenAI
reasoning_effort и его ремаппингGLM-клиентсемантика зависит от версии модели
Наличие reasoning_contentGLM-клиентсвойство серии GLM-4.5

У границы адаптера есть дешёвая проверка на прочность: если она проведена верно, к адаптеру подключается второй совместимый маршрут, а домен этого не замечает. provod.ai для такой проверки удобен тем, что говорит на SDK OpenAI и Anthropic: меняешь ключ и base_url, код не переписываешь. Но ловушка ровно та же, что с GLM - совпадение по SDK не доказывает совпадение по поведению, поэтому второй маршрут гоняется через тот же контрактный набор независимо.

# Тот же адаптер, другой совместимый маршрут - проверяется отдельными тестами client = OpenAI( api\_key=os.environ["PROVOD\_KEY"], base\_url="https://api.provod.ai/v1", ) # домен по-прежнему не знает имени поставщика
Таблица-решение: переносимые элементы в адаптере против модельно-зависимых в GLM-клиенте.

Один параметр, разные смыслы: модельная конфигурация

Третий контрактный тест - на конфигурацию модели - вскрывает самое коварное. Даже одно и то же имя параметра не несёт одинаковой семантики по линейке GLM. По документации Z.AI reasoning_effort поддерживается только на GLM-5.2, причём с объявленным внутренним ремаппингом значений: low/medium превращаются в high, none/minimal выключают режим размышления, xhigh становится max. То есть ты передаёшь low, рассчитывая на экономный режим, а получаешь high. Это не баг, это документированное поведение, и оно не видно из синтаксиса запроса.

Дальше - умолчания. Поведение размышления по умолчанию различается по версии: GLM-5.2, GLM-5.1, GLM-5, GLM-5-Turbo, GLM-5V-Turbo, GLM-4.6 и GLM-4.5 сами решают, думать ли, тогда как GLM-4.7 и GLM-4.5V думают принудительно по умолчанию. Плюс GLM-специфичные поля запроса: объект thinking со значениями type: "enabled" | "disabled" и флаг clear_thinking (по умолчанию true), который отбрасывает reasoning_content предыдущего хода перед отправкой контекста модели. Ни thinking, ни clear_thinking не имеют эквивалента в стандартной схеме чат-комплишенов OpenAI. Всё это - конфигурационные расхождения, которые обязаны жить в GLM-клиенте и никогда не всплывать в домене.

Отсюда следует неприятное для планирования свойство: такой контракт живёт на версии и дате, а не «навсегда». В документации на 18 июля 2026 сосуществуют версии от GLM-4.5 до GLM-5.2, и именно версионно-зависимые умолчания меняются быстрее всего. Поэтому в тесте конфигурации имя модели стоит фиксировать явно - иначе при следующем обновлении линейки он останется зелёным, проверяя уже не то, что ты имел в виду.

Схема ремаппинга reasoning_effort и разделение версий GLM по поведению размышления по умолчанию.

Как это применить у себя: шаги

  1. Определи свой тип аккаунта и регион, затем зафиксируй ровно один base URL из трёх. Общий зарубежный, общий материковый (Zhipu/BigModel) или Coding Plan - это разные контракты, и ключ одного не работает против другого.
  2. Заведи z ai api key в заголовок Bearer внутри адаптера, а не в доменном коде. Домен не должен уметь конструировать запрос руками.
  3. Напиши тест ошибки первым. Замокай ответы с кодами 1000, 1211, 1213, 1302, 1305 и проверь, что каждый переводится в свой доменный тип из плоского {code, message}.
  4. Напиши тест обычного ответа так, чтобы он проходил и при наличии reasoning_content, и без него. Привязка к серии GLM-4.5 не должна течь в домен.
  5. Напиши тест конфигурации: передай reasoning_effort: "low" на GLM-5.2 и закрепи, что клиент осознаёт ремаппинг в high. Зафиксируй умолчание размышления для конкретной версии, которую ты используешь.
  6. Прогони тот же набор против любого другого совместимого маршрута отдельно. Совпадение SDK - не совпадение поведения.

Чего этот подход не решает

Контрактный адаптер не доказывает, что GLM ведёт себя как любой другой совместимый API. Он показывает только, где формы расходятся, - и то в тех местах, куда ты догадался прицелиться тестом. Пороги лимитов, retry-after и цены сюда не входят: коды 1302 и 1305 документированы как категории, а не как числа, и проверенных значений у меня нет.

Главное ограничение я уже назвал в начале, но повторю в конце: это метод к исполнению, а не отчёт о выполненном прогоне. Всё выше - документированная поверхность API на 18 июля 2026. Ценность метода проверяется на твоём сценарии, не на моём.

FAQ

Это один и тот же поставщик - Z.AI, Zhipu, GLM?

По официальной документации Z.AI - международный бренд, материковый маршрут ведёт на Zhipu/BigModel (open.bigmodel.cn), GLM - семейство моделей. За названиями glm ai api и zhipu ai api стоит та же вендор-поверхность, но контракт всё равно проверяется по своему эндпоинту.

Какой base URL брать по умолчанию?

Умолчания нет. SDK требует явного выбора региона, а Coding Plan использует отдельные адреса. Поэтому выбор endpoint - решение, которое принимается до первого запроса, а не подбирается по ходу.

Почему нельзя парсить ошибку как у OpenAI?

Потому что у Z.AI ошибка - плоский {code, message} с числовой таксономией, а не вложенный error. Тест ошибки ловит это первым.

Есть ли бесплатный доступ?

Бесплатные лимиты и тарифы (z ai api free) в проверенные источники этого материала не входили, поэтому подтвердить их я не могу. Смотри актуальную документацию Z.AI на день интеграции.

Итоговое решение простое и проверяемое: планируй GLM-интеграцию через контрактный адаптер и не привязывай доменную логику к имени поставщика. Часть контракта считается переносимой только после того, как закреплённые ожидания совпали - до этого у тебя гипотеза, а не карта. Начальная работа над адаптером окупается тем, что будущая смена контракта локализуется в одном месте, а не расползается по продукту.

provod.ai - один совместимый API к нескольким моделям с рублёвой оплатой из России.

provod.ai — один API для привычных AI-инструментов

Подключайте клиенты, агентов, IDE, SDK, библиотеки и приложения с поддержкой OpenAI-совместимого API: во многих случаях достаточно заменить базовый URL и ключ без изменения прикладного кода.

В одном каталоге — актуальные модели для текста и медиа: GPT от OpenAI, Claude от Anthropic, Gemini от Google, Grok от xAI, DeepSeek, Qwen, GLM, Kimi и MiniMax; для изображений — Nano Banana 2 Pro и GPT Image; для видео — последние версии Seedance, Kling, Veo и Google Omni. Также доступны модели для reasoning, поиска, документов, эмбеддингов, музыки и аудио.

Широкая совместимость не оплачивается отдельной наценкой: тарифы моделей остаются на уровне официальных провайдеров 1:1, а расчёты объединяются в рублёвом балансе.

Подключите привычный инструмент к provod.ai: миграция OpenAI SDK · форма регистрации · цены на модели · защита данных по 152-ФЗ

Источники

  • Z.AI Developer Documentation, Quick Start - https://docs.z.ai/guides/overview/quick-start (обращение 2026-07-18).
  • Z.AI Developer Documentation, API Codes - https://docs.z.ai/api-reference/api-code (обращение 2026-07-18).
  • Z.AI Developer Documentation, Chat Completion - https://docs.z.ai/api-reference/llm/chat-completion (обращение 2026-07-18).
  • Z.AI Developer Documentation, Coding Plan Quick Start - https://docs.z.ai/devpack/quick-start (обращение 2026-07-18).
  • Z.AI (zai-org) GitHub, z-ai-sdk-python - https://github.com/zai-org/z-ai-sdk-python (обращение 2026-07-18).