Vertical Corpora Builder - Domain Datasets for LLM Fine-Tuning avatar

Vertical Corpora Builder - Domain Datasets for LLM Fine-Tuning

Pricing

from $1.00 / 1,000 corpus chunk extracteds

Go to Apify Store
Vertical Corpora Builder - Domain Datasets for LLM Fine-Tuning

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

Oaida Adrian

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

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:

  1. Boilerplate strip — removes script/style/nav/footer/header/ aside and common utility blocks (breadcrumbs, shares, comments, menus), keeping the article body's paragraphs, list items and quotes.
  2. 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.
  3. 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
}
FieldTypeDefaultDescription
domainstringlegalVertical: legal, medical or financial. Written into every record's domain field.
sourcesarray<string>Seed URLs to crawl (required).
outputFormatstringjsonljsonl also writes a downloadable output.jsonl to the key-value store.
chunkSizeinteger512Target chunk size in tokens (64–4096).
maxPagesPerSourceinteger1Pages crawled per seed (1–100). 1 = seed pages only.
maxChunksPerPageinteger0Cap on chunks kept per page (0 = unlimited).
dedupeSimilarityinteger0.95Near-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.

{
"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 SUMMARY record reports how many duplicates were removed.
  • Dataset curation — filter by source/domain/title downstream 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 (maxPagesPerSource high, many seeds) may be slow. Cap with maxChunksPerPage when crawling long documents.
  • The actor follows same-domain links only; cross-domain citations are not crawled.