Patakbuhin ang paper-qa laban sa isang custom OpenAI-compatible endpoint.
Updated 2026-07-30
Kino-configure ng paper-qa ang mga model nito sa pamamagitan ng LiteLLM router dicts, at tinatanggap ng litellm_params ang api_base. Ituro ito sa https://api.apisrouter.com/v1, ipasa ang isang key, at bawat isa sa answer, summary, at agent slots ay maaaring magpatakbo ng anumang catalog model sa ibabaw ng sarili mong paper library.
Mabilisang sagot: isang router dict na may api_base, ginagamit ulit per slot.
Tumatanggap ang Settings object ng paper-qa ng isang model name kasama ang isang opsyonal na LiteLLM router config per slot. Ang router config ay isang model_list na ang litellm_params ay may dalang api_base at api_key, na siyang parehong naka-document na pattern na ginagamit ng README para sa mga locally hosted OpenAI-compatible server; ang isang gateway ay simpleng ang pattern na iyon na may public URL at tunay na key. Itakda ang llm at summary_llm sa model_name na idineklara mo, ikabit ang config sa parehong slots, at niruruta ng paper-qa ang trapiko sa pamamagitan ng gateway. Pinapanatili ng model string sa loob ng litellm_params ang provider convention ng litellm: sinasabi ng openai/<id> sa litellm na magsalita ng chat-completions sa api_base mo, at ang id pagkatapos ng slash ay ipinapasa sa endpoint, kaya ang mga Claude, GPT, Gemini, at GLM id ay puwedeng ma-address gamit ang parehong dict.
gateway_config = dict(
model_list=[
dict(
model_name="claude-sonnet-4-6",
litellm_params=dict(
model="openai/claude-sonnet-4-6",
api_base="https://api.apisrouter.com/v1",
api_key=os.getenv("APISROUTER_API_KEY"),
temperature=0.1,
),
)
]
)Saan ginagastos ng paper-qa ang mga token: tatlong slot kasama ang embeddings.
Gumagawa ang paper-qa (Future-House sa GitHub, humigit-kumulang 9K stars) ng retrieval-augmented question answering sa mga siyentipikong PDF na may agentic loop sa ibabaw nito: nagpapasya ang isang agent kung kailan maghahanap sa library mo, kinokolekta ang mga evidence chunk, sinu-summarize ang relevance ng mga ito, at bumubuo ng isang cited na sagot. Naka-map ito sa tatlong hiwalay na maaaring i-configure na LLM slot. Sinusuri at pinapaikli ng summary_llm ang evidence per retrieved chunk, na siyang gumagawa dito bilang volume slot. Sinusulat ng llm ang huling sagot mula sa naipong evidence, ang quality-critical na hakbang. At ang agent_llm (sa loob ng agent settings) ang gumagawa ng mga desisyon sa tool-selection na nagtutuon sa loop. Naka-default sa isang OpenAI model ang lahat ng tatlo, at bawat isa ay may katugmang _config field (llm_config, summary_llm_config, agent_llm_config) na tumatanggap ng parehong router dict, kaya isang gateway config object lang ang puwedeng ikabit sa bawat slot habang nananatiling independiyente ang model name per slot. Karaniwang paghahati ay isang mabilis na id na nag-su-summarize ng evidence at isang frontier na id na sumusulat ng mga sagot, pareho sa pamamagitan ng isang endpoint at key. Ang embeddings ang ika-apat na workload at sadyang hiwalay: ang embedding setting (default na text-embedding-3-small) ang bumubuo ng vector index ng mga papers mo. Ang paglipat ng chat slots sa isang gateway ay hindi naglilipat ng embeddings, at sinusuportahan ng paper-qa ang local sentence-transformers (ang st- prefix, sa pamamagitan ng local extras) kung gusto mong ganap na independiyente ang index sa anumang remote endpoint.
Buong setup: Settings na may per-slot configs.
Idinideklara ng buong pattern ang isang router entry per model na gusto mong ma-address at ikinakabit ang configs slot by slot. Ang pagdedeklara ng dalawang entry, isang mabilis para sa summaries at isang malakas para sa answers, ay nagpapanatili sa buong setup sa isang dict. Gumagana rin ang parehong routing mula sa CLI, dahil inilalantad ng pqa ang settings surface, pero ang Python path ang reproducible na paraan para sa research use: ang Settings object na gumawa ng isang sagot ay puwedeng i-log katabi mismo ng sagot.
import os
from paperqa import Settings, ask
from paperqa.settings import AgentSettings
def entry(model_id, **params):
return dict(
model_name=model_id,
litellm_params=dict(
model=f"openai/{model_id}",
api_base="https://api.apisrouter.com/v1",
api_key=os.getenv("APISROUTER_API_KEY"),
**params,
),
)
gateway = dict(model_list=[
entry("claude-sonnet-4-6", temperature=0.1),
entry("claude-haiku-4-5-20251001", temperature=0.1),
])
answer = ask(
"What is the evidence for LK-99 room-temperature superconductivity?",
settings=Settings(
llm="claude-sonnet-4-6",
llm_config=gateway,
summary_llm="claude-haiku-4-5-20251001",
summary_llm_config=gateway,
agent=AgentSettings(
agent_llm="claude-sonnet-4-6",
agent_llm_config=gateway,
),
paper_directory="./papers",
),
)Pagpili ng mga model per slot.
I-tune habang naka-fix ang evidence pipeline: parehong library, parehong mga tanong, palitan ang isang slot sa isang pagkakataon. Sa likod ng isang endpoint, isang model_name string ang bawat kandidato, at pinepresyuhan ng per-key usage log ang bawat configuration per tanong, na siyang numerong talagang binabadyet ng isang lab.
- Tumatakbo ang summary_llm nang isang beses per evidence chunk, sa bawat tanong. Sa isang seryosong library, ito ang malaking mayorya ng mga tawag, kaya itinatakda ng isang mabilis na id (claude-haiku-4-5-20251001) ang cost floor ng buong sistema habang paghusga lang ng relevance ang trabaho nito, hindi pagsulat ng prosa.
- Bumubuo ang llm ng cited na sagot mula sa naipong evidence. Dito nangyayari o hindi nangyayari ang hedged at precise na scientific writing; ang claude-sonnet-4-6 at gpt-5.5 ang maaasahang pagpipilian, at kaunti lang ang tawag ng slot na ito per tanong kaya limitado ang premium.
- Ginagabayan ng agent_llm ang loop: kung maghahanap ulit, mangongolekta pa ng ebidensya, o sasagot na. Ang mahihinang desisyon dito ay nag-aaksaya ng tokens sa lahat ng ibang bahagi, kaya isang mid-tier o mas magandang id ang mas matipid na pagpipilian sa kabila ng mababang volume ng slot na ito.
- Sulit subukan ang mga long-context na id tulad ng gemini-3.1-pro-preview bilang answer slot kapag kumukuha ang mga tanong ng ebidensya mula sa maraming papers nang sabay-sabay.
Pay-as-you-go · mas mababa sa opisyal na presyo
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Model | Opisyal na Presyo | Aming Presyo |
|---|---|---|
| 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.5 | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| Gemini 3.1 Pro Preview | $2.00 / $12.00 per M | $1.60 / $9.60 per M |
| GLM-5.2 | $1.14 / $4.00 per M | $1.10 / $4.00 per M |
Ang mga failure mode na specific sa paper-qa.
Isang slot na naiwan sa default nito. Ang pagtakda ng llm at llm_config pero hindi ng summary_llm_config ay nag-iiwan sa summarization sa default na OpenAI model, na humihiling pagkatapos ng OPENAI_API_KEY at nabibigo (o tahimik na hinahati ang routing mo sa dalawang endpoint kung umiiral ang key na iyon). May sariling _config field ang bawat slot; ikabit ang gateway dict sa bawat slot na balak mong ilipat, kasama na ang agent_llm_config. Mga pangalan na hindi tumutugma. Dapat katumbas ng Settings.llm ang isang model_name sa model_list; ang litellm_params.model ang talagang napupunta sa wire. Kung mali ang outer name, walang route ang router; kung may typo ang inner id, nagbabalik ng model-not-found ang gateway. Kapag nagde-debug, tingnan ang dalawang string nang hiwalay dahil magkaiba ang paraan ng pagkabigo nila. Ipinagpalagay na susunod ang embeddings. Ang embedding slot ang bumubuo at nagta-query ng vector index at may sarili itong default at config. Kung wala kang OpenAI key para sa default na embedding, i-configure ang embedding nang tahasan, o gumamit ng local sentence-transformers sa pamamagitan ng st- prefix. Ang muling pagturo ng embeddings sa hinaharap ay nangangahulugan din ng muling pag-index: hindi naghahalo ang mga vector mula sa magkaibang embedding model. Kulang na generation limits para sa mahahabang sagot. Tinatanggap ng litellm_params ang max_tokens per entry, at sinadyang itinakda ito ng mga upstream na halimbawa ng local-endpoint. Ang isang answer slot na walang makatwirang limitasyon ay puwedeng mag-truncate ng mahahabang cited na sagot, na tila kahinaan ng model pero isa lamang parameter. Pagsisi sa routing para sa mga parsing problem. Ang kalidad ng paper-qa ay nakadepende sa PDF parsing at chunking bago pa man makita ng kahit anong model ang text. Kung walang sinisipi ang mga sagot sa isang library na alam mong may kaugnayan, suriin ang indexing step; ang gateway ay nakikita lang ang ipinapadala sa kanya ng retrieval.
Sino ang nagru-route ng paper-qa sa pamamagitan ng isang gateway.
- Mga research group na nagpapatakbo ng literature QA sa mga shared library, kung saan ginagawang isang report ng per-key usage ang tanong na "magkano ang ginagastos ng lab per tanong" sa halip na isang hula.
- Mga team na gustong magkaroon ng Claude-quality na scientific writing sa answer slot habang pinapanatili ang volume ng summarization sa isang mabilis na id, isang key para sa dalawa.
- Mga builder na nag-e-embed ng paper-qa sa internal tools, na pinapalitan ang isang bundle ng vendor secrets ng isang gateway credential per environment.
- Mga benchmarker na naghahambing ng mga answer model sa fixed na evidence pipeline, kung saan ang bawat kandidato ay isang config string sa halip na isang vendor integration.
- Mga developer na walang access sa billing ng isang partikular na vendor. Inaalis ng top-up based na access na walang kailangang card ang per-provider na sign-up dependency.
I-verify ang endpoint at i-debug ang unang tanong.
Kumpirmahin na sine-serve ng gateway ang mga id na idineklara mo; dapat eksaktong tumugma ang litellm_params.model string pagkatapos ng openai/ sa isang si-serve na id. Ang failure ladder sa unang ask(): ang isang error na humihingi ng OPENAI_API_KEY ay nangangahulugang may slot pa ring nasa default model nito na walang kinabit na config; hanapin kung alin sa llm, summary_llm, at agent_llm ang hindi mo nilipat. Ang isang 401 mula sa gateway ay ang api_key sa loob ng litellm_params. Ang isang router error tungkol sa isang hindi kilalang model ay nangangahulugang hindi tumutugma ang Settings.llm sa kahit anong model_name sa listahan. Ang mga kabiguan habang nag-i-index sa halip na sumasagot ay tumuturo sa embedding setting o PDF parsing, hindi sa chat routing. Kumakalat ang isang tanong sa maraming summary call kasama ang agent steps at ang huling sagot, kaya pagkatapos ng unang matagumpay na run, ipinapakita ng per-request view ng APIsRouter console ang slot split sa totoong tokens. Iyon ang numerong dapat panoorin habang lumalaki ang library, dahil ang summary volume ay sumusukat kasabay ng nakuhang ebidensya, hindi lang ng bilang ng tanong.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50Mga madalas itanong
Paano sinusuportahan ng paper-qa ang isang custom OpenAI-compatible base URL?
Sa pamamagitan ng mga LiteLLM router config nito: tumatanggap ang bawat isa sa llm_config, summary_llm_config, at agent_llm_config ng isang model_list na ang litellm_params ay may kasamang api_base at api_key. Ito ang parehong naka-document na pattern na ginagamit ng paper-qa para sa mga locally hosted OpenAI-compatible server, nakatuon na lang sa isang gateway URL.
Puwede bang magmula sa magkaibang vendor ang answer at summary model?
Oo. Ipinapares ng bawat slot ang isang model name sa sarili nitong config, kaya puwedeng mag-summarize ng ebidensya ang isang mabilis na Claude id habang ang GPT-5.5 o Gemini ang sumusulat ng huling sagot, lahat sa pamamagitan ng isang api_base at isang key. Magdeklara ng isang model_list entry per id at i-reference ang mga ito per slot.
Kailangan ko rin bang baguhin ang embedding model?
Hindi, at karaniwan ay hindi mo dapat gawin sa parehong hakbang. Independiyente ang embedding setting sa chat slots, at ang paglipat ng embedding model ay nagpapawalang-bisa sa umiiral mo nang vector index. Kung wala kang key para sa default na embedding, itakda ang embedding nang tahasan o gumamit ng local sentence-transformers gamit ang st- prefix.
Ano ang agent_llm slot at kailangan din ba nito ng config?
Ang agent_llm, sa loob ng AgentSettings, ang nagtutulak sa tool selection: kung kailan maghahanap, mangongolekta ng ebidensya, o sasagot. Naka-default ito sa isang OpenAI model tulad ng ibang slots, kaya ikabit ang agent_llm_config gamit ang parehong gateway dict o susubukan pa rin nitong iruta sa default provider.
Bakit humihingi pa rin ng OPENAI_API_KEY ang paper-qa pagkatapos ng override ko?
May kahit isang slot pa ring nasa default model nito na walang kinabit na router config. Tingnan ang llm, summary_llm, at agent_llm kasama ang kanilang _config fields; pinapangalanan ng error ang model na sinubukan nitong tawagan, na siyang nagtuturo kung aling slot ang naligtaan mo.
Gumagana ba ito mula sa pqa CLI gayundin sa Python?
Inilalantad ng CLI ang parehong settings surface, pero para sa gateway routing, ang Python path ang praktikal na paraan: awkward ang mga router dict bilang command-line flags, at ginagawang reproducible ng isang Settings object na naka-log katabi ng resulta ang mga research run.