Content rules¶
rules.yaml is the optional sidecar that tells the pipeline what your
documents mean — classification rules and split categories — kept
deliberately separate from config.yaml's infrastructure. Save it once
and every classify, split, and ingest call honors it with zero
code changes.
# rules.yaml — beside config.yaml, loaded with it
classify:
rules: # ≤ 20 — presence makes classify closed-set
invoice: Itemized charges, tax info, and payment terms
sec_filing: 10-K/10-Q style financial filings
contract: Signed agreements with parties and obligations
target_pages: "1,3,5-7" # optional — read only these pages (1-based)
max_pages: 5 # optional — cap after selection; 0 = none
split:
categories: # ≤ 50 — presence skips vocabulary discovery
financial_statements: Balance sheets, income statements, cash flow
management_discussion: MD&A narrative sections
notes: Footnotes and disclosures
unmatched: other # require | other | skip (default: other)
Precedence — who wins¶
For every rules-shaped parameter, resolution is:
explicit call argument > rules.yaml preset > open-ended / discovered
classify("doc.pdf")with a saved preset → closed-set against the preset.classify("doc.pdf", categories={"memo": "..."})→ your argument wins; the preset is ignored.classify("doc.pdf", categories={})→ the empty dict is an explicit choice: open-ended, preset bypassed. Same forsplit(..., vocabulary={})→ discovery.- No rules.yaml at all → open-ended classification, discovered split vocabulary. This is the honest default state.
ingest() needs no wiring: its classify and split stages resolve the
preset internally.
Validation¶
The library validates rules at call time and refuses presets the pipeline would choke on:
- More than 20 classification rules or 50 split categories → error.
target_pagesgrammar: 1-based numbers and ascending ranges ("1,3,5-7");"0"and"7-5"are rejected. Out-of-range pages are dropped; a selection that leaves nothing raises.unmatched: requireorskipwithout categories → error (the mode only means something against a vocabulary).
Applying and clearing¶
The file is read with the configuration, so a long-running process
picks up edits after reset_config(). Deleting the file (or clearing
it) returns the pipeline to open-ended everywhere. Rules affect
future runs only — already-ingested documents keep their categories
and sections.
Editing visually
The studio has a rules editor on its Settings page that writes this exact file, and its Try-it page accepts per-run overrides — useful for iterating on rules against a real document before saving them.
Coming from LlamaCloud¶
The concepts map one-to-one:
| LlamaCloud | ingestlib |
|---|---|
| Classification rules (20 max) | classify.rules (20 max) |
| Split categories (50 max) | split.categories (50 max) |
| "Uncategorized pages" dropdown | split.unmatched: require · other · skip (default group-as-Other) |
Inline configuration on an API call |
Per-call arguments |
Saved configuration_id |
rules.yaml |