paperai: bulk LLM extraction over a paperetl corpus
📄 🤖 AI for medical and scientific papers
At a glance
- What is it?
- paperai turns a paperetl article database into a searchable index and runs batched LLM prompts over it to fill report columns. It is a research-team tool with a narrow, document-shaped input, not a general RAG framework.
- Who is it for?
- Adopt paperai if you already have a paperetl-built database and need the same fields extracted from hundreds of articles into CSV, Markdown or annotated PDFs. Do not adopt it if your source material has not been through paperetl, or if you want interactive single-question chat rather than a report run, since the shell and the report configuration serve different jobs.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 63 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem is column filling, not question answering
Reading 300 oncology papers to fill in a table of sample sizes and study objectives is the task paperai describes. The README frames it as generating "bulk answers to questions backed by Large Language Model (LLM) prompts and Retrieval Augmented Generation (RAG) pipelines", and the analogy it offers is "kicking off hundreds of ChatGPT prompts over your data". That framing matters for who should care. This is not a chat interface over a PDF folder. It is a batch job whose output is a structured table, and the unit of work is a column definition, not a conversation.
The audience is narrow and visible in the material: medical and scientific research groups that already have a corpus in the shape paperetl produces. The two example notebooks are an introduction and a young onset colon cancer research project, which tells you the intended user is someone with a clinical or literature-review question and a pile of articles, not someone building a general document assistant. If your documents are contracts, support tickets or internal wikis, the report schema will still run, but nothing in the project is tuned for you.
Index first, prompt second: the two-stage data flow
paperai does not read PDFs itself. The README states plainly that it "indexes databases previously built with paperetl". So the pipeline has a hard upstream boundary: paperetl handles ingestion and produces a database, and paperai consumes that path. Everything downstream depends on paperetl having done its job.
Stage one is embedding. The command python -m paperai.index takes an input data path and an optional index configuration, which can be either a vector model path or an index.yml file. With no configuration, the README says paperai "uses the default txtai embeddings configuration". With an index.yml, the file "takes all the same options as a txtai embeddings instance", and the README's example is two lines: path set to sentence-transformers/all-MiniLM-L6-v2, and content set to True. That content flag is what makes retrieved text available to the prompt later, so a configuration that omits it would leave the LLM stage with nothing to read.
Stage two is the report run. A YAML report configuration names a query, a set of columns, and an options block containing the LLM, a system prompt, a template with {question} and {context} placeholders, a context count, and params. The template in the README instructs the model to extract a field and gives explicit rules: keep it simple, only extract the data, never explain, never restate the field name, and say no data if the field is not found. Retrieval supplies the context, the template supplies the instruction, and the column supplies the question. Output is written as Markdown, CSV, or annotations placed directly on PDFs "when available", which is a hedge worth noting: annotation depends on the source PDF being present in the index.
Install, index, query: the commands that exist
Installation is a single pip command, pip install paperai, with Python 3.10+ supported and a virtual environment recommended. The README also documents installing from GitHub with pip install git+https://github.com/neuml/paperai for unreleased features, and links to txtai's environment-specific prerequisites page for install problems, which is a useful signal that dependency resolution is the usual friction point rather than paperai itself.
Docker is documented as a two-step build. Fetch the Dockerfile with wget from the repository's docker directory, then docker build -t paperai . and docker run --name paperai --rm -it paperai. The README describes a combined image path as well: build a paperetl docker image first, then rebuild paperai with build args BASE_IMAGE=paperetl and START=/scripts/start.sh, giving one image that both indexes and queries.
Once an index exists, the documented entry point is the shell: paperai <path to model directory>, which drops you at a prompt where queries are typed directly. The repository also ships examples/search.py, described as a way to set query parameters, execute searches and display results, which is the programmatic route if the shell is not what you want. The report configuration is where the LLM work happens, and the README's sample options block is the concrete reference: llm pointing at a GGUF file, system as a role string, template as the extraction prompt, context set to 5, and params carrying maxlength 4096 and stripthink True.
The paperetl dependency is the real adoption cost
The most consequential constraint is stated in one clause: paperai indexes databases previously built with paperetl. You cannot point it at a directory of PDFs. If your articles have not been through paperetl, paperai has nothing to index, and the README does not describe an alternative ingestion path. That makes paperetl a prerequisite rather than an optional companion, and it means the effort of adopting paperai includes the effort of getting paperetl to produce a database from your sources.
The second constraint is the model. The README's report example names a specific GGUF file, Intelligent-Internet/II-Medical-8B-1706-GGUF with the Q4_K_M quantisation, and the stripthink parameter suggests the project expects reasoning-style models whose chain of thought needs to be removed from output. Quantised GGUF inference is local and self-hosted, which is good for sensitive clinical text, but it also means you own the hardware and the model download. There is no hosted-API configuration shown in the material, so anyone expecting to plug in a cloud endpoint is reading beyond what the README documents.
The third is context sizing. The sample sets context to 5 and maxlength to 4096. Those two numbers interact, and the README does not explain what happens when five retrieved passages plus the template exceed the window. Truncation, silent field loss, or a hard error are all plausible, and the documentation does not say which. Treat those values as a starting point that needs empirical checking against your own corpus, not as defaults that are known to be safe.
Where a plain txtai embeddings index is the better tool
paperai is built on txtai, and the README is explicit that an index.yml "takes all the same options as a txtai embeddings instance". That relationship defines the honest alternative. If your goal is semantic search over a corpus, returning ranked passages for a human to read, a txtai embeddings index does that directly, with no LLM stage, no report configuration, no template, and no GGUF model to host. You get the retrieval half of paperai and none of the generation half.
The difference in approach is the output shape. txtai returns documents; paperai returns filled cells. An embeddings index answers "show me passages about young onset colon cancer". paperai answers "for each of these papers, what was the sample size", and does so in a batch defined by a YAML file. If you cannot name the columns you want in advance, the report schema gives you nothing that a search interface does not already give you, and you have taken on a model download and a prompt template for no benefit. The reverse also holds: if you can name the columns, running hundreds of prompts by hand is exactly the work paperai exists to remove.
Licence, releases and what maintenance looks like
paperai is Apache-2.0, a permissive licence that permits commercial use and modification with the usual notice and attribution conditions. That is a permissive grant, not legal advice, and the practical question for a research group is whether the model weights you point options.llm at carry compatible terms. The README names a specific third-party GGUF file but says nothing about that model's licence, so the model is a separate licensing decision from the code.
Release cadence is visible in the tags: v2.4.0 in June 2025, v2.5.0 in July 2025, and v2.3.0 before that in December 2024. That pattern suggests occasional bursts rather than a steady drumbeat, which is normal for a research-oriented tool maintained alongside its txtai dependency. The upgrade cost is mostly external. Because index configuration passes through to txtai embeddings options, a txtai release can change what your index.yml accepts, and because the LLM stage depends on a GGUF file you host, swapping models means re-running reports to compare outputs. Neither is expensive in isolation, but both mean an upgrade is a re-run, not a version bump.
The repository is not archived and was pushed recently, so the project is active. What the material does not provide is any statement about backward compatibility for report configurations, which is the file you will have invested the most editing time in.
Who should run the colon cancer notebook before committing
The fastest way to decide is to run the Medical Research Project notebook, which the README links with a Colab badge and describes as researching young onset colon cancer. It exercises the whole path: a corpus, an index, a report configuration with named columns, and generated output. If that notebook's shape matches your problem, paperai fits. If you find yourself wanting to ask follow-up questions of a single paper rather than fill a fixed set of columns, the shell at paperai <path to model directory> is the part you actually want, and the report machinery is overhead.
Two things to verify before you commit a team to it. First, confirm paperetl can produce a database from your sources, because that is the gate everything else sits behind. Second, run one report with your own template and check the maxlength and context values against your longest retrieved context, since the README's 4096 and 5 are illustrative rather than validated. The project's value is concentrated in one behaviour: turning a defined table of fields into a batch job over a corpus you already have in paperetl form. Outside that boundary it is a thin wrapper over txtai, and txtai alone is the shorter path.
Editorial conclusion
Adopt paperai if you already have a paperetl-built database and need the same fields extracted from hundreds of articles into CSV, Markdown or annotated PDFs. Do not adopt it if your source material has not been through paperetl, or if you want interactive single-question chat rather than a report run, since the shell and the report configuration serve different jobs. Before committing, verify that your index.yml model path resolves locally, that the GGUF file named under options.llm is present at that path, and that maxlength is large enough for your context value, because the README does not state what happens when the context exceeds the window.
Community notes