レートリミットに引っかからずに科学文献レビューエージェントを作る方法

生の arXiv + PubMed + Semantic Scholar で文献レビューエージェントを今日組むと、論文 10 本を読み終える前に 429 を食らう。なぜレートリミットが悪化したのか、PaperQA / Undermind が内部で実際に何をしているのか、そして本物のレビューセッションを生き延びる実用パターンを解説する。
要点
- •arXiv は 2024 年後半、LLM スクレイパーが 429 の嵐を引き起こした後、積極的なスロットリングを始めた。ドキュメント上の制限は 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 を 1 つのレート管理済みエンドポイントにまとめる — 1 回 5 credits、成功時のみ課金。
一段落で言う問題
無料の学術 API は素晴らしい — そして生きたまま食い尽くされつつある。arXiv、PubMed、Semantic Scholar は「研究者が 1 人、数秒ごとにポーリングするスクリプトを書く」のが最悪ケースの負荷だった時代に設計された。今やパソコンで Python を書く学部生の誰もが、論文 1 本の参考文献を読むために 50 並列の呼び出しに展開する LLM エージェントを書く。それを似たようなエージェント数千個で掛け算すると、arXiv のスタッフが X で 2024 年後半の「arXiv-pocalypse」と呼ぶパターンになる — 継続的な Rate Exceeded レスポンス、劣化したサービス、そして悪質な行為者よりインディーの開発者を直撃する新しいスロットリングルールの波だ。
結果として、開発環境では論文 5 本で動いていた文献レビューエージェントが、本物のレビューセッションでは途中で倒れる。ユーザーには引用 15 本のはずが 3 本だけの中途半端な答えが返る。
本記事は、そうならないようにエージェントを作る方法についてのものだ。
実際に何が、どこでレート制限されているか
| arXiv | PubMed E-utils | Semantic Scholar | OpenAlex | API Pick Academic | |
|---|---|---|---|---|---|
| カバレッジ | 物理・数学・CS・生物のプレプリント | 生物医学(3,500 万件以上) | 分野横断(2 億件超) | 分野横断(2.5 億件以上) | arXiv + PubMed + bioRxiv + medRxiv |
| レートリミット(未認証) | 1 req / 3 sec | 3 req / sec | 共有 1k/sec プール(実効的には低い) | 100k req / 日 | 呼び出し従量、ユーザー単位のスロットルなし |
| レートリミット(キーあり) | 同じ — キーはバルク用途のみ | 10 req / sec | キー単位バケット(付与は遅い) | 同じ | — |
| 全文を返すか? | はい(XML / PDF リンク) | 抄録のみ | 抄録 + ペイウォール無しの一部 | 抄録 + 一部 | タイトル + URL + 抄録形式のスニペット |
| LLM フレンドリーな形式 | いいえ — Atom XML | いいえ — XML | はい — JSON | はい — JSON | はい — JSON、スニペット整形済み |
| コスト | 無料 | 無料(キー推奨) | 無料、本番にはキー必須 | 無料 | 5 credits/回(約 $0.005) |
実用に耐える製品が実際にやっていること
PaperQA2、Undermind、Elicit、ResearchRabbit、そしてエージェント型 RAG の論文群(例:Open-Source Agentic Hybrid RAG Framework、arXiv 2508.05660)は、いずれも似たパターンに収斂する。エンジニアリング上、最も効くのは 3 つの手だ。
1. クエリ単位ではなく DOI / arXiv ID 単位でキャッシュする
同じ論文が多くの異なるクエリから要求される。検索結果レベルでのキャッシュはほとんど効かない。論文識別子レベルでのキャッシュは効く。doi:10.1038/... をキーにした小さな Redis(あるいは SQLite でも)層は、エージェントトラフィックの 1 午後で元が取れる。
2. 引用グラフを「ゆっくり変わるインデックス」として扱う
Semantic Scholar の強みはキーワード検索ではなく、引用グラフだ。PaperQA2 はそれを、ゼロから論文を発見するためではなく、1 本のシード論文から関連クラスタへ展開するために使う。これははるかに小さいリクエスト量で済み — 論文 1 本につき 1 呼び出しであって数百ではない — レートリミットに十分収まる。
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)"))質問 1 件あたりのコスト:
- academic_search 1〜2 回(5〜10 credits = $0.005〜$0.010)
- 論文 3〜5 本をカバーする extract 1 回(6〜10 credits = $0.006〜$0.010)
- Claude への入力 約 5,000 + 出力 1,200 トークン(約 $0.04)
ざっくり言えば、引用付きの文献レビュー回答 1 件あたり約 5 セント。1 日 100 問なら $5/日 — 研究者 1 人が 1 日に飲むコーヒー代くらいだ。
サブバーティカル別の調整
生物医学文献
エージェントを PubMed(査読済み)寄りにバイアスし、bioRxiv/medRxiv のヒットは明示的にプレプリントとして印を付ける。「最新のエビデンスは何と言っているか」を尋ねるときは、査読済みをより重く評価すべきだ。システムプロンプトに 1 行 — 「プレプリントと査読済みソースが食い違う場合は査読済みを優先し、不一致を注記すること」 — を入れれば、これはきれいに処理できる。
数学 / CS
ここでは arXiv が支配的だ。生物医学よりも S/N 比が良く、基礎的な仕事については新しさより引用が重要になる。広めのクエリで検索し、エージェントに刈り込ませる。
創薬 / 臨床
学術検索ではカバーできない規制・生理活性の次元については、Clinical Search(ClinicalTrials.gov + FDA ラベル + ChEMBL + DrugBank)と組み合わせる。この組み合わせ — 査読済み文献 + 治験レジストリ + 構造データ — こそが、薬剤リポジショニングやファーマコビジランスのエージェントを役立たせる方法だ。
これがどこに一般化するか
レートリミット問題は学術検索に固有のものではない。LLM 以前の時代に API を出したオープンなパブリックデータセットはすべて、今や同じ負荷パターンにさらされている:SEC EDGAR、USPTO、EPO、公的記録データベース、気象サービス、政府オープンデータ。同じエンジニアリングパターンがそのすべてに効く — エンティティレベルでキャッシュし、マネージドプロキシを層として挟み、プロキシを用意できないときはレイテンシを代替策として受け入れる。
より深い変化はこうだ:2026 年において、無料のパブリック API が LLM エージェントの負荷を直接吸収してくれると期待するのはもはや合理的でない。エンドポイントが消えるわけではない — だが「礼儀正しい人間の研究者」向けのレートリミットを「バースト許容なエージェントトラフィック」向けに翻訳するために存在する、有料のマネージドサービス層に包まれていく。API Pick Academic Search は文献レビュー用途における、そうした層の 1 つだ。今後もっと増えるだろう。
よくある質問
arXiv はなぜ 2024 年にあれほど積極的にレートリミットを始めたのか?
LLM 駆動のスクレイパーが原因だ。arXiv のスタッフは開発者向けメーリングリストや X の @arxiv でこのパターンを明言している。LLM エージェントが 1 本の論文の参考文献を取得するために 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 は動くのか?
理由は 3 つ。(1) PaperQA2 は積極的にバッチ化とキャッシュを行う — 同じ DOI ルックアップは二度と発行されない。(2) Semantic Scholar を検索インデックスとしてではなく、主に引用グラフのために使う(論文 1 本につき 1 呼び出し)。(3) 制限を超えない代わりに、質問あたりの実時間が長くなることを許容する。ユーザーが 5 秒応答を期待する製品で同じ UX を実現したいなら、よりスループットの高い層が必要だ。
API Pick Academic Search は実際に何を解決するのか?
レートリミットとソースのカバレッジを管理し、エージェント側がそれを気にしなくて済むようにする。1 回の POST /api/search/academic で arXiv、PubMed、bioRxiv、medRxiv からのランク付き結果がまとめて返り、LLM が消費しやすい形に整形されている。1 回 5 credits(≈ $0.005)、HTTP 200 のときだけ課金される。あなたはエージェントループとプロンプトに集中すればよい。スロットリングは我々の問題だ。
この記事で使われている API
API Pick の CEO。AI エージェントと LLM ワークフロー向けの本番運用可能な API について執筆。