Vertical Corpora Builder - Domain Datasets for LLM Fine-Tuning
Pricing
from $1.00 / 1,000 corpus chunk extracteds
Vertical Corpora Builder - Domain Datasets for LLM Fine-Tuning
Build domain-specific text corpora (legal, medical, financial) for LLM fine-tuning: crawl seed sources, strip boilerplate, dedupe, and emit token-aware chunks as JSONL with full provenance. Outputs a ready-to-train dataset.
Pricing
from $1.00 / 1,000 corpus chunk extracteds
Rating
0.0
(0)
Developer
Oaida Adrian
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 hours ago
Last modified
Categories
Share
Vertical Corpora Builder — Domain Datasets for LLM Fine-Tuning
Build domain-specific text corpora (legal, medical, financial) for LLM fine-tuning, RAG evaluation, or model pre-training. Point the actor at seed sources in your vertical; it crawls, strips boilerplate, removes duplicates, and emits token-aware chunks as JSONL with full provenance — a ready-to-train dataset, not a pile of HTML.
Why this actor
Raw web pages are terrible training data: nav bars, cookie banners, "related articles" and ads drown the signal, and near-identical syndicated text pollutes the corpus. This actor applies the three cleaning steps that matter for vertical corpora:
- Boilerplate strip — removes
script/style/nav/footer/header/asideand common utility blocks (breadcrumbs, shares, comments, menus), keeping the article body's paragraphs, list items and quotes. - Dedupe (exact + near) — exact duplicates are removed by normalised text hash; near-duplicates are collapsed by 6-gram Jaccard similarity (default threshold 0.95), so syndicated copies appear once.
- Token-aware chunking — chunks are split at paragraph boundaries and hard-split on sentence/word boundaries only when a single paragraph exceeds the budget (default 512 tokens, ~4 chars/token). Each chunk stays coherent, which is what fine-tuning actually wants.
Every output record carries provenance: source (hostname), url (exact
page), domain (your vertical), title and chunk_index — so you can
filter, cite, or re-weight the corpus later.
How it works
seed URLs ──▶ crawl (same-domain BFS) ──▶ clean (boilerplate strip)──▶ dedupe (exact + near, configurable) ──▶ token-aware chunk──▶ JSONL records {text, source, url, domain, chunk_index, title}
The crawl logic follows the house ai-web-crawler pattern: a browser
User-Agent, same-domain breadth-first link discovery (bounded by
maxPagesPerSource), and polite parallel fetching. Each seed URL is a
starting point; set maxPagesPerSource: 1 to extract only the seed pages,
or raise it to crawl whole sites.
Input
{"domain": "legal","sources": ["https://www.law.cornell.edu/supremecourt/text/19-1392"],"outputFormat": "jsonl","chunkSize": 512,"maxPagesPerSource": 1,"maxChunksPerPage": 0,"dedupeSimilarity": 0.95}
| Field | Type | Default | Description |
|---|---|---|---|
domain | string | legal | Vertical: legal, medical or financial. Written into every record's domain field. |
sources | array<string> | — | Seed URLs to crawl (required). |
outputFormat | string | jsonl | jsonl also writes a downloadable output.jsonl to the key-value store. |
chunkSize | integer | 512 | Target chunk size in tokens (64–4096). |
maxPagesPerSource | integer | 1 | Pages crawled per seed (1–100). 1 = seed pages only. |
maxChunksPerPage | integer | 0 | Cap on chunks kept per page (0 = unlimited). |
dedupeSimilarity | integer | 0.95 | Near-duplicate Jaccard threshold (0.5–1.0). 1.0 = exact dedupe only. |
Output
One dataset record per chunk (JSONL export = one line per chunk):
{"text": "The Court has long recognized ...","source": "courtlistener.com","url": "https://www.courtlistener.com/opinion/4855702/...","domain": "legal","chunk_index": 0,"title": "Dobbs v. Jackson Women's Health Organization"}
With outputFormat: "jsonl", the same records are also written to
output.jsonl in the actor's default key-value store (Content-Type
application/x-ndjson) for direct download. A SUMMARY record reports
totalChunks, totalPages, rawChunks, duplicatesRemoved,
estimatedTokens, and any failedSources.
Example: legal corpus from public court opinions
{"domain": "legal","sources": ["https://www.law.cornell.edu/supremecourt/text/19-1392","https://www.law.cornell.edu/supremecourt/text/20-843"],"chunkSize": 512,"maxPagesPerSource": 1}
Run from the API:
curl -X POST "https://api.apify.com/v2/acts/darknezz~vertical-corpus-builder/run-sync-get-dataset-items?token=YOUR_TOKEN&timeout=120" \-H "Content-Type: application/json" \-d '{"domain":"legal","sources":["https://www.law.cornell.edu/supremecourt/text/19-1392"],"chunkSize":512,"maxPagesPerSource":1}'
Use cases
- Fine-tuning a domain-specialised LLM (legal reasoning, medical QA, financial analysis) on clean vertical text.
- RAG evaluation — provenance fields let you ground and cite every chunk.
- Corpus research — dedupe keeps token budgets honest; the
SUMMARYrecord reports how many duplicates were removed. - Dataset curation — filter by
source/domain/titledownstream to assemble a bespoke mix.
Pricing
Pay-per-event: $0.001 per chunk-extracted (chunk-extracted is the
primary event). No charge for pages crawled with no extractable text.
Limitations
- Seed URLs must serve server-rendered HTML. JavaScript-only SPAs and sites
behind JS challenge walls (CourtListener's AWS WAF, Justia from datacenter
IPs) need a browser-rendering actor instead; plain HTML opinion archives
such as Cornell LII (
law.cornell.edu/supremecourt/text/) work well. - Chunk size is an estimate (~4 chars/token), not a byte-exact tokeniser count.
- Near-dedupe is O(n²) in chunk count; very large crawls
(
maxPagesPerSourcehigh, many seeds) may be slow. Cap withmaxChunksPerPagewhen crawling long documents. - The actor follows same-domain links only; cross-domain citations are not crawled.