Seed¶
A seed starts a pipeline by building records that do not exist yet, from dimensions you declare. Most synthetic datasets start this way.
The other way to start is a source, which loads records that already exist — a Python list, a local file, a Hugging Face dataset.
Seeding is a two-stage vocabulary: you declare dimensions, then combine them into a source. The combined seed must come first in the pipeline, like any other source.
A dimension on its own is not a step. Seed.values(...) >> LLMStep(...) raises
TypeError — only Seed.product and Seed.zip return something a pipeline can start
with. This is the most common mistake with seeds.
At a glance¶
| Constructor | Returns | Needs |
|---|---|---|
Seed.values(column, values) |
a dimension, not a source | — |
Seed.range(column, start, end) |
a dimension of numbers | — |
Seed.expand(parent, child, mapping) |
a dimension of nested pairs | — |
Seed.product(*dimensions) |
a source: every combination | — |
Seed.zip(*dimensions) |
a source: dimensions aligned by position | — |
Declaring dimensions¶
Seed.values(column, values)¶
| Parameter | Type | Default | Meaning |
|---|---|---|---|
column |
str |
required | the column this dimension fills |
values |
list |
required | the values it takes |
Seed.range(column, start, end, step=1)¶
| Parameter | Type | Default | Meaning |
|---|---|---|---|
column |
str |
required | the column this dimension fills |
start |
int |
required | first value, inclusive |
end |
int |
required | last value, inclusive |
step |
int |
1 |
gap between values |
end is inclusive, unlike Python's own range. Seed.range("grade", 1, 12) gives
twelve values, 1 through 12.
Seed.expand(parent, child, mapping)¶
One dimension holding a parent–child pair, for values that only make sense together.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
parent |
str |
required | the outer column |
child |
str |
required | the inner column |
mapping |
dict[str, list] |
required | each parent value to its child values |
from datafast import Seed
dimension = Seed.expand("topic", "subtopic", {
"Physics": ["Quantum", "Relativity"],
"Biology": ["Genetics", "Evolution"],
})
This is four values in one dimension — (Physics, Quantum), (Physics, Relativity),
(Biology, Genetics), (Biology, Evolution) — not two dimensions of two. That is the
point: crossing topic and subtopic as separate dimensions would pair Physics with
Genetics.
Combining dimensions¶
Seed.product(*dimensions)¶
Every combination — the cartesian product.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
dimensions |
*SeedDimension |
none | the dimensions to cross |
from datafast import Seed
seed = Seed.product(
Seed.values("persona", ["student", "teacher"]),
Seed.values("language", ["en", "fr"]),
)
Four records: each persona against each language. The record count is the product of the
dimension sizes, so it grows fast — three dimensions of ten are a thousand LLM calls.
len(seed) tells you the count before you run anything.
Seed.zip(*dimensions)¶
Dimensions aligned by position, like Python's zip.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
dimensions |
*SeedDimension |
none | the dimensions to align; all must be the same length |
from datafast import Seed
seed = Seed.zip(
Seed.values("question", ["Q1", "Q2", "Q3"]),
Seed.values("answer", ["A1", "A2", "A3"]),
)
Three records, pairing each question with the answer at the same index. Use this for values that correspond, where a product would be meaningless.
All dimensions must be the same length; mismatched lengths raise ValueError naming the
lengths it got. Calling either combiner with no dimensions gives an empty source.
Things worth knowing¶
- A dimension is not a source. Only
Seed.productandSeed.zipstart a pipeline. - Count before you spend.
len(seed)is the number of records, and usually the number of LLM calls the next step will make. - Overlapping columns: last one wins. If two dimensions fill the same column, the later one overwrites the earlier, silently. Give each dimension its own column.
Seed.rangeends inclusive, unlike Python'srange.- Seed never means a random seed. The
seedparameter onSampleandSink.hubis the random one.
Where to go next¶
- Source — the other way to start a pipeline, loading records instead of building them.
- Key Concepts — how seeds fit the record → step → pipeline model.
- Full Glossary — the precise meaning of seed, dimension, record and column.
- Data ops — the transforms that come next.
- API reference — generated signatures for everything on this page.