جست‌وجو

embedding و جستجوی معنایی روی متن فارسی

embedding چیست، شباهت برداری چه چیزی را نشان می‌دهد و چه چیزی را نه، معامله‌ی recall با تأخیر در ایندکس برداری، و چرا فارسی به جست‌وجوی ترکیبی نیاز دارد.

· ۸ دقیقه مطالعه

کاربر در جست‌وجوی سایت شما می‌نویسد «مرخصی استعلاجی چند روز است» و هیچ نتیجه‌ای نمی‌گیرد، در حالی که سندی وجود دارد با عنوان «آیین‌نامه‌ی غیبت پزشکی کارکنان». جست‌وجوی کلیدواژه‌ای شکست خورده چون هیچ کلمه‌ی مشترکی بین پرسش و سند نیست. این دقیقاً همان جایی است که embedding و جستجوی معنایی وارد می‌شوند — و همان جایی که اگر بی‌احتیاط استفاده شوند، مشکل تازه می‌سازند.

این مقاله سه چیز را توضیح می‌دهد: embedding واقعاً چیست، ایندکس برداری چه معامله‌ای بین دقت و سرعت می‌کند، و چرا برای متن فارسی ترکیب جست‌وجوی کلیدواژه‌ای و برداری تقریباً همیشه بهتر از هرکدام به‌تنهایی است.

embedding یعنی چه

یک مدل embedding متن را می‌گیرد و یک بردار عددی با طول ثابت برمی‌گرداند — مثلاً آرایه‌ای از چند صد یا چند هزار عدد اعشاری. طول بردار به مدل بستگی دارد و ربطی به طول متن ورودی ندارد؛ یک کلمه و یک پاراگراف هر دو به بردارهایی با همان ابعاد تبدیل می‌شوند.

نکته‌ی اصلی این است که این اعداد تصادفی نیستند. مدل طوری آموزش دیده که متن‌هایی با معنای نزدیک، بردارهای نزدیک به هم بگیرند. «نزدیکی» را با یک معیار فاصله می‌سنجیم؛ رایج‌ترین‌شان شباهت کسینوسی است که به زاویه‌ی بین دو بردار نگاه می‌کند نه به طولشان.

بنابراین جست‌وجوی معنایی این‌طور کار می‌کند:

  1. برای هر سند (یا هر تکه از سند) یک بار embedding می‌گیرید و ذخیره می‌کنید.
  2. هنگام جست‌وجو، از متن پرسش هم embedding می‌گیرید.
  3. نزدیک‌ترین بردارهای ذخیره‌شده به بردار پرسش را برمی‌گردانید.

هیچ تطبیق رشته‌ای در کار نیست. به همین دلیل «مرخصی استعلاجی» می‌تواند «غیبت پزشکی» را پیدا کند.

«شبیه» یعنی چه، و یعنی چه نیست

اینجا بیشترین سوءتفاهم شکل می‌گیرد. شباهت برداری، شباهت معنایی و موضوعی است، نه درستی منطقی و نه هم‌ارزی.

چند حالتی که بردارها گمراه می‌کنند:

  • نفی. «این قرارداد قابل تمدید است» و «این قرارداد قابل تمدید نیست» از نظر برداری بسیار نزدیک‌اند. مدل موضوع مشترک را می‌بیند، نه تضاد را.
  • جزئیات عددی و تاریخ. «سقف پرداخت ۵۰ میلیون ریال» و «سقف پرداخت ۵۰۰ میلیون ریال» تقریباً یکسان به نظر می‌رسند.
  • نام‌های خاص. نام دو سامانه یا دو شخص با ساختار مشابه ممکن است نزدیک بیفتند، حتی وقتی هیچ ربطی به هم ندارند.
  • پرسش در برابر پاسخ. یک پرسش کوتاه و سندی که جوابش را دارد لزوماً بردارهای نزدیکی ندارند، چون شکل زبانی‌شان فرق می‌کند. بعضی مدل‌ها برای همین حالت آموزش دیده‌اند و بعضی نه؛ این را قبل از انتخاب مدل بررسی کنید.

پس شباهت بالا یعنی «درباره‌ی یک چیز حرف می‌زنند»، نه «یکی جواب دیگری است». هر سیستمی که روی این تمایز حساب باز نکند، دیر یا زود پاسخ مطمئنِ غلط تولید می‌کند.

ایندکس برداری و معامله‌ی recall با تأخیر

