Choice question per document.
Most filings are easy. A regional bank is a regional bank. Some are not: a company that
just sold one of its two segments, or a startup describing a business it plans to enter
rather than one it runs. The model has to pick a group regardless, and the answer for a
hard case looks no different from the answer for an easy one. Telling hard cases from easy
ones is normally where the cost goes: a second model, extra calls, human review.
A Choice already tells you. Alongside the winning option it returns confidence, high when
nearly all the probability landed on one option and low when it spread across several. That
one number separates the answers you can trust from the ones you can’t.
What to do with an untrusted answer depends on your labels. SIC labels form a hierarchy:
industry groups roll up into broader divisions. When the model is unsure of the group,
report the division it belongs to. The division follows from the group, so there is no
second call.
Across 60 filings, a confidence cutoff of 0.9 splits them in half. The confident half is
right 90% of the time; the other half, 40%. Reported one level up, that 40% becomes 70%.
Setup
TYPESAFE_API_KEY. Download filings.jsonl, sic_codes.tsv and
json_cache.json from
typesafe-public-examples into the folder you run
the script from. Every API call is cached in json_cache.json, so the published numbers
replay without calling the API; leave that file out to run everything live.
Numbers below came from jev-1.12 on 2026-08-12.
Build the two levels of the taxonomy
sic_codes.tsv is the industry list the SEC publishes for filers to pick their own code
from, fetched 2026-08-10: 444 four-digit codes, each with an industry title. The digits are
a hierarchy. The first two are the major group (75 of them here, from 01 agricultural
production to 99 non-classifiable), and fixed ranges of major groups make up the ten
divisions, the broadest split SIC has.
Both levels come out of that one file with no model involved: group the codes by their
first two digits, then map those digits to a division.
The filings
filings.jsonl holds 60 annual reports (10-K), each trimmed to Item 1 “Business”, the
section where a company describes what it does, which is the only part an industry code is
about. They span 1993–2024 and run from 700 to 2,200 words. Each one carries the SIC code
its filer chose, plus the accession number to look it up on EDGAR.
The label is self-reported: whoever prepared the filing picked it once, and it goes stale
when a company sells the business the code names and keeps the code. These 60 were
filtered down to filings whose own text supports the code they carry, so the numbers here
measure the recipe rather than the state of EDGAR’s metadata.
Ask one Choice question, and read the confidence
The whole taxonomy fits in one request: a Choice works reliably up to roughly 240 options, and 75 is well inside that. The answer comes back withchoice, the winning group; probabilities, the weight on each
of the 75; and confidence, which says how concentrated that spread was. The recipe reads
confidence rather than the winner’s own probability. A winner at 0.45 with a runner-up at
0.44, and a winner at 0.45 with the rest of the weight scattered thinly, are different
situations, and confidence is what separates them.
Return the group when sure, its division when not
At 0.9 confidence or above, the answer is reported as an industry group; below that, the same answer is reported as the division that group sits in. Every filing still comes back with a usable label. One the model could not classify confidently comes back one level up instead of being dropped or sent on. If a division is too coarse for your application to act on, this branch is where you hand it to a person.What the broader answer buys
We score all 60 filings against the code each filer chose, under both policies: name a group every time, or report the division whenever confidence lands under 0.9.

