مغز RAG کوییور را روی یک endpoint سفارشی سازگار با OpenAI اجرا کنید.

Updated 2026-07-29

LLMEndpointConfig در quivr-core یک فیلد llm_base_url می‌گیرد. supplier را روی openai نگه دارید، llm_base_url را روی https://api.apisrouter.com/v1 تنظیم کنید، یک کلید پاس دهید، و هر brain.ask() پاسخ خود را از طریق gateway با هر id مدل کاتالوگ تولید می‌کند.

پاسخ سریع: llm_base_url در LLMEndpointConfig.

Quivr فعلی همان quivr-core است، یک کتابخانه RAG پایتون، و سیم‌کشی LLM آن صریح است. LLMEndpointConfig supplier (پیش‌فرض openai)، model، llm_base_url، و llm_api_key را حمل می‌کند؛ LLMEndpoint.from_config() client واقعی را از آن فیلدها می‌سازد، و برای supplier openai آن client ChatOpenAI از LangChain است که با base URL شما ساخته شده. llm_base_url را روی https://api.apisrouter.com/v1 تنظیم کنید، model را روی هر id کاتالوگ تنظیم کنید، و endpoint را به Brain خود بدهید. کلید می‌تواند از فیلد config یا محیط بیاید: وقتی llm_api_key تنظیم نشده، quivr-core آن را از یک متغیر محیطی به‌نام‌شده حسب supplier resolve می‌کند، که برای 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، حدود ۳۹ هزار ستاره) به‌عنوان یک اپلیکیشن کامل second-brain شروع شد و به quivr-core پیچید: یک کتابخانه RAG با نظر خاص که در محصول خودتان embed می‌کنید. فایل‌ها را به آن می‌دهید، آن‌ها را پارس و chunk می‌کند، chunk ها را در یک vector store embed می‌کند (FAISS به‌طور پیش‌فرض، PGVector پشتیبانی می‌شود)، و از طریق یک workflow retrieval قابل‌پیکربندی به سؤالات پاسخ می‌دهد. شیء Brain واحد است: Brain.from_files() ingest می‌کند، brain.ask() بازیابی و تولید می‌کند. تولید تنها گامی است که به یک مدل چت نیاز دارد. workflow retrieval context را از اسناد شما جمع‌آوری می‌کند، و LLMEndpoint ای که پاس داده‌اید پاسخ مبتنی را می‌نویسد. آن endpoint یک‌بار از LLMEndpointConfig ساخته می‌شود، پس تصمیم base URL در زمان ساخت گرفته می‌شود و روی هر ask() روی آن brain اعمال می‌شود. چون ChatOpenAI فیلد model را به‌عنوان رشته ساده روی /v1/chat/completions فوروارد می‌کند، id می‌تواند Claude، DeepSeek، GPT، یا Gemین باشد وقتی endpoint پشت llm_base_url آن‌ها را سرویس دهد. یک یادداشت صادقانه درباره وضعیت پروژه: مخزن از اواسط ۲۰۲۵ ساکت بوده، پس quivr-core را به‌عنوان یک کتابخانه پایدار در نظر بگیرید نه سریع‌الحرکت. سطح config توصیف‌شده اینجا با شاخه main فعلی مطابقت دارد، و تاریخچه ساکت یعنی بعید است زیر پای شما تغییر کند؛ همچنین یعنی آموزش‌های قدیمی که اپ کامل بازنشسته‌شده (فایل‌های backend .env، یک frontend میزبانی‌شده) را توصیف می‌کنند دیگر با کد مطابقت ندارند.

راه‌اندازی کامل: یک brain با LLM مسیردهی‌شده از طریق gateway.

