Chạy bộ não RAG của Quivr trên một endpoint tương thích OpenAI tùy chỉnh.

Updated 2026-07-30

LLMEndpointConfig của quivr-core nhận một field llm_base_url. Giữ supplier là openai, đặt llm_base_url thành https://api.apisrouter.com/v1, truyền một key, và mỗi brain.ask() sinh câu trả lời qua gateway với bất kỳ model id catalog nào.

Câu trả lời nhanh: llm_base_url trong LLMEndpointConfig.

Quivr hiện tại là quivr-core, một thư viện Python RAG, và việc nối dây LLM của nó rõ ràng. LLMEndpointConfig mang supplier (mặc định là openai), model, llm_base_url, và llm_api_key; LLMEndpoint.from_config() xây client thực từ các field đó, và với supplier openai client đó là ChatOpenAI của LangChain được xây với base URL của bạn. Đặt llm_base_url thành https://api.apisrouter.com/v1, đặt model thành bất kỳ id catalog nào, và trao endpoint cho Brain của bạn. Key có thể tới từ field cấu hình hoặc môi trường: khi llm_api_key không được đặt, quivr-core phân giải nó từ một biến môi trường đặt tên theo supplier, thứ với supplier openai là OPENAI_API_KEY. Cả hai con đường đều là hành vi upstream, đọc được trong quivr_core/rag/entities/config.py và 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 hiện là gì, và slot LLM nằm ở đâu.

Quivr (QuivrHQ trên GitHub, khoảng 39K star) bắt đầu như một ứng dụng second-brain đầy đủ và chuyển hướng thành quivr-core: một thư viện RAG có quan điểm bạn nhúng vào sản phẩm của chính mình. Bạn cho nó ăn file, nó phân tích và chia đoạn, nhúng các đoạn vào một vector store (FAISS mặc định, hỗ trợ PGVector), và trả lời câu hỏi trên chúng qua một luồng truy xuất có thể cấu hình. Đối tượng Brain là đơn vị: Brain.from_files() nạp dữ liệu, brain.ask() truy xuất và sinh câu trả lời. Sinh câu trả lời là bước duy nhất cần một chat model. Luồng truy xuất lắp ráp context từ tài liệu của bạn, và LLMEndpoint bạn truyền vào viết câu trả lời có căn cứ. Endpoint đó được xây một lần từ LLMEndpointConfig, nên quyết định base URL được đưa ra lúc khởi tạo và áp dụng cho mọi ask() trên brain đó. Vì ChatOpenAI chuyển tiếp field model như một chuỗi thuần qua /v1/chat/completions, id có thể là Claude, DeepSeek, GPT, hoặc Gemini khi endpoint đứng sau llm_base_url phục vụ chúng. Một lưu ý trung thực về tình trạng dự án: repository đã im ắng từ giữa 2025, nên hãy coi quivr-core là một thư viện ổn định thay vì đang thay đổi nhanh. Bề mặt cấu hình mô tả ở đây khớp với nhánh main mới nhất, và lịch sử im ắng nghĩa là nó khó có khả năng thay đổi dưới chân bạn; nó cũng nghĩa là các hướng dẫn cũ mô tả app full-stack đã ngừng (file .env backend, một frontend đã host) không còn khớp với code.

Cài đặt đầy đủ: một brain với LLM định tuyến qua gateway.

Mẫu hoàn chỉnh truyền LLMEndpoint đã cấu hình vào Brain.from_files. Mọi thứ khác về brain (phân tích, chia đoạn, store FAISS, luồng truy xuất) độc lập với endpoint LLM và giữ mặc định của nó. Hãy để ý embedder. Nếu bạn không truyền một cái, quivr-core xây OpenAIEmbeddings của LangChain với mặc định riêng của nó, thứ xác thực bằng OPENAI_API_KEY và nhắm vào endpoint OpenAI gốc. Đó là một client riêng biệt với LLM chat: định tuyến sinh câu trả lời qua gateway không di chuyển nó. Truyền embedder riêng của bạn (một wrapper sentence-transformers cục bộ, hoặc bất kỳ instance Embeddings LangChain nào bạn cấu hình) nếu bạn không muốn nửa embedding phụ thuộc vào một tài khoản 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)

