Semantic Cache للـ AI: قلّل الردود المتكررة بدون ما تبوّظ الدقة
مستوى القارئ: متوسط
هتخرج من المقال ده بطريقة عملية تقلل زمن وتكلفة ردود تطبيق AI، من غير ما تعتمد على cache أعمى يرجّع إجابات قديمة لكل الناس.
المشكلة باختصار
لو عندك chatbot داخلي للدعم الفني، غالبًا المستخدمين بيسألوا نفس المعنى بصيغ مختلفة. واحد يكتب: "إزاي أغير كلمة السر؟"، والتاني يكتب: "فين أعمل reset للباسورد؟". الـ exact cache مش هيعتبرهم نفس السؤال، وهيبعت الاتنين للـ LLM.
اللي بيحصل فعلاً إنك بتدفع تكلفة prompt ووقت استدعاء للنموذج على طلب كان ممكن يتجاب من cache. في سيناريو بسيط لموقع SaaS عنده 50K سؤال دعم يوميًا، لو 35% من الأسئلة متشابهة دلاليًا، فأنت قدام فرصة واضحة لتقليل الاستدعاءات المتكررة.
الفكرة بمثال قبل التعريف
ركز في المثال ده. عندك إجابة محفوظة لسؤال: "How do I reset my password?". بعد دقيقة، مستخدم عربي يسأل: "أعمل reset للباسورد منين؟". الـ string مختلف، لكن المعنى قريب.
Semantic Cache يعمل 3 خطوات: يحوّل السؤال الجديد إلى embedding، يدور في Redis أو vector database عن سؤال قديم قريب، ولو المسافة أقل من threshold محدد يرجّع الإجابة المحفوظة بدل استدعاء النموذج.
التعريف العلمي: Semantic Cache هو cache يستخدم تمثيلًا متجهيًا للنصوص بدل مطابقة النص حرفيًا. المسافة بين المتجهات تقيس قرب المعنى. OpenAI توضح أن embeddings تمثل النص كقائمة أرقام، والمسافات الصغيرة تشير لعلاقة معنوية أقرب.
تنفيذ عملي بـ Python و RedisVL
الافتراض إن عندك Redis متاح على localhost:6379، وتطبيقك يقدر يولّد إجابات من LLM عند الـ miss. المثال التالي يوضح الهيكل، وليس تكاملًا كاملًا مع كل مزود.
pip install redisvl sentence-transformers
from redisvl.extensions.cache.llm import SemanticCache
from redisvl.utils.vectorize import HFTextVectorizer
cache = SemanticCache(
name="support_ai_cache",
redis_url="redis://localhost:6379",
distance_threshold=0.12,
ttl=60 * 60 * 24,
vectorizer=HFTextVectorizer("sentence-transformers/all-MiniLM-L6-v2"),
)
def ask_llm(prompt: str) -> str:
# استبدلها باستدعاء النموذج الحقيقي عندك
return "افتح Settings ثم Security ثم اختار Reset password."
def answer_user(prompt: str) -> str:
hits = cache.check(prompt=prompt, num_results=1)
if hits:
return hits[0]["response"]
response = ask_llm(prompt)
cache.store(prompt=prompt, response=response)
return response
print(answer_user("إزاي أغير كلمة السر؟"))
print(answer_user("فين أعمل reset للباسورد؟"))