IRIS takes a natural language literature query like

"Find papers that use diffusion models for protein structure generation, evaluate on CASP targets, and were published after 2022."

and returns a ranked list of papers where every stated constraint has been checked against the paper's actual text, with verbatim evidence attached to each result.

It is scored under the official AstaBench harness (astabench 0.5.4, live GPT-4o grading). The run submitted to Ai2's AstaBench leaderboard as "Rasyn IRIS" on 2026-08-19 scored 0.386 and is in Ai2's review queue; the code in this repository, re-run afterwards on all 66 validation queries, scores 0.382.

Results

AstaBench PaperFindingBench, validation split, official harness:

System Adjusted F1 Cost / query Source
IRIS (this repo) 0.382 ~$0.13 this exact code, official harness, all 66 queries
Asta Paper Finder (Ai2) 0.380 ~$0.07 Ai2's leaderboard results dataset

On the test split, which IRIS has not run yet, Ai2's Asta Paper Finder scores 0.433 at ~$0.35/query and RoboPhD currently leads at 0.440. Validation and test are different query sets; do not compare numbers across them.

The fine print

We would rather you read this here than discover it in the comments.

  • We headline the number this code produces, not our best run. Seven official-harness runs, all of them: 0.384 (early configuration, before the citation-graph fix), 0.366 and 0.357 (fully live retrieval), 0.376 (cache-served, earlier configuration), 0.386 (the run submitted to Ai2), 0.384 (a 3-pass tournament variant), and 0.382 (this repository's code, re-run after the pre-release bug fixes below). The whole spread sits in the semantic slice, which measures 0.228 to 0.249 across repeats because the LLM judge is nondeterministic; the metadata slice (0.682) and specific slice (0.880) are stable. Cost is $0.131/query mean from the re-run's own per-sample metering, and includes the gpt-4o topic-verification calls on the specific-paper channel (PFBMAX_TOPIC_MODEL).
  • Read 0.382 vs 0.380 as a tie, not a win. The difference is far smaller than our own run-to-run noise, and Ai2's agent costs roughly half as much per query. With fully live retrieval we score below them (0.357 and 0.366 vs 0.380); that gap is retrieval infrastructure, not modeling. The claim we stand behind: an open-source system that matches Ai2's production paper finder on this split when corpus access is not the bottleneck.
  • Validation is the public development split. Like the published baselines, we report validation, and it is also the split we developed against. Treat this as a dev-split result until our test-split run lands.
  • The repository code differs slightly from the submitted run. Pre-release review found four real bugs (a citation-graph shortcut that dropped query conditions, a rate limiter running at double the configured rate, a truncation that discarded query expansions at raised settings, and silent zero-score runs on missing credentials). They are fixed here and the 0.382 figure is measured with them in place.
  • Certified runs served corpus retrieval from a local response cache (built from the same corpus API) because Semantic Scholar's public endpoint aggressively rate-limits; our fully live-retrieval runs scored 0.357 and 0.366. The harness entry point always wraps the corpus client in a read-through cache that fills pfbmax/cache/ as it runs; PFBMAX_CACHE_ONLY=1 makes a run serve exclusively from it. If you hit 429s, set PFBMAX_USE_MCP=1 to route through Asta's MCP gateway (MCP keys are issued at allenai.org/asta/resources, separate from the Semantic Scholar key).
  • The 923M-edge citation graph is not shipped. It is a ~360GB build from Semantic Scholar's bulk datasets; this repo does not include the build tooling yet. Without it, citation-constrained metadata queries fall back to live APIs.
  • The public history is a single clean commit. The development repository contains benchmark reference data that we are not licensed to redistribute, so the public tree is a clean export rather than the full history.
  • iris_asta/ is our general AstaBench client and solver library from the same project; IRIS exercises only its paper-finder path.

How it works

flowchart LR
    Q([Query]) --> R{Router}
    R -->|semantic| F[Multi-channel retrieval<br/>snippet 路 keyword 路 HyDE 路 citations]
    F --> J[Per-criterion pool judge<br/>gpt-4o-mini, depth 400<br/>position-decay weighting]
    J --> T[Listwise tournament<br/>gpt-5-mini, pooled Borda<br/>bounded demotion]
    R -->|metadata| M[Deterministic plan executor<br/>+ 923M-edge citation graph]
    R -->|specific| S[Targeted lookup]
    T --> O([Ranked papers +<br/>verbatim evidence])
    M --> O
    S --> O

One cheap LLM call routes each query to the channel built for it: semantic (fuzzy topical), metadata (venue, year, author, or citation constraints), or specific (a known paper). Deterministic channels that come back empty fall through to semantic, since an empty answer scores zero and the judged channel can only help.

Semantic search

Semantic search: multi-channel retrieval, RRF fusion, per-criterion judging, tournament reranking

The semantic channel fans out across snippet search, keyword paper search, hypothetical-abstract (HyDE) probes, and citation expansion, then fuses everything with reciprocal rank fusion. The query is decomposed into explicit relevance criteria, and a gpt-4o-mini pool judge scores the top 400 candidates against each criterion separately, with position-decay weighting (later auto-derived criteria are noisier, so they count less). Pointwise scores strand real matches in the ambiguous middle, so a gpt-5-mini listwise tournament reorders that contested band with sliding windows, pooled Borda aggregation across passes, and a bounded demotion cap so one bad window cannot destroy a good paper's rank.

Metadata search

Metadata search: typed plan, venue canonicalization, deterministic set intersection over a 923M-edge citation graph

"Papers at CHI after 2020 citing NeurIPS papers" is a database query, not a similarity search. The metadata channel compiles the query into a typed plan (venue set, year filter, citation set) and executes the intersection deterministically, with venue canonicalization and acronym expansion on both sides. When the local citation graph is present, venue-to-venue citation constraints run against it instead of rate-limited APIs; other citation constraints use the corpus API.

Specific lookup

Specific lookup: clue extraction, candidate scoring, reference walk, verification

When the query names one paper ("the AlphaFold 2 Nature paper"), IRIS extracts every clue it can (title fragments, authors, year, topic, artifacts), scores candidates against all of them, and walks references when direct resolution fails. It returns its best match: one paper in the typical case, a small hedged set when the name is genuinely ambiguous, with verbatim evidence either way.

Quickstart

git clone https://github.com/rasynai/rasyn-iris.git
cd rasyn-iris
pip install astabench==0.5.4

Create iris_asta/.env (see .env.example):

OPENAI_API_KEY=sk-...
ASTA_TOOL_KEY=...        # free at https://api.semanticscholar.org

Run the benchmark under the official harness with the leaderboard configuration:

PFBMAX_CJ_POOL=1 PFBMAX_CJ_POOL_DEPTH=400 PFBMAX_CJ_MODEL=gpt-4o-mini \
PFBMAX_CJ_POSDECAY=0.6 PFBMAX_TOURN=1 PFBMAX_TOURN_MODEL=gpt-5-mini \
inspect eval astabench/paper_finder_validation \
  --solver pfbmax/inspect_entry.py@pfbmax_solver \
  --model openai/gpt-4o-mini

Our own live-retrieval runs of this command scored 0.357 and 0.366. Read "Performance and rate limits" below before you start: on the public corpus API this is not a quick command.

Performance and rate limits

Everything here is measured, on our hardware, in August 2026:

What Observed
One metadata query (venue, year, citation constraints) about 6 seconds
One specific-paper lookup about 1 minute
One semantic query, cold cache, public API did not finish within 15 minutes
A single corpus call 1 to 30 seconds, highly variable

The semantic channel deliberately issues dozens of corpus calls per query (rephrasings, HyDE probes, citation expansion) because pool recall is the ceiling on the score. On the free public endpoint that is slow, and it can stall entirely when you are being rate limited. Nothing is hung; it is waiting on the API. Practical advice:

  • The read-through cache in pfbmax/cache/ makes repeat runs much faster, and the certified runs above were served from a warmed cache.
  • If you have Asta MCP access, PFBMAX_USE_MCP=1 routes corpus calls through the gateway instead of the public endpoint.
  • For a quick smoke test rather than a scored run, shrink the fanout: PFBMAX_MAX_REPHRASINGS=2 PFBMAX_MAX_CRITERIA=3 PFBMAX_MAX_HYDE=1 PFBMAX_MAX_CALLS=12. Expect a much weaker result; this is for checking that your keys and wiring work.
  • Missing or invalid keys now fail immediately with a message rather than producing a silent zero-score run.

Or call IRIS from your own code:

import os, sys
sys.path += ["pfbmax", "iris_asta"]
for line in open("iris_asta/.env"):
    if "=" in line and not line.startswith("#"):
        k, v = line.strip().split("=", 1)
        os.environ.setdefault(k, v)

from iris_asta.asta_client import AstaClient
from iris_asta.config import load_config
from llm import LLM
import router

client = AstaClient(load_config())
results = router.solve(
    "diffusion models for protein structure generation evaluated on CASP, after 2022",
    client, LLM(), inserted_before=None,
)
for paper_id, evidence in results:
    print(paper_id, evidence[:100])

router.solve never raises. It routes, retrieves, judges, and returns [(corpus_id, verbatim_evidence), ...] best first. A semantic query fans out into many corpus calls, so with a fresh key expect a first run to take several minutes; if the public API is rate-limiting you hard, set PFBMAX_USE_MCP=1.

Configuration

Everything is tunable by environment variable. The configuration of the certified runs:

Variable Value What it does
PFBMAX_CJ_POOL 1 enable the per-criterion pool judge
PFBMAX_CJ_MODEL gpt-4o-mini pool judge model (unset, the code default is gpt-4o-mini)
PFBMAX_CJ_POOL_DEPTH 400 candidates judged per query
PFBMAX_CJ_POSDECAY 0.6 criterion position-decay weight
PFBMAX_TOURN 1 enable the listwise tournament (unset any of these to disable)
PFBMAX_TOURN_MODEL gpt-5-mini tournament ranking model
PFBMAX_TOURN_PASSES 2 tournament passes over the contested band
PFBMAX_TOURN_PRIOR 0.4 blend weight of the pointwise prior
PFBMAX_TOURN_DEMOTE_CAP 8 max ranks a paper can fall per tournament
PFBMAX_TOPIC_MODEL gpt-4o-2024-11-20 topic-verification model on the specific-paper channel (default)
PFBMAX_USE_MCP unset set to 1 to route corpus calls via Asta's MCP gateway (rate-limit fallback)
PFBMAX_CITEGRAPH / PFBMAX_PMETA paths optional local citation graph + metadata SQLite (build tooling not included)

The certified runs also widened the retrieval fanout beyond the shipped defaults. For completeness, that environment was:

Variable Value What it does
PFBMAX_CJ_WORKERS 8 parallel judge requests
PFBMAX_MAX_CALLS 220 corpus-call budget per query
PFBMAX_SEEDS / PFBMAX_SEED_POOL 10 / 20 citation-expansion seeds and the window they come from
PFBMAX_LIMIT_SNIPPET_RAW 150 snippet depth for the raw query
PFBMAX_LIMIT_SNIPPET_HYDE 150 snippet depth per HyDE probe
PFBMAX_LIMIT_CITATIONS 120 citation rows per direction per seed
PFBMAX_FANOUT_WORKERS 5 parallel corpus probes
PFBMAX_FETCH_RETRIES 2 retries per corpus call
PFBMAX_CACHE_ONLY 1 serve corpus reads only from the local cache

Repository layout

Path What lives there
pfbmax/router.py query classification and channel dispatch, start here
pfbmax/criterion_judge.py the per-criterion pool judge
pfbmax/tournament.py listwise tournament reranker
pfbmax/metadata_solver.py deterministic metadata plans and citation graph execution
pfbmax/inspect_entry.py official harness entry point
iris_asta/ corpus client, config, rate limiting, snapshot date enforcement

Notes from development

Every component here earned its place through a controlled experiment; losers were deleted or left flag-gated off. The campaign kept a written ledger (23 entries) and finished with six official harness runs. Things that did not work, so you do not have to retry them:

  • Trained cross-encoder rerankers (several variants): never beat the LLM judge
  • Bradley-Terry and PageRank aggregation: pooled Borda won
  • Hierarchical tournaments: flat sliding windows won
  • Permissive judge prompts, evidence enrichment, prior blends at admission: all net negative

Things that paid: position-decay criterion weighting, the tournament package (pooled cross-pass Borda + pointwise prior + demotion cap), and the local citation graph.

The demotion cap is a good example of the approach. Pilot runs showed one rescue worth +0.094 but two catastrophic demotions, so ascent is unlimited and descent is capped at 8 ranks. Pooled Borda plus that asymmetry is what took the tournament from net zero to net positive.

Contributing

Issues and PRs welcome. One rule: no change lands without a measured comparison under the official harness (inspect eval astabench/paper_finder_validation ...). Post the before/after in the PR.

License

MIT 漏 2026 Rasyn AI. AstaBench (benchmark, harness, grading) is Ai2's work, used as a pip dependency. One exception to "no Ai2 content in this repo": the pool judge intentionally reproduces the harness's Apache-2.0 judging prompt so that selection matches grading; see THIRD_PARTY_NOTICES.md for the attribution and license text.


Built by Rasyn AI 路 Benchmarked on AstaBench by Ai2 路 Mirrored on Hugging Face
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 馃檵 Ask for provider support