Claude через /v1/messages или /v1/chat/completions: что будет с кэшем

Claude отвечает в обоих форматах, но скидку за кэш даёт только Anthropic-формат. Расчёт разницы и инструкция по переключению кода и инструментов.

5 мин · · экономия · разработка

Многие подключают Claude API через OpenAI-совместимый формат: SDK уже стоит, код написан под chat.completions, менять ничего не хочется. Это работает, но для Claude у такого подключения есть цена — кэш промптов в нём не учитывается. Разберём, где разница существенна, сколько она стоит в деньгах и как перевести на Anthropic-формат свой код и инструменты.

Два формата, один ключ

Zukko принимает запросы в двух форматах:

  • OpenAI-совместимый — POST https://api.zukko.pro/v1/chat/completions (а также /v1/responses);
  • Anthropic-совместимый — POST https://api.zukko.pro/v1/messages.

Ключ fetch_... и баланс общие. Любую модель можно вызвать в любом формате — шлюз конвертирует запрос и ответ. Разница не в том, какие модели доступны, а в том, как считается кэш.

Claude API в OpenAI-совместимом формате: что с кэшем

Правило короткое:

  • в Anthropic-формате (/v1/messages, Claude Code, Anthropic SDK) шлюз видит, сколько входа пришло из кэша, и считает эти токены по цене чтения кэша;
  • в OpenAI-формате (/v1/chat/completions) для Claude весь вход идёт по цене входа.

Для коротких разовых запросов разницы нет: кэшировать там нечего. Она появляется там, где из запроса в запрос повторяется длинное начало — у агентов, ботов с большой инструкцией, при работе с одним и тем же документом.

Сколько это стоит

Шаг агента на claude-sonnet-5: контекст 100 000 токенов, из них 95 000 — повторяющееся начало, 5 000 — новое, ответ 2 000 токенов. Цены Zukko за 1 млн токенов: вход $0.2, чтение кэша $0.025, выход $1.013.

Через /v1/messages, если начало прочитано из кэша:

(95 000 × 0.025 + 5 000 × 0.2 + 2 000 × 1.013) / 1 000 000 = (2 375 + 1 000 + 2 026) / 1 000 000 = $0.005401

Через /v1/chat/completions весь вход по цене входа:

(100 000 × 0.2 + 2 000 × 1.013) / 1 000 000 = (20 000 + 2 026) / 1 000 000 = $0.022026

На 200 таких шагах: $1.0802 против $4.4052. Расчёт упрощён: в реальной сессии часть шагов ещё и записывает в кэш новые куски контекста, запись у Claude Sonnet 5 стоит $0.25 за миллион. Точную картину покажет поле usage в ответах и раздел «Использование» в кабинете. Полная формула с записью и чтением — в статье о том, как считаются чтение и запись кэша.

Как переключить свой код на Anthropic SDK

Было — OpenAI SDK:

bash
from openai import OpenAI

client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")

resp = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": question},
    ],
)
print(resp.choices[0].message.content)

Стало — Anthropic SDK (pip install anthropic):

bash
import anthropic

client = anthropic.Anthropic(base_url="https://api.zukko.pro", api_key="fetch_ваш_ключ")

resp = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=2048,
    system=[{
        "type": "text",
        "text": SYSTEM_PROMPT,
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": question}],
)
print("".join(block.text for block in resp.content if block.type == "text"))
print("из кэша:", resp.usage.cache_read_input_tokens,
      "записано:", resp.usage.cache_creation_input_tokens)

Что меняется:

  1. Base URL без /v1 — Anthropic SDK сам добавляет /v1/messages.
  2. Системный промпт — отдельный параметр system, а не сообщение с ролью system.
  3. max_tokens обязателен.
  4. Ответ — список блоков content, текст собирается из блоков типа text.
  5. Метка кэша — cache_control на постоянной части. Без неё в своём коде кэш не сработает. Минимальная длина кэшируемого префикса по документации Anthropic — 1 024 токена для Claude Sonnet 5 и 512 для Claude Opus 5.5.

Если в коде есть вызов инструментов (function calling), переносить придётся и его: в Anthropic-формате вызовы и результаты инструментов — это блоки tool_use и tool_result внутри сообщений, а не отдельные поля. Это самая трудоёмкая часть миграции; начните с тех вызовов, где контекст длинный и повторяется.

Проверить без SDK можно через curl:

bash
curl https://api.zukko.pro/v1/messages \
  -H "Authorization: Bearer fetch_ваш_ключ" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 512,
    "messages": [{"role": "user", "content": "Привет"}]
  }'

