Primitive

Split

Give Wity a thread, a contract, a chat export or a log, and say what one item is. You get back every email, clause, message or entry as its own piece, with exact character positions, in under a tenth of a second. Nothing is summarised, reworded or dropped: every item is a slice of your original text.

Signature

split(text, unit)

Returns

the text, cut into whole items

Use it for

One document → the things inside it.

New in wity-1

Split runs on the same model as your decisions. Cut a document into items, then ask any question about every item, with one API key and one bill. Try it in the console.

Why it matters#

Real inputs arrive in bundles. A custodian export holds hundreds of emails, a contract fifty clauses, a support log thousands of entries. Your decisions are about one of them at a time: is this email privileged, is this clause one-sided, does this entry need a human. Cutting by size splits sentences in half and glues two emails together; cutting by regex breaks on the first unusual header. Split cuts where the meaning changes.

A custodian export, “one item per email”

→ 7 emailsevery header intact

A services agreement, “one item per clause”

→ 14 itemstitle, parties, 12 clauses

A team chat export, “one item per message”

→ 12 messagesone per line

One call#

Send the text and the unit in plain words. The response lists the items in document order; each one is exactly text[start:end] of what you sent, with surrounding whitespace trimmed.

From: dana.whitlock@kestrelfoods.com
Subject: Batch 2207 seal test
Team, the seal integrity test on batch 2207 failed at 3 of 20 sample points. Can we hold the batch?
From: marcus.reyes@kestrelfoods.com
Subject: RE: Batch 2207 seal test
We can't hold it, the order ships Monday. Ship it and we'll retest next week.
From: events@kestrelfoods.com
Subject: Friday social - pizza and quiz night
Reminder: quiz night in the canteen at 5:30.
curl https://api.wity.alphanimble.com/v1/split \
-H "Authorization: Bearer $WITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "From: dana.whitlock@kestrelfoods.com\nSubject: Batch 2207 ...", "split": "one item per email" }'
{
"items": [
{ "start": 0, "end": 186, "text": "From: dana.whitlock@kestrelfoods.com\nSubject: Batch 2207 seal test\nTeam, the seal ..." },
{ "start": 188, "end": 361, "text": "From: marcus.reyes@kestrelfoods.com\nSubject: RE: Batch 2207 seal test\nWe can't hold ..." },
{ "start": 363, "end": 499, "text": "From: events@kestrelfoods.com\nSubject: Friday social - pizza and quiz night\n..." }
],
"how": "model",
"timing_ms": { "total": 231 },
"usage": { "input_tokens": 512, "output_tokens": 0 }
}

Split, then decide on every piece#

This is the pattern Split was built for. Cut the bundle into items, ask one typed question about each item in parallel, and keep the ones that pass, still in document order and still pointing at the exact place in the original. Relevance, privilege, risk, routing: whatever you would ask about one item, now asked about all of them.

import os, requests
from concurrent.futures import ThreadPoolExecutor
API = "https://api.wity.alphanimble.com"
H = {"Authorization": f"Bearer {os.environ['WITY_API_KEY']}"}
http = requests.Session()
def split(text, how):
r = http.post(f"{API}/v1/split", headers=H, json={"text": text, "split": how}, timeout=120)
r.raise_for_status()
return r.json()["items"]
def is_yes(item, question):
r = http.post(f"{API}/v1/systemone", headers=H, timeout=60, json={
"state": item["text"], "reasoning": "off",
"questions": {"q": {"type": "noul", "instructions": question}}})
r.raise_for_status()
return r.json()["answers"]["q"]["noul"] # P(yes)
emails = split(export_text, "one item per email")
with ThreadPoolExecutor(8) as pool:
p = list(pool.map(lambda e: is_yes(e, "Is this email about the failed seal test?"), emails))
relevant = [e for e, py in zip(emails, p) if py >= 0.5] # in document order, with exact offsets

Each item is an ordinary decision, so everything in Probabilities & confidence applies: act on the sure ones, route the close ones to a person.

Say what an item is#

In plain words

