15 β Prompt caching¶
β¬ οΈ Oldingi: 14 β Token, narx va limitlar Β· π README Β· Keyingi: 16 β Xatolar, retry va ishonchlilik β‘οΈ
Bu bobda: o'tgan bobda tokenni va narxni o'rgandingiz. Endi narxni keskin tushiradigan eng kuchli dastagimizni ko'ramiz β prompt caching (prompt keshlash). Agar siz bir xil katta kontekstni qayta-qayta yuborsangiz (katta system prompt, uzun hujjat, few-shot misollar), har safar uning to'liq narxini to'laysiz. Prompt caching o'sha o'zgarmas qismni Anthropic serverida saqlab qo'yadi β keyingi so'rovlar uni ~0.1Γ narxda (90% gacha arzon) va tezroq qayta ishlatadi. Biz bitta qoidani β prefiks moslik β chuqur tushunamiz,
cache_controlni qanday qo'yishni, keshniusageorqali tekshirishni, va eng muhimi β keshni jim buzadigan tuzoqlarni (Date.now(), UUID, tartibsiz JSON) topib tuzatishni o'rganamiz. Yakunda "katta hujjat bilan suhbat" quramiz: hujjat bir marta keshlanadi, o'nlab savol arzon qayta ishlatadi.Halollik eslatmasi: bu bobdagi API shakllari β
cache_control: { type: "ephemeral" }(system bloki, tool ta'rifi yoki xabar blokida), top-levelcache_controlbilan avtomatik keshlash,ttl: "1h", vamsg.usage.cache_creation_input_tokens/cache_read_input_tokensmaydonlari β@anthropic-ai/sdk0.104 va Anthropic hujjatiga muvofiq yozilgan. Keshning haqiqiy ishlashini ko'rish uchun bir xil prefiks bilan kamida ikki marta API ga so'rov yuborish kerak (kalit + tarmoq), shuning uchun quyidagi misollar to'g'ri tuzilgan, biroq raqamli natijalar sizning prompt o'lchamingizga bog'liq. Minimal keshlanadigan prefiks model'ga bog'liq (Opus 4.8 da β 4096 token) β bundan kichigi jim keshlanmaydi (xato bermaydi, shunchaki ishlamaydi).
Nega kerak? β "hujjatni qadab qo'yish"¶
Tasavvur qiling, sizda 30 sahifalik mahsulot qo'llanmasi bor va foydalanuvchilar shu qo'llanma bo'yicha kuniga yuzlab savol berishadi. Har bir savolda siz Claude'ga butun qo'llanmani (aytaylik, 20 000 token) qaytadan yuborasiz. 20 000 token har safar β har savolda to'liq input narxi. Savol bir jumla bo'lsa ham, narxning 99% i o'sha o'zgarmas qo'llanmaga ketadi. Bu isrof.
Mana shu yerda yechim β prompt caching. Caching (keshlash) β bu hisoblangan natijani saqlab qo'yib, keyin uni qaytadan hisoblamasdan ishlatish. Prompt caching'da Claude promptingizning katta, o'zgarmas oldingi qismini (prefiksini) server tomonida saqlab qo'yadi. Keyingi so'rovlar o'sha qismni qaytadan "o'qimaydi" β keshdan oladi. Natija: keshlangan qism ~0.1Γ narxda (90% gacha arzon) va tezroq ishlanadi.
Analogiya: katta hujjatni har savolda qaytadan yuklash (upload) o'rniga, uni bir marta yuklab qadab (pin) qo'yasiz. Endi har savol shunchaki "o'sha qadalgan hujjatga" murojaat qiladi β yuklash takrorlanmaydi.
Asosiy use case'lar:
- Hujjat bo'yicha savol-javob β katta hujjatni keshlab, o'nlab savol bering (bu bobning kapston ilovasi; 09 β Vision va hujjatlar dagi "PDF bilan suhbat"ning narx tomoni).
- Katta system prompt'li chatbot β har turda yuboriladigan barqaror yo'riqnomani keshlang.
- Few-shot pipeline'lar β bir xil misollar to'plamini keshlang.
- Ko'p turdagi suhbat (multi-turn) β o'sib boruvchi tarixni keshlang (03 β Messages API da ko'rganimizdek, har so'rovda butun tarix yuboriladi β keshlash uni arzonlashtiradi).
Bitta qoida β prefiks moslik¶
Keshlash haqida faqat bitta narsani chuqur tushunsangiz, qolgani o'z-o'zidan kelib chiqadi:
Keshlash β bu PREFIKS moslik. Prefiksning istalgan joyida BIR bayt o'zgarsa, undan keyingi hamma narsa keshni yo'qotadi.
Kesh kaliti β promptning breakpoint'gacha bo'lgan aniq baytlaridan hosil bo'ladi. N-pozitsiyadagi bitta bayt farq qilsa, N va undan keyingi barcha breakpoint'lar uchun kesh bekor bo'ladi.
Buni to'g'ri ishlatish uchun render tartibini bilish shart. So'rov shu tartibda quriladi:
Demak: BARQAROR (o'zgarmas) narsani oldinga qo'ying, O'ZGARUVCHAN narsani oxiriga. Muzlatilgan system prompt, qotirilgan hujjat β boshida. Foydalanuvchining har safar o'zgaradigan savoli, timestamp'lar β oxirida, breakpoint'dan keyin.
Mana shu rasm butun bobni o'zida jamlaydi: barqaror prefiks oldinda, breakpoint o'rtada, o'zgaruvchan savol oxirida. Birinchi chaqiruv keshni yozadi, qolganlar o'qiydi.
API: cache_control ni qanday qo'yamiz¶
Keshlashni yoqish uchun siz biror content blokiga cache_control: { type: "ephemeral" } qo'shasiz. ephemeral β "vaqtinchalik" degani: kesh standart holatda 5 daqiqa yashaydi (har o'qishda muddat yangilanadi).
Eng keng tarqalgan holat β katta hujjatni system ichida bir blok sifatida keshlash:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // ANTHROPIC_API_KEY .env dan (02-bob)
const katta_hujjat = "..."; // 20 000+ token: qo'llanma, kodbaza, kitob bobi...
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
system: [
{
type: "text",
text: katta_hujjat,
cache_control: { type: "ephemeral" }, // <- shu blok va undan oldingisi keshlanadi
},
],
messages: [
{ role: "user", content: "Hujjatning asosiy fikrlarini sana." }, // <- o'zgaruvchan, keshsiz
],
});
E'tibor bering: system endi satr emas, bloklar massivi β chunki bizga cache_control ni aniq bir blokga qo'yish kerak. Hujjat β keshlanadi; oxirdagi savol β yo'q.
Yana soddaroq: top-level cache_control (avto-keshlash)¶
Agar breakpointni qo'lda qaerga qo'yishni o'ylab o'tirmoqchi bo'lmasangiz, messages.create() ga top-level cache_control bering β SDK oxirgi keshlanadigan blokni avtomatik keshlaydi:
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
cache_control: { type: "ephemeral" }, // <- oxirgi keshlanadigan blok avto-keshlanadi
system: katta_hujjat, // bu yerda oddiy satr ham bo'ladi
messages: [{ role: "user", content: "Asosiy fikrlarni sana." }],
});
Ikki muhim chegara:
- Eng ko'pi 4 ta breakpoint bitta so'rovda.
- Uzunroq saqlash uchun
ttl: "1h"(1 soat):cache_control: { type: "ephemeral", ttl: "1h" }. Buning narxi yuqoriroq (pastda "Iqtisod" qismida ko'ramiz).
Bir hujjat β uch savol, arzon¶
Endi haqiqiy foydani ko'rsataylik: hujjatni bir marta keshlab, unga uch xil savol beramiz. Birinchi savol keshni yozadi; qolganlari keshdan o'qiydi.
const katta_hujjat = "..."; // 20 000+ token barqaror kontekst
// Hujjat har so'rovda BIR XIL β shuning uchun keshlanadi.
// Faqat savol o'zgaradi β u keshsiz, har safar to'liq narxda.
async function sora(savol) {
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
system: [
{ type: "text", text: katta_hujjat, cache_control: { type: "ephemeral" } },
],
messages: [{ role: "user", content: savol }],
});
// keshni tekshiramiz (pastda batafsil)
console.log("yozildi:", msg.usage.cache_creation_input_tokens,
"o'qildi:", msg.usage.cache_read_input_tokens);
return msg.content[0].text;
}
console.log(await sora("Qaytarish siyosati qanday?")); // 1: keshni YOZADI
console.log(await sora("Yetkazib berish necha kun?")); // 2: keshdan O'QIYDI
console.log(await sora("Kafolat muddati qancha?")); // 3: keshdan O'QIYDI
Birinchi sora() da cache_creation_input_tokens katta son bo'ladi (hujjat keshga yozildi). Keyingilarida cache_read_input_tokens katta bo'ladi (hujjat keshdan o'qildi, ~0.1Γ narx), cache_creation esa 0 β chunki qayta yozish kerak emas edi.
Kesh ishladimi? β usage orqali tekshirish¶
Keshlashni qo'shdingiz, lekin u haqiqatan ishlayaptimi? Buni taxmin qilmang β msg.usage da uchta maydon aniq aytib beradi:
| Maydon | Ma'nosi |
|---|---|
cache_creation_input_tokens |
Shu so'rovda keshga yozilgan token (siz ~1.25Γ yozish narxini to'ladingiz) |
cache_read_input_tokens |
Shu so'rovda keshdan o'qilgan token (siz ~0.1Γ to'ladingiz β arzon) |
input_tokens |
To'liq narxda ishlangan token (keshlanmagan qoldiq) |
Buni har so'rovda log qiling:
const msg = await client.messages.create({ /* ... yuqoridagidek ... */ });
console.log("Keshga yozildi :", msg.usage.cache_creation_input_tokens);
console.log("Keshdan o'qildi :", msg.usage.cache_read_input_tokens);
console.log("Keshsiz (to'liq):", msg.usage.input_tokens);
O'qish qoidasi:
- 1-so'rov:
cache_creation_input_tokens > 0(yozildi),cache_read_input_tokens = 0(hali kesh yo'q edi). - 2, 3, ... so'rov (bir xil prefiks):
cache_read_input_tokens > 0(o'qildi β β kesh ishlayapti),cache_creation = 0. - Agar takror so'rovlarda ham
cache_read_input_tokens0 bo'lib qolsa β β οΈ prefiksda jim keshbuzar bor. Hech narsa keshlanmayapti.
Diqqat β
input_tokensfaqat keshlanmagan qoldiq. To'liq prompt o'lchami =input_tokens + cache_creation_input_tokens + cache_read_input_tokens. Agar ilovangiz katta kontekst yuborsa, lekininput_tokenskichik chiqsa β bu xato emas; qolgani keshdan kelgan. Yig'indini hisoblang, bitta maydonni emas.
Jim keshbuzarlar β eng ko'p uchraydigan xato¶
Bu bobning eng muhim qismi. Ko'pchilik cache_control ni qo'yadi, lekin cache_read_input_tokens har safar 0 chiqadi va sababini topolmaydi. Sabab deyarli har doim bitta: prefiksning boshida har so'rovda o'zgaradigan biror narsa bor. U bitta bayt o'zgartiradi, shu bilan undan keyingi hamma narsa keshni yo'qotadi.
Eng keng tarqalgan jim keshbuzarlar:
// β 1) system prompt'da Date.now() / new Date()
const system = `Joriy vaqt: ${Date.now()}. Sen yordamchisan...`;
// -> har so'rovda boshqa son -> prefiks o'zgaradi -> kesh promah
// β 2) UUID yoki so'rov ID si oldinda
const system = `So'rov ID: ${crypto.randomUUID()}. Sen yordamchisan...`;
// -> har so'rov noyob -> hech qachon keshlanmaydi
// β 3) tartibsiz JSON.stringify (kalit tartibi har xil bo'lishi mumkin)
const system = `Sozlamalar: ${JSON.stringify(sozlamalar)}`;
// -> obyekt kalitlari tartibi farq qilsa -> baytlar farq qiladi -> kesh promah
// β 4) foydalanuvchi ID si prefiks boshida
const system = `Foydalanuvchi ${userId}. Sen yordamchisan...`;
// -> har foydalanuvchi alohida prefiks -> foydalanuvchilar orasida kesh ulashilmaydi
Har biri prefiks baytlarini o'zgartiradi β kesh promah (cache miss).
Qanday tuzatamiz? Uch qoida:
- O'zgaruvchan baytlarni oxiriga ko'chiring β breakpoint'dan keyingi qismga, ya'ni
messagesichidagi oxirgi xabarga. 5-turdagi xabar undan oldingi 4 turni bekor qilmaydi. - JSON kalitlarini barqaror tartibda bering β
JSON.stringifyni tartiblang. - System promptni muzlating β vaqt/rejim/ism kabi dinamik narsalarni system prompt'ga qo'shmang.
// β
To'g'ri: barqaror prefiks oldinda, dinamik narsa oxirida
const BARQAROR_SYSTEM = "Sen do'kon yordamchisan. Quyidagi qoidalarga amal qil: ..."; // hech qachon o'zgarmaydi
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
system: [
{ type: "text", text: BARQAROR_SYSTEM, cache_control: { type: "ephemeral" } },
],
messages: [
{
role: "user",
// vaqt va savol β OXIRDA, breakpoint'dan keyin. Keshni buzmaydi.
content: `Joriy vaqt: ${new Date().toISOString()}.\nSavol: Kafolat qancha?`,
},
],
});
// JSON ni barqaror tartibda bersangiz:
const barqaror_json = JSON.stringify(sozlamalar, Object.keys(sozlamalar).sort());
Yodda tuting. Tool to'plamini va modelni suhbat o'rtasida o'zgartirmang.
tools0-pozitsiyada renderlanadi β bitta tool qo'shsangiz/olib tashlasangiz/tartibini o'zgartirsangiz, butun kesh bekor bo'ladi. Model almashtirsangiz ham (kesh model'ga bog'langan) β xuddi shu. "Rejim" kerak bo'lsa, tool to'plamini almashtirmang; rejimni xabar mazmuni sifatida bering.
Iqtisod: qachon foyda beradi?¶
Keshlash bepul emas β yozish biroz qimmatroq. Lekin o'qish juda arzon. Raqamlar (asosiy input narxiga nisbatan):
| Amal | Narx |
|---|---|
| Kesh o'qish (cache read) | ~0.1Γ (90% arzon) |
| Kesh yozish, 5 daqiqa TTL | ~1.25Γ |
Kesh yozish, 1 soat TTL (ttl: "1h") |
~2Γ |
| Keshsiz oddiy input | 1Γ |
Break-even (foyda chegarasi): 5 daqiqalik TTL bilan ikki so'rov foyda chegarasiga yetadi β 1.25Γ + 0.1Γ = 1.35Γ, keshsiz 2Γ o'rniga. Ya'ni agar bir xil prefiksni kamida 2 marta ishlatsangiz, allaqachon yutdingiz. 1 soatlik TTL bilan kamida 3 so'rov kerak (2Γ + 0.2Γ = 2.2Γ, keshsiz 3Γ o'rniga) β lekin u keshni 1 soat tirik tutadi, gaplari ko'p, lekin siyrak (bursty) trafik uchun.
Minimal prefiks. Eng muhimi: prefiks juda qisqa bo'lsa, umuman keshlanmaydi β xato bermaydi, shunchaki cache_creation_input_tokens: 0 qaytaradi. Minimal o'lcham model'ga bog'liq:
| Model | Minimal keshlanadigan prefiks |
|---|---|
| Opus 4.8, Opus 4.7, Haiku 4.5 | β 4096 token |
| Sonnet 4.6 | β 2048 token |
Demak 3000 tokenli prompt Sonnet 4.6 da keshlanadi, lekin Opus 4.8 da jim keshlanmaydi. Agar kesh "ishlamayapti"dek tuyulsa, prefiks o'lchamini ham tekshiring.
Qachon keshlamaslik kerak? Agar promptingiz har so'rovda boshidanoq farq qilsa (qayta ishlatiladigan barqaror prefiks yo'q), keshlash faqat yozish narxini behuda to'lashga olib keladi, o'qish esa hech qachon bo'lmaydi. Bunday holda
cache_controlni qo'shmang.
Kapston: katta hujjat bilan suhbat¶
Endi hammasini birlashtiramiz β kichik "hujjat bilan suhbat" ilovasi. Hujjat bir marta keshlanadi, foydalanuvchi xohlagancha savol beradi, va biz har savolda kesh tejovini log qilamiz.
import Anthropic from "@anthropic-ai/sdk";
import fs from "node:fs";
const client = new Anthropic();
// 1) Katta hujjatni o'qiymiz (matn β kodbaza, qo'llanma, kitob...).
// Bu BARQAROR prefiks: har so'rovda bir xil -> keshlanadi.
const hujjat = fs.readFileSync("qollanma.txt", "utf8");
const SYSTEM = "Sen quyidagi hujjat bo'yicha aniq, qisqa javob beradigan yordamchisan. "
+ "Faqat hujjatdagi ma'lumotga tayan. Bilmasang, 'hujjatda yo'q' deb ayt.";
async function sora(savol) {
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
// BARQAROR prefiks: system yo'riqnoma + katta hujjat. Breakpoint hujjatdan keyin.
system: [
{ type: "text", text: SYSTEM },
{ type: "text", text: hujjat, cache_control: { type: "ephemeral" } },
],
// O'ZGARUVCHAN: faqat savol, oxirda. Keshni buzmaydi.
messages: [{ role: "user", content: savol }],
});
const u = msg.usage;
const tejov = u.cache_read_input_tokens > 0 ? "β
keshdan o'qildi" : "yangi / keshsiz";
console.log(`[${tejov}] yozildi=${u.cache_creation_input_tokens} `
+ `o'qildi=${u.cache_read_input_tokens} keshsiz=${u.input_tokens}`);
return msg.content[0].text;
}
// Foydalanuvchi ketma-ket savol beradi β hujjat faqat 1-savolda keshga yoziladi.
console.log(await sora("Qaytarish siyosati qanday?")); // keshni yozadi
console.log(await sora("Yetkazib berish necha kun?")); // keshdan o'qiydi (arzon)
console.log(await sora("Kafolat muddati qancha?")); // keshdan o'qiydi (arzon)
console.log(await sora("To'lov usullari qaysilar?")); // keshdan o'qiydi (arzon)
Birinchi savol katta hujjatni keshga yozadi (cache_creation katta). Qolgan uch savol o'sha keshni o'qiydi (cache_read katta, narx ~0.1Γ). Agar hujjat 20 000 token bo'lsa, 4 savoldan keyin siz uni 1.25Γ + 3Γ0.1Γ = ~1.55Γ narxda ishlatdingiz β keshsiz 4Γ o'rniga. Bu ~60% tejov, faqat to'rt savolda.
E'tibor bering: SYSTEM yo'riqnoma ham, hujjat ham barqaror, ikkalasi ham breakpoint'dan oldin. Faqat savol o'zgaradi va u messages ichida, oxirda.
Tuzoqlar va ehtiyotkorlik¶
| Muammo | Sabab | Yechim |
|---|---|---|
cache_read_input_tokens doim 0 |
Prefiksda jim keshbuzar (Date.now, UUID, ID, tartibsiz JSON) | O'zgaruvchanni oxiriga ko'chiring, JSON ni tartiblang, system'ni muzlating |
cache_creation_input_tokens ham 0 |
Prefiks minimal'dan qisqa (Opus 4.8 da < 4096 token) | Prefiks o'lchamini oshiring yoki keshlashdan voz keching |
| Kesh kutilmaganda buzildi | Tool to'plami yoki model suhbat o'rtasida o'zgardi | Tool va modelni barqaror saqlang; "rejim"ni xabar mazmuni qiling |
| Faqat yozish bor, o'qish yo'q | Har so'rov noyob prefiks; qayta ishlatiladigan prefiks yo'q | Bu holatda keshlash foydasiz β cache_control ni olib tashlang |
| Breakpoint butun promptdan keyin qo'yilgan | Har so'rov alohida kesh yozadi, o'qish yo'q | Breakpointni barqaror qism oxiriga qo'ying, o'zgaruvchandan oldin |
| 5+ breakpoint qo'yildi | Eng ko'pi 4 ta breakpoint | 4 ta bilan cheklang |
| Kesh tez "o'lib" qolyapti | 5 daqiqalik TTL trafik tanaffusidan qisqa | ttl: "1h" ishlating yoki keshni qayta-isiting |
Diqqat β narxni o'lchang, taxmin qilmang. Keshlash foydasini ko'rish uchun haqiqiy
usageraqamlarini log qiling va bir necha so'rovda kuzating. "Keshlash qo'shdim, demak arzon bo'ldi" β bu xato xulosa: agarcache_read_input_tokens0 bo'lsa, siz aslida 1.25Γ to'lab, hech narsa tejamayapsiz. Token narxini hisoblash 14 β Token, narx va limitlar bobida; ishonchlilik va xatolar β keyingi 16 β Xatolar, retry va ishonchlilik bobida.
Mashqlar¶
Quyidagi mashqlarning ko'pi haqiqiy ANTHROPIC_API_KEY va tarmoq talab qiladi β chunki keshni faqat bir necha so'rovdan keyin usage orqali ko'rish mumkin. client β new Anthropic() (02-bob).
Oson¶
- Birinchi keshlash. Kamida ~5000 tokenli katta matnni
systemichidacache_control: { type: "ephemeral" }bilan yuboring, bir savol bering.msg.usage.cache_creation_input_tokensnoldan katta ekanini ko'ring (kesh yozildi). - Top-level avto-keshlash. Xuddi shu matnni
systemoddiy satr sifatida + top-levelcache_control: { type: "ephemeral" }bilan yuboring. Natija 1-mashqdagidek bo'lganini tekshiring. - O'qishni ko'rish. 1-mashqdagi so'rovni ikki marta (bir xil prefiks bilan) yuboring. Ikkinchisida
cache_read_input_tokensnoldan katta ekanini ko'ring.
O'rta¶
- Jim keshbuzarni topish.
systemprompt boshiga${Date.now()}qo'shing va ikki marta yuboring.cache_read_input_tokens0 bo'lib qolganini ko'ring. KeyinDate.now()nimessagesdagi oxirgi xabarga ko'chiring β endicache_readnoldan katta bo'lishini tasdiqlang. - JSON tartibini barqarorlashtirish. Sozlamalar obyektini
JSON.stringify(obj)bilan system'ga qo'shib ikki marta yuboring (orada obyekt kalitlari tartibini o'zgartiring). Kesh buzilishini ko'ring, so'ngJSON.stringify(obj, Object.keys(obj).sort())bilan tuzating. - Break-even hisobi. 20 000 tokenli prefiksni 5 savolda ishlatsangiz, keshli va keshsiz narxni
usageraqamlari asosida solishtiring (yozish ~1.25Γ, o'qish ~0.1Γ, keshsiz 1Γ). Necha foiz tejadingiz?
Qiyin¶
- Hujjat bilan suhbat. Kapstondagi ilovani quring: katta matnni bir marta keshlang, unga 4 ta turli savol bering. Har savolda kesh holatini (
yozildi/o'qildi) log qiling. Faqat 1-savol keshni yozganini ko'rsating. - Minimal prefiks chegarasi. Atayin ~1000 tokenli kichik prefiksni Opus 4.8 da
cache_controlbilan yuboring.cache_creation_input_tokens0 bo'lib qolishini (jim keshlanmaslik) ko'ring. Keyin prefiksni ~5000 tokenga oshirib, kesh ishga tushishini tasdiqlang. - Foydalanuvchilar orasida ulashish. Bir xil katta system promptni ikki xil foydalanuvchi savoli bilan yuboring (savol β
messagesda, oxirda; foydalanuvchi ID si prefiksda EMAS). Ikkinchi so'rovdacache_readnoldan katta ekanini β ya'ni prefiks foydalanuvchilar orasida ulashilganini β ko'ring.
Yechimlar
Yechimlar
ANTHROPIC_API_KEY(.env) talab qiladi.clientβnew Anthropic()(02-bob). Katta matnni o'zingiznikiga moslang (kamida ~5000 token, Opus 4.8 uchun yaxshisi ~5000+).
1-mashq yechimi¶
const matn = "..."; // ~5000+ token barqaror matn
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [
{ type: "text", text: matn, cache_control: { type: "ephemeral" } },
],
messages: [{ role: "user", content: "Bu matn nima haqida? Bir jumlada ayt." }],
});
console.log("yozildi:", msg.usage.cache_creation_input_tokens); // > 0 bo'lishi kerak
Birinchi so'rovda kesh yoziladi, shuning uchun cache_creation_input_tokens noldan katta. cache_read esa hali 0 (kesh endigina paydo bo'ldi).
2-mashq yechimi¶
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
cache_control: { type: "ephemeral" }, // oxirgi keshlanadigan blokni avto-keshlaydi
system: matn, // oddiy satr ham bo'ladi
messages: [{ role: "user", content: "Bu matn nima haqida?" }],
});
console.log("yozildi:", msg.usage.cache_creation_input_tokens);
Top-level cache_control qo'lda blok ajratmasdan oxirgi keshlanadigan blokni keshlaydi. Natija 1-mashqdagidek: cache_creation noldan katta.
3-mashq yechimi¶
async function bir_marta() {
return client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [{ type: "text", text: matn, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "Bu matn nima haqida?" }],
});
}
const a = await bir_marta();
console.log("1:", a.usage.cache_creation_input_tokens, a.usage.cache_read_input_tokens);
const b = await bir_marta(); // BIR XIL prefiks
console.log("2:", b.usage.cache_creation_input_tokens, b.usage.cache_read_input_tokens);
// 1: katta, 0 (yozildi)
// 2: 0, katta (o'qildi β kesh ishladi!)
Ikkinchi so'rovda prefiks bir xil bo'lgani uchun cache_read_input_tokens noldan katta β kesh o'qildi. Bu keshlash haqiqatan ishlayotganining isboti.
4-mashq yechimi¶
// β Jim keshbuzar: Date.now() prefiks BOSHIDA
async function buzuq() {
return client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [
// har so'rovda boshqa son -> prefiks o'zgaradi -> kesh promah
{ type: "text", text: `Vaqt: ${Date.now()}\n${matn}`, cache_control: { type: "ephemeral" } },
],
messages: [{ role: "user", content: "Bu nima haqida?" }],
});
}
console.log((await buzuq()).usage.cache_read_input_tokens); // 0
console.log((await buzuq()).usage.cache_read_input_tokens); // 0 β hech qachon o'qilmaydi
// β
Tuzatilgan: vaqt OXIRGA, messages ichiga ko'chdi
async function togri() {
return client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [{ type: "text", text: matn, cache_control: { type: "ephemeral" } }], // barqaror
messages: [{ role: "user", content: `Vaqt: ${Date.now()}\nBu nima haqida?` }], // o'zgaruvchan, oxirda
});
}
await togri(); // yozadi
console.log((await togri()).usage.cache_read_input_tokens); // > 0 β endi o'qiladi
Date.now() prefiks boshida bo'lganda har so'rov noyob bo'ladi β kesh hech qachon o'qilmaydi. Uni breakpoint'dan keyingi messages ga ko'chirsangiz, prefiks barqarorlashadi va kesh ishlaydi.
5-mashq yechimi¶
const sozlamalar = { til: "uz", rejim: "qisqa", daraja: 2 };
// β Tartibsiz: kalitlar tartibi farq qilsa, baytlar farq qiladi
const buzuq = `Sozlamalar: ${JSON.stringify(sozlamalar)}\n${matn}`;
// β
Barqaror: kalitlar har doim bir xil tartibda
const togri = `Sozlamalar: ${JSON.stringify(sozlamalar, Object.keys(sozlamalar).sort())}\n${matn}`;
// `togri` ni ikki marta yuborsangiz, ikkinchisida cache_read > 0.
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [{ type: "text", text: togri, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "Davom et." }],
});
JSON.stringify ni Object.keys(...).sort() bilan tartiblang β shunda kalitlar tartibi qanday bo'lishidan qat'i nazar, chiqqan satr har safar bir xil baytlar bo'ladi va prefiks barqaror qoladi.
6-mashq yechimi¶
const matn = "..."; // ~20 000 token
const savollar = ["Q1?", "Q2?", "Q3?", "Q4?", "Q5?"];
let yozish = 0, oqish = 0, keshsiz = 0;
for (const s of savollar) {
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [{ type: "text", text: matn, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: s }],
});
yozish += msg.usage.cache_creation_input_tokens;
oqish += msg.usage.cache_read_input_tokens;
keshsiz += msg.usage.input_tokens;
}
// Taxminiy narx birligi (input narxiga nisbatan koeffitsiyent):
const keshli = yozish * 1.25 + oqish * 0.1 + keshsiz * 1;
const keshsizN = (yozish + oqish + keshsiz) * 1; // hammasi to'liq narxda bo'lsa edi
console.log("Keshli:", keshli, "Keshsiz:", keshsizN);
console.log("Tejov:", (100 * (1 - keshli / keshsizN)).toFixed(1), "%");
5 savolda hujjat 1 marta yoziladi (~1.25Γ) va 4 marta o'qiladi (4Γ0.1Γ). Katta prefiks uchun tejov 60% dan oshadi. Yig'indiga input_tokens (savollar) ham kiradi β ular keshlanmaydi.
7-mashq yechimi¶
import fs from "node:fs";
const hujjat = fs.readFileSync("qollanma.txt", "utf8");
const SYSTEM = "Sen hujjat bo'yicha javob beradigan yordamchisan. Faqat hujjatga tayan.";
async function sora(savol) {
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 512,
system: [
{ type: "text", text: SYSTEM },
{ type: "text", text: hujjat, cache_control: { type: "ephemeral" } }, // barqaror prefiks oxiri
],
messages: [{ role: "user", content: savol }], // o'zgaruvchan
});
const u = msg.usage;
console.log(u.cache_read_input_tokens > 0 ? "β
keshdan o'qildi" : "π‘ yangi/yozildi",
`(yozildi=${u.cache_creation_input_tokens}, o'qildi=${u.cache_read_input_tokens})`);
return msg.content[0].text;
}
await sora("Qaytarish siyosati?"); // π‘ yozildi
await sora("Yetkazish muddati?"); // β
o'qildi
await sora("Kafolat?"); // β
o'qildi
await sora("To'lov usullari?"); // β
o'qildi
Faqat birinchi savol keshni yozadi (cache_creation katta). Qolgan uchtasi o'qiydi. Bu "hujjat bilan suhbat"ning narx poydevori: bir marta yukla/keshla, ko'p marta arzon so'ra.
8-mashq yechimi¶
const kichik = "..."; // ~1000 token (Opus 4.8 minimal 4096 dan kichik)
const m1 = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 128,
system: [{ type: "text", text: kichik, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "Salom" }],
});
console.log("kichik prefiks yozildi:", m1.usage.cache_creation_input_tokens); // 0 β jim keshlanmadi!
const katta = "..."; // ~5000 token (4096 dan katta)
const m2 = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 128,
system: [{ type: "text", text: katta, cache_control: { type: "ephemeral" } }],
messages: [{ role: "user", content: "Salom" }],
});
console.log("katta prefiks yozildi:", m2.usage.cache_creation_input_tokens); // > 0 β ishladi
Opus 4.8 da minimal keshlanadigan prefiks β 4096 token. Undan kichigi xato bermaydi, lekin cache_creation_input_tokens 0 qaytaradi β kesh jim ishlamaydi. Prefiksni oshirsangiz, kesh ishga tushadi.
9-mashq yechimi¶
const SYSTEM = "..."; // ~5000+ token barqaror system prompt (foydalanuvchi ID si YO'Q)
async function sora(savol) {
return client.messages.create({
model: "claude-opus-4-8",
max_tokens: 256,
system: [{ type: "text", text: SYSTEM, cache_control: { type: "ephemeral" } }],
// foydalanuvchi ID si va savol β messages ichida, oxirda
messages: [{ role: "user", content: savol }],
});
}
const u1 = await sora("Foydalanuvchi A: narxlar qanday?"); // yozadi
const u2 = await sora("Foydalanuvchi B: ish vaqti qachon?"); // o'qiydi β boshqa savol, BIR XIL prefiks
console.log(u1.usage.cache_creation_input_tokens); // > 0
console.log(u2.usage.cache_read_input_tokens); // > 0 β prefiks ulashildi!
System prompt barqaror va foydalanuvchiga bog'liq emas β shuning uchun u har xil foydalanuvchi so'rovlari orasida ulashiladi. Agar foydalanuvchi ID sini prefiks boshiga qo'yganingizda, har foydalanuvchi alohida kesh yozardi va bu ulashish yo'qolardi. Foydalanuvchiga oid narsani har doim messages ga, oxirga qo'ying.
Keyingi qadam. Endi siz narxni keskin tushiradigan eng kuchli dastagni bilasiz: bir xil katta prefiksni qayta-qayta yuborsangiz, uni keshlang. Bitta qoidani yodda tuting β keshlash prefiks moslik: barqaror narsa oldinda, o'zgaruvchan narsa (vaqt, savol, ID) oxirda.
cache_control: { type: "ephemeral" }ni katta barqaror blokga qo'ying,msg.usage.cache_read_input_tokensorqali ishlayotganini tekshiring, va jim keshbuzarlardan (Date.now, UUID, tartibsiz JSON) saqlaning. Keyingi bobda ilovangizni ishonchli qilamiz: API xatolari, qayta urinish (retry), eksponensial kechikish va429/529kabi holatlarni qanday to'g'ri boshqarishni o'rganamiz.
β¬ οΈ Oldingi: 14 β Token, narx va limitlar Β· π README Β· Keyingi: 16 β Xatolar, retry va ishonchlilik β‘οΈ