Rode o paper-qa contra um endpoint personalizado compatível com OpenAI.

Updated 2026-07-30

O paper-qa configura seus modelos através de dicts de router do LiteLLM, e litellm_params aceita api_base. Aponte-o para https://api.apisrouter.com/v1, passe uma chave, e os slots de resposta, resumo, e agente podem cada um rodar qualquer modelo do catálogo sobre sua própria biblioteca de papers.

Resposta rápida: um dict de router com api_base, reutilizado por slot.

O objeto Settings do paper-qa aceita um nome de modelo mais uma config de router do LiteLLM opcional por slot. A config de router é um model_list cujo litellm_params carrega api_base e api_key, que é o mesmo padrão documentado que o README usa para servidores compatíveis com OpenAI hospedados localmente; um gateway é simplesmente esse padrão com uma URL pública e uma chave real. Defina llm e summary_llm para o model_name que você declarou, anexe a config aos dois slots, e o paper-qa roteia pelo gateway. A string de modelo dentro de litellm_params mantém a convenção de provider do litellm: openai/<id> diz ao litellm para falar chat-completions com seu api_base, e o id depois da barra é passado para o endpoint, então ids Claude, GPT, Gemini, e GLM são todos endereçáveis com o mesmo 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,
            ),
        )
    ]
)

Onde o paper-qa gasta tokens: três slots mais embeddings.

O paper-qa (Future-House no GitHub, cerca de 9 mil estrelas) faz resposta de pergunta com retrieval-augmented sobre PDFs científicos com um loop agêntico por cima: um agente decide quando buscar na sua biblioteca, reúne trechos de evidência, resume sua relevância, e compõe uma resposta citada. Isso mapeia para três slots de LLM configuráveis separadamente. summary_llm avalia e condensa evidência por trecho recuperado, o que o torna o slot de volume. llm escreve a resposta final a partir da evidência montada, a etapa crítica para qualidade. E agent_llm (dentro das configurações de agente) toma as decisões de seleção de ferramenta que guiam o loop. Os três têm como padrão um modelo OpenAI, e cada um tem um campo _config correspondente (llm_config, summary_llm_config, agent_llm_config) que aceita o mesmo dict de router, então um objeto de config de gateway pode ser anexado a cada slot enquanto o nome do modelo por slot permanece independente. Uma divisão comum é um id rápido resumindo evidência e um id de ponta escrevendo respostas, ambos através de um endpoint e chave. Embeddings são a quarta carga de trabalho e deliberadamente separados: a configuração de embedding (padrão text-embedding-3-small) constrói o índice vetorial dos seus papers. Mover slots de chat para um gateway não move embeddings, e o paper-qa suporta sentence-transformers locais (o prefixo st-, via os extras locais) se você quiser o índice totalmente independente de qualquer endpoint remoto.

Configuração completa: Settings com configs por slot.

O padrão completo declara uma entrada de router por modelo que você quer endereçável e anexa configs slot por slot. Declarar duas entradas, uma rápida para resumos e uma forte para respostas, mantém a configuração inteira em um dict. O mesmo roteamento funciona a partir da CLI, já que o pqa expõe a superfície de settings, mas o caminho Python é o reproduzível para uso de pesquisa: o objeto Settings que produziu uma resposta pode ser registrado junto à própria resposta.

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

Escolhendo modelos por slot.

Ajuste com o pipeline de evidência fixo: mesma biblioteca, mesmas perguntas, troque um slot de cada vez. Atrás de um endpoint, cada candidato é uma string de model_name, e o log de uso por chave precifica cada configuração por pergunta, que é o número que um laboratório de fato orça.

  • summary_llm roda uma vez por trecho de evidência, toda pergunta. Em uma biblioteca séria, isso é a esmagadora maioria das chamadas, então um id rápido (claude-haiku-4-5-20251001) define o piso de custo do sistema inteiro tendo só que julgar relevância, não escrever prosa.
  • llm compõe a resposta citada a partir da evidência montada. É aqui que escrita científica precisa e ponderada acontece ou não; claude-sonnet-4-6 e gpt-5.5 são as escolhas confiáveis, e o slot é poucas chamadas por pergunta então o prêmio é limitado.
  • agent_llm guia o loop: se deve buscar de novo, reunir mais evidência, ou responder. Decisões fracas aqui desperdiçam tokens em todo o resto, o que torna um id de camada média ou melhor a escolha econômica apesar do baixo volume do slot.
  • Ids de contexto longo como gemini-3.1-pro-preview valem a pena testar como o slot de resposta quando perguntas puxam evidência de muitos papers de uma vez.

Pague pelo uso · abaixo do preço oficial

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

ModeloPreço oficialNosso preço
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

Os modos de falha específicos do paper-qa.

