Workflow leaderboard / General / Corpus annotation

Annotate named entities with boundary adjudication

标注命名实体并裁决边界分歧

General / 通用 Corpus annotation / 语料标注 curated verified 2026-08-02

Create span-level entity labels with explicit boundary rules, independent annotation and a lossless adjudication record.

Variants

Free & local / 免费本地 ~45 min setup

Any 8 GB laptop for a small corpus. Use a secured server for multiple annotators.

ComponentRolePriceLink
doccano 1.8.4 from PyPI; repository release 1.8.5 also observed text sequence labelling and JSONL export Free / 免费MIT-licensed open-source annotation platform; hosting is separatechecked 2026-08-02 https://pypi.org/project/doccano/1.8.4/

Span annotation codebook

offset_standard: zero_based_half_open
labels:
  PERSON: named individual
  ORGANIZATION: named formal organization
  LOCATION: named geographic place
boundary_rules:
  include_titles: false
  include_trailing_possessive: false
  nested_entities: forbidden
  discontinuous_entities: forbidden
uncertainty:
  action: skip_and_comment
adjudication:
  preserve_original_annotations: true
  record_decision_reason: true
  record_adjudicator: true

Save as validate_spans.py

import json, sys
errors=[]
for line_no,line in enumerate(open(sys.argv[1],encoding='utf-8'),1):
    row=json.loads(line); text=row['text']
    for span in row.get('label',[]):
        start,end,label=span
        if not (isinstance(start,int) and isinstance(end,int) and 0 <= start < end <= len(text)):
            errors.append((line_no,span,'invalid offsets'))
        elif text[start:end].strip() != text[start:end]: errors.append((line_no,span,'boundary includes whitespace'))
print(json.dumps({'errors':errors},ensure_ascii=False,indent=2))
raise SystemExit(bool(errors))

Install and validate an export

uv venv --python 3.11 .venv
. .venv/bin/activate
uv pip install 'doccano==1.8.4'
doccano init
# Create the first user interactively or with a password supplied through your secret manager.
doccano webserver --port 8000
# In a second shell: doccano task
# Export JSONL without overwriting the raw export, then run:
python validate_spans.py exports/annotations.raw.jsonl

Known pitfalls

  • Character offsets can shift after Unicode normalization or text cleaning.
  • Do not normalize source text after annotation begins.
  • Token-level agreement can hide systematic boundary disagreement.
  • Never overwrite independent annotations with adjudicated labels.

Evidence