الگوی کامل LLMEndpoint پیکربندی‌شده را به Brain.from_files پاس می‌دهد. هرچیز دیگر درباره brain (پارس‌کردن، chunk کردن، store FAISS، workflow retrieval) مستقل از endpoint LLM است و پیش‌فرض‌های خود را نگه می‌دارد. به embedder توجه کنید. اگر یکی پاس ندهید، quivr-core OpenAIEmbeddings از LangChain را با پیش‌فرض‌های خودش می‌سازد، که با OPENAI_API_KEY احراز هویت می‌کند و endpoint استاندارد OpenAI را هدف می‌گیرد. آن client جدایی از LLM چت است: مسیردهی تولید از طریق gateway آن را جابه‌جا نمی‌کند. embedder خودتان را پاس دهید (یک wrapper sentence-transformers محلی، یا هر instance Embeddings از LangChain که پیکربندی می‌کنید) اگر نمی‌خواهید نیمه embedding به یک حساب 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 بسازید، دو brain روی همان فایل‌ها، و پاسخ‌ها را روی یک مجموعه سؤال ثابت diff کنید. usage log هر-کلید هر اجرای کاندید را قیمت‌گذاری می‌کند، پس کیفیت-به-ازای-token اندازه‌گیری می‌شود نه استدلال می‌شود.

  • تولید RAG ورودی-سنگین است: chunk های بازیابی‌شده بر prompt غالب‌اند. قیمت هر-token-ورودی هزینه یک پاسخ را تعیین می‌کند، به همین دلیل یک id سریع اغلب صورت‌حساب را بدون لمس کیفیت retrieval نصف می‌کند.
  • claude-sonnet-4-6 پیش‌فرض قابل‌اعتماد برای پاسخ‌های مبتنی است که به context بازیابی‌شده احترام می‌گذارند و وقتی اسناد پاسخ را ندارند تمیز رد می‌کنند.
  • محصولات embed-شده پرحجم (کاربرد اعلام‌شده Quivr) روی claude-haiku-4-5-20251001، deepseek-v4-flash، یا gemini-3.5-flash برای ترکیب سؤال روزمره خوب کار می‌کنند.
  • max_context_tokens در همان config حکومت می‌کند چقدر context بازیابی‌شده pipeline بسته‌بندی می‌کند؛ بالابردن آن طبیعتاً با id های long-context جفت می‌شود و هزینه ورودی را متناسب بالا می‌برد.
  • پیشوندهای مدل ناشناخته به یک tokenizer عمومی برای بودجه‌بندی برمی‌گردند، که آرایشی است؛ خود درخواست id شما را بدون تغییر به endpoint حمل می‌کند.

پرداخت بر اساس مصرف · پایین‌تر از قیمت رسمی

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. enum supplier یک کلاس چت LangChain انتخاب می‌کند، و openai به ChatOpenAI با llm_base_url شما نگاشت می‌شود. اگر یک آموزش به شما بگوید یک پروکسی LiteLLM یا تنظیم api_base داخل Quivr پیکربندی کنید، معماری قدیمی‌تری را توصیف می‌کند؛ فیلد فعلی llm_base_url روی LLMEndpointConfig است. اپ کامل بازنشسته شده. دستورالعمل‌هایی درباره یک backend .env، راه‌اندازی Supabase، یا یک انتخاب‌گر مدل داخل-اپ به اپلیکیشن پیش-پیچش اشاره دارند، که دیگر چیزی نیست که مخزن ارسال می‌کند. پیکربندی اکنون در کد پایتون شما رخ می‌دهد (یا اپ خودتان حول کتابخانه). env var کلید از supplier استخراج می‌شود. برای supplier openai آن OPENAI_API_KEY است، حتی وقتی endpoint OpenAI نیست. اگر ترجیح می‌دهید آن نام را overload نکنید، llm_api_key را صریح در config پاس دهید، که اولویت دارد و محیط را تمیز نگه می‌دارد. embedder جدا است. مسیردهی تولید embedding ها را جابه‌جا نمی‌کند؛ embedder پیش‌فرض OpenAIEmbeddings با credential های خودش است. دو نیمه را مستقل تصمیم بگیرید، و re-embedding یک store موجود فقط اگر خود مدل embedding را تغییر دهید لازم است.

