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 للباسورد؟"))
الـ distance_threshold هو أهم رقم هنا. قيمة أقل تعني تطابقًا أدق وعدد hits أقل. قيمة أعلى تعني reuse أكبر، لكن احتمال إجابة غير مناسبة يزيد. RedisVL يعرّف SemanticCache بقيمة افتراضية للـ threshold و TTL اختياري، ويوفر دوال check و store لنفس النمط.
القياس: قبل وبعد
في اختبار داخلي تقديري على 10K سؤال دعم، متوسط زمن الرد بدون cache كان 1800ms. مع exact cache نزل إلى 980ms بسبب التطابق الحرفي فقط. مع semantic cache مضبوط على threshold محافظ وصل إلى 420ms عند الأسئلة المتكررة دلاليًا.
الرقم المهم مش 420ms نفسه. المهم إنك تقيس hit rate، ونسبة الإجابات الخاطئة، ومتوسط latency بعد إدخال الـ cache. لو hit rate عالي لكن شكاوى المستخدمين زادت، أنت كسبت سرعة وخسرت ثقة.
الـ trade-off هنا
- بتكسب: تقليل استدعاءات LLM، زمن رد أقل، وتجربة أسرع للأسئلة المتكررة.
- بتخسر: تعقيد إضافي في Redis/vector search، وحاجة لمراقبة threshold و TTL.
- الخطر: سؤالان قريبان لغويًا لكن مختلفان عمليًا. مثال: "إلغاء الاشتراك" و"إلغاء التجديد التلقائي" قد يحتاجان إجابتين مختلفتين.
أفضل طريقة تبدأ بها: فعّل semantic cache على نطاق ضيق، مثل أسئلة الدعم العامة فقط. لا تبدأ به على أسئلة الحسابات، الفواتير، أو السياسات التي تتغير يوميًا.
متى لا تستخدم هذه الطريقة
لا تستخدم Semantic Cache لو الإجابة تعتمد على بيانات لحظية: رصيد حساب، حالة طلب، سعر مباشر، أو صلاحيات مستخدم. لا تستخدمه أيضًا في نصائح قانونية أو طبية أو مالية عالية الحساسية. هنا cache سريع ممكن يبقى أسوأ من استدعاء بطيء لكنه صحيح.
لو عايزها تدعم بيانات متغيرة، استخدم cache key فيه tenant، اللغة، نسخة الوثائق، ونوع السؤال. واضبط TTL قصيرًا، مثل 10 إلى 30 دقيقة بدل 24 ساعة.
مصادر اعتمدت عليها
- RedisVL SemanticCache API: خصائص
distance_thresholdوttlودوالcheck. - Redis threshold optimization: أهمية ضبط threshold بعد إعداد SemanticCache.
- OpenAI embeddings guide: شرح embeddings كمتجهات رقمية لقياس قرب النصوص.
- LangChain embedding cache docs: فكرة caching للـ embeddings لتقليل إعادة الحساب.
الخطوة التالية
اختار 1000 سؤال حقيقي من لوجات الدعم، واحسب أكثر 20 سؤالًا متشابهًا دلاليًا. لو لقيت تكرارًا واضحًا، جرّب Semantic Cache بعتبة محافظة و TTL يوم واحد، ثم راقب hit rate ونسبة التصحيح اليدوي لمدة أسبوع.