Reconto de tokens
Conta os tokens dun texto ou dunha solicitude completa antes de enviala.
POST https://api.shannon-ai.com/v1/tokenize
POST https://api.shannon-ai.com/v1/messages/count_tokens
Os dous endpoints contan co tokenizador do modelo que nomeas, e non se executa ningún modelo. Cobren os modelos open-weight alojados. /v1/tokenize acepta un texto simple ou unha conversa de Chat Completions. /v1/messages/count_tokens acepta unha solicitude no formato Anthropic Messages, que é a chamada que fan o SDK de Anthropic e Claude Code.
Contar é gratuíto. Unha chamada necesita a túa clave API, non quita nada do teu saldo e non aparece no teu rexistro de uso.
Contar un texto
Envía model e text. O texto cóntase tal cal, sen formato de chat ao seu redor.
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
} Os números das respostas desta páxina son exemplos. O mesmo texto dá un reconto distinto noutro modelo.
Contar unha solicitude de chat
Envía model e messages, con tools cando a solicitude os ten, exactamente como os enviarías a /v1/chat/completions. A resposta é o tamaño de toda a entrada.
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
} Campos de /v1/tokenize
| Campo | Tipo | Descrición |
|---|---|---|
model | string | Obrigatorio. Un id de modelo open-weight alojado. As maiúsculas e minúsculas trátanse igual. |
text | string | Un texto para contar tal cal, sen formato de chat. Ata 4,000,000 bytes. Envía text ou messages; cando están presentes os dous, cóntase text. |
messages | array | Mensaxes de chat no formato Chat Completions. Contanse como a entrada completa dunha solicitude: cada mensaxe co formato que o modelo de chat do modelo pon ao seu redor. |
tools | array | Definicións de ferramentas que incluír no reconto. Úsanse xunto con messages. |
A resposta é un obxecto JSON con estes campos:
| Campo | Tipo | Descrición |
|---|---|---|
model | string | O id do modelo para o que se fixo o reconto, na súa grafía publicada. |
tokens | integer | Con text: os tokens do texto. Con messages: os tokens de toda a entrada, imaxes incluídas. |
Contar unha solicitude de Messages
Envía o corpo que enviarías a /v1/messages: model, messages, e system e tools cando os uses. Os SDK oficiais de Anthropic chaman a este endpoint mediante 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
} Campos de /v1/messages/count_tokens
| Campo | Tipo | Descrición |
|---|---|---|
model | string | Obrigatorio. Un id de modelo open-weight alojado. |
messages | array | Obrigatorio. Mensaxes no formato Anthropic Messages. Contanse os bloques text, image, tool_use e tool_result. |
system | string | array | O system prompt: unha cadea ou unha matriz de bloques de texto. |
tools | array | Definicións de ferramentas con name, description e input_schema. |
Aceptados por compatibilidade, sen efecto no reconto: tool_choice, max_tokens, temperature, top_p, stop_sequences, stream, thinking. Podes pasar o corpo dunha solicitude real sen cambios.
A resposta é un obxecto JSON con estes campos:
| Campo | Tipo | Descrición |
|---|---|---|
input_tokens | integer | Os tokens de toda a entrada: system prompt, mensaxes, ferramentas e imaxes. |
Modelos admitidos
Os dous endpoints contan para os modelos open-weight alojados. GET /v1/models lista /v1/tokenize e /v1/messages/count_tokens nos endpoints de cada modelo que os admite. Calquera outro valor de model, incluídos os ids de Shannon, recibe 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
Para un modelo Shannon, le os recontos de tokens do obxecto usage dunha resposta.
Como se fai o reconto
Cada modelo cóntase co seu propio tokenizador e o seu propio modelo de chat. Non se usa ningunha estimación a partir de caracteres ou palabras.
| Que se conta | Regra |
|---|---|
| Un texto | Os tokens da cadea tal como se envía. Unha cadea baleira conta 0. |
| Mensaxes | As mensaxes e as ferramentas dispóñense co modelo de chat propio do modelo, ata o punto no que comeza a resposta, e todo ese prompt cóntase. |
| Roles | Contanse as mensaxes system, user, assistant e tool. developer cóntase como system. Unha mensaxe sen contido nin chamada a unha ferramenta non engade nada. |
| Chamadas a ferramentas e resultados | As chamadas a ferramentas de turnos anteriores do asistente e os seus resultados forman parte do reconto, nos dous endpoints. |
| Imaxes | Unha imaxe enviada dentro do corpo (base64 ou unha URL data:) engade un token por cada parche de 28 × 28 píxeles: ceil(width / 28) × ceil(height / 28). Unha imaxe dada como URL http(s) non a descargan estes endpoints e conta 1,024. |
Exemplo: unha imaxe de 1,024 × 768 píxeles conta ceil(1024 / 28) × ceil(768 / 28) = 37 × 28 = 1,036 tokens.
O reconto e o que se cobra por unha solicitude
O reconto dunha solicitude completa faise da mesma maneira que o reconto de entrada dunha solicitude real co mesmo modelo, mensaxes e ferramentas. Unha resposta informa ese número como usage.prompt_tokens en Chat Completions, como usage.input_tokens en Responses e como usage.input_tokens máis usage.cache_read_input_tokens en Messages.
- O reconto é a entrada antes do desconto da entrada en caché. Unha solicitude real pode ler parte desa entrada da caché e facturar esa parte á tarifa de caché. Caché de prompts
- Unha imaxe dada como URL
http(s)conta 1,024 aquí. Unha solicitude real descarga a imaxe e cóntaa polo seu tamaño en píxeles, así que os dous números poden diferir. Envía a imaxe en base64 para obter o mesmo número. - A saída non forma parte do reconto. A resposta dunha solicitude real factúrase ademais como tokens de saída, razoamento incluído.
- Un reconto de
textnon ten formato de chat. Úsao para medir un documento ou unha parte dun prompt, e a formamessagespara medir unha solicitude.
Para converter un reconto en custo, multiplícao polo prezo de entrada do modelo por 1M de tokens. Modelos e prezos
Límites
| Límite | Valor | Por riba |
|---|---|---|
Lonxitude de text | 4,000,000 bytes (UTF-8) | 413 coa mensaxe text too long |
| Corpo da solicitude | 32 MiB | 413 |
| Por solicitude | Un texto ou unha conversa | Envía unha solicitude por texto para contar varios textos. |
As chamadas de reconto non contan para o límite de 120 solicitudes por minuto. Límites e saldo
Erros
| Estado | Tipo | Mensaxe | Cando |
|---|---|---|---|
400 | invalid_request_error | tokenize is available for the hosted open models; unknown model: <model> | /v1/tokenize cun model que non é un id de modelo open-weight alojado. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <model> | /v1/messages/count_tokens cun model que non é un id de modelo open-weight alojado, ou sen model. |
400 | invalid_request_error | send `text` or `messages` | /v1/tokenize sen text nin messages. |
401 | authentication_error | Missing authentication / Invalid API key | Non se enviou ningunha clave, ou a clave non é válida. |
413 | invalid_request_error | text too long | text ten máis de 4,000,000 bytes. Un corpo de máis de 32 MiB tamén recibe 413. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | A solicitude non ten un tipo de contido JSON. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Falta un campo obrigatorio (model en /v1/tokenize, messages en /v1/messages/count_tokens) ou un campo ten o tipo incorrecto. |
503 | api_error | token counting is temporarily unavailable for this model | O reconto non se pode facer para este modelo neste momento. Téntao de novo máis tarde. |
/v1/tokenize devolve erros coa forma de OpenAI. En /v1/messages/count_tokens, os erros do propio endpoint (400 polo modelo, 503) veñen coa forma de Anthropic, e 401, 413, 415 e 422 veñen coa forma de OpenAI. Le primeiro o código de estado e despois error.type e error.message, que están presentes nas dúas formas.
{
"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"
}
}