Подсчет токенов
Посчитайте токены текста или целого запроса до его отправки.
POST https://api.shannon-ai.com/v1/tokenize
POST https://api.shannon-ai.com/v1/messages/count_tokens
Оба эндпоинта считают токенизатором названной вами модели, и никакая модель при этом не запускается. Они охватывают размещенные модели с открытыми весами. /v1/tokenize принимает простой текст или разговор в формате Chat Completions. /v1/messages/count_tokens принимает запрос в формате Anthropic Messages; именно этот вызов делают Anthropic SDK и Claude Code.
Подсчет бесплатный. Для вызова нужен ваш API-ключ, он ничего не списывает с баланса и не попадает в журнал использования.
Подсчет текста
Отправьте model и text. Текст считается как есть, без форматирования чата вокруг него.
import requests
response = requests.post(
"https://api.shannon-ai.com/v1/tokenize",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"text": "Hello, world",
},
)
print(response.json()["tokens"]) const response = await fetch("https://api.shannon-ai.com/v1/tokenize", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
text: "Hello, world",
}),
});
const { tokens } = await response.json();
console.log(tokens); curl https://api.shannon-ai.com/v1/tokenize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"text": "Hello, world"
}' {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"tokens": 3
} Числа в ответах на этой странице — примеры. Один и тот же текст на другой модели даст другой результат.
Подсчет чат-запроса
Отправьте model и messages, а также tools, если они есть в запросе, точно так же, как вы отправили бы их на /v1/chat/completions. Ответ — размер всего входа.
import requests
request = {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the weather in Paris?"},
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
],
}
response = requests.post(
"https://api.shannon-ai.com/v1/tokenize",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=request,
)
print(response.json()["tokens"]) const request = {
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
messages: [
{ role: "system", content: "You are a concise assistant." },
{ role: "user", content: "What is the weather in Paris?" },
],
tools: [
{
type: "function",
function: {
name: "get_weather",
description: "Current weather for a city",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
},
],
};
const response = await fetch("https://api.shannon-ai.com/v1/tokenize", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify(request),
});
const { tokens } = await response.json();
console.log(tokens); curl https://api.shannon-ai.com/v1/tokenize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the weather in Paris?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}
]
}' {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"tokens": 164
} Поля эндпоинта /v1/tokenize
| Поле | Тип | Описание |
|---|---|---|
model | string | Обязательное. Id размещенной модели с открытыми весами. Регистр не учитывается. |
text | string | Текст, который считается как есть, без форматирования чата. До 4,000,000 байт. Отправьте text или messages; если есть оба, считается text. |
messages | array | Сообщения чата в формате Chat Completions. Они считаются как полный вход запроса: каждое сообщение вместе с форматированием, которое добавляет вокруг него шаблон чата модели. |
tools | array | Определения инструментов, которые нужно включить в подсчет. Используются вместе с messages. |
Ответ — JSON-объект с такими полями:
| Поле | Тип | Описание |
|---|---|---|
model | string | Id модели, для которой выполнен подсчет, в опубликованном написании. |
tokens | integer | Для text: токены текста. Для messages: токены всего входа, включая изображения. |
Подсчет запроса Messages
Отправьте тело, которое вы отправили бы на /v1/messages: model, messages, а также system и tools, если вы их используете. Официальные Anthropic SDK вызывают этот эндпоинт через messages.count_tokens.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
count = client.messages.count_tokens(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system="You are a concise assistant.",
messages=[
{"role": "user", "content": "Summarise the attached report."}
],
)
print(count.input_tokens) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const count = await client.messages.countTokens({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system: "You are a concise assistant.",
messages: [
{ role: "user", content: "Summarise the attached report." },
],
});
console.log(count.input_tokens); curl https://api.shannon-ai.com/v1/messages/count_tokens \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"system": "You are a concise assistant.",
"messages": [
{"role": "user", "content": "Summarise the attached report."}
]
}' {
"input_tokens": 21
} Поля эндпоинта /v1/messages/count_tokens
| Поле | Тип | Описание |
|---|---|---|
model | string | Обязательное. Id размещенной модели с открытыми весами. |
messages | array | Обязательное. Сообщения в формате Anthropic Messages. Подсчитываются блоки text, image, tool_use и tool_result. |
system | string | array | Системный промпт: строка или массив текстовых блоков. |
tools | array | Определения инструментов с name, description и input_schema. |
Принимаются для совместимости и на подсчет не влияют: tool_choice, max_tokens, temperature, top_p, stop_sequences, stream, thinking. Можно передать тело реального запроса без изменений.
Ответ — JSON-объект с такими полями:
| Поле | Тип | Описание |
|---|---|---|
input_tokens | integer | Токены всего входа: системный промпт, сообщения, инструменты и изображения. |
Поддерживаемые модели
Оба эндпоинта считают для размещенных моделей с открытыми весами. GET /v1/models перечисляет /v1/tokenize и /v1/messages/count_tokens в endpoints каждой модели, которая их поддерживает. Любое другое значение model, включая id Shannon, получает ответ 400.
DeepSeek-V4-Pro-0813-3BIT-REAPGLM-5.2-3BIT-REAPKimi-K3-3BIT-REAPNemotron3Ultra-3BIT-REAPMiniMax-M3-3BIT-REAPDeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAPKimi-K2.6-W4A16-AUTOROUND-REAPLaguna-S-2.1-W4A16-AUTOROUND-REAPinkling-W4A16-AUTOROUND-REAPMiMo-V2.5-Pro-W8A16MiMo-V2.5-W8A16Hy3-W8A16
Для модели Shannon читайте число токенов из объекта usage ответа.
Как выполняется подсчет
Каждая модель считается своим токенизатором и своим шаблоном чата. Оценки по символам или словам не используются.
| Что подсчитывается | Правило |
|---|---|
| Текст | Токены строки в том виде, как она отправлена. Пустая строка дает 0. |
| Сообщения | Сообщения и инструменты раскладываются по собственному шаблону чата модели вплоть до места, где начинается ответ, и считается весь этот промпт. |
| Роли | Считаются сообщения system, user, assistant и tool. developer считается как system. Сообщение без контента и без вызова инструмента ничего не добавляет. |
| Вызовы инструментов и результаты | Вызовы инструментов в предыдущих ходах ассистента и их результаты входят в подсчет на обоих эндпоинтах. |
| Изображения | Изображение, отправленное внутри тела (base64 или URL data:), добавляет один токен на каждый участок 28 × 28 пикселей: ceil(width / 28) × ceil(height / 28). Изображение, заданное URL http(s), эти эндпоинты не скачивают, и оно считается как 1,024. |
Пример: изображение 1,024 × 768 пикселей считается как ceil(1024 / 28) × ceil(768 / 28) = 37 × 28 = 1,036 токенов.
Подсчет и то, сколько списывается за запрос
Подсчет всего запроса выполняется так же, как подсчет входа реального запроса с той же моделью, сообщениями и инструментами. Ответ сообщает это число как usage.prompt_tokens в Chat Completions, как usage.input_tokens в Responses и как usage.input_tokens плюс usage.cache_read_input_tokens в Messages.
- Подсчитывается вход до скидки на кэшированный ввод. Реальный запрос может прочитать часть этого входа из кэша и оплатить ее по тарифу кэшированного ввода. Кэширование запросов
- Изображение, заданное URL
http(s), здесь считается как 1,024. Реальный запрос скачивает изображение и считает его по размеру в пикселях, поэтому два числа могут различаться. Отправьте изображение в base64, чтобы получить то же число. - Вывод в подсчет не входит. Ответ реального запроса тарифицируется дополнительно как выходные токены, включая reasoning.
- Подсчет по
textне включает форматирование чата. Используйте его для измерения документа или части промпта, а формуmessages— для измерения запроса.
Чтобы превратить число токенов в стоимость, умножьте его на цену входа модели за 1M токенов. Модели и цены
Лимиты
| Лимит | Значение | При превышении |
|---|---|---|
Длина text | 4,000,000 байт (UTF-8) | 413 с сообщением text too long |
| Тело запроса | 32 MiB | 413 |
| На один запрос | Один текст или один разговор | Чтобы посчитать несколько текстов, отправляйте по одному запросу на текст. |
Вызовы подсчета не входят в лимит 120 запросов в минуту. Лимиты и баланс
Ошибки
| Статус | Тип | Сообщение | Когда |
|---|---|---|---|
400 | invalid_request_error | tokenize is available for the hosted open models; unknown model: <model> | /v1/tokenize с model, который не является id размещенной модели с открытыми весами. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <model> | /v1/messages/count_tokens с model, который не является id размещенной модели с открытыми весами, или без model. |
400 | invalid_request_error | send `text` or `messages` | /v1/tokenize без text и без messages. |
401 | authentication_error | Missing authentication / Invalid API key | Ключ не отправлен или недействителен. |
413 | invalid_request_error | text too long | text длиннее 4,000,000 байт. Тело больше 32 MiB тоже получает ответ 413. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | У запроса нет типа содержимого JSON. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Отсутствует обязательное поле (model на /v1/tokenize, messages на /v1/messages/count_tokens) или у поля неверный тип. |
503 | api_error | token counting is temporarily unavailable for this model | Сейчас подсчет для этой модели выполнить нельзя. Повторите попытку позже. |
/v1/tokenize возвращает ошибки в формате OpenAI. На /v1/messages/count_tokens ошибки самого эндпоинта (400 для модели, 503) приходят в формате Anthropic, а 401, 413, 415 и 422 — в формате OpenAI. Сначала читайте код статуса, затем error.type и error.message, которые есть в обоих форматах.
{
"error": {
"type": "invalid_request_error",
"message": "tokenize is available for the hosted open models; unknown model: shannon-3"
}
} {
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "count_tokens is available for the hosted open models; unknown model: shannon-3"
}
}