Запустіть paper-qa проти кастомного OpenAI-сумісного ендпоінта.

Updated 2026-07-30

paper-qa налаштовує свої моделі через словники роутера LiteLLM, а litellm_params приймає api_base. Вкажіть на https://api.apisrouter.com/v1, передайте один ключ — і слоти відповіді, підсумку й агента можуть кожен працювати на будь-якій моделі каталогу над вашою власною бібліотекою статей.

Коротка відповідь: словник роутера з api_base, повторно використаний на кожен слот.

Об'єкт Settings у paper-qa бере назву моделі плюс опційну конфігурацію роутера LiteLLM на слот. Конфігурація роутера — це model_list, чиї litellm_params несуть api_base і api_key, той самий задокументований патерн, який README використовує для локально хостованих OpenAI-сумісних серверів; шлюз — це просто цей патерн з публічним URL і реальним ключем. Встановіть llm і summary_llm на model_name, який ви задекларували, приєднайте конфігурацію до обох слотів, і paper-qa маршрутизується через шлюз. Рядок моделі всередині litellm_params тримає конвенцію провайдера litellm: openai/<id> каже litellm говорити chat-completions до вашого api_base, а id після скісної риски пересилається до ендпоінта, тож id Claude, GPT, Gemini і GLM усі адресовні тим самим словником.

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,
            ),
        )
    ]
)

Де paper-qa витрачає токени: три слоти плюс ембедінги.

paper-qa (Future-House на GitHub, приблизно 9 тис. зірок) робить пошук із доповненням (RAG) над науковими PDF з агентним циклом зверху: агент вирішує, коли шукати у вашій бібліотеці, збирає фрагменти доказів, підсумовує їхню релевантність і складає процитовану відповідь. Це мапиться на три окремо налаштовувані слоти LLM. summary_llm оцінює й стискає докази на кожен отриманий фрагмент, що робить його об'ємним слотом. llm пише фінальну відповідь із зібраних доказів, критичний для якості крок. А agent_llm (усередині налаштувань агента) приймає рішення про вибір інструментів, що керують циклом. Усі три за замовчуванням — модель OpenAI, і кожен має відповідне поле _config (llm_config, summary_llm_config, agent_llm_config), що приймає той самий словник роутера, тож один об'єкт конфігурації шлюзу можна прикріпити до кожного слоту, поки назва моделі на слот лишається незалежною. Поширений поділ — швидкий id підсумовує докази, а фронтирний id пише відповіді, обидва через один ендпоінт і ключ. Ембедінги — четверте навантаження й свідомо окреме: налаштування ембедінга (за замовчуванням text-embedding-3-small) будує векторний індекс ваших статей. Переміщення слотів чату на шлюз не рухає ембедінги, і paper-qa підтримує локальні sentence-transformers (префікс st-, через local extras), якщо ви хочете, щоб індекс був повністю незалежним від будь-якого віддаленого ендпоінта.

Повне налаштування: Settings з конфігураціями на слот.

Повний патерн декларує один запис роутера на кожну модель, яку хочете адресовну, і прикріплює конфігурації слот за слотом. Декларування двох записів, швидкого для підсумків і сильного для відповідей, тримає все налаштування в одному словнику. Та сама маршрутизація працює з CLI, оскільки pqa відкриває поверхню налаштувань, але шлях Python — відтворюваний для дослідницького використання: об'єкт Settings, що видав відповідь, можна залогувати поруч із самою відповіддю.

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",
    ),
)

Вибір моделей на слот.

Налаштовуйте із зафіксованим конвеєром доказів: та сама бібліотека, ті самі питання, міняйте один слот за раз. За одним ендпоінтом кожен кандидат — рядок model_name, а лог використання за ключем оцінює кожну конфігурацію на питання, і це число, яке лабораторія справді бюджетує.

  • summary_llm запускається раз на фрагмент доказів, на кожне питання. У серйозній бібліотеці це переважна більшість викликів, тож швидкий id (claude-haiku-4-5-20251001) встановлює нижню межу вартості для всієї системи, маючи лише оцінити релевантність, а не писати прозу.
  • llm складає процитовану відповідь із зібраних доказів. Тут або відбувається, або ні, обережне й точне наукове письмо; claude-sonnet-4-6 і gpt-5.5 — надійний вибір, а слот отримує мало викликів на питання, тож премія обмежена.
  • agent_llm керує циклом: чи шукати знову, збирати більше доказів чи відповідати. Слабкі рішення тут марнують токени всюди інде, що робить id середнього рівня чи кращий економічним вибором попри низький обсяг слоту.
  • Id з довгим контекстом, такі як gemini-3.1-pro-preview, варто протестувати як слот відповіді, коли питання витягують докази з багатьох статей одночасно.

Оплата за фактом · нижче офіційних цін

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.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

Збої, специфічні саме для paper-qa.

