Change your NER labels at request time. Retrain nothing.
This article walks through named-entity-extraction, a workable example from the open-source SIE repo on GitHub: zero-shot entity extraction across four regulated domains with span-exact validation. SIE is Superlinked’s self-hosted inference engine, one cluster that serves embedding, reranking, OCR, vision, entity-extraction, and generation models behind three primitives (extract, encode, score). The example is a complete project; two commands reproduce the committed run. Built by Superlinked.
The traditional NER lifecycle goes like this. Define your entity types. Annotate a few thousand examples. Fine-tune a model. Deploy it. Then, three weeks later, someone asks you to also extract “recoupment amounts” and you’re back at step two.
Zero-shot NER breaks that loop. GLiNER accepts the label set as part of the request, so “what entities do we extract” becomes a runtime parameter instead of a training decision. The named-entity-extraction example in the SIE repo shows how far that flexibility actually stretches, and it does so on text with real stakes: authentic excerpts from SEC filings, CMS healthcare documentation, NTSB rail-safety reports, and Supreme Court opinions.
Four domains that would traditionally mean four annotation projects and four fine-tuned models. Here it’s one model (urchade/gliner_multi-v2.1) and four different label lists sent with the requests.
The same model, different questions
The trick is in what changes between domains. For the financial excerpt, the labels ask about monetary amounts, dates, and company names. For the healthcare text, they shift to codes, coverage terms, and timeframes. Rail safety wants locations, temperatures, and equipment. Legal wants parties, citations, and holdings. The model weights never move; only the request does.
If you’ve priced out what a domain shift costs with a fine-tuned pipeline (annotation time, training runs, eval cycles, redeployment), the economics of a request-time label change are hard to argue with. The open question is always accuracy, and that’s exactly what this example exists to measure rather than assert.
Verified inputs, validated outputs
Everything about the harness is built for auditability. Source excerpts live in data/cases.json and are verified by SHA-256 hash before any extraction runs, so the text going into the model is provably the published text. Then every extraction the model returns is checked mechanically: the predicted label must come from the requested label set, the confidence score must be finite, and the extracted span must match the input text exactly, character for character.
The committed run validates 53 recorded spans against 28 required anchors, offline, from saved artifacts. Anyone can re-verify the results without a GPU.
One design decision worth copying: raw model responses are preserved with errors intact. Where the model fumbled, the fumble is in the record, available for inspection and threshold analysis. Most demo repos quietly filter their failures; this one treats them as data, which is what you’ll need when you’re deciding on confidence thresholds for production.
Pinned and reproducible
The run is pinned to SIE v0.6.23 with documented hardware and latency measurements, and requests flow through audit envelopes that record the SDK arguments alongside source provenance. That level of pinning sounds excessive for an example until you try to reproduce someone’s NER numbers from a repo that says “results may vary”. Here, divergence is detectable: if your run differs, something specific changed, and the manifest tells you where to look.
Running it takes two commands against a local server:
uv syncuv run python run.pySet SIE_BASE_URL and SIE_API_KEY to target a hosted cluster instead. The same script, the same validations, your infrastructure.
Span-exact matching is stricter than it sounds
The requirement that extracted spans match the input character for character deserves a moment, because it’s the check most NER integrations skip. Plenty of extraction pipelines accept output that’s merely close: the model returns “36.08 million” when the document says “$36,080,000”, or normalizes a date, or trims a qualifier from a legal phrase. Each individual normalization looks helpful. Collectively they mean your extractions can no longer be located in the source, which breaks highlighting, breaks auditing, and breaks any downstream process that needs to quote the document rather than the model’s memory of it.
Character-exact spans keep the extraction anchored. Every entity in the output carries an implicit proof: search the source text and you will find this exact string. For the four domains in this example, where the documents are regulatory and the quotes may end up in front of an examiner, that property isn’t a nicety. It’s the requirement.
Where this pattern earns its keep
Zero-shot extraction is most valuable exactly where this example tests it: regulated domains where the entity types are specific, the documents are authoritative, and the schema keeps evolving. Compliance teams add entity types constantly. Legal discovery changes scope per matter. Healthcare documentation reviews depend on codes and timeframes that differ by claim type. A pipeline that absorbs those changes at request time, with span-exact validation proving the extractions are grounded in the source, is a fundamentally different operational posture than one that needs a training cycle per change.
Take the harness, swap in your own documents and your own labels, and check the spans that come back. If GLiNER holds up on your text the way it holds up on SEC and CMS excerpts, you just deleted a fine-tuning pipeline from your roadmap.
Try it on GitHub: superlinked/sie/examples/named-entity-extraction