paper-qa를 커스텀 OpenAI 호환 엔드포인트에서 실행하기.

Updated 2026-07-30

paper-qa는 LiteLLM 라우터 딕셔너리를 통해 모델을 설정하며, litellm_params가 api_base를 받습니다. 이를 https://api.apisrouter.com/v1로 지정하고 키 하나를 넘기면, 답변, 요약, 에이전트 슬롯 각각이 여러분의 논문 라이브러리 위에서 어떤 카탈로그 모델로든 실행될 수 있습니다.

빠른 답: api_base를 가진 라우터 딕셔너리, 슬롯마다 재사용.

paper-qa의 Settings 객체는 모델 이름과 함께 슬롯별로 선택적인 LiteLLM 라우터 설정을 받습니다. 그 라우터 설정은 litellm_params가 api_base와 api_key를 담는 model_list이며, 이는 README가 로컬 호스팅된 OpenAI 호환 서버에 쓰는 것과 같은 문서화된 패턴입니다; 게이트웨이는 그저 그 패턴에 공개 URL과 실제 키를 넣은 것뿐입니다. llm과 summary_llm을 여러분이 선언한 model_name으로 설정하고, 그 설정을 두 슬롯 모두에 붙이면 paper-qa가 게이트웨이를 통해 라우팅됩니다. litellm_params 안의 모델 문자열은 litellm의 프로바이더 관례를 유지합니다: openai/<id>는 litellm에게 여러분의 api_base에 chat-completions로 말하라고 알려주고, 슬래시 뒤의 id는 그대로 엔드포인트에 전달되므로, Claude, GPT, Gemini, GLM id 모두 같은 딕셔너리로 주소 지정할 수 있습니다.

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(GitHub의 Future-House, 약 9천 스타)는 위에 에이전트 루프를 얹은 과학 논문 PDF에 대한 검색 증강 질의응답을 합니다: 에이전트가 언제 여러분의 라이브러리를 검색할지 결정하고, 근거 조각을 모으고, 관련성을 요약하고, 출처가 명시된 답변을 구성합니다. 이는 별도로 설정 가능한 세 개의 LLM 슬롯에 대응됩니다. summary_llm은 검색된 조각마다 근거를 평가하고 압축하는데, 이것이 물량 슬롯입니다. llm은 조립된 근거로부터 최종 답변을 쓰는, 품질이 결정적인 단계입니다. 그리고 (agent 설정 안의) agent_llm은 루프를 조종하는 툴 선택 결정을 합니다. 세 개 모두 기본값은 OpenAI 모델이며, 각각은 같은 라우터 딕셔너리를 받는 짝이 되는 _config 필드(llm_config, summary_llm_config, agent_llm_config)를 가지고 있어서, 게이트웨이 설정 객체 하나를 각 슬롯에 붙이면서도 슬롯별 모델 이름은 독립적으로 유지할 수 있습니다. 흔한 조합은 근거를 요약하는 빠른 id와 답변을 쓰는 프론티어 id를 엔드포인트 하나와 키 하나로 쓰는 것입니다. 임베딩은 네 번째 워크로드이며 의도적으로 분리되어 있습니다: 임베딩 설정(기본값 text-embedding-3-small)이 여러분 논문의 벡터 인덱스를 만듭니다. 채팅 슬롯을 게이트웨이로 옮겨도 임베딩은 옮겨지지 않으며, 인덱스를 어떤 원격 엔드포인트와도 완전히 독립적으로 두고 싶다면 paper-qa는 로컬 sentence-transformers(local extras를 통한 st- 프리픽스)를 지원합니다.

전체 설정: 슬롯별 설정을 가진 Settings.

전체 패턴은 주소 지정하고 싶은 모델마다 라우터 항목 하나를 선언하고 슬롯별로 설정을 붙입니다. 요약용 빠른 항목 하나와 답변용 강한 항목 하나, 두 항목을 선언하면 전체 설정이 딕셔너리 하나에 들어갑니다. pqa가 설정 표면을 노출하므로 같은 라우팅이 CLI에서도 작동하지만, 연구 용도로는 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가 경제적인 선택입니다.
  • gemini-3.1-pro-preview 같은 롱컨텍스트 id는 질문이 여러 논문에서 한꺼번에 근거를 끌어올 때 답변 슬롯으로 테스트할 가치가 있습니다.

