Skip to content
jeff.retrieval.section-idv1.4.0

Document section classification

Identifies the type of document section a passage belongs to, using your list of section types and descriptions. Returns none when no type fits.

Open in playground

Example

Context

document
An installation services agreement between a home energy installer and a housing developer.

Input

Either party may end this agreement on 60 days' written notice. If the developer ends it, any invoices then unpaid fall due at once.

Labels (the options)

scope
What work the installer will do, and where
payment
Prices, invoicing and when payment is due
termination
How and when either party may end the agreement
liability
Who is responsible for loss or damage, and the limits
none
None of these sections
Answer (JSON)
value termination, confidence 1
Top options
  1. termination 1
  2. payment 0
  3. none 0

The passage is about ending the agreement, so it comes from the termination section.

Open in playground

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "An installation services agreement between a home energy installer and a housing developer.",    }, labels={        "scope": "What work the installer will do, and where",        "payment": "Prices, invoicing and when payment is due",        "termination": "How and when either party may end the agreement",        "liability": "Who is responsible for loss or damage, and the limits",        "none": "None of these sections",    })     decision = decide("Either party may end this agreement on 60 days' written notice. If the developer ends it, any invoices then unpaid fall due at once.")     print(decision.value, decision.confidence)

More examples

  • When invoices fall dueanswer payment · confidence 1

    Context

    document
    An installation services agreement between a home energy installer and a housing developer.

    Input

    The installer will invoice the developer at the end of each month for the units installed in that month. Each invoice is payable within 30 days of its date.

    Labels (the options)

    scope
    What work the installer will do, and where
    payment
    Prices, invoicing and when payment is due
    termination
    How and when either party may end the agreement
    liability
    Who is responsible for loss or damage, and the limits
    none
    None of these sections
    Answer (JSON)
    value payment, confidence 1
    Top options
    1. payment 1
    2. none 0
    3. scope 0

    The passage says when the installer invoices and when invoices fall due, so it comes from the payment section.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "An installation services agreement between a home energy installer and a housing developer.",    }, labels={        "scope": "What work the installer will do, and where",        "payment": "Prices, invoicing and when payment is due",        "termination": "How and when either party may end the agreement",        "liability": "Who is responsible for loss or damage, and the limits",        "none": "None of these sections",    })     decision = decide("The installer will invoice the developer at the end of each month for the units installed in that month. Each invoice is payable within 30 days of its date.")     print(decision.value, decision.confidence)
  • Which homes the installer fitsanswer scope · confidence 0.927

    Context

    document
    An installation services agreement between a home energy installer and a housing developer.

    Input

    The installer will supply and fit one Aster 2 heat pump in each of the 48 homes on the Mill Brook site, plots 1 to 48, and commission each unit.

    Labels (the options)

    scope
    What work the installer will do, and where
    payment
    Prices, invoicing and when payment is due
    termination
    How and when either party may end the agreement
    liability
    Who is responsible for loss or damage, and the limits
    none
    None of these sections
    Answer (JSON)
    value scope, confidence 0.927
    Top options
    1. scope 0.927
    2. none 0.073
    3. payment 0

    The passage says which homes the installer fits and what it does there, so it comes from the scope section.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "An installation services agreement between a home energy installer and a housing developer.",    }, labels={        "scope": "What work the installer will do, and where",        "payment": "Prices, invoicing and when payment is due",        "termination": "How and when either party may end the agreement",        "liability": "Who is responsible for loss or damage, and the limits",        "none": "None of these sections",    })     decision = decide("The installer will supply and fit one Aster 2 heat pump in each of the 48 homes on the Mill Brook site, plots 1 to 48, and commission each unit.")     print(decision.value, decision.confidence)
  • Cap on the installer's liabilityanswer liability · confidence 1

    Context

    document
    An installation services agreement between a home energy installer and a housing developer.

    Input

    The installer's total liability for any loss or damage arising under this agreement is limited to the price of the units installed in the 12 months before the claim.

    Labels (the options)

    scope
    What work the installer will do, and where
    payment
    Prices, invoicing and when payment is due
    termination
    How and when either party may end the agreement
    liability
    Who is responsible for loss or damage, and the limits
    none
    None of these sections
    Answer (JSON)
    value liability, confidence 1
    Top options
    1. liability 1
    2. payment 0
    3. none 0

    The passage limits the installer's liability for loss or damage, so it comes from the liability section.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "An installation services agreement between a home energy installer and a housing developer.",    }, labels={        "scope": "What work the installer will do, and where",        "payment": "Prices, invoicing and when payment is due",        "termination": "How and when either party may end the agreement",        "liability": "Who is responsible for loss or damage, and the limits",        "none": "None of these sections",    })     decision = decide("The installer's total liability for any loss or damage arising under this agreement is limited to the price of the units installed in the 12 months before the claim.")     print(decision.value, decision.confidence)
  • Signatures and dateanswer none · confidence 1

    Context

    document
    An installation services agreement between a home energy installer and a housing developer.

    Input

    Signed for and on behalf of Fenwick Home Energy Ltd: R. Fenwick, Director. Signed for and on behalf of Ashgrove Homes Ltd: P. Mensah, Director. Date: 2 November 2026.

    Labels (the options)

    scope
    What work the installer will do, and where
    payment
    Prices, invoicing and when payment is due
    termination
    How and when either party may end the agreement
    liability
    Who is responsible for loss or damage, and the limits
    none
    None of these sections
    Answer (JSON)
    value none, confidence 1
    Top options
    1. none 1
    2. termination 0
    3. liability 0

    The signature block serves none of the listed sections, so the answer is none.

    Open in playground

    import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "An installation services agreement between a home energy installer and a housing developer.",    }, labels={        "scope": "What work the installer will do, and where",        "payment": "Prices, invoicing and when payment is due",        "termination": "How and when either party may end the agreement",        "liability": "Who is responsible for loss or damage, and the limits",        "none": "None of these sections",    })     decision = decide("Signed for and on behalf of Fenwick Home Energy Ltd: R. Fenwick, Director. Signed for and on behalf of Ashgrove Homes Ltd: P. Mensah, Director. Date: 2 November 2026.")     print(decision.value, decision.confidence)

