Come costruire un agente per la revisione della letteratura scientifica senza incappare nei rate limit

Monta oggi un agente di revisione della letteratura su arXiv + PubMed + Semantic Scholar grezzi e ti scontrerai con i 429 prima di finire dieci paper. Ecco perché i rate limit sono peggiorati, cosa fanno davvero PaperQA / Undermind sotto il cofano e un pattern funzionante che sopravvive a una sessione di revisione reale.
In breve
- •arXiv ha iniziato ad applicare un throttling aggressivo alla fine del 2024 dopo che gli scraper LLM hanno provocato tempeste di 429; il limite documentato è 1 richiesta ogni 3 secondi, ma la tolleranza reale ai burst è più bassa.
- •Le 1.000 req/sec di Semantic Scholar sono condivise tra tutti i chiamanti non autenticati — di fatto inutilizzabili per agenti in produzione.
- •PubMed E-utils limita il traffico non autenticato a 3 req/sec; con una API key, 10 req/sec.
- •Gli agenti che funzionano (PaperQA2, Undermind, Elicit) usano tutti uno strato di proxy / cache davanti a queste fonti.
- •API Pick Academic Search avvolge arXiv, PubMed, bioRxiv e medRxiv in un unico endpoint con la frequenza gestita — 5 crediti per chiamata, solo in caso di successo.
Il problema in un paragrafo
Le API accademiche gratuite sono meravigliose e vengono divorate vive. arXiv, PubMed e Semantic Scholar sono stati progettati in un'epoca in cui "un ricercatore scrive uno script che interroga ogni pochi secondi" era il caso peggiore di carico. Oggi ogni studente universitario con Python scrive un agente LLM che lancia cinquanta chiamate parallele per leggere le referenze di un singolo paper. Moltiplicalo per migliaia di agenti simili e ottieni il pattern che lo staff di arXiv descrive su X come l'"arXiv-pocalypse" della fine del 2024 — risposte Rate Exceeded prolungate, servizio degradato e un'ondata di nuove regole di throttling che colpiscono gli sviluppatori indie più duramente dei malintenzionati.
Il risultato: un agente di revisione della letteratura che funziona su cinque paper nell'ambiente di sviluppo crolla a metà di una sessione di revisione reale. L'utente riceve una risposta a metà con tre citazioni invece di quindici.
Questo articolo parla di come costruire l'agente perché ciò non accada.
Cosa ha davvero un rate limit e dove
| arXiv | PubMed E-utils | Semantic Scholar | OpenAlex | API Pick Academic | |
|---|---|---|---|---|---|
| Copertura | Preprint di fisica, matematica, CS, bio | Biomedica (35M+ record) | Interdisciplinare (>200M) | Interdisciplinare (250M+) | arXiv + PubMed + bioRxiv + medRxiv |
| Rate limit (senza auth) | 1 req / 3 sec | 3 req / sec | Pool condiviso 1k/sec (di fatto basso) | 100k req / giorno | Pagamento a chiamata, nessun throttle per utente |
| Rate limit (con chiave) | Uguale — chiavi solo per il volume | 10 req / sec | Bucket per chiave (concesso lentamente) | Uguale | — |
| Restituisce il testo completo? | Sì (XML / link PDF) | Solo abstract | Abstract + selezione senza paywall | Abstract + selezione | Titolo + URL + snippet in forma di abstract |
| Formato LLM-friendly | No — Atom XML | No — XML | Sì — JSON | Sì — JSON | Sì — JSON, snippet già formattati |
| Costo | Gratis | Gratis (chiave consigliata) | Gratis, chiave obbligatoria in produzione | Gratis | 5 crediti/chiamata (~$0.005) |
Cosa fanno davvero i prodotti che funzionano
PaperQA2, Undermind, Elicit, ResearchRabbit e i paper sul RAG agentico (p. es. Open-Source Agentic Hybrid RAG Framework, arXiv 2508.05660) convergono tutti su un pattern simile. Tre mosse di ingegneria contano più di tutte:
1. Metti in cache per DOI / arXiv ID, non per query
Lo stesso paper viene richiesto da molte query diverse. Mettere in cache a livello di risultato di ricerca aiuta a malapena; mettere in cache a livello di identificatore del paper sì. Un piccolo strato di Redis (o anche SQLite) indicizzato su doi:10.1038/... si ripaga in un pomeriggio di traffico di agente.
2. Tratta il grafo delle citazioni come l'indice a lento cambiamento
Il punto di forza di Semantic Scholar non è la ricerca per parole chiave; è il grafo delle citazioni. PaperQA2 lo usa per espandere da un paper seme a un cluster correlato, non per scoprire paper da zero. È un volume di richieste molto più piccolo — una chiamata per paper, non centinaia — e resta ben sotto il rate limit.
3. Accetta la latenza come compromesso, OPPURE fai da proxy al rate limit
O fai aspettare gli utenti 30-60 secondi per una query attenta e rispettosa del throttle (la scelta di PaperQA2), oppure aggiungi uno strato che aggrega il traffico tra gli utenti e presenta all'agente un'unica interfaccia tollerante ai burst (la scelta di API Pick). Entrambe funzionano. Mescolarle — una UX a bassa latenza su API pubbliche con rate limit senza un buffer — è ciò che fallisce.
Codice funzionante: un agente di letteratura che porta a termine
L'agente minimo vitale che sopravvive a una sessione di revisione reale:
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)"))Costo per domanda:
- 1-2 chiamate a academic_search (5-10 crediti = $0.005-$0.010)
- 1 chiamata a extract che copre 3-5 paper (6-10 crediti = $0.006-$0.010)
- ~5.000 token di input + 1.200 di output verso Claude (~$0.04)
In cifra tonda: ~5 centesimi per risposta di revisione della letteratura con citazioni. A 100 domande/giorno fa $5/giorno — più o meno quanto costa la caffeina quotidiana di un ricercatore ragionevole.
Aggiustamenti per sotto-verticale
Letteratura biomedica
Orienta l'agente verso PubMed (peer-reviewed) e segna esplicitamente come preprint gli hit di bioRxiv/medRxiv. Quando chiedi "cosa dicono le evidenze più recenti", l'agente dovrebbe dare un peso maggiore a ciò che è peer-reviewed. Una riga nel system prompt — "Se le fonti preprint e peer-reviewed sono in disaccordo, dai priorità a quelle peer-reviewed e segnala la discrepanza" — risolve la cosa in modo pulito.
Matematica / CS
Qui domina arXiv. Il rapporto segnale-rumore è migliore che in biomedicina, e per il lavoro fondazionale le citazioni contano più della recency. Cerca con query più ampie e lascia che l'agente faccia la potatura.
Scoperta di farmaci / clinico
Abbinalo a Clinical Search (ClinicalTrials.gov + etichette FDA + ChEMBL + DrugBank) per le dimensioni regolatoria e di bioattività che la ricerca accademica non può coprire. La combinazione — letteratura peer-reviewed + registro degli studi clinici + dati strutturali — è ciò che rende utile un agente di riposizionamento dei farmaci o di farmacovigilanza.
Dove tutto questo si generalizza
Il problema del rate limit non è esclusivo della ricerca accademica. Qualsiasi dataset pubblico e aperto che ha rilasciato API nell'era pre-LLM è ora sottoposto agli stessi pattern di carico: SEC EDGAR, USPTO, EPO, database di registri pubblici, servizi meteo, dati aperti governativi. Lo stesso pattern di ingegneria vale per tutti — fare cache a livello di entità, mettere uno strato di proxy gestito, accettare la latenza come alternativa quando non puoi permetterti il proxy.
Il cambiamento più profondo: nel 2026 non è più ragionevole aspettarsi che una API pubblica gratuita assorba direttamente il carico di un agente LLM. Gli endpoint non spariranno — ma vengono avvolti da uno strato di servizi gestiti a pagamento che esiste per tradurre i rate limit da "ricercatore umano educato" in traffico da "agente tollerante ai burst". API Pick Academic Search è uno di questi strati per il caso d'uso della revisione della letteratura. Aspettatene altri.
Domande frequenti
Perché arXiv ha iniziato ad applicare rate limit così aggressivi nel 2024?
Per colpa degli scraper guidati da LLM. Lo staff di arXiv è stato esplicito sulla sua mailing list per sviluppatori e su @arxiv su X riguardo al pattern: un agente LLM lancia 50 richieste parallele per recuperare le referenze di un singolo paper, moltiplicalo per migliaia di utenti che eseguono flussi simili e l'intero indice si degrada. La regola dei 3 secondi tra le richieste è sempre stata documentata, ma l'applicazione è diventata rigida a partire dalla fine del 2024 / inizio 2025.
Le 1.000 req/sec di Semantic Scholar sono davvero condivise?
Sì — quello è il pool non autenticato, condiviso tra tutti gli IP che colpiscono l'API pubblica. In pratica, le richieste non autenticate iniziano a fallire nelle ore di punta indipendentemente dalla tua frequenza individuale. Il consiglio ufficiale è richiedere una API key, che ti sposta su un bucket per chiave. La richiesta richiede settimane e viene concessa presupponendo un uso accademico, non commerciale.
E le E-utils di PubMed?
Migliori delle altre — 3 req/sec senza chiave, 10 req/sec con. Richiedi una API key NCBI via email; di solito viene concessa in giornata per scopi di ricerca dichiarati. Tuttavia: 10 req/sec va bene per un singolo utente ma è insufficiente per un prodotto multiutente in cui ogni domanda dell'utente si dirama in diverse chiamate a PubMed.
Perché PaperQA2 funziona dove il mio agente fatto in casa no?
Per tre motivi. (1) PaperQA2 raggruppa e mette in cache in modo aggressivo — lo stesso lookup di DOI non viene mai fatto due volte. (2) Usa Semantic Scholar soprattutto per il suo grafo delle citazioni (una chiamata per paper) invece che come indice di ricerca. (3) Accetta un wall-clock più lungo per domanda in cambio del non superamento dei limiti. Se vuoi la stessa UX in un prodotto in cui gli utenti si aspettano risposte in 5 secondi, ti serve uno strato a throughput più alto.
Cosa risolve davvero API Pick Academic Search?
Gestisce i rate limit e la copertura delle fonti così che il tuo agente non debba farlo. Una singola chiamata POST /api/search/academic restituisce risultati ordinati da arXiv, PubMed, bioRxiv e medRxiv insieme, già nella forma adatta al consumo da parte di un LLM. 5 crediti per chiamata (≈$0.005), scalati solo sull'HTTP 200. Tu ti concentri sul loop dell'agente e sul prompt; il throttling è un problema nostro.
API usate in questo articolo
Sarah Choy è la CEO di API Pick. Scrive sulla creazione di API pronte per la produzione per agenti IA e flussi di lavoro con LLM.