Cách xây dựng agent tổng quan tài liệu khoa học mà không bị giới hạn tần suất

Dựng một agent tổng quan tài liệu trực tiếp trên arXiv + PubMed + Semantic Scholar thô ngay hôm nay, bạn sẽ dính lỗi 429 trước khi đọc xong mười bài báo. Đây là lý do các giới hạn tần suất trở nên tệ hơn, PaperQA / Undermind thực sự làm gì bên trong, và một mẫu thiết kế hoạt động được, sống sót qua một phiên tổng quan thực tế.
Tóm tắt
- •arXiv bắt đầu siết tần suất mạnh tay vào cuối năm 2024 sau khi các scraper LLM gây ra những cơn bão lỗi 429; giới hạn được ghi trong tài liệu là 1 request mỗi 3 giây, nhưng dung sai với các đợt burst trong thực tế còn thấp hơn.
- •Mức 1.000 req/giây của Semantic Scholar được chia sẻ chung cho mọi caller chưa xác thực — trên thực tế là không dùng được cho các agent chạy production.
- •PubMed E-utils giới hạn lưu lượng chưa xác thực ở mức 3 req/giây; có API key thì được 10 req/giây.
- •Các agent chạy được (PaperQA2, Undermind, Elicit) đều dùng một lớp proxy / cache đặt trước những nguồn này.
- •API Pick Academic Search gói arXiv, PubMed, bioRxiv và medRxiv vào một endpoint duy nhất đã quản lý tần suất — 5 credit mỗi lần gọi, chỉ trừ khi thành công.
Vấn đề gói gọn trong một đoạn văn
Các API học thuật miễn phí thật tuyệt vời và chúng đang bị ngốn sạch. arXiv, PubMed và Semantic Scholar được thiết kế vào thời mà "một nhà nghiên cứu viết một script poll vài giây một lần" là tình huống tải nặng nhất. Giờ đây mỗi sinh viên đại học biết Python đều viết một agent LLM bung ra năm mươi lần gọi song song để đọc phần tài liệu tham khảo của một bài báo duy nhất. Nhân với hàng nghìn agent tương tự và bạn có được mẫu mà nhân viên arXiv gọi trên X là "arXiv-pocalypse" của cuối năm 2024 — những phản hồi Rate Exceeded kéo dài, dịch vụ suy giảm, và một làn sóng quy tắc siết tần suất mới đánh vào các nhà phát triển độc lập nặng hơn cả những kẻ xấu.
Kết quả: một agent tổng quan tài liệu chạy được với năm bài báo trong môi trường dev lại sụp đổ giữa chừng một phiên tổng quan thực tế. Người dùng nhận được một câu trả lời dang dở với ba trích dẫn thay vì mười lăm.
Bài viết này bàn về cách xây dựng agent sao cho chuyện đó không xảy ra.
Cái gì thực sự bị giới hạn tần suất và ở đâu
| arXiv | PubMed E-utils | Semantic Scholar | OpenAlex | API Pick Academic | |
|---|---|---|---|---|---|
| Độ bao phủ | Preprint vật lý, toán, CS, sinh học | Y sinh (hơn 35 triệu bản ghi) | Liên ngành (>200 triệu) | Liên ngành (hơn 250 triệu) | arXiv + PubMed + bioRxiv + medRxiv |
| Giới hạn tần suất (chưa auth) | 1 req / 3 giây | 3 req / giây | Pool chung 1k/giây (thực tế thấp) | 100k req / ngày | Trả tiền theo lần gọi, không siết theo người dùng |
| Giới hạn tần suất (có key) | Như cũ — key chỉ dùng cho tải lượng lớn | 10 req / giây | Bucket theo key (cấp chậm) | Như cũ | — |
| Trả về toàn văn? | Có (link XML / PDF) | Chỉ abstract | Abstract + phần chọn lọc không paywall | Abstract + phần chọn lọc | Tiêu đề + URL + snippet dạng abstract |
| Định dạng thân thiện với LLM | Không — Atom XML | Không — XML | Có — JSON | Có — JSON | Có — JSON, snippet đã định hình sẵn |
| Chi phí | Miễn phí | Miễn phí (nên có key) | Miễn phí, bắt buộc key khi chạy production | Miễn phí | 5 credit/lần gọi (~$0.005) |
Các sản phẩm chạy được thực sự làm gì
PaperQA2, Undermind, Elicit, ResearchRabbit và các bài báo về RAG dạng agentic (ví dụ Open-Source Agentic Hybrid RAG Framework, arXiv 2508.05660) đều hội tụ về một mẫu tương tự. Ba nước đi kỹ thuật quan trọng nhất:
1. Cache theo DOI / arXiv ID, không phải theo query
Cùng một bài báo được nhiều query khác nhau yêu cầu. Cache ở cấp kết quả tìm kiếm gần như chẳng giúp ích; cache ở cấp định danh bài báo thì có. Một lớp Redis nhỏ (hoặc thậm chí SQLite) đánh index theo doi:10.1038/... tự hoàn vốn chỉ trong một buổi chiều lưu lượng agent.
2. Coi đồ thị trích dẫn như chỉ mục ít thay đổi
Điểm mạnh của Semantic Scholar không phải là tìm kiếm theo từ khóa; đó là đồ thị trích dẫn. PaperQA2 dùng nó để mở rộng từ một bài báo hạt giống ra một cụm liên quan, chứ không để khám phá bài báo từ con số không. Đó là khối lượng request nhỏ hơn nhiều — một lần gọi mỗi bài báo, không phải hàng trăm — và giữ mức thấp hơn hẳn giới hạn tần suất.
3. Chấp nhận độ trễ như một sự đánh đổi, HOẶC proxy giới hạn tần suất
Hoặc bạn để người dùng chờ 30-60 giây cho một query cẩn thận, tôn trọng giới hạn (lựa chọn của PaperQA2), hoặc bạn thêm một lớp gom lưu lượng qua nhiều người dùng và trình cho agent một giao diện duy nhất chịu được burst (lựa chọn của API Pick). Cả hai đều chạy được. Trộn lẫn chúng — một trải nghiệm độ trễ thấp đặt trên các API công khai bị giới hạn tần suất mà không có buffer — chính là thứ đổ vỡ.
Code chạy được: một agent tài liệu chạy đến cùng
Agent tối thiểu khả dụng sống sót qua một phiên tổng quan thực tế:
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)"))Chi phí mỗi câu hỏi:
- 1-2 lần gọi academic_search (5-10 credit = $0.005-$0.010)
- 1 lần gọi extract bao phủ 3-5 bài báo (6-10 credit = $0.006-$0.010)
- ~5.000 token đầu vào + 1.200 token đầu ra gửi tới Claude (~$0.04)
Làm tròn: ~5 xu cho mỗi câu trả lời tổng quan tài liệu kèm trích dẫn. Với 100 câu hỏi/ngày là $5/ngày — cỡ tiền cà phê mỗi ngày của một nhà nghiên cứu bình thường.
Tinh chỉnh theo từng ngách nhỏ
Tài liệu y sinh
Thiên agent về phía PubMed (bình duyệt) và đánh dấu rõ ràng các hit từ bioRxiv/medRxiv là preprint. Khi hỏi "bằng chứng mới nhất nói gì", agent nên cho tài liệu bình duyệt trọng số cao hơn. Một dòng trong system prompt — "Nếu nguồn preprint và nguồn bình duyệt mâu thuẫn nhau, ưu tiên nguồn bình duyệt và nêu rõ sự khác biệt" — xử lý gọn gàng việc này.
Toán học / CS
arXiv chiếm ưu thế ở đây. Tỷ lệ tín hiệu trên nhiễu tốt hơn so với y sinh, và với công trình nền tảng thì trích dẫn quan trọng hơn tính mới. Tìm với các query rộng hơn và để agent tự lọc bớt.
Phát triển thuốc / lâm sàng
Kết hợp với Clinical Search (ClinicalTrials.gov + nhãn FDA + ChEMBL + DrugBank) cho các chiều pháp lý và hoạt tính sinh học mà tìm kiếm học thuật không bao phủ được. Sự kết hợp — tài liệu bình duyệt + sổ đăng ký thử nghiệm + dữ liệu cấu trúc — chính là thứ khiến một agent tái định vị thuốc hoặc cảnh giác dược trở nên hữu ích.
Nơi điều này khái quát hóa được
Vấn đề giới hạn tần suất không chỉ riêng có ở tìm kiếm học thuật. Bất kỳ tập dữ liệu công khai mở nào từng phát hành API vào thời tiền LLM giờ đây đều chịu chung những mẫu tải đó: SEC EDGAR, USPTO, EPO, các cơ sở dữ liệu hồ sơ công, dịch vụ thời tiết, dữ liệu mở của chính phủ. Cùng một mẫu kỹ thuật đó áp dụng được cho tất cả — cache ở cấp thực thể, thêm một lớp proxy đã quản lý, chấp nhận độ trễ như một giải pháp thay thế khi bạn không kham nổi proxy.
Sự dịch chuyển sâu xa hơn: vào năm 2026, kỳ vọng một API công khai miễn phí hấp thụ trực tiếp tải của agent LLM không còn hợp lý nữa. Các endpoint không biến mất — nhưng chúng đang được bọc bởi một lớp dịch vụ quản lý có tính phí, tồn tại để dịch các giới hạn tần suất kiểu "nhà nghiên cứu lịch sự" thành lưu lượng "agent chịu được burst". API Pick Academic Search là một trong những lớp đó cho trường hợp tổng quan tài liệu. Sẽ còn nhiều lớp như vậy nữa.
Câu hỏi thường gặp
Tại sao arXiv bắt đầu siết giới hạn tần suất mạnh tay đến vậy vào năm 2024?
Vì các scraper do LLM điều khiển. Nhân viên arXiv đã nói thẳng trên mailing list dành cho developer và trên @arxiv ở X về mẫu hành vi này: một agent LLM bung ra 50 request song song để lấy phần tài liệu tham khảo của một bài báo duy nhất, nhân với hàng nghìn người dùng chạy những workflow tương tự, và cả chỉ mục bị suy giảm. Quy tắc 3 giây giữa các request luôn có trong tài liệu, nhưng việc thực thi trở nên nghiêm ngặt từ cuối năm 2024 / đầu năm 2025.
Mức 1.000 req/giây của Semantic Scholar có thật sự là dùng chung không?
Đúng vậy — đó là pool chưa xác thực, chia sẻ chung cho mọi IP truy cập API công khai. Trên thực tế, các request chưa xác thực bắt đầu lỗi vào giờ cao điểm bất kể tần suất riêng của bạn. Lời khuyên chính thức là xin một API key, thứ chuyển bạn sang một bucket theo từng key. Việc xét duyệt mất vài tuần và được cấp với giả định là dùng cho mục đích học thuật, không phải thương mại.
Còn E-utils của PubMed thì sao?
Tốt hơn các nguồn khác — 3 req/giây khi không có key, 10 req/giây khi có. Xin API key của NCBI qua email; thường được cấp ngay trong ngày cho các mục đích nghiên cứu đã khai báo. Dù vậy: 10 req/giây là ổn cho một người dùng đơn lẻ nhưng không đủ cho một sản phẩm nhiều người dùng, nơi mỗi câu hỏi của người dùng bung ra thành nhiều lần gọi PubMed.
Tại sao PaperQA2 chạy được trong khi agent tự chế của tôi thì không?
Có ba lý do. (1) PaperQA2 gom nhóm và cache rất quyết liệt — cùng một lần tra cứu DOI không bao giờ được thực hiện hai lần. (2) Nó dùng Semantic Scholar chủ yếu cho đồ thị trích dẫn (một lần gọi mỗi bài báo) thay vì như một chỉ mục tìm kiếm. (3) Nó chấp nhận thời gian chờ thực (wall-clock) lâu hơn cho mỗi câu hỏi để đổi lấy việc không vượt giới hạn. Nếu bạn muốn trải nghiệm tương tự trong một sản phẩm mà người dùng kỳ vọng phản hồi trong 5 giây, bạn cần một lớp có throughput cao hơn.
API Pick Academic Search thực sự giải quyết điều gì?
Nó quản lý các giới hạn tần suất và độ bao phủ nguồn để agent của bạn không phải làm việc đó. Chỉ một lần gọi POST /api/search/academic trả về kết quả đã xếp hạng từ arXiv, PubMed, bioRxiv và medRxiv gộp lại, đã được định hình sẵn cho LLM tiêu thụ. 5 credit mỗi lần gọi (≈$0.005), chỉ bị trừ khi HTTP 200. Bạn tập trung vào vòng lặp của agent và prompt; việc siết tần suất là vấn đề của chúng tôi.
Các API dùng trong bài viết này
Sarah Choy là CEO của API Pick. Cô viết về việc xây dựng các API sẵn sàng cho production cho AI agent và quy trình LLM.