Use when

  • You have split documents into passages and need to classify each passage by section type.

Avoid when

  • Your documents already have reliable headings that code can read directly.

Context and input

FieldKindDescription
passage
inputThe passage's text.
document
contextWhat the document is: its kind and parties, one line.

Functions

KeyInterfaceInstructionsLabels
sectionclassifyWhich section of the document is this passage from? Choose the section kind whose main purpose the passage serves, using the descriptions. Judge by its content, not by topics it mentions in passing: a termination clause that mentions unpaid fees is still about termination. Headings may be missing, numbered or worded differently from the section names. none: the passage serves none of the listed section kinds (for example a kind of section that is not on the list), even when a listed kind is similar.from the caller

How it was measured

Test accuracy: the share of test rows whose top answer was right.

  • 90.9% on CUAD, a public benchmark of real contract paragraphs (1,168 rows). public benchmark
  • 99.8% on the in-house test (2,000 rows). in-house: same generator as the training data
  • 99.6% on the in-house test in domains never seen in training (2,000 rows). in-house: same generator as the training data

When confident

From the calibration set: at or above the threshold confidence, how often the answer is right, and how often the adapter is that confident. Below it, escalate.

FunctionRight when confidentConfident onThresholdCalibration rows
section99.8%100.0%0.532,000

Caveats

  • The CUAD rows were kept only where an LLM agreed with the label, which removes the hardest real passages.

Base: Jeff v1.4. Adapter trained: 25 October 2026.

Base

jeff-base v1.4

Call it

jeff.retrieval.section-id.section, with placeholders for its input and context.

import os import jeff with jeff.Jeff.remote("https://api.jeffhub.ai", token=os.environ["JEFF_API_KEY"], timeout_s=30) as client:     decide = client.function("jeff.retrieval.section-id.section", context={        "document": "<document>",    })     decision = decide("<passage>")     print(decision.value, decision.confidence)

Download

Weights: mstrasser/jeff-adapter-section-id (v1.4)

Licence: Apache-2.0