Chọn model sinh câu trả lời cho RAG.

So sánh ứng viên là một thay đổi lúc khởi tạo: xây hai LLMEndpoint dựa trên cùng base URL, hai brain trên cùng file, và so sánh khác biệt câu trả lời trên một bộ câu hỏi cố định. Log sử dụng theo từng key định giá mỗi lần chạy ứng viên, nên chất lượng-trên-token được đo lường thay vì tranh luận.

  • Sinh câu trả lời RAG nặng đầu vào: các đoạn truy xuất chi phối prompt. Giá theo token đầu vào đặt chi phí một câu trả lời, đây là lý do một id nhanh thường giảm một nửa hóa đơn mà không chạm vào chất lượng truy xuất.
  • claude-sonnet-4-6 là mặc định đáng tin cậy cho câu trả lời có căn cứ tôn trọng context truy xuất và từ chối gọn gàng khi tài liệu không chứa câu trả lời.
  • Các sản phẩm nhúng lưu lượng cao (trường hợp dùng đã nêu của Quivr) chạy tốt trên claude-haiku-4-5-20251001, deepseek-v4-flash, hoặc gemini-3.5-flash cho bộ câu hỏi hằng ngày.
  • max_context_tokens trong cùng cấu hình quản lý lượng context truy xuất pipeline nhồi vào; nâng nó lên tự nhiên đi kèm với id long-context và nâng chi tiêu đầu vào tương ứng.
  • Các tiền tố model không xác định rơi về một tokenizer chung để lập ngân sách, chỉ mang tính thẩm mỹ; chính request mang id của bạn không đổi tới endpoint.

Trả theo mức sử dụng · thấp hơn giá chính thức

Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.

Mô hìnhGiá chính thứcGiá của chúng tôi
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

Sửa lại những hiểu lầm phổ biến về Quivr.

Các hướng dẫn đang lưu hành mô tả những bề mặt Quivr không còn nữa, nên đáng nói rõ code hiện tại thực sự làm gì. quivr-core dựa trên LangChain, không dựa trên LiteLLM. Enum supplier chọn một lớp chat LangChain, và openai ánh xạ tới ChatOpenAI với llm_base_url của bạn. Nếu một hướng dẫn bảo bạn cấu hình một proxy LiteLLM hoặc cài đặt api_base bên trong Quivr, nó mô tả một kiến trúc cũ hơn; field hiện tại là llm_base_url trên LLMEndpointConfig. App full-stack đã ngừng. Các hướng dẫn về file .env backend, cài đặt Supabase, hoặc một bộ chọn model trong app tham chiếu ứng dụng trước-khi-chuyển-hướng, thứ không còn là những gì repository xuất xưởng nữa. Cấu hình giờ diễn ra trong code Python của bạn (hoặc app riêng của bạn xoay quanh thư viện). Biến env cho key được suy ra từ supplier. Với supplier openai đó là OPENAI_API_KEY, ngay cả khi endpoint không phải OpenAI. Nếu bạn không muốn dùng chung tên đó, hãy truyền llm_api_key rõ ràng trong cấu hình, thứ ưu tiên hơn và giữ môi trường sạch. Embedder là riêng biệt. Định tuyến sinh câu trả lời không di chuyển embedding; embedder mặc định là OpenAIEmbeddings với credential riêng của nó. Quyết định hai nửa độc lập, và chỉ cần nhúng lại một store hiện có nếu bạn đổi chính model embedding.