چه کسانی quivr-core را از طریق یک gateway مسیردهی می‌کنند.

  • تیم‌های محصول که RAG را در اپ‌های خود embed می‌کنند و می‌خواهند مدل تولید یک مقدار config باشد، نه یک تعهد vendor داخل stack.
  • توسعه‌دهندگانی که بسیاری brain در tier های کیفیت مختلف اجرا می‌کنند: یک کلید، یک endpoint، id مدل به ازای هر brain.
  • تیم‌هایی که پاسخ‌های مبتنی با کیفیت Claude پشت یک config به‌شکل OpenAI می‌خواهند بدون اضافه‌کردن یک SDK یا حساب provider دوم.
  • سازندگانی که مدل‌های تولید را روی یک corpus ثابت benchmark می‌کنند، جایی که هر کاندید یک تغییر LLMEndpointConfig است.
  • توسعه‌دهندگان بدون دسترسی به صورت‌حساب یک vendor خاص. دسترسی مبتنی بر شارژ بدون الزام کارت وابستگی ثبت‌نام هر-provider را حذف می‌کند.

endpoint را تأیید کنید و اولین ask() را عیب‌یابی کنید.

تأیید کنید gateway مدل شما را قبل از ingest کردن هر چیزی فهرست می‌کند؛ فیلد model باید دقیقاً با یک id سرویس‌داده‌شده مطابقت داشته باشد. شکست‌های اجرای اول قابل‌پیش‌بینی‌اند. هشداری که کلید API برای supplier openai تنظیم نشده یعنی نه llm_api_key و نه OPENAI_API_KEY هنگام ساخت config قابل‌مشاهده بودند؛ هشدار هنگام ساخت رخ می‌دهد، شکست در اولین ask(). یک 401 یعنی کلید resolve‌شده متعلق به endpoint در llm_base_url نیست. یک خطای model-not-found یک غلط‌تایپی id در برابر /v1/models است. و یک خطای authentication مرتبط با embedding در طول Brain.from_files همان embedder پیش‌فرض جدا است که credential های OpenAI خودش را می‌خواهد، که هیچ تنظیم llm_base_url آن را رفع نمی‌کند؛ یک embedder که کنترل می‌کنید پاس دهید. وقتی پاسخ‌ها جاری شوند، کنسول APIsRouter مدل، شمارش token، و هزینه هر-درخواست را نشان می‌دهد. برای کتابخانه‌ای که chunk های بازیابی‌شده را در هر prompt بسته‌بندی می‌کند، عدد token-به-ازای-هر-پاسخ روی corpus واقعی شما همان رقمی است که باید انتخاب مدل شما را هدایت کند.

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 می‌سازد. آن را روی endpoint gateway تنظیم کنید و هر id مدل کاتالوگ را پاس دهید.

آیا Quivr مبتنی‌بر LiteLLM است؟

در codebase فعلی خیر. quivr-core کلاس‌های چت LangChain را حسب supplier انتخاب می‌کند؛ 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، یا هر id دیگری که endpoint سرویس دهد زیر supplier openai کار می‌کند.

کدام متغیر محیطی کلید را نگه می‌دارد؟

وقتی llm_api_key در config تنظیم نشده، quivr-core متغیر را از نام supplier استخراج می‌کند: OPENAI_API_KEY برای supplier openai. یک llm_api_key صریح در LLMEndpointConfig اولویت دارد و از overload‌کردن آن نام جلوگیری می‌کند.

آیا llm_base_url embedding ها را هم جابه‌جا می‌کند؟

خیر. embedder پیش‌فرض یک client جدای OpenAIEmbeddings با credential ها و endpoint خودش است. تولید را از طریق gateway مسیردهی کنید و اگر می‌خواهید نیمه embedding هم از OpenAI خارج باشد embedder خودتان را پاس دهید.

آیا پروژه Quivr هنوز نگه‌داری می‌شود؟

مخزن از اواسط ۲۰۲۵ ساکت بوده، پس آن را یک کتابخانه پایدار در نظر بگیرید نه یک پروژه فعال. سطح llm_base_url مستندشده اینجا با شاخه main فعلی مطابقت دارد، و اپ کامل پیش-پیچشی که جایگزین کرد بازنشسته شده.