22 β Xarajat, token va keshlash¶
β¬ οΈ Oldingi: 21 β Lokal LLM: Ollama Β· π Kitob boshi Β· Keyingi: 23 β Ishonchlilik: xato, retry, rate limit β‘οΈ
Bu bobda: LLM xarajati qanday hisoblanishini β token birligi orqali β chuqur tushunamiz. Kirish (input) va chiqish (output) tokenlari alohida narxlanishini, chiqish odatda qimmatroq ekanini ko'ramiz;
resp.usagedan haqiqiy sarfni o'qiymiz. So'rov yuborishdan oldin token sanashni o'rganamiz (tiktokenOpenAI uchun,count_tokensAnthropic uchun) va aniq narx hisoblash funksiyasi yozamiz. So'ng xarajatni kamaytirishning to'rt asosiy usulini β arzon model, qisqa prompt,max_tokenscheklash va keshlash (prompt caching) β amalda qo'llaymiz. Oxirida Batch API bilan ommaviy ishni ~50% arzonlashtirishni va har so'rov narxini loglashni ko'ramiz.
Muammodan boshlaymiz: hisob to'satdan katta keldi¶
LLM ilovasini qurib, sinab ko'rdingiz β ajoyib ishlaydi. Bir oydan keyin provayder hisobini ochasiz va hayron qolasiz: "Men shunchaki bir nechta so'rov yubordim, nega bunchalik?" Sabab β har bir so'rov pul turadi, va siz buni o'lchamasangiz, xarajat sezilmay o'sib boradi.
Yaxshi xabar: LLM xarajati bashoratli va boshqariladigan. Uni o'lchash, oldindan hisoblash va kamaytirish β bir necha aniq texnika. Bu bobning maqsadi: siz har bir so'rovning narxini bilib, ongli ravishda boshqaradigan dasturchiga aylanishingiz.
Hayotiy o'xshatish. LLM β taksometrli taksi kabi. Har metr (token) uchun hisoblagich aylanadi. Manzilni bilmasdan o'tirsangiz, oxirida hisobni ko'rib hayron bo'lasiz. Lekin marshrutni rejalashtirsangiz, eng qisqa yo'lni tanlasangiz va keraksiz aylanishlardan qochsangiz β xuddi shu manzilga ancha arzon yetib borasiz.
Atamalar
Token β LLM matnni o'lchaydigan birlik (so'z yoki so'z bo'lagi). Input (kirish) token β siz modelga yuborgan matn (prompt, suhbat tarixi, kontekst). Output (chiqish) token β model qaytargan javob. Narx million token (1 000 000 = 1e6) hisobida e'lon qilinadi.
Token va narx asoslari: input va output alohida narxlanadi¶
Eng muhim haqiqat: kirish va chiqish tokenlari alohida narxlanadi, va chiqish odatda 3-5 barobar qimmatroq. Sababi β chiqishni model "fikrlab", bittama-bitta generatsiya qiladi; bu hisoblash jihatidan qimmatroq. Kirish esa shunchaki o'qiladi.
Demak, narx ikkita raqamdan iborat (har million token uchun):
- Input narxi β yuborgan har million token uchun.
- Output narxi β olgan har million token uchun (qimmatroq).
Misol uchun, faraziy narxlar (million token uchun): input $0.15, output $0.60. Agar so'rovingiz 1000 input + 500 output token sarflasa:
input = 1000 / 1 000 000 * 0.15 = 0.00015 $
output = 500 / 1 000 000 * 0.60 = 0.00030 $
jami = 0.00045 $ (taxminan yarim sent)
E'tibor bering: chiqish ikki barobar kam token bo'lsa ham, qimmatroq narx tufayli xarajatning kattaroq qismini tashkil qildi. Shuning uchun "javobni qisqartirish" ko'pincha "promptni qisqartirish"dan ko'ra ko'proq tejaydi.
Narxlar o'zgaradi β har doim tekshiring
Bu bobdagi barcha narxlar misol uchun. Haqiqiy narxlar tez-tez o'zgaradi (odatda arzonlashadi) va modelga qarab farq qiladi. Kodingizda narxni bitta joyda (konfiguratsiya/lug'atda) saqlang va provayderning rasmiy narx sahifasidan dolzarb qiymatni oling. Hech qachon narxni kod ichiga "sochib" yozmang.
resp.usage dan haqiqiy sarfni o'qish¶
So'rov yuborilgach, provayder javob obyektida aniq sarflangan tokenlarni qaytaradi. Buni usage maydonidan o'qiymiz β taxmin emas, haqiqiy raqam:
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI()
# Eslatma: model nomlari o'zgaradi β provayder ro'yxatini tekshiring.
MODEL = "gpt-5.4-mini"
resp = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": "Python'da ro'yxatni qanday saralayman?"}],
)
u = resp.usage
print("Kirish (input) tokenlar:", u.prompt_tokens)
print("Chiqish (output) tokenlar:", u.completion_tokens)
print("Jami:", u.total_tokens)
prompt_tokens β siz yuborgan, completion_tokens β model qaytargan tokenlar. Ularni alohida bilish narx hisoblash uchun zarur, chunki ular turlicha narxlanadi.
Anthropic'da usage boshqacha nomlanadi
Claude'ning native SDK'sida sarf resp.usage.input_tokens va resp.usage.output_tokens deb ataladi (prompt/completion emas). Mazmun bir xil β faqat maydon nomi farq qiladi:
Token sanash OLDINDAN: hisobni so'rovdan oldin biling¶
Ba'zan so'rov yubormasdan, oldindan matn necha token ekanini bilish kerak β masalan, kontekst oynasiga sig'adimi yoki narxni jo'natishdan oldin baholash uchun.
OpenAI uchun: tiktoken¶
OpenAI modellari uchun tiktoken kutubxonasi aniq token sonini lokal (so'rovsiz, bepul) hisoblaydi:
import tiktoken
# Model uchun to'g'ri tokenizatorni oladi
enc = tiktoken.encoding_for_model("gpt-5.4-mini")
matn = "Salom! Bugun ob-havo qanday?"
tokenlar = enc.encode(matn) # tokenlar ro'yxati (sonlar)
print("Token soni:", len(tokenlar)) # masalan, 9
enc.encode(text) matnni tokenlarga (sonlar ro'yxatiga) aylantiradi; len(...) ularning sonini beradi. Bu β siz yuborayotgan matn necha input token ekanini aniq aytadi.
Hayotiy o'xshatish.
tiktokenβ pochta jo'natishdan oldin paketni tarozida o'lchash kabi. Pochtaga bormasdan ham, uydagi tarozida og'irligini (va shu bilan narxini) bilib olasiz. Lekin diqqat: bu tarozi faqat bitta pochta xizmati (OpenAI) o'lchovi uchun sozlangan.
tiktoken FAQAT OpenAI uchun aniq
tiktoken β OpenAI modellarining tokenizatori. Claude yoki Gemini token sonini u aniq hisoblamaydi (ular boshqa tokenizator ishlatadi) β faqat taxminiy baho beradi. Boshqa provayder uchun aniq son kerak bo'lsa, o'sha provayderning o'z usulini ishlating.
Anthropic (Claude) uchun: count_tokens¶
Claude uchun aniq token sonini SDK'ning maxsus chaqiruvi beradi (bu generatsiya emas β arzon/bepul hisoblash):
import anthropic
client = anthropic.Anthropic()
natija = client.messages.count_tokens(
model="claude-haiku-4-5",
messages=[{"role": "user", "content": "Salom! Bugun ob-havo qanday?"}],
)
print("Kirish tokenlar:", natija.input_tokens)
Bu so'rovni yuborishdan oldin promptingiz necha input token ekanini Claude'ning o'z o'lchovida aniq aytadi.
Narx hisoblash funksiyasi¶
Endi tokenni pulga aylantiramiz. Formulasi sodda:
Buni qayta ishlatiladigan funksiya qilamiz. Narxlarni bitta lug'atda saqlaymiz, shunda o'zgartirish oson:
# Narxlar β million token uchun (USD). MISOL qiymatlar!
# Dolzarb narxni provayder sahifasidan oling.
NARXLAR = {
"gpt-5.4-mini": {"input": 0.15, "output": 0.60},
"gpt-5.5": {"input": 1.25, "output": 10.00},
"claude-haiku-4-5": {"input": 0.80, "output": 4.00},
"gemini-2.5-flash": {"input": 0.10, "output": 0.40},
}
def narx_hisobla(model: str, input_tok: int, output_tok: int) -> float:
"""So'rov narxini USD'da qaytaradi."""
n = NARXLAR[model]
return (input_tok / 1e6 * n["input"]) + (output_tok / 1e6 * n["output"])
# Foydalanish β resp.usage bilan:
xarajat = narx_hisobla(MODEL, u.prompt_tokens, u.completion_tokens)
print(f"Bu so'rov narxi: ${xarajat:.6f}")
Endi har bir so'rov narxini aniq bilasiz. Bu β keyingi qadamning (xarajatni kamaytirish) asosi: o'lchamasangiz, boshqara olmaysiz.
Avval taxmin, keyin haqiqat
Katta ish (masalan, 10 000 hujjatni qayta ishlash) boshlashdan oldin: bitta namuna so'rovning usage'sini oling, narxini hisoblang, so'ng 10 000 ga ko'paytiring. Shunday qilib butun ishning narxini boshlashdan oldin bilasiz β va yoqimsiz syurprizdan qochasiz.
Xarajatni kamaytirishning 4 yo'li¶
Endi eng amaliy qism. Xarajatni kamaytirishning to'rtta asosiy richagi bor.
1. Arzon model tanlang β vazifaga moslang¶
Eng katta tejamkorlik: har vazifaga eng arzon yetarli modelni tanlash. Oddiy vazifa (tasniflash, qisqa javob, format o'zgartirish) uchun "mini/haiku/flash" toifasidagi model ko'pincha kuchli modeldek ishlaydi β lekin 10-20 barobar arzon.
Hayotiy o'xshatish. Non olishga sport mashinasida bormaysiz. Kuchli model β Formula-1 bolidi: murakkab poyga uchun zo'r, lekin kundalik mayda yumush uchun isrof. Tasniflash, qisqa javob kabi "non olish" vazifalariga arzon, tejamkor model yetadi.
# Oddiy vazifa -> arzon model
javob = client.chat.completions.create(
model="gpt-5.4-mini", # mini: arzon, oddiy tasniflash uchun yetarli
messages=[{"role": "user", "content": "Bu sharh ijobiymi yoki salbiy? 'Ajoyib mahsulot!'"}],
max_tokens=5,
)
2. Qisqa prompt + faqat kerakli kontekst¶
Har bir ortiqcha so'z β input token, ya'ni pul. Promptni qisqartiring, takror yo'riqnomalarni olib tashlang. Eng muhimi β RAG'da (13-17-boblar) faqat eng tegishli bo'laklarni yuboring, butun hujjatni emas. Ko'p kontekst nafaqat qimmat, balki javob sifatini ham pasaytiradi.
3. max_tokens bilan chiqishni cheklang¶
Chiqish qimmatroq bo'lgani uchun, uni cheklash β kuchli richag. max_tokens modelga "bundan uzun yozma" deydi. Agar sizga qisqa javob kerak bo'lsa, uzun "esse" uchun to'lamang:
javob = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": "Bir jumlada javob ber: Python nima?"}],
max_tokens=40, # uzun javobga pul ketishining oldini oladi
)
max_tokens β cheklov, talab emas
max_tokens β chiqishning yuqori chegarasi, aniq uzunligi emas. Model undan oldin ham tugatishi mumkin. Lekin chegara juda kichik bo'lsa, javob o'rtada kesilib qolishi mumkin (finish_reason == "length") β bunda chegarani biroz oshiring.
4. Keshlash β keyingi bo'limda¶
To'rtinchi va eng kuchli richaglardan biri β keshlash. Bunga alohida e'tibor beramiz.
Prompt caching: bir xil prefiksni qayta-qayta to'lamang¶
Ko'p ilovalarda har so'rovning boshi bir xil bo'ladi: uzun system yo'riqnoma, qo'llanma, misol to'plami yoki RAG kontekst. Har safar bu katta prefiksni qayta yuborasiz β va har safar uning input tokeni uchun to'liq to'laysiz. Bu β isrof.
Prompt caching shu muammoni hal qiladi: provayder bir xil prefiksni xotirada saqlaydi va keyingi so'rovlarda uni qayta o'qimaydi β kesh'dan o'qigan tokenlar ancha arzon (odatda 10% narxda) hisoblanadi.
Hayotiy o'xshatish. Har gal restoranga kelganingizda menyuni qaytadan chop ettirmaysiz β u stolda turadi. Faqat bugungi buyurtmangizni aytasiz. Prompt caching ham shunday: katta o'zgarmas qism (menyu = system/kontekst) bir marta "stolga qo'yiladi", keyin siz faqat yangi so'rov (buyurtma) uchun to'liq to'laysiz.
OpenAI: avtomatik kesh¶
OpenAI'da kesh avtomatik ishlaydi β alohida sozlash shart emas. Agar so'rov boshidagi prefiks (odatda kamida ~1024 token) avvalgi so'rov bilan bir xil bo'lsa, u keshdan o'qiladi. Shart: o'zgarmas qism (system, kontekst) boshida, o'zgaruvchan qism (foydalanuvchi savoli) oxirida bo'lsin.
Keshdan necha token o'qilganini usage ichidan ko'rasiz:
resp = client.chat.completions.create(model=MODEL, messages=msgs)
# Avtomatik keshdan o'qilgan input tokenlar:
print(resp.usage.prompt_tokens_details.cached_tokens)
Anthropic: cache_control bilan aniq belgilash¶
Claude'da kesh'ni o'zingiz belgilaysiz β qaysi blok keshlanishini cache_control bilan ko'rsatasiz:
import anthropic
client = anthropic.Anthropic()
resp = client.messages.create(
model="claude-haiku-4-5",
max_tokens=300,
system=[
{
"type": "text",
"text": KATTA_QOLLANMA, # uzun, o'zgarmas kontekst
"cache_control": {"type": "ephemeral"}, # shu blokni keshla
}
],
messages=[{"role": "user", "content": "Foydalanuvchi savoli"}],
)
# Kesh statistikasi:
print(resp.usage.cache_creation_input_tokens) # keshga yozildi (birinchi marta)
print(resp.usage.cache_read_input_tokens) # keshdan o'qildi (arzon)
Birinchi so'rovda cache_creation_input_tokens to'ladi (keshni yaratish biroz qimmatroq), keyingi so'rovlarda esa cache_read_input_tokens β juda arzon.
Keshlash qachon foyda beradi?
Kesh katta, o'zgarmas, qayta-qayta ishlatiladigan prefiks bo'lganda eng foydali: uzun system yo'riqnoma, hujjat/qo'llanma ustida ko'p savol, few-shot misollar to'plami, suhbat tarixi. Agar har so'rov butunlay boshqacha bo'lsa β kesh foyda bermaydi. Promptni o'zgarmas qism boshida, o'zgaruvchan qism oxirida bo'ladigan qilib tuzing.
Batch API: shoshilmaydigan ish uchun ~50% arzon¶
Agar sizda ko'p so'rov bor, lekin darhol javob shart emas bo'lsa (masalan, kechasi 50 000 sharhni tasniflash), Batch API ~50% arzonroq narx beradi. Siz so'rovlar to'plamini bir faylda yuborasiz, provayder ularni navbat bilan (odatda 24 soat ichida) bajaradi va natijani qaytaradi.
Bu β real vaqt (chatbot, foydalanuvchi kutadi) uchun emas, fon ishi (offline tahlil, ommaviy generatsiya, ma'lumot tayyorlash) uchun. Vaqtni xarajatga almashtirasiz: sabr qilsangiz β yarim narx.
Batch β keyinroq chuqurroq
Batch API'ning to'liq oqimi (fayl tayyorlash, yuborish, natijani kutib olish) provayderga qarab farq qiladi va alohida mavzu. Hozircha asosiy g'oyani yodda tuting: shoshilmaydigan ommaviy ish = Batch API = ~2 barobar arzon.
Har so'rov narxini loglash¶
Xarajatni boshqarishning birinchi qadami β uni ko'rish. Har so'rovdan keyin narxni hisoblab loglang. Bu sizga "qaysi xususiyat qancha pul yeyapti" degan savolga javob beradi va keyinchalik (25-bobda) to'liq kuzatuv tizimiga ulanadi:
import logging
logging.basicConfig(level=logging.INFO)
def sorov_log_bilan(messages, model=MODEL):
resp = client.chat.completions.create(model=model, messages=messages)
u = resp.usage
narx = narx_hisobla(model, u.prompt_tokens, u.completion_tokens)
logging.info(
"model=%s in=%d out=%d narx=$%.6f",
model, u.prompt_tokens, u.completion_tokens, narx,
)
return resp.choices[0].message.content
javob = sorov_log_bilan([{"role": "user", "content": "Salom!"}])
Har so'rovning narxini loglab borsangiz, oy oxirida hayron bo'lmaysiz β har bir tiyinning qayerga ketganini bilasiz. 25-bobda bu loglarni to'liq kuzatuv (observability) tizimiga β har foydalanuvchi/xususiyat bo'yicha xarajat dashboardiga β aylantiramiz.
Hayotiy o'xshatish. Xarajat logi β taksida hisoblagichni ko'z oldingizda ushlab turish kabi. Manzilga yetganda hisobni ko'rib hayron bo'lmaysiz, chunki yo'l davomida har metrni kuzatib bordingiz β va kerak bo'lsa, marshrutni o'zgartirdingiz.
Xulosa¶
- LLM xarajati token orqali o'lchanadi: kirish (input) va chiqish (output) tokenlari alohida narxlanadi, chiqish odatda 3-5 barobar qimmatroq. Shuning uchun javobni qisqartirish ko'pincha promptni qisqartirishdan ko'ra ko'proq tejaydi.
- Haqiqiy sarfni
resp.usagedan o'qing: OpenAI'daprompt_tokens/completion_tokens, Anthropic'dainput_tokens/output_tokens. - Token sanashni oldindan qiling: OpenAI uchun
tiktoken(encoding_for_model,len(enc.encode(text))), Anthropic uchunclient.messages.count_tokens(...).tiktokenfaqat OpenAI uchun aniq β Claude/Gemini'da taxminiy. - Narx =
(input_tok/1e6 * input_narx) + (output_tok/1e6 * output_narx). Narxni bitta joyda saqlang; provayder sahifasidan dolzarbini oling, chunki narxlar o'zgaradi. - Xarajatni kamaytirishning 4 yo'li: (1) vazifaga arzon model moslash, (2) qisqa prompt + faqat kerakli kontekst, (3)
max_tokensbilan chiqishni cheklash, (4) keshlash. - Prompt caching: bir xil katta prefiks (system/kontekst) qayta ishlatilsa, kesh uni arzonlashtiradi. OpenAI β avtomatik (prefiks bir xil bo'lsa); Anthropic β
cache_controlbilan. Kesh tokenlariniusagedan ko'ring. - Batch API β shoshilmaydigan ommaviy so'rovlarni ~50% arzon bajaradi (vaqtni narxga almashtirasiz).
- Har so'rov narxini loglang β o'lchamasangiz, boshqara olmaysiz; bu 25-bobdagi kuzatuvga ko'prik.
Amaliy mashqlar¶
-
(Oson) 5-7 bobdagi biror skriptingizga
resp.usageni chop etishni qo'shing.prompt_tokens,completion_tokensvatotal_tokensni ko'ring. Bir xil savolni qisqa va uzun prompt bilan yuborib, input token farqini taqqoslang. -
(Oson)
tiktokenni o'rnating va qisqa funksiya yozing: matn berilganda token sonini qaytarsin. Uni o'zbekcha va inglizcha bir xil ma'noli jumlaga qo'llang β qaysi biri ko'proq token? (Eslatma: tokenizator inglizchaga moslangani uchun o'zbekcha matn ko'proq token bo'lishi mumkin.) -
(O'rtacha) Bobdagi
narx_hisoblafunksiyasini vaNARXLARlug'atini ko'chiring. Bitta savolniminiva kuchli model bilan yuboring, ikkalasiningusage'sidan narxni hisoblang va taqqoslang. Necha barobar farq chiqdi? -
(O'rtacha) Uzun (kamida ~1500 token) o'zgarmas system yo'riqnoma yozing va unga 3 ta turli savol yuboring. OpenAI'da
resp.usage.prompt_tokens_details.cached_tokensni har so'rovda chop eting β ikkinchi va uchinchi so'rovda kesh ishladimi? (Anthropic ishlatsangiz:cache_controlqo'shib,cache_read_input_tokensni kuzating.) -
(Qiyin) "Xarajat hisoblagich" yarating:
class XarajatKuzatuvchiyozing, u har so'rovdan keyinqosh(resp.usage, model)chaqirilganda umumiy input/output token va umumiy narxni yig'ib borsin;hisobot()metodi jami sarfni chop etsin. Unitry/exceptbilan o'rab, 10 ta turli so'rovda sinab ko'ring va umumiy xarajatni chiqaring.
β¬ οΈ Oldingi: 21 β Lokal LLM: Ollama Β· π Kitob boshi Β· Keyingi: 23 β Ishonchlilik: xato, retry, rate limit β‘οΈ