사용한 만큼 지불 · 공식 요금보다 저렴

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_list 안의 model_name과 같아야 합니다; litellm_params.model이 실제로 와이어에 나가는 것입니다. 바깥 이름을 잘못 맞추면 라우터에 경로가 없고, 안쪽 id에 오타가 있으면 게이트웨이가 model-not-found를 반환합니다. 디버깅할 때는 이 두 문자열을 따로 확인하세요, 서로 다르게 실패하기 때문입니다. 임베딩이 따라올 거라고 가정하는 경우. 임베딩 슬롯이 벡터 인덱스를 만들고 조회하며 자체 기본값과 설정을 가집니다. 기본 임베딩을 위한 OpenAI 키가 없다면 embedding을 명시적으로 설정하거나, st- 프리픽스로 로컬 sentence-transformers를 쓰세요. 나중에 임베딩을 다시 지정하면 재인덱싱도 필요합니다: 서로 다른 임베딩 모델의 벡터는 섞이지 않습니다. 긴 답변에 대한 생성 한도 누락. litellm_params는 항목별로 max_tokens를 받으며, 업스트림의 로컬 엔드포인트 예제도 이를 의도적으로 설정합니다. 합리적인 한도 없는 답변 슬롯은 긴 출처 명시 답변을 잘라낼 수 있는데, 이는 모델의 약점처럼 보이지만 사실 파라미터 문제입니다. 파싱 문제를 라우팅 탓으로 돌리는 경우. paper-qa의 품질은 어떤 모델이 텍스트를 보기도 전에 PDF 파싱과 청킹에 달려 있습니다. 관련성이 있다고 아는 라이브러리에서 답변이 아무것도 인용하지 않는다면, 인덱싱 단계를 살펴보세요; 게이트웨이는 검색이 보내주는 것만 봅니다.

어떤 사람들이 게이트웨이를 통해 paper-qa를 쓰는가.

  • 공유 라이브러리에 대해 문헌 QA를 실행하는 연구 그룹 — 키별 사용량이 "연구실이 질문당 얼마나 쓰는가"를 추측이 아니라 보고서로 바꿔줍니다.
  • 요약 물량은 빠른 id에 두면서 답변 슬롯에서는 Claude급 과학적 글쓰기를 원하는 팀, 키 하나로 둘 다.
  • 내부 도구에 paper-qa를 내장하는 빌더 — 벤더 시크릿 묶음을 환경당 게이트웨이 자격 증명 하나로 대체.
  • 고정된 근거 파이프라인에서 답변 모델을 비교하는 벤치마커 — 각 후보가 벤더 통합이 아니라 설정 문자열입니다.
  • 특정 벤더의 결제 수단에 접근할 수 없는 개발자. 카드 없이 충전만으로 사용할 수 있어 프로바이더별 가입 의존성이 사라집니다.

엔드포인트 검증 및 첫 질문 디버깅.

여러분이 선언한 id를 게이트웨이가 서빙하는지 확인하세요; openai/ 뒤의 litellm_params.model 문자열은 서빙되는 id와 정확히 일치해야 합니다. 첫 ask()의 실패 사다리: OPENAI_API_KEY를 요구하는 오류는 어떤 슬롯이 설정 없이 여전히 기본 모델에 있다는 뜻입니다; llm, summary_llm, agent_llm 중 어느 것을 옮기지 않았는지 찾으세요. 게이트웨이에서 나오는 401은 litellm_params 안의 api_key입니다. 알 수 없는 모델에 대한 라우터 오류는 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 각각이 litellm_params에 api_base와 api_key를 포함하는 model_list를 받습니다. 이는 paper-qa가 로컬 호스팅된 OpenAI 호환 서버에 쓰는 것과 같은 문서화된 패턴이며, 대신 게이트웨이 URL을 가리키게 한 것입니다.

답변 모델과 요약 모델이 다른 벤더에서 올 수 있나요?

네. 각 슬롯이 모델 이름과 자신만의 설정을 짝짓기 때문에, 빠른 Claude id가 근거를 요약하는 동안 GPT-5.5나 Gemini가 최종 답변을 쓸 수 있으며, 모두 api_base 하나와 키 하나로요. id당 model_list 항목 하나를 선언하고 슬롯별로 참조하세요.

임베딩 모델도 바꿔야 하나요?

아니요, 그리고 보통 같은 단계에서 바꾸면 안 됩니다. 임베딩 설정은 채팅 슬롯과 독립적이며, 임베딩 모델을 바꾸면 기존 벡터 인덱스가 무효화됩니다. 기본 임베딩용 키가 없다면 embedding을 명시적으로 설정하거나 st- 프리픽스로 로컬 sentence-transformers를 쓰세요.

agent_llm 슬롯은 무엇이고 그것도 설정이 필요한가요?

AgentSettings 안의 agent_llm은 툴 선택을 이끕니다: 언제 검색하고, 근거를 모으고, 답할지. 다른 슬롯처럼 기본값이 OpenAI 모델이므로, 같은 게이트웨이 딕셔너리로 agent_llm_config를 붙이세요, 그렇지 않으면 여전히 기본 프로바이더로 라우팅을 시도합니다.

오버라이드 이후에도 paper-qa가 왜 여전히 OPENAI_API_KEY를 요구하나요?

적어도 한 슬롯이 라우터 설정 없이 여전히 기본 모델에 있는 것입니다. llm, summary_llm, agent_llm과 그들의 _config 필드를 확인하세요; 오류가 호출을 시도한 모델을 지목하므로 어느 슬롯을 놓쳤는지 알 수 있습니다.

이것이 Python뿐 아니라 pqa CLI에서도 작동하나요?

CLI도 같은 설정 표면을 노출하지만, 게이트웨이 라우팅에는 Python 경로가 실용적입니다: 라우터 딕셔너리는 커맨드라인 플래그로는 어색하고, 결과 옆에 기록된 Settings 객체가 연구 실행을 재현 가능하게 만들어 줍니다.