مدل RAG (بازیابی افزوده تولیدی)
آیا می توان چند فیلد در دیتابیس طراحی کرد و از چند مدل همزمان استفاده کرد؟
بله، نهتنها میشود، بلکه در بعضی سناریوهای **RAG چندمدلی** این کار میتواند خیلی مفید باشد.
ماجرا این است که Embedding همان یک بردار است، ولی شما میتوانید برای هر مدل **یک ستون جدا** در دیتابیس برداریتان داشته باشید.
—
## 📦 سناریو
فرض کنیم جدول `documents` دارید:
“`sql
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding_e5 VECTOR(1024), — خروجی مدل multilingual-e5-large
embedding_openai VECTOR(1536), — خروجی مدل text-embedding-3-small
metadata JSONB
);
“`
– **`embedding_e5`**
برای جستجوهای چندزبانه سریع (لوکال)
– **`embedding_openai`**
برای جستجوهایی که نیاز به کیفیت بالاتر و semantic matching قویتر دارند
—
## 🔄 طرز استفاده
در کوئری جستجو بسته به نیاز، میتوانید از هر ستون برداری که بخواهید استفاده کنید:
“`sql
— جستجو با مدل e5
SELECT id, content
FROM documents
ORDER BY embedding_e5 <-> ‘[بردار کوئری]’ LIMIT 5;
— جستجو با مدل OpenAI
SELECT id, content
FROM documents
ORDER BY embedding_openai <-> ‘[بردار کوئری]’ LIMIT 5;
“`
حتی میتوانید یک **جستجوی ترکیبی** (Hybrid Search) با وزندهی اجرا کنید، مثلاً ۷۰٪ e5 + ۳۰٪ OpenAI.
—
## 📌 کاربرد این روش
– **مقایسه کیفیت مدلها** در پروژه قبل از انتخاب نهایی
– **Hybrid Search** برای سناریوهایی که نیاز به تعادل بین سرعت و دقت دارید
– **پشتیبان گرفتن**: اگر API گیرد کند یا قطع شود، بتوانید از مدل لوکال استفاده کنید
– **تقسیم وظیفه**: مثلاً مدل کوچکتر برای autocomplete یا search مقدماتی، مدل بزرگتر برای فیلتر نهایی
—
اگر بخواهید، میتوانم **ساختار دیتابیس + کد Python** را طوری آماده کنم که هر متن را با دو یا چند مدل همزمان فیلدبرداری کرده و در `pgvector` ذخیره کند، و قابلیت جستجوی انتخابی یا ترکیبی را بدهد.
میخواهید این کد را بسازم تا مستقیم در RAG پزشکیتان استفاده شود؟
برای ذخیرهسازی کتابهای شما به شکلی که هم قابل بررسی و ویرایش باشد و هم برای مدل RAG (بازیابی افزوده تولیدی) بهینه باشد، ما نیاز داریم که هم متن کامل کتابها را ذخیره کنیم و هم آنها را به قطعات کوچکتر (chunks) تقسیم کرده و بردارهای (embeddings) آنها را نیز ذخیره کنیم.
با توجه به سیستم شما که از Django و PostgreSQL با pgvector
استفاده میکنید، بهترین رویکرد میتواند ترکیبی از این موارد باشد:
- ذخیرهسازی متن کامل کتابها (برای بررسی و ویرایش):
- در PostgreSQL: میتوانید یک مدل Django برای
Book
(کتاب) ایجاد کنید که فیلدهایی برای عنوان، نویسنده، سال انتشار و مهمتر از همه،content
داشته باشد. فیلدcontent
میتواند از نوعTextField
باشد که قابلیت ذخیره متون طولانی را دارد. این بخش برای شما جهت بررسی، ویرایش و مدیریت کتابها عالی خواهد بود.
- آمادهسازی برای RAG (بهینهترین حالت برای هوش مصنوعی):
- تقسیمبندی متن (Chunking): قبل از ذخیرهسازی برای RAG، باید هر کتاب را به قطعات کوچکتر (مثلاً پاراگرافها یا چند جمله) تقسیم کنید. این کار باعث میشود هنگام جستجو، مدل هوش مصنوعی دقیقتر و مرتبطتر عمل کند.
- تولید بردارهای متنی (Embeddings): برای هر یک از این قطعات متنی، باید یک بردار عددی (embedding) با استفاده از مدلهای زبان بزرگ (مانند
sentence-transformers
که قبلاً در موردش صحبت کردیم) تولید کنید. این بردارها نشاندهنده معنای هر قطعه متن هستند. - ذخیرهسازی بردارها در
pgvector
: در مدل Django خود، یک فیلد دیگر به نامembedding
از نوعVectorField
(که توسطpgvector
فراهم میشود) ایجاد کنید. هر بردار تولید شده برای یک قطعه متن را در این فیلد ذخیره کنید. همچنین، فیلدی برایchunk_text
(متن اصلی قطعه) وbook_id
(برای ارجاع به کتاب اصلی) در نظر بگیرید. - استفاده از پایگاه داده وکتور تخصصی (مانند Qdrant یا Weaviate): اگرچه
pgvector
برای شروع و مقیاسهای کوچکتر عالی است، اما برای حجم بسیار زیاد داده (هزاران صفحه کتاب)، ممکن است بخواهید یک پایگاه داده وکتور تخصصی مانند Qdrant یا Weaviate را در کنار PostgreSQL استفاده کنید. این سیستمها برای جستجوی شباهت معنایی (semantic search) با بردارها بهینهسازی شدهاند و عملکرد بهتری ارائه میدهند.
چرا این روش بهینه است؟
- قابلیت ویرایش و مدیریت: شما میتوانید متن کامل کتابها را در PostgreSQL به راحتی مدیریت و ویرایش کنید.
- جستجوی معنایی کارآمد: با ذخیره بردارها در
pgvector
(یا پایگاه داده وکتور تخصصی)، مدل RAG میتواند به سرعت قطعات متنی مرتبط با سؤال کاربر را پیدا کند، حتی اگر کلمات دقیقاً یکسان نباشند. - مقیاسپذیری:
pgvector
امکان ایندکسگذاری (مانند HNSW) را فراهم میکند که جستجو در حجم زیاد بردارها را تسریع میبخشد. - کاهش توهم (Hallucination): با محدود کردن پاسخهای AI به دانش موجود در کتابهای شما، از تولید اطلاعات نادرست جلوگیری میشود.
بهینه ترین حالت برای حداکثر تعداد کاراکترها در یک پاراگراف (یا “chunk”) در متد RAG:
به طور کلی، برای چانکها در مدل RAG، ما به دنبال تعادلی بین این دو نکته هستیم:
- حفظ معنای کامل: هر چانک باید به اندازه کافی بزرگ باشد که یک ایده یا مفهوم کامل را در خود جای دهد. اگر چانکها خیلی کوچک باشند، ممکن است معنای جمله یا پاراگراف از دست برود.
- بهرهوری در جستجو و توکنگذاری: چانکها نباید آنقدر بزرگ باشند که:
- جستجوی شباهت بیاثر شود: چانکهای خیلی طولانی ممکن است حاوی اطلاعات غیرمرتبط زیادی باشند که دقت جستجوی شباهت را کاهش دهد.
- هزینه و زمان توکنگذاری مدل LLM را بالا ببرد: وقتی چانکهای بازیابیشده به مدل زبان بزرگ (LLM) فرستاده میشوند، هرچه طولانیتر باشند، توکنهای بیشتری مصرف میکنند که هم از نظر هزینه و هم از نظر زمان پاسخدهی میتواند چالشبرانگیز باشد. مدلهای LLM نیز معمولاً دارای حداکثر تعداد توکن ورودی (context window) هستند.
توصیههای عملی:
-
متوسط 200 تا 500 کلمه (حدود 1000 تا 2500 کاراکتر فارسی):
-
این محدوده اغلب یک نقطه شروع عالی و متعادل است. یک پاراگراف متوسط یا چند جمله میتواند در این بازه قرار گیرد و معمولاً یک ایده کامل را بیان میکند.
-
برای زبان فارسی، با توجه به اینکه کلمات ممکن است طولانیتر باشند و ساختار جملات کمی متفاوت باشد، 200 تا 500 کلمه معادل تقریباً 1000 تا 2500 کاراکتر (با احتساب فاصله) است.
-
نکته مهم: استفاده از “Overlap” (همپوشانی):
-
هنگام تقسیمبندی به چانکها، توصیه میشود که هر چانک با چانک قبلی خود کمی همپوشانی (مثلاً 10-20% از طول چانک) داشته باشد. این کار تضمین میکند که اگر یک مفهوم مهم دقیقاً در مرز دو چانک قرار گیرد، از دست نرود.
-
مدل Embedding شما:
-
برخی از مدلهای Embedding محدودیت ورودی توکن دارند (مثلاً 512 توکن). اگر مدل شما چنین محدودیتی دارد، باید چانکهای خود را متناسب با آن تنظیم کنید. مدلهای
sentence-transformers
معمولاً محدودیتهای بالاتری دارند و انعطافپذیرترند. -
روش تقسیمبندی (Chunking Strategy):
-
تقسیمبندی بر اساس پاراگراف: اگر کتابهای شما ساختار پاراگرافی خوبی دارند، تقسیم هر پاراگراف به یک چانک میتواند بسیار مؤثر باشد.
-
تقسیمبندی بر اساس تعداد کلمات/کاراکترها: این روش رایجترین است. میتوانید یک حداکثر تعداد کلمه یا کاراکتر را برای هر چانک تعیین کنید.
-
تقسیمبندی معنایی (Semantic Chunking): روشهای پیشرفتهتری وجود دارند که سعی میکنند متن را بر اساس تغییرات معنایی به چانکها تقسیم کنند، اما پیادهسازی آنها پیچیدهتر است.
پیشنهاد نهایی برای شروع کار شما:
من پیشنهاد میکنم با تقسیمبندی متن به چانکهایی با حداکثر 400 کلمه (تقریباً 2000 کاراکتر فارسی) با 10-20% همپوشانی شروع کنید.
این یک نقطه شروع بسیار قوی است و شما میتوانید با آزمایش و بررسی نتایج، این مقادیر را به مرور زمان تنظیم کنید تا به بهترین عملکرد برای دادههای خاص خود برسید.
اگر خودم از ابتدا هنگام تالیف کتاب هایم دقت کنم و هر پاراگ راف را به گونه ای بنویسم که نیاز به خرد کردن یا همپوشانی نداشته باشد آیا مشکل حل می شود؟
بله؛ اگر از ابتدا هر پاراگراف را «خودبسنده» و زیر سقف هدف بنویسید، عملاً به خردکردن و همپوشانی نیاز ندارید.
– پیشنهاد اندازه: 300–400 توکن (تقریباً 1200–1800 کاراکتر).
– نکات برای کیفیت RAG:
– پاراگرافها را حول یک ایده کامل بنویسید؛ نه خیلی کوتاه، نه خیلی بلند.
– در امبدینگ، عنوان فصل/زیرعنوان را به متن پاراگراف اضافه کنید تا زمینه حفظ شود.
– در بازیابی، کنار هر پاراگراف میتوانید «همسایهها» را هم واکشی کنید (window retrieval) تا اگر مرز معنایی رد شد، پوشش داده شود.
– یک ولیدیتور طول روی مدل بگذارید تا تخطی تصادفی رخ ندهد.
در صورت رعایت این موارد، اندازه و انسجام پاراگرافها برای RAG کافی است و نیاز عملی به همپوشانی از بین میرود.