"one item per email", "one item per clause", "one item per message", "one item per news story", "one item per changelog entry": any unit you can name. A few structures are cut by rule, instantly and exactly:

  • sentence, line (also log entries), bullet / list item, paragraph (blank-line separated)
  • speaker turn: consecutive lines by the same speaker stay together

As a split spec

When you know what your data looks like, say so. A spec gives the unit plus up to eight short descriptions each of where items start, what stays together and where an item never starts. It sharpens the cuts on formats Wity would otherwise have to guess at.

{
"text": "...",
"split": {
"unit": "email",
"starts_at": ["a 'From:' header line"],
"keep_together": ["the headers, body, quoted reply and signature of one email"],
"never_split": ["at blank lines inside an email"]
}
}

Teach it your format#

When your documents are cut a particular way (your ticket export, your firm's contract template, a log format nobody else uses), show Wity how. Make a split skill with one or more example splits: the text and its items (or the character offsets where items start). Wity learns from them in seconds and then splits documents like them your way. In the console, split a document, fix the cuts where they are off, and click Teach this split.

curl https://api.wity.alphanimble.com/v1/skills \
-H "Authorization: Bearer $WITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "our-tickets",
"split": "one item per ticket",
"examples": [
{ "text": "#4471 Login fails\nOpened by ana, 09:02\n...\n#4472 Invoice question\n...",
"items": ["#4471 Login fails\nOpened by ana, 09:02\n...", "#4472 Invoice question\n..."] }
]
}'
# a few seconds later, split with it like any split
curl https://api.wity.alphanimble.com/v1/split -H "Authorization: Bearer $WITY_API_KEY" -H "Content-Type: application/json" \
-d '{ "text": "...", "skill": "our-tickets" }'
  • One example already helps where the plain instruction cuts your format wrong. Splitting JSON, INI, XML and key-value data into fields, one example lifted accuracy on other documents of the same kind from 0.73 to 0.99. Across 14 unusual formats, a skill switched itself on after one example in half the cases, and there it went from 0.68 to 0.91.
  • It checks itself. A skill is used only if it beats the plain instruction on examples it did not learn from: with two or more, each one held back in turn; with one, it learns from the first half of the items and is checked on the second. Where the plain instruction already cuts well, the skill stays off and splits exactly as before (active, quality on the skill). Every split with a skill says which version answered and how: "skill": {"name", "version", "answered_by", "active"}.
  • Examples of the same kind teach the most. A skill learns your format, not a new instruction: keep one skill per kind of document.
steptypical time
Make a skill, add examplesreturns at once
Learn from one example2 to 4 seconds
Learn from three examplesabout 10 seconds
A split with a skillthe same as without

Split skills live with your other skills: list, rename, add or delete examples with the skills API, or in the console's Skills & sessions page.

How good it is#

Measured on the live splitter (19 October 2026) against hand-labelled item boundaries: 70 real documents (GitHub and Hacker News threads, IRC logs, mailing lists, server logs, changelogs, contract provisions and news feeds) and about 390 test documents in formats from emails to JSON, XML and config files:

Item boundaries
F1
0.99 on the 70 real documents; 0.91 across the test set; 0.87 on formats it never saw in training.
Speed
median
0.08 s per document on the server (p95 0.12 s), for typical documents; a 20,000-character list of 70 entries took about 1.4 s.
Text changed
characters
None, by construction: items are positions in your text, never rewritten text.
Cost
example
A 2,000-character document is about 800 input tokens: well under $0.0001, so a thousand of them cost about 4 cents.

Good to know#

  • Up to 60,000 characters per request. Long texts are read in windows, so a long list costs about the same per character as a short one.
  • Cuts fall at line breaks or after a sentence (. ! ? ; : ) ] and a space). Fields inside one line, like {"a": 1, "b": 2}, are not cut apart.
  • Where it is weakest: formats it has never seen, cut an unusual way. That is what split skills are for.
  • Billing: usage.input_tokens counts the text once plus a few hundred tokens of instructions (texts over about 5,000 characters are read in overlapping windows and count up to about twice), at the usual $0.042 per million. Requests that fail cost nothing.
  • Full request and response reference: POST /v1/split.

Previous

← Score

Next

Generate →