يعتمد بحث المتجهات الأصلي لـ Aurabase (RAG، pgvector، التضمينات) على آلية الفهرسة نفسها، الموضحة بالتفصيل في صفحة Native AI في صفحة Postgres. يفترض هذا الدليل وجود جدول Postgres مثبت عليه pgvector بالفعل، وعمود من النوع vector، وبضعة آلاف من الصفوف على الأقل. أدناه، غالبًا ما يكون الفحص التسلسلي البسيط أسرع من الفهرس التقريبي.
الأساسيات
- لا يتطلب HNSW أي مرحلة تدريب، على عكس IVFFlat: تم بناء الفهرس على عمليات الإدراج، وهو متوفر في pgvector منذ الإصدار 0.5.0.
- هناك معلمتان تحددان جودة الفهرس عند الإنشاء:
m(الاتصالات لكل عقدة، الافتراضي 16) وef_construction(عرض البحث عند الإنشاء، الافتراضي 64). - يتم ضبط المعلمة الثالثة،
hnsw.ef_search(pgvector الافتراضي: 40)، لكل طلب، دون إعادة بناء الفهرس، للتحكيم في الاستدعاء وزمن الوصول. - pgvector caps فهرسة HNSW من النوع
vectorإلى 2000 بُعدًا. أبعد من ذلك (التضمين بأبعاد 3072، على سبيل المثال)، يعد التحويل إلىhalfvecضروريًا للفهرسة. - pgvector 0.8.6 هو الإصدار المضمن في صورة المستأجر Aurabase Postgres، وتم التحقق منه مباشرة في Dockerfile في 24 أغسطس 2026.
ما هو مؤشر HNSW في pgvector؟
يرمز HNSW إلى عالم صغير هرمي قابل للملاحة. إنه فهرس بياني: يصبح كل متجه عقدة متصلة بأقرب جيرانه، ويتم تنظيمها في عدة طبقات متراكبة. يبدأ البحث في أعلى الرسم البياني، على الطبقة المتناثرة، ثم ينتقل طبقة تلو الأخرى إلى الطبقات المجاورة الأكثر صلة. وبذلك يصبح وقت البحث لوغاريتميًا تقريبًا، وليس خطيًا على عدد الأسطر.
يعمل IVFFlat، وهو الفهرس الآخر لـ pgvector، بشكل مختلف: فهو يقسم مساحة المتجه إلى قوائم يحددها تمرير التدريب على عينة موجودة، قبل أن يتمكن من فهرسة أي شيء. لا يوجد في HNSW هذا القيد، حيث تعمل كل عملية إدراج على إثراء الرسم البياني بشكل مباشر، مما يجعل من الأسهل العمل على جدول ينمو بشكل مستمر. من ناحية أخرى، يستهلك مؤشر HNSW ذاكرة أكبر ويستغرق وقتًا أطول في الإنشاء مقارنة بمؤشر IVFFlat المكافئ على نفس وحدة التخزين.
يقدم pgvector دعم HNSW في الإصدار 0.5.0. تضيف الإصدارات اللاحقة إمكانات مفيدة لهذا الدليل: النوع halfvec (0.7.0) لفهرسة ما يتجاوز 2000 بُعد، والمعلمة hnsw.iterative_scan (0.8.0) لتحسين الاستدعاء في الاستعلامات التي تمت تصفيتها. إذا قمت بمقارنة pgvector بقاعدة متجهات مخصصة قبل اتخاذ القرار، فإن مقارنة pgvector مقابل Pinecone وWeaviate وQdrant توضح تفاصيل المقايضات.
تحقق من إصدار pgvector الخاص بك قبل إنشاء الفهرس
قم بتأكيد إصدار pgvector المثبت أولاً. يؤدي الامتداد القديم جدًا إلى فشل بعض الميزات الموجودة في هذا الدليل بصمت، خاصة halfvec و hnsw.iterative_scan.
HNSW موجود منذ pgvector 0.5.0. يتطلب النوع halfvec، الضروري لفهرسة التضمينات التي تتجاوز 2000 بُعدًا، الإصدار 0.7.0 على الأقل. تطلب المعلمة hnsw.iterative_scan الإصدار 0.8.0.
في مشاريع Aurabase، لا يُطرح السؤال: صورة Postgres تتضمن pgvector 0.8.6، سواء في مجموعة Postgres المشتركة (docker/Postgres.Dockerfile، المبنية مباشرة على pgvector/pgvector:0.8.6-pg16-bookworm) وعلى مثيلات Postgres 16 CNPG المخصصة لكل مشروع (docker/Postgres.CNPG.Dockerfile، التي ترث pgvector 0.8.6 من صورة CloudNativePG الرسمية). تم التحقق منه في كلا ملفي Dockerfiles في 24 أغسطس 2026.
اختر نوع العمود المناسب وفقًا لحجم التضمينات الخاصة بك
يعتمد نوع العمود على حجم التضمينات الخاصة بك، وليس فقط النموذج الذي يقوم بإنشائها. يخزن pgvector ناقلًا كلاسيكيًا من النوع vector، مع حد أقصى يبلغ 16000 بُعدًا في التخزين. لكن فهرسة HNSW على هذا النوع تقتصر على 2000 بُعد: أبعد من ذلك، يفشل CREATE INDEX.
غالبًا ما تتجاوز نماذج التضمين الشائعة هذا الحد: text-embedding-3-large من OpenAI أوgemini-embedding-2 من Google تنتج أصلاً ما يصل إلى 3072 بُعدًا. لفهرسة هذه المتجهات باستخدام HNSW، قم بتحويل العمود إلى halfvec (دقة التخزين إلى النصف)، مما يدفع حد الفهرسة إلى ما هو أبعد من 2000 بُعد.
| الأبعاد | العمود | HNSW على ناقلات | يتطلب الصب |
|---|---|---|---|
| 768 | التضمين_768 | نعم | لا |
| 1536 | التضمين_1536 | نعم | لا |
| 3072 | embedding_3072 | لا (> 2000 خافت) | نعم، طاقم العمل::halfvec(3072) |
يوضح محرك Aurabase RAG هذا الحل الوسط في الإنتاج: ثلاث فئات من الأبعاد مدعومة (768، 1536، 3072)، مخزنة في ثلاثة أعمدة متميزة من نفس جدول embeddings. تتم فهرسة الأعمدة 768 و1536 مباشرةً في HNSW على النوع vector. تتم فهرسة العمود 3072 من خلال قالب ::halfvec(3072)، وذلك على وجه التحديد للتحايل على الحد الأقصى للأبعاد لعام 2000.
للحصول على تفاصيل حول الاستيعاب (التقطيع، الاتصال بموفر التضمين، الإدراج)، راجع البرنامج التعليمي لخط أنابيب RAG على pgvector.
قم بإنشاء الفهرس باستخدام المعلمات m وef_construction
يعد الحد الأدنى من بناء الجملة كافيًا للفهرس الأول، بالقيم الافتراضية لـ pgvector.
ثم يطبق pgvector m = 16 و ef_construction = 64. لضبط هذه القيم بشكل صريح، استخدم جملة WITH:
قبل إنشاء فهرس HNSW على طاولة كبيرة، قم مؤقتًا بزيادة maintenance_work_mem للجلسة: وهذا، وفقًا لوثائق pgvector نفسها، هو الرافعة الأكثر مباشرة لتقليل وقت البناء.
ماذا تتغير المعلمة م؟
m يعين الحد الأقصى لعدد الاتصالات التي تحتفظ بها كل عقدة في الرسم البياني لكل طبقة. تعمل القيمة الأعلى على تكثيف الرسم البياني: يزداد الاستدعاء، لكن الذاكرة المستهلكة ووقت الإنشاء يزداد أيضًا، بشكل خطي تقريبًا. الافتراضي (16) مناسب لمعظم الحالات. إن الارتفاع إلى 24 أو 32 له ما يبرره بشكل خاص على التضمينات الكبيرة، حيث يصبح التمييز بين الجيران القريبين والبعيدين أكثر دقة.
ما الذي يتغير ef_construction؟
ef_construction يضبط حجم قائمة المرشحين التي تم استكشافها أثناء إنشاء الفهرس، لكل عقدة مدرجة. تعمل القيمة الأعلى على تحسين جودة الرسم البياني النهائي، وبالتالي احتمالية الاستدعاء، على حساب وقت بناء أطول. على عكس m، لا توجد تكلفة لهذه المعلمة في وقت الاستعلام: فهي استثمار لمرة واحدة، ويتم دفعه مرة واحدة فقط عند إنشاء الفهرس.
فهارس جزئية لفئات أبعاد متعددة في نفس الجدول
عندما يقوم جدول بتخزين عدة أعمدة متجهة (واحد لكل فئة بُعد، كما تفعل Aurabase)، قم بفهرسة كل عمود على حدة باستخدام عبارة WHERE colonne IS NOT NULL. يتجنب هذا الفهرس الجزئي فهرسة الأسطر الفارغة للفئات التي لا يستخدمها سطر معين، مما يقلل من حجم الفهرس ويسرع من بنائه دون تكلفة أي شيء في الاستدعاء.
يجب أن يتوافق اختيار فئة المشغل (vector_cosine_opsأو vector_l2_ops أو vector_ip_ops) مع المقياس الذي تم تدريب نموذج التضمين عليه. يتم تدريب أحدث نماذج تضمين النص على تشابه جيب التمام: vector_cosine_ops (أو halfvec_cosine_ops في عمود مصبوب) هو الخيار الافتراضي الأكثر أمانًا.
قم بتعيين ef_search في وقت الاستعلام
يتم تعيين ef_search في كل استعلام، وليس عند إنشاء الفهرس. فهو يحدد حجم قائمة المرشحين التي تم استكشافها أثناء البحث: كلما زاد حجمها، كان الاسترجاع أفضل، على حساب زمن الوصول الأطول. يقوم pgvector بتعيين قيمته الافتراضية على 40.
نادرًا ما يكون 40 كافيًا بمجرد أن يجمع الاستعلام البحث المتجه مع مرشح WHERE المطبق بعد مسح الفهرس (على مساحة اسم، أو مستأجر، أو أي معيار آخر لبيانات التعريف). يعيد فحص HNSW ef_search المرشحين الأوليين، ثم يتجاهل المرشح جزءًا منهم. إذا نجا عدد قليل جدًا من المرشحين، فسينتهي الأمر بـ LIMIT النهائي غير ممتلئ.
وبالتالي، يقوم محرك Aurabase RAG بتوسيع ef_search ديناميكيًا وفقًا للمطلوب top_k، بدلاً من الاحتفاظ بالقيمة الثابتة 40: ef = max(top_k × 4, 64). يستخدم البحث عن أقرب 5 نتائج ef_search = 64؛ بحث عن أفضل 50 استخدام ef_search = 200. تظل هذه الصيغة قابلة للتعديل حسب متغير البيئة لعمليات النشر التي تحتاج إلى استبدال آخر للاستدعاء/زمن الاستجابة.
يضيف pgvector 0.8 رافعة ثانية لنفس المشكلة: hnsw.iterative_scan. في الوضع strict_order أو relaxed_order، يقوم البحث بتوسيع نطاق البحث تدريجيًا حتى يجمع نتائج كافية بعد التصفية، بدلاً من التوقف عند قائمة ثابتة من المرشحين. يقوم Aurabase بتنشيطه افتراضيًا في strict_order، ولكنه يحمي المكالمة في نقطة حفظ. في إصدار pgvector قبل 0.8، حيث لا توجد هذه المعلمة، يستمر الاستعلام في الوضع المنخفض بدلاً من الفشل.
بناء خط أنابيب RAG الكامل
يعد مؤشر HNSW هذا مجرد جزء واحد من خط أنابيب RAG الكامل: التقطيع، والتضمين، والتناول، ثم البحث. يقوم برنامجنا التعليمي خطوة بخطوة ببناء خط الأنابيب هذا من البداية إلى النهاية على pgvector، بدءًا من الإدراج الأول وحتى استعلام التشابه. توضح الوثائق الفنية أيضًا تفاصيل جميع إمكانات الذكاء الاصطناعي الأصلية لـ Aurabase المبنية على Postgres.