[ blog · tutorial ]10 min read

Как построить агента для обзора научной литературы и не упереться в rate-limit

Sarah ChoyОпубликовано 3 мая 2026 г.10 мин чтения
Как построить агента для обзора научной литературы и не упереться в rate-limit

Соберите сегодня агента для обзора литературы поверх сырых arXiv + PubMed + Semantic Scholar — и упрётесь в 429-е раньше, чем разберёте десять статей. Разбираем, почему лимиты стали жёстче, что на самом деле делают под капотом PaperQA / Undermind, и рабочий паттерн, который переживает реальную сессию обзора.

Кратко

  • arXiv начал агрессивно троттлить в конце 2024 года после того, как LLM-скрейперы спровоцировали штормы 429-х; задокументированный лимит — 1 запрос раз в 3 секунды, но на практике терпимость к всплескам ниже.
  • 1 000 запросов/сек у Semantic Scholar делятся между всеми неаутентифицированными вызовами — для продакшен-агентов это фактически непригодно.
  • PubMed E-utils ограничивает неаутентифицированный трафик 3 запросами/сек; с API-ключом — 10 запросов/сек.
  • Рабочие агенты (PaperQA2, Undermind, Elicit) все используют слой прокси / кэша перед этими источниками.
  • API Pick Academic Search оборачивает arXiv, PubMed, bioRxiv и medRxiv в один эндпоинт с управляемыми лимитами — 5 кредитов за вызов, оплата только за успех.

Проблема в одном абзаце

Бесплатные академические API прекрасны — и их съедают заживо. arXiv, PubMed и Semantic Scholar проектировались в эпоху, когда худшим случаем нагрузки был 'один исследователь написал скрипт, опрашивающий сервер раз в несколько секунд'. Теперь каждый студент с Python пишет LLM-агента, который веером отправляет полсотни параллельных вызовов, чтобы прочитать ссылки одной статьи. Умножьте на тысячи похожих агентов — и получите паттерн, который сотрудники arXiv называют в X 'arXiv-pocalypse' конца 2024 года: непрекращающиеся ответы Rate Exceeded, деградация сервиса и волна новых правил троттлинга, которые ударили по инди-разработчикам сильнее, чем по нарушителям.

Итог: агент для обзора литературы, который в dev-окружении справляется с пятью статьями, разваливается на середине реальной сессии обзора. Пользователь получает наполовину готовый ответ с тремя цитатами вместо пятнадцати.

Эта статья — о том, как собрать агента так, чтобы этого не случилось.

Что именно ограничивается и где