Слот, лишений на своєму значенні за замовчуванням. Встановлення llm і llm_config, але не summary_llm_config, лишає підсумовування на типовій моделі OpenAI, яка тоді вимагає OPENAI_API_KEY і провалюється (чи тихо розділяє вашу маршрутизацію на два ендпоінти, якщо цей ключ існує). Кожен слот має власне поле _config; прикріпіть словник шлюзу до кожного слоту, який плануєте перемістити, включно з agent_llm_config. Назви, що не збігаються. Settings.llm має дорівнювати model_name у model_list; litellm_params.model — те, що насправді йде на дріт. Не збіжіть зовнішню назву — і роутер не має маршруту; помиліться в написанні внутрішнього id — і шлюз поверне model-not-found. При налагодженні перевіряйте ці два рядки окремо, бо вони падають по-різному. Припущення, що ембедінги слідують автоматично. Слот ембедінга будує й запитує векторний індекс і має власне значення за замовчуванням і конфігурацію. Якщо у вас немає ключа OpenAI для типового ембедінга, налаштуйте embedding явно чи використовуйте локальні sentence-transformers через префікс st-. Перенаправлення ембедінгів пізніше також означає переіндексацію: вектори з різних моделей ембедінга не змішуються. Відсутні ліміти генерації для довгих відповідей. litellm_params приймає max_tokens на запис, і апстрим-приклади для локального ендпоінта встановлюють його свідомо. Слот відповіді без розумного ліміту може обрізати довгі процитовані відповіді, що виглядає як слабкість моделі, а насправді параметр. Звинувачення маршрутизації в проблемах розбору. Якість paper-qa залежить від розбору й розбиття PDF ще до того, як будь-яка модель побачить текст. Якщо відповіді нічого не цитують у бібліотеці, яку ви знаєте релевантною, перевірте крок індексації; шлюз бачить лише те, що надсилає йому пошук.

Хто спрямовує paper-qa через шлюз.

  • Дослідницькі групи, що запускають QA з літератури над спільними бібліотеками, де використання за ключем перетворює "скільки лабораторія витрачає на питання" з здогадки на звіт.
  • Команди, що хочуть наукового письма якості Claude у слоті відповіді, тримаючи об'єм підсумовування на швидкому id, один ключ для обох.
  • Будівники, що вбудовують paper-qa у внутрішні інструменти, заміняючи пакет секретів постачальників одним обліковим даним шлюзу на середовище.
  • Бенчмаркери, що порівнюють моделі відповідей на фіксованих конвеєрах доказів, де кожен кандидат — рядок конфігурації, а не інтеграція постачальника.
  • Розробники без доступу до білінгу певного постачальника. Доступ на основі поповнення без вимоги картки прибирає залежність від реєстрації в кожного провайдера.

Перевірте ендпоінт і налагодьте перше питання.

Підтвердіть, що шлюз обслуговує задекларовані id; рядок litellm_params.model після openai/ має точно збігатися з обслуговуваним id. Драбина збоїв на першому ask(): помилка, що вимагає OPENAI_API_KEY, означає, що якийсь слот усе ще на типовій моделі без прикріпленої конфігурації; знайдіть, який з llm, summary_llm і agent_llm ви не перемістили. 401 від шлюзу — це api_key всередині litellm_params. Помилка роутера про невідому модель означає, що Settings.llm не збігається з жодним model_name у списку. Збої під час індексації, а не відповіді, вказують на налаштування ембедінга чи розбір PDF, а не на маршрутизацію чату. Одне питання розгалужується на багато викликів підсумку плюс кроки агента плюс фінальну відповідь, тож після першого успішного прогону вигляд на кожен запит у консолі APIsRouter показує поділ слотів у реальних токенах. Це число варто спостерігати, коли бібліотека зростає, бо обсяг підсумків масштабується з отриманими доказами, а не лише з кількістю питань.

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

Поширені запитання

Як paper-qa підтримує кастомний OpenAI-сумісний base URL?

Через свої конфігурації роутера LiteLLM: кожен з llm_config, summary_llm_config і agent_llm_config приймає model_list, чиї litellm_params включають api_base і api_key. Це той самий задокументований патерн, який paper-qa використовує для локально хостованих OpenAI-сумісних серверів, вказаний натомість на URL шлюзу.

Чи можуть моделі відповіді й підсумку бути від різних постачальників?

Так. Кожен слот поєднує назву моделі з власною конфігурацією, тож швидкий id Claude може підсумовувати докази, поки GPT-5.5 чи Gemini пише фінальну відповідь, усе через один api_base і один ключ. Задекларуйте один запис model_list на id і посилайтеся на них по слоту.

Чи потрібно змінювати модель ембедінга теж?

Ні, і зазвичай не варто на тому самому кроці. Налаштування ембедінга незалежне від слотів чату, а перемикання моделей ембедінга робить недійсним ваш наявний векторний індекс. Якщо у вас немає ключа для типового ембедінга, встановіть embedding явно чи використовуйте локальні sentence-transformers з префіксом st-.

Що таке слот agent_llm і чи потрібна йому теж конфігурація?

agent_llm, усередині AgentSettings, керує вибором інструментів: коли шукати, збирати докази чи відповідати. За замовчуванням він, як і інші слоти, — модель OpenAI, тож прикріпіть agent_llm_config з тим самим словником шлюзу, інакше він все одно спробує маршрутизуватися до типового провайдера.

Чому paper-qa все ще просить OPENAI_API_KEY після мого перевизначення?

Принаймні один слот усе ще на типовій моделі без прикріпленої конфігурації роутера. Перевірте llm, summary_llm і agent_llm плюс їхні поля _config; помилка називає модель, яку вона намагалась викликати, що ідентифікує пропущений слот.

Чи працює це з CLI pqa так само, як із Python?

CLI відкриває ту саму поверхню налаштувань, але для маршрутизації через шлюз шлях Python практичніший: словники роутера незручні як прапорці командного рядка, а об'єкт Settings, залогований поруч із результатами, робить дослідницькі прогони відтворюваними.