التخزين المؤقت للمطالبات
تلقائيتقوم النماذج المستضافة ذات الأوزان المفتوحة (open-weight) بتخزين بادئات المطالبات المكررة تلقائيًا. عندما يبدأ الطلب بنفس مطالبة النظام، والأدوات، والرسائل السابقة لطلب حديث على نفس النموذج، يتم قراءة هذه البادئة المشتركة من ذاكرة التخزين المؤقت وتُحتسب بنسبة 25% من سعر مدخلات النموذج. لا يوجد شيء لتفعيله، وعمليات الكتابة في ذاكرة التخزين المؤقت مجانية.
كيف يعمل
- البادئة، بالترتيب — تُقرأ المطالبة بالترتيب: مطالبة النظام، ثم تعريفات الأدوات، ثم الرسائل. تتطابق ذاكرة التخزين المؤقت من بداية هذا التسلسل حتى أول token يختلف.
- ما الذي يُعتبر 'إصابة' (hit) — الطلب الذي تبدأ مطالبته بنفس محتوى طلب حديث — عادةً ما يكون الدور السابق من نفس المحادثة مع إضافة رسائل جديدة. البادئة المتطابقة هي مدخلات مخبأة؛ وكل شيء بعدها هو مدخلات عادية.
- الدقة (Granularity) — تحتفظ ذاكرة التخزين المؤقت بالمطالبة في كتل من 1,568 token، لذا لا تُخزَّن مؤقتاً المطالبة الأقصر من نحو 1,500 token. عدد المخبأ في الرد هو عدد مدخلاتك مضروباً في الحصة المخبأة من المطالبة، مقرباً إلى الأسفل. وليس بالضرورة من مضاعفات حجم الكتلة.
- من دون إصابة — الطلب الذي لا توجد بدايته في ذاكرة التخزين المؤقت يُحاسَب بسعر المدخلات العادي. لا تُنشر مدة بقاء للمطالبات المخبأة والإصابة غير مضمونة: اقرأ
usageلمعرفة ما أخذه الطلب من ذاكرة التخزين المؤقت. - بلا مفتاح تبديل — الطلب لا يشترك في الميزة، ولا يوجد حقل يوقف التخزين المؤقت.
- أي النماذج — كل معرف open-weight مستضاف. يبلغ GET /v1/models عن capabilities.prompt_caching: true و pricing.cached_input_per_million_usd لها. نماذج Shannon تفرض سعرًا موحدًا.
رؤية إصابة التخزين المؤقت في رد
أرسل طلبين يبدآن بنفس توجيهات النظام الطويلة واطبع استخدام كل منهما. الرقم الأول هو مدخلات الطلب، والثاني هو الجزء منها الذي قُرئ من ذاكرة التخزين المؤقت.
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
handbook = open("handbook.txt").read() # a long text that stays the same
def ask(question):
response = client.chat.completions.create(
model="Kimi-K3-3BIT-REAP",
messages=[
{"role": "system", "content": handbook},
{"role": "user", "content": question},
],
)
usage = response.usage
print(usage.prompt_tokens, usage.prompt_tokens_details.cached_tokens)
ask("What is the refund policy?")
ask("Who approves travel?") # same start: read the second number import { readFileSync } from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const handbook = readFileSync("handbook.txt", "utf8"); // a long text that stays the same
async function ask(question) {
const response = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
messages: [
{ role: "system", content: handbook },
{ role: "user", content: question },
],
});
const usage = response.usage;
console.log(usage.prompt_tokens, usage.prompt_tokens_details.cached_tokens);
}
await ask("What is the refund policy?");
await ask("Who approves travel?"); // same start: read the second number # handbook.txt is a long text that stays the same. jq builds the JSON body from it
# and prints the usage object of the reply. Run it twice with different questions.
jq -Rs '{
model: "Kimi-K3-3BIT-REAP",
messages: [
{role: "system", content: .},
{role: "user", content: "What is the refund policy?"}
]
}' handbook.txt \
| curl -s https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d @- \
| jq .usage التسعير
تُحتسب tokens المدخلات المخبأة بنسبة 25% من سعر مدخلات النموذج، مقربة إلى $0.001 لكل 1M. الكتابة في ذاكرة التخزين المؤقت لا تكلف شيئًا إضافيًا، وتُحتسب المخرجات كالمعتاد. سعر التخزين المؤقت لكل معرف موجود في جدول 'النماذج والتسعير'. النماذج والأسعار
تُحاسَب مدخلات الاستدعاء على النحو (المدخلات − المخبأ) × سعر المدخلات + المخبأ × سعر المخبأ. عدد المخبأ لا يكون أبداً أكبر من عدد المدخلات.
| النموذج | المدخلات / 1M | المدخلات المخبأة / 1M |
|---|---|---|
DeepSeek-V4-Pro-0813-3BIT-REAP | $1.95 | $0.488 |
GLM-5.2-3BIT-REAP | $0.73 | $0.183 |
Kimi-K3-3BIT-REAP | $3.83 | $0.958 |
Nemotron3Ultra-3BIT-REAP | $0.75 | $0.188 |
MiniMax-M3-3BIT-REAP | $0.50 | $0.125 |
DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP | $0.50 | $0.125 |
Kimi-K2.6-W4A16-AUTOROUND-REAP | $0.78 | $0.195 |
Laguna-S-2.1-W4A16-AUTOROUND-REAP | $0.50 | $0.125 |
inkling-W4A16-AUTOROUND-REAP | $1.42 | $0.355 |
MiMo-V2.5-Pro-W8A16 | $0.50 | $0.125 |
MiMo-V2.5-W8A16 | $0.50 | $0.125 |
Hy3-W8A16 | $0.50 | $0.125 |
يسرد سجل الاستخدام المدخلات المخبأة لكل استدعاء. وتشمل الـ tokens المحاسَبة والتكلفة فيه سعر المخبأ بالفعل. المفاتيح والاستخدام
حقول الاستخدام
| نقطة النهاية (Endpoint) | المدخلات المخبأة | الاستنتاج (Reasoning) |
|---|---|---|
/v1/chat/completions | usage.prompt_tokens_details.cached_tokens — جزء من prompt_tokens | usage.completion_tokens_details.reasoning_tokens — جزء من completion_tokens |
/v1/responses | usage.input_tokens_details.cached_tokens — جزء من input_tokens | usage.output_tokens_details.reasoning_tokens — جزء من output_tokens |
/v1/messages | usage.cache_read_input_tokens — يُبلغ عنها بشكل منفصل: input_tokens هو الجزء غير المخبأ؛ و cache_creation_input_tokens تكون دائمًا 0 | يتم حساب التفكير (thinking) ضمن output_tokens |
{
"usage": {
"prompt_tokens": 20000,
"completion_tokens": 812,
"total_tokens": 20812,
"prompt_tokens_details": {
"cached_tokens": 18000
},
"completion_tokens_details": {
"reasoning_tokens": 604
}
}
} {
"usage": {
"input_tokens": 20000,
"input_tokens_details": {
"cached_tokens": 18000
},
"output_tokens": 812,
"output_tokens_details": {
"reasoning_tokens": 604
},
"total_tokens": 20812
}
} {
"usage": {
"input_tokens": 2000,
"cache_read_input_tokens": 18000,
"cache_creation_input_tokens": 0,
"output_tokens": 812
}
} يحمل الرد المبثوث الحقول نفسها في استخدامه الأخير. لا تحتاج إلى طلبه:
| نقطة النهاية (Endpoint) | أين يصل الاستخدام |
|---|---|
/v1/chat/completions | usage في آخر جزء قبل data: [DONE]. يُرسل في كل بث. |
/v1/responses | response.usage في الحدث response.completed. |
/v1/messages | usage في الحدث message_delta. أما usage في message_start فيحتوي على أصفار. |
كيفية زيادة إصابات التخزين المؤقت
- حافظ على استقرار مطالبة النظام وتعريفات الأدوات بدقة (byte-for-byte) عبر الاستدعاءات. ضع القيم المتغيرة لكل استدعاء مثل الطوابع الزمنية أو معرفات الطلبات في نهاية الرسالة الأخيرة، وليس في مطالبة النظام.
- قم بالإلحاق بالسجل فقط. إن تحرير أو تقليم أو تلخيص الأدوار السابقة يغير البادئة، وكل شيء بعد أول تغيير يُحتسب كمدخلات عادية.
- لا تعيد ترتيب الأدوات أو الرسائل أو كتل المحتوى بين الاستدعاءات، وقم بتسلسل JSON (مخططات الأدوات، وسيطات الأدوات ونتائجها) بنفس الطريقة في كل مرة.
- ابقَ على معرّف نموذج واحد طوال المحادثة، وأرسل الاستدعاء التالي بعد السابق بوقت قصير.
تُبقي API بداية المحادثة ثابتة في هذه الحالات:
- رسالة
systemأوdeveloperتُرسل لاحقاً في المحادثة تبقى في مكانها. فهي لا تغيّر بداية المطالبة، لذا تبقى الأدوار التي قبلها مخبأة. - تُقارن وسائط استدعاءات الأدوات في أدوار المساعد السابقة بالقيمة. ترتيب المفاتيح والمسافات في ذلك JSON لا يهمان.
- تقرأ نقاط النهاية الثلاث المحادثة بالطريقة نفسها. المحادثة التي تُستكمل على نقطة نهاية أخرى تحتفظ ببادئتها المشتركة عندما يكون المحتوى نفسه.
حقول الطلب
يتم قبول prompt_cache_key (في Chat Completions و Responses) و cache_control في كتل محتوى Messages، لذا تعمل أكواد العميل الحالية دون تغيير. كلاهما ليس إلزامياً: فالتخزين المؤقت (caching) تلقائي ويعمل بنفس الطريقة بدونهما.
| الحقل | يُرسل إلى | ما هو |
|---|---|---|
prompt_cache_key | /v1/chat/completions, /v1/responses | مفتاح توجيه للتخزين المؤقت في OpenAI API. |
cache_control | /v1/messages | نقطة فصل للتخزين المؤقت على كتلة محتوى أو كتلة system أو رسالة في Anthropic API. |
stream_options | /v1/chat/completions | يطلب include_usage من OpenAI API إرسال الاستخدام في البث. هنا ينتهي كل بث بالاستخدام. |
حساب الـ tokens
نقطتا نهاية مجانيتان، POST /v1/tokenize وPOST /v1/messages/count_tokens، تحسبان tokens نص أو طلب كامل للنماذج المفتوحة الأوزان المستضافة قبل أن ترسله. لها صفحتها الخاصة: عدّ الـ tokens