Ai định tuyến quivr-core qua một gateway.

  • Các đội sản phẩm nhúng RAG vào app của họ muốn model sinh câu trả lời là một giá trị cấu hình, không phải một cam kết vendor gắn cứng vào stack.
  • Lập trình viên chạy nhiều brain ở các tầng chất lượng khác nhau: một key, một endpoint, một model id theo từng brain.
  • Các đội muốn câu trả lời có căn cứ chất lượng Claude đứng sau một cấu hình hình dạng OpenAI mà không cần thêm một SDK hoặc tài khoản provider thứ hai.
  • Người xây dựng benchmark model sinh câu trả lời trên một corpus cố định, nơi mỗi ứng viên là một thay đổi LLMEndpointConfig.
  • Lập trình viên không có quyền truy cập billing của một vendor cụ thể. Truy cập dựa trên nạp tiền không yêu cầu thẻ loại bỏ phụ thuộc đăng ký theo từng provider.

Xác minh endpoint và debug ask() đầu tiên.

Xác nhận gateway liệt kê model của bạn trước khi nạp bất cứ gì; field model phải khớp chính xác một id được phục vụ. Lỗi lần chạy đầu có thể dự đoán được. Một cảnh báo rằng API key cho supplier openai chưa được đặt nghĩa là cả llm_api_key và OPENAI_API_KEY đều không hiển thị khi cấu hình được xây; cảnh báo xảy ra lúc xây, lỗi xảy ra ở lần ask() đầu tiên. Một lỗi 401 nghĩa là key đã phân giải không thuộc về endpoint trong llm_base_url. Một lỗi model-not-found là một lỗi chính tả id so với /v1/models. Và một lỗi xác thực liên quan tới embedding trong lúc Brain.from_files là embedder mặc định riêng biệt đang hỏi credential OpenAI của chính nó, thứ không cài đặt llm_base_url nào sửa được; hãy truyền một embedder bạn kiểm soát. Khi câu trả lời đã chạy, console APIsRouter hiển thị model theo từng request, số lượng token, và chi tiêu. Với một thư viện nhồi các đoạn truy xuất vào mỗi prompt, con số token-mỗi-câu-trả-lời trên corpus thực tế của bạn là con số nên định hướng lựa chọn model của bạn.

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $APISROUTER_API_KEY" | head -50

Câu hỏi thường gặp

Quivr có hỗ trợ một base URL tương thích OpenAI tùy chỉnh không?

Có. LLMEndpointConfig của quivr-core có một field llm_base_url, và với supplier openai thư viện xây ChatOpenAI của LangChain dựa trên URL đó. Đặt nó thành endpoint gateway và truyền bất kỳ model id catalog nào.

Quivr có dựa trên LiteLLM không?

Không phải trong codebase hiện tại. quivr-core chọn các lớp chat LangChain theo supplier; supplier openai dùng ChatOpenAI với llm_base_url của bạn. Các hướng dẫn mô tả một api_base LiteLLM bên trong Quivr tham chiếu một kiến trúc cũ hơn.

brain.ask() có thể trả lời với model Claude hoặc DeepSeek không?

Có. Field model được chuyển tiếp như một chuỗi thuần qua /v1/chat/completions, nên claude-sonnet-4-6, deepseek-v4-flash, hoặc bất kỳ id nào khác endpoint phục vụ đều hoạt động dưới supplier openai.

Biến môi trường nào chứa key?

Khi llm_api_key không được đặt trong cấu hình, quivr-core suy ra biến từ tên supplier: OPENAI_API_KEY cho supplier openai. Một llm_api_key rõ ràng trong LLMEndpointConfig ưu tiên hơn và tránh dùng chung tên đó.

llm_base_url có di chuyển cả embedding không?

Không. Embedder mặc định là một client OpenAIEmbeddings riêng biệt với credential và endpoint riêng. Định tuyến sinh câu trả lời qua gateway và truyền embedder riêng của bạn nếu bạn muốn nửa embedding cũng tách khỏi OpenAI.

Dự án Quivr có còn được bảo trì không?

Repository đã im ắng từ giữa 2025, nên hãy coi nó như một thư viện ổn định thay vì đang hoạt động tích cực. Bề mặt llm_base_url tài liệu ở đây khớp với nhánh main mới nhất, và app full-stack trước-khi-chuyển-hướng nó thay thế đã ngừng.