اگر هزار سند دارید، می‌توانید فاصله‌ی بردار پرسش را با تک‌تک بردارها حساب کنید. این جست‌وجوی کامل (brute force) دقیق‌ترین نتیجه‌ی ممکن را می‌دهد. با ده میلیون سند همین کار برای هر درخواست غیرقابل قبول کند می‌شود.

ایندکس‌های برداری این را با جست‌وجوی تقریبی نزدیک‌ترین همسایه (ANN) حل می‌کنند: ساختاری می‌سازند که فقط بخش کوچکی از فضا را می‌گردد. نتیجه تقریبی است — گاهی نزدیک‌ترین همسایه‌ی واقعی را از دست می‌دهد.

از اینجا یک معامله‌ی سه‌طرفه بیرون می‌آید که هر ایندکس برداری با آن درگیر است:

ضلعمعنیاگر فشار بیاورید
recallچند درصد نتایج درست واقعاً برگردانده می‌شودبالا بردنش تأخیر و حافظه را زیاد می‌کند
تأخیرزمان پاسخ هر پرسشکم کردنش recall را پایین می‌آورد
حافظه و هزینهاندازه‌ی ایندکس در RAMفشرده‌سازی بردارها recall را کم می‌کند

چند نکته‌ی عملی:

  • اول با جست‌وجوی کامل شروع کنید. تا وقتی حجم داده کوچک است، ANN فقط پیچیدگی اضافه می‌کند.
  • recall را واقعاً اندازه بگیرید. روش ساده: روی یک نمونه‌ی کوچک، نتایج ANN را با نتایج brute force مقایسه کنید. اگر این عدد را ندارید، نمی‌دانید ایندکس‌تان چقدر نتیجه از دست می‌دهد.
  • کاهش ابعاد و کوانتیزه کردن بردارها حافظه را چشمگیر کم می‌کند و همیشه مقداری دقت می‌گیرد. اندازه‌ی این کاهش را روی داده‌ی خودتان بسنجید، نه بر اساس ادعای عمومی.
  • فیلتر ابرداده (تاریخ، دسته، سطح دسترسی) را در نظر بگیرید. ترکیب فیلتر با ANN می‌تواند recall را به‌شدت پایین بیاورد اگر ایندکس برای آن طراحی نشده باشد.

چرا فارسی جست‌وجوی ترکیبی می‌خواهد

جست‌وجوی برداری در فهمیدن منظور خوب است و در تطبیق دقیق ضعیف. متن فارسی هر دو را لازم دارد.

اصطلاح و نام دقیق مهم است. پرسش‌های واقعی کاربران سازمانی پر از شماره‌ی بخشنامه، نام سامانه، کد کالا و نام افراد است. اگر کاربر «بخشنامه ۱۴۰۳/۲۲۷» را می‌خواهد، شباهت معنایی ده بخشنامه‌ی شبیه برمی‌گرداند و هیچ‌کدام همان نیست. جست‌وجوی کلیدواژه‌ای این حالت را بی‌خطا حل می‌کند.

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

داده‌ی آموزشی فارسی کمتر است. مدل‌های چندزبانه فارسی را می‌فهمند، اما نه لزوماً به کیفیت انگلیسی، و در حوزه‌های تخصصی — حقوقی، پزشکی، فنی — فاصله بیشتر می‌شود. کلیدواژه در این حوزه‌ها یک تور ایمنی است.

الگوی عملی جست‌وجوی ترکیبی:

  1. هر دو جست‌وجو را موازی اجرا کنید: کلیدواژه‌ای (مثل BM25) و برداری.
  2. نتایج را با یک روش ترکیب رتبه — مثلاً Reciprocal Rank Fusion — در یک فهرست ادغام کنید. مزیتش این است که به نمره‌های ناهم‌مقیاس دو سیستم وابسته نیست.
  3. چند ده نامزد بالا را با یک reranker دقیق‌تر دوباره مرتب کنید و فقط چند تای اول را جلوتر بفرستید.

اگر خروجی این جست‌وجو قرار است به یک مدل زبانی برود، بقیه‌ی خط لوله را در مقاله‌ی RAG توضیح داده‌ایم.

چند اشتباه رایج

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

ایندکس برداری یک پایگاه داده‌ی دقیق نیست؛ یک تقریب‌زننده است. با همین فرض طراحی‌اش کنید.

جمع‌بندی: embedding ابزار خوبی برای پیدا کردن «چیزهای مرتبط» است، نه برای «تطبیق دقیق». در فارسی هر دو را لازم دارید. نرمال‌سازی را یکسان اجرا کنید، recall ایندکس‌تان را واقعاً اندازه بگیرید، و کلیدواژه را کنار بردار نگه دارید.