AI Infrastructure

بی‌اعتبارسازی کش برای سیستم‌های RAG پویا

سیستم‌های تولید تقویت‌شده با بازیابی (RAG) قدرتمند هستند، اما با یک چالش معماری حیاتی مواجه‌اند: تازگی داده‌ها. هنگامی که پایگاه دانش شما به‌طور پویا به‌روزرسانی می‌شود، انبار برداری و کش‌های محلی می‌توانند جاسازی‌های منقضی‌شده را ارائه دهند که منجر به توهم یا پاسخ‌های قدیمی می‌شود. مدیریت این «کهنه‌بودن» صرفاً یک بهینه‌سازی نیست؛ بلکه یک الزام دقت است. این مقاله استراتژی‌های محکم بی‌اعتبارسازی کش را برای اطمینان از بازتاب آخرین حقیقت در خط لوله RAG شما بررسی می‌کند.

مشکل داده‌های برداری منقضی‌شده

در یک جریان کاری استاندارد RAG، اسناد به تکه‌ها تقسیم شده، جاسازی می‌شوند و در یک پایگاه داده برداری ذخیره می‌شوند. بسیاری از پیاده‌سازی‌ها همچنین از یک کش معنایی برای ذخیره جفت‌های پرسش-پاسخ به منظور کاهش تأخیر و هزینه استفاده می‌کنند. خطر در شکاف زمانی بین به‌روزرسانی یک سند و زمانی که ایندکس یا کش آن تغییر را بازتاب می‌دهد نهفته است.

اگر کاربری بر اساس یک سیاستی که اخیراً به‌روزرسانی شده سوالی بپرسد، اما جستجوی برداری جاسازی قدیمی را برگرداند، مدل زبانی بزرگ (LLM) پاسخی بر اساس اطلاعات منسوخ تولید خواهد کرد. این امر اعتماد کاربر را سایش می‌دهد و می‌تواند منجر به ریسک‌های تجاری قابل توجه شود.

استراتژی ۱: بی‌اعتبارسازی مبتنی بر نسخه

قابل‌اتکا‌ترین روش، نسخه‌بندی صریح است. هر سند یا تکه باید یک فیلد متادیتا داشته باشد که نسخه یا زمان戳 آخرین تغییر آن را نشان دهد. هنگامی که یک تکه جدید در پایگاه داده برداری upsert می‌شود، نسخه قدیمی یا حذف می‌شود یا به عنوان غیرفعال علامت‌گذاری می‌گردد.

برای کش‌های معنایی، می‌توانید یک «اثر انگشت» از اسناد منبعی که برای تولید پاسخ کش‌شده استفاده شده‌اند را ذخیره کنید. قبل از ارائه یک نتیجه کش‌شده، اطمینان حاصل کنید که اثر انگشت‌های تکه‌های برتر بازیابی‌شده فعلی با آن‌هایی که در ورودی کش وجود دارد مطابقت دارند. اگر مطابقت نداشته باشند، کش را بی‌اعتبار کنید و یک پاسخ تازه تولید کنید.


import hashlib
import time

def generate_fingerprint(chunks: list[dict]) -> str:
    """
    تولید یک هش سازگار برای مجموعه‌ای از تکه‌های بازیابی‌شده.
    """
    # مرتب‌سازی تکه‌ها بر اساس شناسه برای اطمینان از ترتیب سازگار
    sorted_chunks = sorted(chunks, key=lambda x: x['id'])
    # ایجاد یک نمایش رشته‌ای از شناسه‌ها و نسخه‌های تکه‌ها
    content = ''.join(f"{c['id']}:{c['version']}" for c in sorted_chunks)
    return hashlib.md5(content.encode('utf-8')).hexdigest()

def check_cache_validity(cache_key: str, current_chunks: list[dict], cache_store: dict) -> bool:
    """
    بررسی اینکه آیا یک پاسخ کش‌شده بر اساس نسخه‌های تکه‌ها هنوز معتبر است.
    """
    if cache_key not in cache_store:
        return False
    
    cached_fingerprint = cache_store[cache_key]['fingerprint']
    current_fingerprint = generate_fingerprint(current_chunks)
    
    # اگر داده‌های پایه تغییر کرده باشد، بی‌اعتبار کنید
    if cached_fingerprint != current_fingerprint:
        print(f"کش برای {cache_key} به دلیل تغییر داده بی‌اعتبار شد.")
        del cache_store[cache_key]
        return False
        
    # همچنین TTL را به عنوان یک شبکه ایمنی ثانویه بررسی کنید
    if time.time() - cache_store[cache_key]['timestamp'] > 300: # ۵ دقیقه
        del cache_store[cache_key]
        return False
        
    return True

استراتژی ۲: تخلیه کش مبتنی بر رویداد

برای سیستم‌هایی با پهنای باند بالا، بررسی اثر انگشت در هر پرسش بار محاسباتی اضافه می‌کند. یک جایگزین، رویکرد مبتنی بر رویداد است. هنگامی که یک به‌روزرسانی سند رخ می‌دهد، یک رویداد را به یک صف پیام (مانند Kafka یا Redis Pub/Sub) منتشر کنید.

یک کارگر پس‌زمینه به دنبال این رویدادها گوش می‌دهد و به‌طور پیش‌دستانه ورودی‌های کش مرتبط را تخلیه می‌کند. می‌توانید شناسه‌های اسناد را به کلیدهای کش نگاشت کنید. هنگامی که یک شناسه سند به‌روزرسانی می‌شود، تمام کلیدهای کش معنایی را که به آن سند ارجاع داده بودند جستجو کرده و حذف می‌کنید. این رویکرد مسیر پرسش را سریع نگه می‌دارد و هزینه بی‌اعتبارسازی را به مسیر نوشتن منتقل می‌کند.

رویکرد ترکیبی: انقضا احتمالی

در سناریوهایی که نسخه‌بندی دقیق دشوار است، می‌توانید از انقضا احتمالی با یک زمان زندگی (TTL) بسیار کوتاه استفاده کنید. اگرچه این کار یکپارچگی را تضمین نمی‌کند، اما تنظیم TTL روی ۳۰ تا ۶۰ ثانیه اطمینان می‌دهد که داده‌ها هرگز *بسیار* کهنه نباشند. این روش بهتر است با منطق بررسی نسخه‌های فوق برای فیلدهای حیاتی ترکیب شود. برای زمینه‌های غیرحیاتی، یک TTL کوتاه اغلب برای تعادل بین تأخیر و تازگی کافی است.

نتیجه‌گیری

سیستم‌های RAG پویا به چیزی فراتر از جستجوی شباهت برداری نیاز دارند؛ آن‌ها به یک استراتژی یکپارچگی داده نیاز دارند. با پیاده‌سازی اثر انگشت مبتنی بر نسخه برای کش‌های معنایی و استفاده از تخلیه مبتنی بر رویداد برای ایندکس‌های برداری، می‌توانید ریسک ارائه داده‌های منقضی‌شده را به‌طور قابل توجهی کاهش دهید. با ممیزی خط لوله RAG فعلی خود برای شناسایی جایی که فرض‌های تازگی داده‌ها مطرح می‌شوند شروع کنید و سپس منطق بی‌اعتبارسازی را که با نیازمندی‌های یکپارچگی شما مطابقت دارد پیاده‌سازی کنید. در عصر هوش مصنوعی بلادرنگ، تازگی یک ویژگی است، نه یک باگ.

Share: