Ejecuta paper-qa contra un endpoint personalizado compatible con OpenAI.
Updated 2026-07-30
paper-qa configura sus modelos a través de diccionarios de router de LiteLLM, y litellm_params acepta api_base. Apúntalo a https://api.apisrouter.com/v1, pasa una clave, y los slots de respuesta, resumen y agente pueden correr cada uno cualquier modelo del catálogo sobre tu propia biblioteca de papers.
Respuesta rápida: un diccionario de router con api_base, reutilizado por slot.
El objeto Settings de paper-qa toma un nombre de modelo más una config de router de LiteLLM opcional por slot. La config de router es un model_list cuyos litellm_params llevan api_base y api_key, que es el mismo patrón documentado que usa el README para servidores compatibles con OpenAI alojados localmente; un gateway es simplemente ese patrón con una URL pública y una clave real. Configura llm y summary_llm al model_name que declaraste, adjunta la config a ambos slots, y paper-qa enruta a través del gateway. El string del modelo dentro de litellm_params mantiene la convención de proveedor de litellm: openai/<id> le dice a litellm que hable chat-completions con tu api_base, y el id después de la barra se pasa al endpoint, así que los ids de Claude, GPT, Gemini y GLM son todos direccionables con el mismo diccionario.
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,
),
)
]
)Dónde gasta paper-qa tokens: tres slots más embeddings.
paper-qa (Future-House en GitHub, unas 9K estrellas) hace preguntas y respuestas con recuperación aumentada sobre PDFs científicos con un bucle agéntico encima: un agente decide cuándo buscar en tu biblioteca, recopila fragmentos de evidencia, resume su relevancia, y compone una respuesta citada. Eso se mapea en tres slots de LLM configurables por separado. summary_llm evalúa y condensa evidencia por cada fragmento recuperado, lo que lo convierte en el slot de volumen. llm escribe la respuesta final a partir de la evidencia ensamblada, el paso crítico para la calidad. Y agent_llm (dentro de la config del agente) toma las decisiones de selección de herramientas que dirigen el bucle. Los tres usan por defecto un modelo de OpenAI, y cada uno tiene un campo _config correspondiente (llm_config, summary_llm_config, agent_llm_config) que acepta el mismo diccionario de router, así que un objeto de config de gateway puede adjuntarse a cada slot mientras el nombre del modelo por slot permanece independiente. Una división común es un id rápido resumiendo evidencia y un id de vanguardia escribiendo respuestas, ambos a través de un endpoint y una clave. Los embeddings son la cuarta carga de trabajo y deliberadamente separada: el ajuste de embedding (por defecto text-embedding-3-small) construye el índice vectorial de tus papers. Mover los slots de chat a un gateway no mueve los embeddings, y paper-qa admite sentence-transformers local (el prefijo st-, vía los extras locales) si quieres el índice completamente independiente de cualquier endpoint remoto.
Configuración completa: Settings con configs por slot.
El patrón completo declara una entrada de router por cada modelo que quieras direccionable y adjunta configs slot por slot. Declarar dos entradas, una rápida para resúmenes y una fuerte para respuestas, mantiene toda la configuración en un diccionario. El mismo enrutamiento funciona desde la CLI, ya que pqa expone la superficie de settings, pero la ruta de Python es la reproducible para uso de investigación: el objeto Settings que produjo una respuesta puede registrarse junto a la respuesta misma.
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",
),
)Elegir modelos por slot.
Ajusta con el pipeline de evidencia fijo: misma biblioteca, mismas preguntas, cambia un slot a la vez. Detrás de un endpoint cada candidato es un string model_name, y el log de uso por clave tasa cada configuración por pregunta, que es el número que un laboratorio realmente presupuesta.
- summary_llm corre una vez por fragmento de evidencia, en cada pregunta. En una biblioteca seria esto es la abrumadora mayoría de las llamadas, así que un id rápido (claude-haiku-4-5-20251001) fija el piso de coste para todo el sistema mientras solo tiene que juzgar relevancia, no escribir prosa.
- llm compone la respuesta citada a partir de la evidencia ensamblada. Aquí es donde la escritura científica precisa y matizada ocurre o no; claude-sonnet-4-6 y gpt-5.5 son las opciones confiables, y el slot son pocas llamadas por pregunta así que la prima está acotada.
- agent_llm dirige el bucle: si buscar de nuevo, recopilar más evidencia, o responder. Decisiones débiles aquí desperdician tokens en todos lados, lo que hace que un id de nivel medio o mejor sea la opción económica pese al bajo volumen del slot.
- Vale la pena probar ids de contexto largo como gemini-3.1-pro-preview como el slot de respuesta cuando las preguntas extraen evidencia de muchos papers a la vez.
Pago por uso · por debajo del precio oficial
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Modelo | Precio oficial | Nuestro precio |
|---|---|---|
| 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 |
Los modos de fallo específicos de paper-qa.
Un slot dejado en su valor por defecto. Configurar llm y llm_config pero no summary_llm_config deja la sumarización en el modelo de OpenAI por defecto, que entonces exige OPENAI_API_KEY y falla (o divide silenciosamente tu enrutamiento entre dos endpoints si esa clave existe). Cada slot tiene su propio campo _config; adjunta el diccionario de gateway a cada slot que pretendas mover, agent_llm_config incluido. Nombres que no coinciden. Settings.llm debe ser igual a un model_name en model_list; litellm_params.model es lo que realmente va por el cable. Desajusta el nombre externo y el router no tiene ruta; escribe mal el id interno y el gateway devuelve model-not-found. Al depurar, revisa los dos strings por separado porque fallan de forma distinta. Embeddings que se asume que siguen. El slot de embedding construye y consulta el índice vectorial y tiene su propio valor por defecto y config. Si no tienes una clave de OpenAI para el embedding por defecto, configura embedding explícitamente, o usa sentence-transformers local vía el prefijo st-. Reapuntar embeddings más tarde también significa reindexar: los vectores de distintos modelos de embedding no se mezclan. Límites de generación faltantes para respuestas largas. litellm_params acepta max_tokens por entrada, y los ejemplos de endpoint local upstream lo configuran deliberadamente. Un slot de respuesta sin un límite sensato puede truncar respuestas citadas largas, lo que se presenta como debilidad del modelo pero es un parámetro. Culpar al enrutamiento por problemas de parseo. La calidad de paper-qa depende del parseo y troceo de PDF antes de que cualquier modelo vea texto. Si las respuestas no citan nada en una biblioteca que sabes relevante, inspecciona el paso de indexación; el gateway solo ve lo que la recuperación le envía.
Quién enruta paper-qa a través de un gateway.
- Grupos de investigación que ejecutan QA de literatura sobre bibliotecas compartidas, donde el uso por clave convierte "cuánto gasta el laboratorio por pregunta" de una suposición en un reporte.
- Equipos que quieren escritura científica de calidad Claude en el slot de respuesta manteniendo el volumen de sumarización en un id rápido, una clave para ambos.
- Constructores que integran paper-qa en herramientas internas, reemplazando un paquete de secretos de proveedor por una credencial de gateway por entorno.
- Benchmarkers que comparan modelos de respuesta sobre pipelines de evidencia fijos, donde cada candidato es un string de config en lugar de una integración de proveedor.
- Desarrolladores sin acceso a la facturación de un proveedor concreto. El acceso mediante recarga sin necesidad de tarjeta elimina la dependencia de registrarse en cada proveedor.
Verifica el endpoint y depura la primera pregunta.
Confirma que el gateway sirve los ids que declaraste; el string litellm_params.model después de openai/ debe coincidir exactamente con un id servido. La escalera de fallos en un primer ask(): un error exigiendo OPENAI_API_KEY significa que algún slot sigue en su modelo por defecto sin config adjunta; encuentra cuál de llm, summary_llm y agent_llm no moviste. Un 401 del gateway es el api_key dentro de litellm_params. Un error de router sobre un modelo desconocido significa que Settings.llm no coincide con ningún model_name en la lista. Los fallos durante la indexación en lugar de al responder apuntan al ajuste de embedding o al parseo de PDF, no al enrutamiento de chat. Una pregunta se abre en muchas llamadas de resumen más pasos de agente más la respuesta final, así que después de la primera ejecución exitosa, la vista por petición de la consola de APIsRouter muestra la división por slot en tokens reales. Ese es el número a vigilar a medida que crece la biblioteca, porque el volumen de resumen escala con la evidencia recuperada, no solo con el número de preguntas.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50Preguntas frecuentes
¿Cómo admite paper-qa una URL base personalizada compatible con OpenAI?
A través de sus configs de router de LiteLLM: cada uno de llm_config, summary_llm_config y agent_llm_config acepta un model_list cuyos litellm_params incluyen api_base y api_key. Es el mismo patrón documentado que paper-qa usa para servidores compatibles con OpenAI alojados localmente, apuntado a una URL de gateway en su lugar.
¿Pueden los modelos de respuesta y resumen venir de distintos proveedores?
Sí. Cada slot empareja un nombre de modelo con su propia config, así que un id de Claude rápido puede resumir evidencia mientras GPT-5.5 o Gemini escribe la respuesta final, todo a través de un api_base y una clave. Declara una entrada de model_list por id y referéncialas por slot.
¿Necesito cambiar también el modelo de embedding?
No, y normalmente no deberías hacerlo en el mismo paso. El ajuste de embedding es independiente de los slots de chat, y cambiar de modelo de embedding invalida tu índice vectorial existente. Si te falta una clave para el embedding por defecto, configura embedding explícitamente o usa sentence-transformers local con el prefijo st-.
¿Qué es el slot agent_llm y también necesita la config?
agent_llm, dentro de AgentSettings, dirige la selección de herramientas: cuándo buscar, recopilar evidencia, o responder. Usa por defecto un modelo de OpenAI como los otros slots, así que adjunta agent_llm_config con el mismo diccionario de gateway o seguirá intentando enrutar al proveedor por defecto.
¿Por qué paper-qa sigue pidiendo OPENAI_API_KEY después de mi override?
Al menos un slot sigue en su modelo por defecto sin config de router adjunta. Revisa llm, summary_llm y agent_llm más sus campos _config; el error nombra el modelo que intentó llamar, lo que identifica el slot que te faltó.
¿Funciona esto también desde la CLI pqa además de Python?
La CLI expone la misma superficie de settings, pero para enrutamiento por gateway la ruta de Python es la práctica: los diccionarios de router son incómodos como flags de línea de comandos, y un objeto Settings registrado junto a los resultados hace que las ejecuciones de investigación sean reproducibles.