[ blog · tutorial ]10 min read

레이트 리밋에 막히지 않는 과학 문헌 리뷰 에이전트 만들기

Sarah Choy2026년 5월 3일 게시10분 분량
레이트 리밋에 막히지 않는 과학 문헌 리뷰 에이전트 만들기

오늘 arXiv + PubMed + Semantic Scholar를 날것 그대로 써서 문헌 리뷰 에이전트를 만들면 논문 열 편도 못 채우고 429에 막힌다. 레이트 리밋이 왜 더 심해졌는지, PaperQA / Undermind가 내부에서 실제로 무엇을 하는지, 그리고 실제 리뷰 세션을 버텨내는 동작하는 패턴을 정리했다.

한눈에

  • arXiv는 LLM 스크레이퍼가 429 폭주를 일으킨 뒤 2024년 말부터 공격적으로 스로틀링을 시작했다. 문서상 한도는 3초당 1회지만 실제 버스트 허용치는 그보다 낮다.
  • Semantic Scholar의 1,000 req/sec는 인증 안 한 모든 호출자가 공유한다 — 프로덕션 에이전트에는 사실상 쓸 수 없다.
  • PubMed E-utils는 인증 없는 트래픽을 3 req/sec로 제한하고, API 키가 있으면 10 req/sec다.
  • 실제로 동작하는 에이전트(PaperQA2, Undermind, Elicit)는 모두 이 소스들 앞에 프록시 / 캐시 레이어를 둔다.
  • API Pick Academic Search는 arXiv, PubMed, bioRxiv, medRxiv를 레이트가 관리되는 단일 엔드포인트로 감싼다 — 호출당 5 크레딧, 성공시에만 과금.

한 문단으로 보는 문제

무료 학술 API는 훌륭하지만 산 채로 잡아먹히고 있다. arXiv, PubMed, Semantic Scholar는 '한 연구자가 몇 초마다 폴링하는 스크립트를 짠다'가 최악의 부하이던 시대에 설계됐다. 이제는 Python을 아는 학부생이라면 누구나, 논문 한 편의 참고문헌을 읽으려고 50개의 병렬 호출을 펼치는 LLM 에이전트를 만든다. 비슷한 에이전트 수천 개를 곱하면 arXiv 운영진이 X에서 2024년 말의 "arXiv-pocalypse"라 부른 패턴이 나온다 — 지속적인 Rate Exceeded 응답, 서비스 저하, 그리고 악성 행위자보다 인디 빌더를 더 세게 때리는 새 스로틀링 규칙의 물결.

결과적으로, 개발 환경에서 논문 다섯 편으로 잘 돌던 문헌 리뷰 에이전트가 실제 리뷰 세션 중반에 쓰러진다. 사용자는 인용 열다섯 개가 아니라 세 개만 달린 미완성 답변을 받는다.

이 글은 그런 일이 일어나지 않도록 에이전트를 만드는 법에 관한 것이다.

실제로 무엇이, 어디서 레이트 리밋에 걸리나

레이트 리밋은 작성 시점 기준 문서화된 값. arXiv와 Semantic Scholar는 인시던트 중 더 세게 스로틀링할 권리를 모두 유보한다 — 대량 연동 전에 확인하라.
arXivPubMed E-utilsSemantic ScholarOpenAlexAPI Pick Academic
커버리지물리, 수학, CS, 생물 프리프린트생의학 (3,500만+ 레코드)범분야 (2억+)범분야 (2.5억+)arXiv + PubMed + bioRxiv + medRxiv
레이트 리밋 (인증 없음)3초당 1 req초당 3 req공유 1k/sec 풀 (사실상 낮음)하루 10만 req호출당 과금, 사용자별 스로틀 없음
레이트 리밋 (키 있음)동일 — 키는 벌크용만초당 10 req키별 버킷 (발급이 느림)동일
전문(full text) 반환?예 (XML / PDF 링크)초록만초록 + 일부 무료 공개초록 + 일부제목 + URL + 초록형 스니펫
LLM 친화 형식아니오 — Atom XML아니오 — XML예 — JSON예 — JSON예 — JSON, 스니펫 사전 정형
비용무료무료 (키 권장)무료, 프로덕션엔 키 필수무료호출당 5 크레딧 (~$0.005)

실제로 동작하는 제품들이 하는 일

PaperQA2, Undermind, Elicit, ResearchRabbit, 그리고 에이전틱 RAG 논문들(예: Open-Source Agentic Hybrid RAG Framework, arXiv 2508.05660)은 모두 비슷한 패턴으로 수렴한다. 가장 중요한 엔지니어링 수는 셋이다:

1. 쿼리가 아니라 DOI / arXiv ID로 캐싱하라

같은 논문이 서로 다른 여러 쿼리로 요청된다. 검색 결과 수준에서 캐싱하면 거의 도움이 안 되지만, 논문 식별자 수준에서 캐싱하면 도움이 된다. doi:10.1038/... 같은 키로 동작하는 작은 Redis(혹은 SQLite여도 충분) 레이어는 에이전트 트래픽 한나절이면 본전을 뽑는다.