Um slot deixado no padrão. Definir llm e llm_config mas não summary_llm_config deixa a sumarização no modelo OpenAI padrão, que então exige OPENAI_API_KEY e falha (ou divide silenciosamente seu roteamento entre dois endpoints se essa chave existir). Cada slot tem seu próprio campo _config; anexe o dict de gateway a todo slot que você pretende mover, agent_llm_config incluído. Nomes que não se alinham. Settings.llm precisa ser igual a um model_name em model_list; litellm_params.model é o que de fato vai para a conexão. Desalinhe o nome externo e o router não tem rota; erre a digitação do id interno e o gateway retorna model-not-found. Ao depurar, verifique as duas strings separadamente porque elas falham de formas diferentes. Embeddings assumidos como acompanhantes. O slot de embedding constrói e consulta o índice vetorial e tem seu próprio padrão e config. Se você não tem uma chave OpenAI para o embedding padrão, configure embedding explicitamente, ou use sentence-transformers locais via o prefixo st-. Redirecionar embeddings depois também significa reindexar: vetores de modelos de embedding diferentes não se misturam. Limites de geração faltando para respostas longas. litellm_params aceita max_tokens por entrada, e os exemplos de endpoint local upstream o definem deliberadamente. Um slot de resposta sem um limite sensato pode truncar respostas citadas longas, o que se apresenta como fraqueza de modelo mas é um parâmetro. Culpar o roteamento por problemas de parsing. A qualidade do paper-qa depende de parsing de PDF e chunking antes de qualquer modelo ver texto. Se respostas não citam nada em uma biblioteca que você sabe ser relevante, inspecione a etapa de indexação; o gateway só vê o que a recuperação envia a ele.

Quem roteia o paper-qa por um gateway.

  • Grupos de pesquisa rodando QA de literatura sobre bibliotecas compartilhadas, onde uso por chave transforma "quanto o laboratório gasta por pergunta" de um chute em um relatório.
  • Times que querem escrita científica com qualidade Claude no slot de resposta enquanto mantêm o volume de sumarização em um id rápido, uma chave para os dois.
  • Desenvolvedores incorporando o paper-qa em ferramentas internas, substituindo um pacote de segredos de fornecedor por uma credencial de gateway por ambiente.
  • Pessoas fazendo benchmark comparando modelos de resposta em pipelines de evidência fixos, onde cada candidato é uma string de config em vez de uma integração de fornecedor.
  • Desenvolvedores sem acesso ao faturamento de um determinado fornecedor. O acesso baseado em recarga sem exigência de cartão remove a dependência de cadastro por provedor.

Verifique o endpoint e depure a primeira pergunta.

Confirme que o gateway serve os ids que você declarou; a string litellm_params.model depois de openai/ precisa corresponder a um id servido exatamente. A escada de falha em um primeiro ask(): um erro exigindo OPENAI_API_KEY significa que algum slot ainda está no modelo padrão sem config anexada; descubra qual de llm, summary_llm, e agent_llm você não moveu. Um 401 do gateway é a api_key dentro de litellm_params. Um erro de router sobre um modelo desconhecido significa que Settings.llm não corresponde a nenhum model_name na lista. Falhas durante a indexação em vez de na resposta apontam para a configuração de embedding ou parsing de PDF, não roteamento de chat. Uma pergunta se ramifica em muitas chamadas de resumo mais etapas de agente mais a resposta final, então depois da primeira execução bem-sucedida, a visão por requisição do console da APIsRouter mostra a divisão de slots em tokens reais. Esse é o número a observar conforme a biblioteca cresce, porque o volume de resumo escala com a evidência recuperada, não só com a contagem de perguntas.

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

Perguntas frequentes

Como o paper-qa suporta uma base URL personalizada compatível com OpenAI?

Através de suas configs de router do LiteLLM: cada um de llm_config, summary_llm_config, e agent_llm_config aceita um model_list cujo litellm_params inclui api_base e api_key. Esse é o mesmo padrão documentado que o paper-qa usa para servidores compatíveis com OpenAI hospedados localmente, apontado para uma URL de gateway em vez disso.

Os modelos de resposta e resumo podem vir de fornecedores diferentes?

Sim. Cada slot combina um nome de modelo com sua própria config, então um id Claude rápido pode resumir evidência enquanto GPT-5.5 ou Gemini escreve a resposta final, tudo através de um api_base e uma chave. Declare uma entrada de model_list por id e as referencie por slot.

Preciso mudar o modelo de embedding também?

Não, e geralmente você não deveria fazer isso na mesma etapa. A configuração de embedding é independente dos slots de chat, e trocar de modelo de embedding invalida seu índice vetorial existente. Se você não tem uma chave para o embedding padrão, defina embedding explicitamente ou use sentence-transformers locais com o prefixo st-.

O que é o slot agent_llm e ele também precisa da config?

agent_llm, dentro de AgentSettings, conduz a seleção de ferramenta: quando buscar, reunir evidência, ou responder. Tem como padrão um modelo OpenAI como os outros slots, então anexe agent_llm_config com o mesmo dict de gateway ou ele ainda vai tentar rotear para o provider padrão.

Por que o paper-qa ainda pede OPENAI_API_KEY depois da minha sobrescrita?

Pelo menos um slot ainda está no modelo padrão sem config de router anexada. Verifique llm, summary_llm, e agent_llm mais seus campos _config; o erro nomeia o modelo que tentou chamar, o que identifica o slot que você perdeu.

Isso funciona pela CLI pqa assim como pelo Python?

A CLI expõe a mesma superfície de settings, mas para roteamento por gateway o caminho Python é o prático: dicts de router são desajeitados como flags de linha de comando, e um objeto Settings registrado junto aos resultados torna execuções de pesquisa reproduzíveis.