Лимиты задокументированы на момент написания. arXiv и Semantic Scholar оба оставляют за собой право ужесточать троттлинг во время инцидентов — проверяйте перед высоконагруженной интеграцией.
arXivPubMed E-utilsSemantic ScholarOpenAlexAPI Pick Academic
ПокрытиеПрепринты по физике, математике, CS, биологииБиомедицина (35M+ записей)Междисциплинарное (>200M)Междисциплинарное (250M+)arXiv + PubMed + bioRxiv + medRxiv
Лимит (без аутентификации)1 запрос / 3 сек3 запроса / секОбщий пул 1k/сек (фактически низкий)100k запросов / деньПлата за вызов, без пер-юзер троттлинга
Лимит (с ключом)Тот же — ключи только для bulk10 запросов / секПер-ключевой бакет (выдаётся медленно)Тот же
Возвращает полный текст?Да (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, а не по запросу

Одну и ту же статью запрашивают множество разных запросов. Кэширование на уровне результата поиска почти не помогает; кэширование на уровне идентификатора статьи — помогает. Небольшой слой Redis (или даже SQLite) с ключом doi:10.1038/... окупается за один день агентского трафика.

2. Относитесь к графу цитирований как к медленно меняющемуся индексу

Сила Semantic Scholar не в поиске по ключевым словам, а в графе цитирований. PaperQA2 использует его, чтобы развернуть от одной затравочной статьи к связанному кластеру, а не чтобы искать статьи с нуля. Это куда меньший объём запросов — один вызов на статью, а не сотни — и остаётся с большим запасом ниже лимита.

3. Примите задержку как компромисс — ИЛИ проксируйте лимит

Либо вы заставляете пользователей ждать 30–60 секунд ради аккуратного, уважающего троттлинг запроса (выбор PaperQA2), либо добавляете слой, который агрегирует трафик между пользователями и предъявляет агенту единый интерфейс, терпимый к всплескам (выбор API Pick). Работают оба. Не работает их смесь — низколатентный UX поверх лимитированных публичных API без буфера.

Рабочий код: агент для обзора литературы, который доходит до конца

Минимально жизнеспособный агент, переживающий реальную сессию обзора:

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

Стоимость одного вопроса:

  • 1–2 вызова academic_search (5–10 кредитов = $0.005–$0.010)
  • 1 вызов extract, охватывающий 3–5 статей (6–10 кредитов = $0.006–$0.010)
  • ~5 000 входных + 1 200 выходных токенов к Claude (~$0.04)

Округлённо: ~5 центов за ответ обзора литературы с цитатами. При 100 вопросах/день это $5/день — примерно столько стоит дневная порция кофеина для одного нормального исследователя.

Поднастройки под суб-вертикали

Биомедицинская литература

Сместите агента в сторону PubMed (рецензируемое) и явно помечайте находки bioRxiv/medRxiv как препринты. Когда спрашивают "что говорят последние данные", агент должен сильнее взвешивать рецензируемое. Строка в системном промпте — "Если препринт и рецензируемый источник расходятся, отдавай предпочтение рецензируемому и отмечай расхождение" — решает это чисто.

Математика / CS

Здесь доминирует arXiv. Соотношение сигнал/шум лучше, чем в биомеде, а для фундаментальных работ цитирования важнее свежести. Ищите более широкими запросами и давайте агенту отсеивать лишнее.

Разработка лекарств / клиника

Связывайте с Clinical Search (ClinicalTrials.gov + этикетки FDA + ChEMBL + DrugBank) ради регуляторных измерений и биоактивности, которые академический поиск покрыть не может. Комбинация — рецензируемая литература + реестр испытаний + структурные данные — это то, как агент для перепрофилирования лекарств или фармаконадзора становится полезным.

Где это обобщается

Проблема rate-limit'ов не уникальна для академического поиска. Любой открытый публичный датасет, выпустивший API в до-LLM эпоху, сейчас подвергается тем же паттернам нагрузки: SEC EDGAR, USPTO, EPO, базы публичных записей, метеосервисы, государственные открытые данные. Тот же инженерный паттерн работает для всех: кэшировать на уровне сущности, добавить управляемый прокси-слой, принять задержку как альтернативу, когда прокси не по карману.

Более глубокий сдвиг: в 2026 году уже неразумно ожидать, что бесплатный публичный API напрямую поглотит нагрузку LLM-агентов. Эндпоинты не исчезают — но их оборачивает слой платных управляемых сервисов, который существует, чтобы переводить лимиты 'вежливого исследователя-человека' в 'терпимый к всплескам агентский трафик'. API Pick Academic Search — один из таких слоёв для сценария обзора литературы. Ждите ещё.

Часто задаваемые вопросы

Почему arXiv начал так агрессивно ограничивать запросы в 2024 году?

Из-за LLM-скрейперов. Сотрудники arXiv прямо говорили об этом в рассылке для разработчиков и в @arxiv на X: LLM-агент веером отправляет 50 параллельных запросов, чтобы подтянуть ссылки для одной статьи, умножьте это на тысячи пользователей с похожими сценариями — и весь индекс деградирует. Правило 'не чаще одного запроса раз в 3 секунды' было задокументировано всегда, но жёстко принуждать к нему начали с конца 2024 / начала 2025 года.

1 000 запросов/сек у Semantic Scholar действительно общие?

Да — это неаутентифицированный пул, общий для всех IP, обращающихся к публичному API. На практике в часы пик неаутентифицированные запросы начинают отваливаться независимо от вашей собственной частоты. Официальная рекомендация — подать заявку на API-ключ, который переводит вас в отдельный пер-ключевой бакет. Заявка рассматривается неделями и выдаётся в предположении академического, а не коммерческого использования.

А что насчёт PubMed E-utils?

Лучше остальных — 3 запроса/сек без ключа, 10 запросов/сек с ключом. Заявку на API-ключ NCBI подают по email; обычно её одобряют в тот же день при заявленных исследовательских целях. Но всё же: 10 запросов/сек хватает одному пользователю, но недостаточно для многопользовательского продукта, где каждый вопрос веером порождает несколько вызовов к PubMed.

Почему PaperQA2 работает там, где мой самописный агент — нет?

Три причины. (1) PaperQA2 агрессивно батчит и кэширует — один и тот же поиск по DOI никогда не делается дважды. (2) Он использует Semantic Scholar в первую очередь ради графа цитирований (один вызов на статью), а не как поисковый индекс. (3) Он мирится с большим временем ответа на вопрос в обмен на то, чтобы не превышать лимиты. Если вам нужен такой же UX в продукте, где пользователи ждут ответ за 5 секунд, нужен слой с большей пропускной способностью.

Что именно решает 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

Сара Чой — CEO API Pick. Пишет о продакшен-готовых API для AI-агентов и LLM-воркфлоу.