cane-format
A lightweight, dependency-free Python library for CANE (Context-Anchored Natural Expression), an output format for LLM-based named entity recognition: write annotated text as CANE for few-shot prompts, parse model output back into character spans, and convert between CANE and common annotation formats.
CANE is introduced in the paper CANE is a Format: Rethinking Output Formats for Few-Shot LLM-Based Named Entity Recognition (Findings of EMNLP 2026).
Documentation: https://coree.github.io/cane-format/
pip install cane-format # Python 3.10+, no dependencies
Early release; the API may change before 1.0.
Example
Entities:
`metastatic breast cancer` is a DISEASE found in `metastatic breast cancer cells`
`breast cancer cells` is a CELL found in `metastatic breast cancer cells caused`
`headache` and `nausea` are a ADR found in `caused headache and` and `and nausea`
One record per entity. The text after found in is an anchor that locates the entity;
discontinuous entities list their parts joined by and.
| Variant | Anchor | Discontinuous entities |
|---|---|---|
| Base | ✗ | ✗ |
| Disco | ✗ | ✓ |
| Context | ✓ | ✗ |
| Full | ✓ | ✓ |
Usage
import cane_format as cane
examples = cane.read_brat("corpus/train")
prompt = cane.build_prompt(new_text, examples=examples[:5], variant="full")
output = your_llm(prompt) # this library makes no model calls
result = cane.loads(output, text=new_text, variant="full", labels={"DRUG", "ADR"})
result.entities # entities with character offsets
result.issues # lines that could not be grounded
cane.write_brat([result.document], "predictions/")
Evaluation: nervaluate-disco via
cane.to_nervaluate(docs).
Formats
| Format | Read / write |
|---|---|
| CANE | loads, dumps |
| brat standoff | read_brat, write_brat |
| BioC JSON | read_bioc_json, write_bioc_json |
| CoNLL / IOB | read_conll, write_conll |
| Inline XML | read_xml, write_xml |
| Offset JSON | read_json, write_json |
cane-format convert corpus/ train.conll --from brat --to conll --on-conflict outermost
cane-format parse output.cane --text doc.txt --variant full --to brat -o predictions/
Behaviour
- Text is kept unchanged; offsets are verified against the text.
- What a format cannot represent raises an error, or is dropped with a warning if requested.
- Strict by default; lenient matching is opt-in.
Grammar
output ::= HEADER | [HEADER NEWLINE] ( EMPTY | record { NEWLINE record } )
record ::= [HANDLE] parts COPULA [ARTICLE] LABEL [ANCHOR_INTRO anchors]
parts ::= QUOTE text QUOTE { PART_CONNECTIVE QUOTE text QUOTE }
anchors ::= QUOTE text QUOTE { ANCHOR_CONNECTIVE QUOTE text QUOTE }
Citation
If you use CANE or this library in your work, please cite the paper:
@inproceedings{cornelius-etal-2026-cane,
title = "{CANE} is a Format: Rethinking Output Formats for Few-Shot {LLM}-Based Named Entity Recognition",
author = "Cornelius, Joseph and
Ito, Kei K and
Rinaldi, Fabio",
editor = "Lee, Hung-Yi and
Dev, Sunipa and
Li, Jessy and
Elliott, Desmond",
booktitle = "Findings of the {A}ssociation for {C}omputational {L}inguistics: {EMNLP} 2026",
month = oct,
year = "2026",
address = "Budapest, Hungary",
publisher = "Association for Computational Linguistics",
url = "https://aclanthology.org/2026.findings-emnlp.1398/",
pages = "29773--29800",
ISBN = "979-8-89176-462-0"
}
This code base is developed with the assistance of Claude (Anthropic).
Metadata
Release files for cane-format 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cane_format-0.1.1.tar.gz | 252.5 kB | Without provenance | Details for cane_format-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cane_format-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for cane_format-0.1.1-py3-none-any.whl |
Total release size: 308.0 kB
Release files / cane_format-0.1.1.tar.gz
| Download URL | cane_format-0.1.1.tar.gz |
|---|---|
| Size | 252.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ce9616597b2c0f6666d88c97e9ea01b447ff56cc60eb8d1370a77b1ce15d9a72
|
|
BLAKE2b-256 checksum How to use checksums |
a5d4cd7d0dab20eed7b5ad1ae2779d318331a007dfe2ddf0f924d2f832ec51f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / cane_format-0.1.1-py3-none-any.whl
| Download URL | cane_format-0.1.1-py3-none-any.whl |
|---|---|
| Size | 55.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19cb1a0c5051cf139fc149971b524a04175bbfd7e83f23d50994e4c5a6cce112
|
|
BLAKE2b-256 checksum How to use checksums |
2b05923db310f9dbca797239514233eacd9171c750daeb984c0ce291eb1daa50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for cane-format 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.