2. 인용 그래프를 느리게 변하는 인덱스로 다뤄라

Semantic Scholar의 강점은 키워드 검색이 아니라 인용 그래프다. PaperQA2는 이것을 시드 논문 한 편에서 관련 클러스터로 확장하는 데 쓰지, 백지에서 논문을 발견하는 데 쓰지 않는다. 그것은 훨씬 작은 요청량 — 수백 번이 아니라 논문당 한 번 — 이며 레이트 리밋에 한참 못 미친다.

3. 지연을 트레이드오프로 받아들이거나, 레이트 리밋을 프록시하라

조심스럽고 스로틀을 존중하는 쿼리를 위해 사용자를 30~60초 기다리게 하거나(PaperQA2의 선택), 아니면 사용자 간 트래픽을 집계해 에이전트에는 버스트를 견디는 단일 인터페이스를 보여주는 레이어를 더하거나(API Pick의 선택)다. 둘 다 동작한다. 둘을 섞는 것 — 버퍼 없이 레이트 리밋에 걸리는 공개 API 위에 저지연 UX를 얹는 것 — 이 실패한다.

동작하는 코드: 완주하는 문헌 에이전트

실제 리뷰 세션을 버텨내는 최소한의 에이전트:

import requests
from anthropic import Anthropic

KEY = "pk_yourkey"
client = Anthropic()

def fetch_tool(path: str) -> dict:
    return requests.get(f"https://www.apipick.com{path}/tool-schema").json()["claude"]

# Two tools: academic search + URL extract for the full body
TOOLS = [
    fetch_tool("/api/search/academic"),
    fetch_tool("/api/extract"),
]

SYSTEM = """You are a literature-review research assistant. Process:

1. Use academic_search with the user's question to find relevant papers
   from arXiv, PubMed, bioRxiv, and medRxiv. One call usually returns
   the right set of seed papers.

2. For papers worth citing in detail, use extract_urls on the paper's URL
   to pull the body. Batch up to 5 URLs per call.

3. Answer the user's question with inline citations in the form
   [Author Year, doi/arxiv URL]. Quote findings verbatim where possible.

4. If the search returned <3 substantive results, expand the query and
   try once more. Don't loop indefinitely — say "I couldn't find a strong
   answer in the indexed literature" if nothing matches.

Be precise. Cite every factual claim. Distinguish preprints (arXiv,
bioRxiv, medRxiv) from peer-reviewed (PubMed) when it matters."""

def call_tool(block):
    name_to_path = {"academic_search": "/api/search/academic", "extract_urls": "/api/extract"}
    r = requests.post(
        f"https://www.apipick.com{name_to_path[block.name]}",
        json=block.input,
        headers={"x-api-key": KEY},
        timeout=60,
    )
    return {"type": "tool_result", "tool_use_id": block.id,
            "content": r.text, "is_error": r.status_code != 200}

def review(question: str) -> str:
    msgs = [{"role": "user", "content": question}]
    while True:
        r = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=4096,
            system=SYSTEM,
            tools=TOOLS,
            messages=msgs,
        )
        msgs.append({"role": "assistant", "content": r.content})
        if r.stop_reason == "end_turn":
            return "\n".join(b.text for b in r.content if b.type == "text")
        if r.stop_reason == "tool_use":
            results = [call_tool(b) for b in r.content if b.type == "tool_use"]
            msgs.append({"role": "user", "content": results})

print(review("Recent advances in LLM-based protein structure prediction (2025)"))

질문당 비용:

  • academic_search 호출 1~2회 (5~10 크레딧 = $0.005~$0.010)
  • 논문 3~5편을 포괄하는 extract 호출 1회 (6~10 크레딧 = $0.006~$0.010)
  • Claude로 가는 입력 ~5,000 + 출력 1,200 토큰 (~$0.04)

대략: 인용이 달린 문헌 리뷰 답변당 약 5센트. 하루 100개 질문이면 $5/일 — 어지간한 연구자 한 명의 하루 카페인 값쯤 된다.

서브버티컬별 조정

생의학 문헌

에이전트가 PubMed(피어 리뷰)를 선호하도록 기울이고, bioRxiv/medRxiv 히트는 프리프린트로 명시적으로 표시하라. "최신 근거가 무엇을 말하는가"를 물을 때 에이전트는 피어 리뷰에 더 큰 가중치를 둬야 한다. 시스템 프롬프트에 한 줄 — "프리프린트와 피어 리뷰 소스가 어긋나면 피어 리뷰를 따르고 불일치를 명시하라" — 이면 깔끔하게 처리된다.

수학 / CS

여기서는 arXiv가 지배적이다. 신호 대 잡음비가 생의학보다 좋고, 기반 연구에서는 신선도보다 인용이 더 중요하다. 더 넓은 쿼리로 검색하고 에이전트가 가지치기하게 하라.

