شغّل عقل RAG الخاص بـ Quivr على نقطة نهاية مخصصة متوافقة مع OpenAI.
Updated 2026-07-29
يأخذ LLMEndpointConfig في quivr-core حقل llm_base_url. أبقِ supplier بقيمة openai، اضبط llm_base_url على https://api.apisrouter.com/v1، مرّر مفتاحاً واحداً، وكل brain.ask() يُولِّد إجابته عبر البوابة بأي معرّف نموذج من الكتالوج.
إجابة سريعة: llm_base_url في LLMEndpointConfig.
Quivr الحالي هو quivr-core، مكتبة RAG بلغة Python، وربطه بـ LLM صريح. يحمل LLMEndpointConfig حقول supplier (openai افتراضياً)، وmodel، وllm_base_url، وllm_api_key؛ يبني LLMEndpoint.from_config() العميل الفعلي من تلك الحقول، وبالنسبة لـ supplier بقيمة openai ذلك العميل هو ChatOpenAI الخاص بـ LangChain، مُنشَأ بـ base URL الخاص بك. اضبط llm_base_url على https://api.apisrouter.com/v1، اضبط model على أي معرّف كتالوج، وسلِّم نقطة النهاية إلى Brain الخاص بك. يمكن أن يأتي المفتاح من حقل الإعداد أو من البيئة: عندما لا يُضبَط llm_api_key، يحلّه quivr-core من متغيّر بيئة مُسمّى على اسم المزوّد، الذي هو بالنسبة لـ supplier بقيمة openai هو OPENAI_API_KEY. كلا المسارين سلوك upstream، مقروء في quivr_core/rag/entities/config.py وquivr_core/llm/llm_endpoint.py.
from quivr_core.llm import LLMEndpoint
from quivr_core.rag.entities.config import (
DefaultModelSuppliers, LLMEndpointConfig)
llm = LLMEndpoint.from_config(LLMEndpointConfig(
supplier=DefaultModelSuppliers.OPENAI,
model="claude-sonnet-4-6", # any catalog id
llm_base_url="https://api.apisrouter.com/v1",
llm_api_key=os.environ["APISROUTER_API_KEY"],
))ما هو Quivr الآن، وأين تجلس فتحة LLM.
بدأ Quivr (QuivrHQ على GitHub، بنحو 39 ألف نجمة) كتطبيق عقل ثانٍ كامل وتحوّل إلى quivr-core: مكتبة RAG صاحبة رأي تُضمِّنها في منتجك الخاص. تُطعِمه ملفات، يُحلِّلها ويُقطِّعها، يُضمِّن المقاطع في مخزن متجهات (FAISS افتراضياً، مع دعم PGVector)، ويجيب على أسئلة حولها عبر سير عمل استرجاع قابل للإعداد. كائن Brain هو الوحدة: Brain.from_files() يُدخِل، وbrain.ask() يسترجع ويُولِّد. التوليد هو الخطوة الوحيدة التي تحتاج نموذج محادثة. يجمع سير عمل الاسترجاع السياق من مستنداتك، ويكتب LLMEndpoint الذي مررته الإجابة المبنية على السياق. تُبنى تلك النقطة النهائية مرة واحدة من LLMEndpointConfig، لذا يُتَّخَذ قرار base URL عند وقت الإنشاء وينطبق على كل ask() على ذلك العقل. لأن ChatOpenAI يُمرِّر حقل model كسلسلة نصية عادية عبر /v1/chat/completions، يمكن أن يكون المعرّف Claude أو DeepSeek أو GPT أو Gemini عندما تخدمه نقطة النهاية خلف llm_base_url. ملاحظة صادقة واحدة عن حالة المشروع: كان المستودع هادئاً منذ منتصف 2025، لذا عامل quivr-core كمكتبة مستقرة بدلاً من سريعة الحركة. سطح الإعداد الموصوف هنا يطابق فرع main الأحدث، والتاريخ الهادئ يعني أنه من غير المرجّح أن يتغيّر تحتك؛ يعني أيضاً أن الدروس القديمة التي تصف التطبيق الكامل المتقاعد (ملفات .env خلفية، واجهة أمامية مُستضافة) لم تعد تطابق الكود.
الإعداد الكامل: عقل بـ LLM موجَّه عبر بوابة.
النمط الكامل يُمرِّر LLMEndpoint المُعَدّ إلى Brain.from_files. كل شيء آخر عن العقل (التحليل، التقطيع، مخزن FAISS، سير عمل الاسترجاع) مستقل عن نقطة نهاية LLM ويحتفظ بافتراضاته. انتبه للمُضمِّن. إذا لم تُمرِّر واحداً، يبني quivr-core نموذج OpenAIEmbeddings الخاص بـ LangChain بافتراضاته الخاصة، الذي يُصادِق بـ OPENAI_API_KEY ويستهدف نقطة نهاية OpenAI الجاهزة. ذلك عميل منفصل عن LLM المحادثة: توجيه التوليد عبر البوابة لا يُحرِّكه. مرّر مُضمِّنك الخاص (غلاف sentence-transformers محلي، أو أي مثيل LangChain Embeddings تُعِدّه) إذا كنت لا تريد أن يعتمد نصف التضمين على حساب OpenAI.
import os
from quivr_core import Brain
from quivr_core.llm import LLMEndpoint
from quivr_core.rag.entities.config import (
DefaultModelSuppliers, LLMEndpointConfig)
llm = LLMEndpoint.from_config(LLMEndpointConfig(
supplier=DefaultModelSuppliers.OPENAI,
model="claude-sonnet-4-6",
llm_base_url="https://api.apisrouter.com/v1",
llm_api_key=os.environ["APISROUTER_API_KEY"],
max_output_tokens=2048,
temperature=0.3,
))
brain = Brain.from_files(
name="team-docs",
file_paths=["handbook.pdf", "runbook.md"],
llm=llm,
# embedder=... # separate component; see note above
)
print(brain.ask("What is the on-call escalation policy?").answer)اختيار نموذج توليد لإجابات RAG.
مقارنة المرشَّحين تغيير عند وقت الإنشاء: ابنِ LLMEndpoint اثنين مقابل نفس base URL، عقلين فوق نفس الملفات، وقارن الإجابات بالاختلاف على مجموعة أسئلة ثابتة. سجل الاستخدام لكل مفتاح يسعّر تشغيل كل مرشّح، لذا تُقاس الجودة لكل token بدلاً من الجدال بشأنها.
- توليد RAG ثقيل بالمدخل: المقاطع المسترجَعة تهيمن على الموجّه. سعر token المدخل يحدّد تكلفة إجابة، ولهذا معرّف سريع غالباً ما يُنصِّف الفاتورة دون لمس جودة الاسترجاع.
- claude-sonnet-4-6 هو الافتراضي الموثوق للإجابات المبنية على السياق التي تحترم السياق المسترجَع وترفض بنظافة عندما لا تحتوي المستندات على الإجابة.
- المنتجات المُضمَّنة عالية الحجم (حالة الاستخدام المعلنة لـ Quivr) تعمل جيداً على claude-haiku-4-5-20251001 أو deepseek-v4-flash أو gemini-3.5-flash لمزيج الأسئلة اليومي.
- max_context_tokens في نفس الإعداد يحكم كم من السياق المسترجَع يحزمه الأنبوب؛ رفعه يقترن طبيعياً بمعرّفات طويلة السياق ويرفع الإنفاق على المدخل تناسبياً.
- بادئات نموذج غير معروفة تسقط إلى مُرمِّز عام للموازنة، وهو تجميلي؛ الطلب نفسه يحمل معرّفك دون تغيير إلى نقطة النهاية.
ادفع حسب الاستخدام · أقل من السعر الرسمي
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| النموذج | السعر الرسمي | سعرنا |
|---|---|---|
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| Claude Haiku 4.5 20251001 | $1.00 / $5.00 per M | $0.80 / $4.00 per M |
| GPT-5.4 mini | $0.75 / $4.50 per M | $0.60 / $3.60 per M |
| DeepSeek V4 Flash | $0.14 / $0.28 per M | $0.10 / $0.30 per M |
| Gemini 3.5 Flash | $1.50 / $9.00 per M | $1.20 / $7.20 per M |
تصحيحات لأساطير Quivr الشائعة.
تصف الأدلة المتداولة أسطحاً لم يعد Quivr يملكها، لذا يستحق ذكر ما يفعله الكود الحالي فعلياً. quivr-core مدعوم بـ LangChain، لا بـ LiteLLM. يختار تعداد supplier فئة محادثة LangChain، وopenai يُطابِق ChatOpenAI بـ llm_base_url الخاص بك. إذا أخبرك دليل بإعداد بروكسي LiteLLM أو إعداد api_base داخل Quivr، فهو يصف عمارة أقدم؛ الحقل الحالي هو llm_base_url على LLMEndpointConfig. التطبيق الكامل متقاعد. التعليمات حول .env خلفي، إعداد Supabase، أو منتقي نموذج داخل التطبيق تشير إلى التطبيق قبل التحوّل، الذي لم يعد ما يشحنه المستودع. يحدث الإعداد الآن في كود Python الخاص بك (أو تطبيقك الخاص حول المكتبة). متغيّر بيئة المفتاح مُشتَق من المزوّد. بالنسبة لـ supplier بقيمة openai هو OPENAI_API_KEY، حتى عندما لا تكون نقطة النهاية OpenAI. إذا فضّلت عدم إثقال ذلك الاسم، مرّر llm_api_key صراحة في الإعداد، الذي يسبق وتبقى البيئة نظيفة. المُضمِّن منفصل. توجيه التوليد لا يُحرِّك التضمينات؛ المُضمِّن الافتراضي هو OpenAIEmbeddings ببيانات اعتماده الخاصة. قرّر النصفين بشكل مستقل، وإعادة تضمين مخزن موجود مطلوبة فقط إذا غيّرت نموذج التضمين نفسه.
من يوجّه quivr-core عبر بوابة.
- فرق المنتج التي تُضمِّن RAG في تطبيقاتها وتريد أن يكون نموذج التوليد قيمة إعداد، لا التزام بائع مبني في المكدس.
- المطورون الذين يشغّلون عقولاً كثيرة بمستويات جودة مختلفة: مفتاح واحد، نقطة نهاية واحدة، معرّف نموذج لكل عقل.
- الفرق التي تريد إجابات مبنية على السياق بجودة Claude خلف إعداد على شكل OpenAI دون إضافة SDK ثانٍ أو حساب مزوّد.
- المُنشِئون الذين يقيّمون نماذج التوليد على مجموعة ثابتة، حيث كل مرشّح تغيير واحد في LLMEndpointConfig.
- المطورون الذين لا يملكون وصولاً إلى فوترة بائع معيّن. الوصول القائم على تعبئة الرصيد بدون شرط بطاقة يزيل الاعتماد على التسجيل لكل مزوّد.
تحقق من نقطة النهاية وصحّح أخطاء أول ask().
أكّد أن البوابة تسرد نموذجك قبل إدخال أي شيء؛ يجب أن يطابق حقل model معرّفاً مخدوماً تماماً. أعطال أول تشغيل متوقَّعة. تحذير بأن مفتاح API لـ supplier بقيمة openai غير مضبوط يعني أنه لا llm_api_key ولا OPENAI_API_KEY كانا مرئيَّين عند بناء الإعداد؛ يحدث التحذير عند البناء، والفشل عند أول ask(). 401 يعني أن المفتاح المُحلَّل لا ينتمي إلى نقطة النهاية في llm_base_url. خطأ model-not-found هو خطأ إملائي في المعرّف مقابل /v1/models. وخطأ مصادقة متعلق بالتضمين أثناء Brain.from_files هو المُضمِّن الافتراضي المنفصل يطلب بيانات اعتماد OpenAI الخاصة به، الذي لن يُصلِحه أي إعداد llm_base_url؛ مرّر مُضمِّناً تتحكم فيه. بمجرد تدفّق الإجابات، تعرض لوحة APIsRouter النموذج لكل طلب، وعدد tokens، والإنفاق. بالنسبة لمكتبة تحزم مقاطع مسترجَعة في كل موجّه، رقم tokens لكل إجابة على مجموعتك الحقيقية هو الرقم الذي يجب أن يقود اختيار نموذجك.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50الأسئلة الشائعة
هل يدعم Quivr base URL مخصصاً متوافقاً مع OpenAI؟
نعم. يملك LLMEndpointConfig في quivr-core حقل llm_base_url، وبالنسبة لـ supplier بقيمة openai تبني المكتبة ChatOpenAI الخاص بـ LangChain مقابل ذلك الـ URL. اضبطه على نقطة نهاية البوابة ومرّر أي معرّف نموذج من الكتالوج.
هل Quivr مبني على LiteLLM؟
ليس في قاعدة الكود الحالية. يختار quivr-core فئات محادثة LangChain حسب المزوّد؛ يستخدم supplier بقيمة openai ChatOpenAI بـ llm_base_url الخاص بك. الأدلة التي تصف api_base لـ LiteLLM داخل Quivr تشير إلى عمارة أقدم.
هل يمكن لـ brain.ask() الإجابة بنماذج Claude أو DeepSeek؟
نعم. يُمرَّر حقل model كسلسلة نصية عادية عبر /v1/chat/completions، لذا يعمل claude-sonnet-4-6 أو deepseek-v4-flash أو أي معرّف آخر تخدمه نقطة النهاية تحت supplier بقيمة openai.
أي متغيّر بيئة يحمل المفتاح؟
عندما لا يُضبَط llm_api_key في الإعداد، يشتق quivr-core المتغيّر من اسم المزوّد: OPENAI_API_KEY لـ supplier بقيمة openai. llm_api_key صريح في LLMEndpointConfig يسبق ويتجنّب إثقال ذلك الاسم.
هل يُحرِّك llm_base_url التضمينات أيضاً؟
لا. المُضمِّن الافتراضي هو عميل OpenAIEmbeddings منفصل ببيانات اعتماده ونقطة نهايته الخاصة. وجّه التوليد عبر البوابة ومرّر مُضمِّنك الخاص إذا أردت إخراج نصف التضمين أيضاً عن OpenAI.
هل مشروع Quivr لا يزال يُصان؟
كان المستودع هادئاً منذ منتصف 2025، لذا عامله كمكتبة مستقرة بدلاً من نشطة. سطح llm_base_url الموثَّق هنا يطابق فرع main الأحدث، والتطبيق الكامل قبل التحوّل الذي استبدله متقاعد.