Как переключить инструменты

ИнструментФормат для ClaudeBase URL
Claude CodeAnthropichttps://api.zukko.pro
Roo Codeпровайдер Anthropic, включить Use custom base URLhttps://api.zukko.pro
OpenCodeпровайдер anthropichttps://api.zukko.pro/v1
Cline, Kilo Codeв нашей инструкции — OpenAI Compatiblehttps://api.zukko.pro/v1
Cursorтолько OpenAI-форматhttps://api.zukko.pro/v1

Claude Code уже работает в Anthropic-формате и сам расставляет метки кэша. Нужны две переменные: ANTHROPIC_BASE_URL=https://api.zukko.pro и ANTHROPIC_AUTH_TOKEN=fetch_... (именно AUTH_TOKEN).

OpenCode подключается через провайдера anthropic, но адрес здесь с /v1 — без него запросы уходят на /messages и получают 404. Пример конфига — в инструкции для OpenCode.

Roo Code — провайдер Anthropic, ключ fetch_..., включённый Use custom base URL и адрес без /v1. Если нужной модели нет в списке этого провайдера, остаётся OpenAI Compatible — и тогда вход Claude без скидки за кэш. Пошагово — в инструкции для расширений VS Code.

Cline в нашей инструкции подключён через OpenAI Compatible. В документации Cline есть и провайдер Anthropic с опцией Use custom base URL; выбирать модель там нужно из его списка. Если вы пробуете этот путь, адрес указывайте без /v1, как в Roo Code, а при 404 проверьте суффикс.

Cursor и Kilo Code в нашей схеме работают через OpenAI-формат. Claude в них доступен, но длинный контекст оплачивается по полной цене входа.

У GPT кэш виден в обоих форматах

Для моделей GPT выбор формата на кэш не влияет. В OpenAI-формате число прочитанных из кэша токенов приходит в usage.prompt_tokens_details.cached_tokens и учитывается по цене чтения. Запись в кэш у GPT отдельно не списывается: первый запрос целиком идёт по цене входа. Через /v1/messages кэш GPT тоже учитывается. Поэтому GPT-модели в инструментах, которые умеют только OpenAI-формат, кэш не теряют.

Если инструмент умеет только OpenAI-формат, а контексты длинные, сравните на своих задачах Claude и, например, gpt-6.1-sol: прогоните одинаковую задачу и посмотрите итог в разделе «Использование». Вывод о качестве делайте по своим результатам, а не по названию модели. Подробнее о форматах — в разделе документации «Выбор провайдера».

Как убедиться, что скидка работает

  1. Отправьте один и тот же длинный запрос в Anthropic-формате дважды с интервалом меньше пяти минут.
  2. В первом ответе cache_creation_input_tokens больше нуля, во втором — cache_read_input_tokens.
  3. Сравните заголовок X-Zukko-Cost-Micros (стоимость запроса в микродолларах, есть у обычных, не потоковых ответов) у двух запросов.

Если ключа ещё нет, создайте его на странице API-ключей — один ключ работает в обоих форматах. Актуальный список моделей и цены — GET https://api.zukko.pro/v1/models или страница «Модели» в кабинете.

Частые вопросы

Работает ли Claude через /v1/chat/completions вообще?

Да. Запрос и ответ корректные, просто для Claude в этом формате весь вход считается по цене входа, без скидки за кэш.

Почему у Anthropic SDK адрес без /v1, а у OpenCode с /v1?

Anthropic SDK и Claude Code сами добавляют /v1 к адресу. Провайдер anthropic в OpenCode этого не делает, поэтому суффикс указывают вручную.

Нужен ли заголовок anthropic-version?

SDK ставят его сами. В ручных запросах через curl добавляйте anthropic-version: 2023-06-01.

Можно ли вызывать GPT через /v1/messages?

Да, шлюз конвертирует формат для любой модели. Чтение кэша GPT учитывается и там, и в /v1/chat/completions.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.