Liczenie tokenów
Policz tokeny tekstu lub całego zapytania, zanim je wyślesz.
POST https://api.shannon-ai.com/v1/tokenize
POST https://api.shannon-ai.com/v1/messages/count_tokens
Oba endpointy liczą tokenizerem wskazanego modelu i żaden model się nie uruchamia. Obejmują hostowane modele open-weight. /v1/tokenize przyjmuje zwykły tekst albo rozmowę Chat Completions. /v1/messages/count_tokens przyjmuje zapytanie w formacie Anthropic Messages, czyli wywołanie, które wykonują SDK Anthropic i Claude Code.
Liczenie jest bezpłatne. Wywołanie wymaga Twojego klucza API, nic nie pobiera z salda i nie pojawia się w dzienniku użycia.
Policz tekst
Wyślij model i text. Tekst jest liczony taki, jaki jest, bez formatowania czatu wokół niego.
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
} Liczby w odpowiedziach na tej stronie to przykłady. Ten sam tekst daje inną liczbę w innym modelu.
Policz zapytanie czatu
Wyślij model i messages, z tools, jeśli zapytanie je ma, dokładnie tak, jak wysłałbyś je do /v1/chat/completions. Odpowiedzią jest rozmiar całego wejścia.
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
} Pola /v1/tokenize
| Pole | Typ | Opis |
|---|---|---|
model | string | Wymagane. Id hostowanego modelu open-weight. Wielkie i małe litery są traktowane tak samo. |
text | string | Tekst do policzenia takim, jaki jest, bez formatowania czatu. Do 4,000,000 bajtów. Wyślij text albo messages; gdy są oba, liczony jest text. |
messages | array | Wiadomości czatu w formacie Chat Completions. Są liczone jako pełne wejście zapytania: każda wiadomość z formatowaniem, które szablon czatu modelu umieszcza wokół niej. |
tools | array | Definicje narzędzi do uwzględnienia w liczbie. Używane razem z messages. |
Odpowiedź to obiekt JSON z tymi polami:
| Pole | Typ | Opis |
|---|---|---|
model | string | Id modelu, dla którego policzono, w opublikowanym zapisie. |
tokens | integer | Z text: tokeny tekstu. Z messages: tokeny całego wejścia, z obrazami włącznie. |
Policz zapytanie Messages
Wyślij treść, którą wysłałbyś do /v1/messages: model, messages oraz system i tools, jeśli ich używasz. Oficjalne SDK Anthropic wywołują ten endpoint przez 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
} Pola /v1/messages/count_tokens
| Pole | Typ | Opis |
|---|---|---|
model | string | Wymagane. Id hostowanego modelu open-weight. |
messages | array | Wymagane. Wiadomości w formacie Anthropic Messages. Liczone są bloki text, image, tool_use i tool_result. |
system | string | array | Prompt systemowy: ciąg znaków albo tablica bloków tekstu. |
tools | array | Definicje narzędzi z name, description i input_schema. |
Akceptowane dla zgodności, bez wpływu na liczbę: tool_choice, max_tokens, temperature, top_p, stop_sequences, stream, thinking. Możesz przekazać treść prawdziwego zapytania bez zmian.
Odpowiedź to obiekt JSON z tymi polami:
| Pole | Typ | Opis |
|---|---|---|
input_tokens | integer | Tokeny całego wejścia: prompt systemowy, wiadomości, narzędzia i obrazy. |
Obsługiwane modele
Oba endpointy liczą dla hostowanych modeli open-weight. GET /v1/models wymienia /v1/tokenize i /v1/messages/count_tokens w endpoints każdego modelu, który je obsługuje. Każda inna wartość model, w tym id Shannon, dostaje odpowiedź 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
Dla modelu Shannon odczytaj liczby tokenów z obiektu usage odpowiedzi.
Jak powstaje liczba
Każdy model jest liczony własnym tokenizerem i własnym szablonem czatu. Nie używa się szacunku ze znaków ani ze słów.
| Co jest liczone | Reguła |
|---|---|
| Tekst | Tokeny ciągu znaków w wysłanej postaci. Pusty ciąg liczy się jako 0. |
| Wiadomości | Wiadomości i narzędzia są układane według własnego szablonu czatu modelu, aż do miejsca, w którym zaczyna się odpowiedź, i cały ten prompt jest liczony. |
| Role | Liczone są wiadomości system, user, assistant i tool. developer jest liczone jako system. Wiadomość bez treści i bez wywołania narzędzia niczego nie dodaje. |
| Wywołania narzędzi i wyniki | Wywołania narzędzi z wcześniejszych tur asystenta i ich wyniki wchodzą do liczby, w obu endpointach. |
| Obrazy | Obraz wysłany w treści (base64 lub URL data:) dodaje jeden token na każdy fragment 28 × 28 pikseli: ceil(width / 28) × ceil(height / 28). Obraz podany jako URL http(s) nie jest pobierany przez te endpointy i liczy się jako 1,024. |
Przykład: obraz 1,024 × 768 pikseli liczy się jako ceil(1024 / 28) × ceil(768 / 28) = 37 × 28 = 1,036 tokenów.
Liczba i to, co zapytanie kosztuje
Liczba dla całego zapytania jest wyznaczana tak samo jak liczba wejścia prawdziwego zapytania z tym samym modelem, wiadomościami i narzędziami. Odpowiedź zgłasza ją jako usage.prompt_tokens w Chat Completions, jako usage.input_tokens w Responses oraz jako usage.input_tokens plus usage.cache_read_input_tokens w Messages.
- Liczba to wejście przed zniżką za wejście z cache. Prawdziwe zapytanie może odczytać część tego wejścia z cache i rozliczyć ją po stawce cache. Cache'owanie promptów
- Obraz podany jako URL
http(s)liczy się tu jako 1,024. Prawdziwe zapytanie pobiera obraz i liczy go według rozmiaru w pikselach, więc obie liczby mogą się różnić. Wyślij obraz jako base64, aby dostać tę samą liczbę. - Wyjście nie wchodzi do liczby. Odpowiedź prawdziwego zapytania jest rozliczana dodatkowo jako tokeny wyjścia, z wnioskowaniem włącznie.
- Liczba dla
textnie ma formatowania czatu. Użyj jej do zmierzenia dokumentu lub części promptu, a formymessagesdo zmierzenia zapytania.
Aby zamienić liczbę na koszt, pomnóż ją przez cenę wejścia modelu za 1M tokenów. Modele i ceny
Limity
| Limit | Wartość | Powyżej niego |
|---|---|---|
Długość text | 4,000,000 bajtów (UTF-8) | 413 z komunikatem text too long |
| Treść zapytania | 32 MiB | 413 |
| Na zapytanie | Jeden tekst lub jedna rozmowa | Aby policzyć kilka tekstów, wyślij jedno zapytanie na tekst. |
Wywołania liczące nie wliczają się do limitu 120 zapytań na minutę. Limity i saldo
Błędy
| Status | Typ | Komunikat | Kiedy |
|---|---|---|---|
400 | invalid_request_error | tokenize is available for the hosted open models; unknown model: <model> | /v1/tokenize z model, który nie jest id hostowanego modelu open-weight. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <model> | /v1/messages/count_tokens z model, który nie jest id hostowanego modelu open-weight, albo bez model. |
400 | invalid_request_error | send `text` or `messages` | /v1/tokenize bez text i bez messages. |
401 | authentication_error | Missing authentication / Invalid API key | Nie wysłano klucza albo klucz jest nieprawidłowy. |
413 | invalid_request_error | text too long | text jest dłuższe niż 4,000,000 bajtów. Treść powyżej 32 MiB też dostaje odpowiedź 413. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Zapytanie nie ma typu zawartości JSON. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Brakuje wymaganego pola (model w /v1/tokenize, messages w /v1/messages/count_tokens) albo pole ma błędny typ. |
503 | api_error | token counting is temporarily unavailable for this model | Liczby nie da się w tej chwili wyznaczyć dla tego modelu. Spróbuj później. |
/v1/tokenize zwraca błędy w kształcie OpenAI. W /v1/messages/count_tokens błędy samego endpointu (400 dla modelu, 503) przychodzą w kształcie Anthropic, a 401, 413, 415 i 422 w kształcie OpenAI. Czytaj najpierw kod statusu, potem error.type i error.message, które występują w obu kształtach.
{
"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"
}
}