AI / Agents

Skills
llms.txt
llms-full.txt

Developers

Joseph Cornelius

Author

Community

Full license MIT

Meta

Requires: Python >=3.10
Package Info

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).