신약 개발 / 임상

학술 검색이 다룰 수 없는 규제·생물활성 차원을 위해 Clinical Search(ClinicalTrials.gov + FDA 라벨 + ChEMBL + DrugBank)와 짝지어라. 이 조합 — 피어 리뷰 문헌 + 임상시험 등록부 + 구조 데이터 — 이야말로 약물 재창출이나 약물감시 에이전트가 쓸모를 갖추는 방식이다.

이것이 일반화되는 지점

레이트 리밋 문제는 학술 검색에만 국한되지 않는다. LLM 이전 시대에 API를 내놓은 모든 공개 공공 데이터셋이 지금 같은 부하 패턴에 시달리고 있다: SEC EDGAR, USPTO, EPO, 공공기록 데이터베이스, 기상 서비스, 정부 오픈 데이터. 같은 엔지니어링 패턴이 이 모두에 통한다 — 엔티티 수준에서 캐싱하고, 관리형 프록시를 한 겹 얹고, 프록시를 감당할 수 없을 때는 지연을 대안으로 받아들여라.

더 깊은 변화는 이것이다: 2026년에는 무료 공개 API가 LLM 에이전트 부하를 직접 흡수해 주리라 기대하는 것이 더 이상 합리적이지 않다. 엔드포인트가 사라지는 것은 아니지만, '예의 바른 인간 연구자' 레이트 리밋을 '버스트를 견디는 에이전트 트래픽'으로 번역하기 위해 존재하는 유료 관리형 서비스 레이어로 감싸지고 있다. API Pick Academic Search는 문헌 리뷰 용례를 위한 그런 레이어 중 하나다. 더 많이 나올 것으로 예상하라.

자주 묻는 질문

arXiv는 왜 2024년부터 그렇게 공격적으로 레이트 리밋을 걸기 시작했나?

LLM 기반 스크레이퍼 때문이다. arXiv 운영진은 개발자 메일링 리스트와 X의 @arxiv 계정에서 그 패턴을 분명히 밝혀 왔다. LLM 에이전트 하나가 논문 한 편의 참고문헌을 가져오려고 50개의 병렬 요청을 펼치고, 비슷한 워크플로를 돌리는 수천 명의 사용자를 곱하면 인덱스 전체 성능이 저하된다. '요청 사이 3초' 규칙은 늘 문서화되어 있었지만, 강제 집행이 빡빡해진 것은 2024년 말 / 2025년 초부터다.

Semantic Scholar의 1,000 req/sec가 정말 공유되나?

그렇다 — 그것은 인증 안 한 풀이며, 공개 API를 때리는 모든 IP가 공유한다. 실제로는 개별 호출 속도와 무관하게 피크 시간대에 인증 없는 요청이 실패하기 시작한다. 공식 권고는 API 키를 신청하는 것인데, 그러면 키별 버킷으로 옮겨진다. 신청에는 몇 주가 걸리고, 상업적이 아닌 학술적 용도를 전제로 발급된다.

PubMed의 E-utils는 어떤가?

다른 곳보다 낫다 — 키 없이 3 req/sec, 키가 있으면 10 req/sec다. NCBI API 키는 이메일로 신청하며, 명시한 연구 목적이라면 보통 당일에 발급된다. 그래도 10 req/sec는 단일 사용자에게는 충분하지만, 모든 사용자 질문이 여러 PubMed 호출로 펼쳐지는 멀티유저 제품에는 부족하다.

왜 내가 직접 만든 에이전트는 안 되는데 PaperQA2는 되나?

이유는 셋이다. (1) PaperQA2는 적극적으로 배칭하고 캐싱한다 — 같은 DOI 조회는 두 번 하지 않는다. (2) Semantic Scholar를 검색 인덱스가 아니라 주로 인용 그래프 용도(논문당 한 번 호출)로 쓴다. (3) 한도를 넘지 않는 대신 질문당 더 긴 실제 소요 시간을 감수한다. 사용자가 5초 응답을 기대하는 제품에서 같은 UX를 원한다면, 더 높은 처리량의 레이어가 필요하다.

API Pick Academic Search는 실제로 무엇을 해결하나?

레이트 리밋과 소스 커버리지를 대신 관리해 주므로 에이전트가 신경 쓸 필요가 없다. POST /api/search/academic 한 번의 호출이 arXiv, PubMed, bioRxiv, medRxiv에서 랭킹된 결과를 LLM이 소비하기 좋은 형태로 함께 반환한다. 호출당 5 크레딧(≈$0.005), HTTP 200일 때만 차감. 당신은 에이전트 루프와 프롬프트에 집중하면 되고, 스로틀링은 우리 문제다.

이 글에서 사용한 API

Sarah Choy
작성
Sarah Choy
CEO, API Pick

Sarah Choy는 API Pick의 CEO입니다. AI 에이전트와 LLM 워크플로를 위한 프로덕션 등급 API에 대해 씁니다.