🎲AGSoft Seed
One queued job, N full runs — and it tells you which seed you got
- seed
- seed_str
Seed farming, without the clicking
Half the time a seed is a single number and you're done: type it, lock it, iterate on the prompt. The other half is seed farming - hunting twenty variations for the one hand that isn't mangled, the one face that looks like the person. The community's answer to that is "just do a batch of 50 and pick the best", and it's right, but ComfyUI makes you assemble the batch from two crude tools: turn up batch_size in Empty Latent (one sampling pass, N images), or hit Queue ten times and babysit it.
🎲AGSoft Seed is a third option. Its seed output is a list, and ComfyUI's list execution runs everything downstream once per element - so the whole chain re-executes per seed, N times, in one queued job. Same GPU cost, but each generation is its own run with its own Save Image, its own filename, and its own workflow embedded in the PNG. That last bit is the underrated part: every file records the seed that actually made it, so dragging one back into ComfyUI gives you the exact graph for that image rather than "the batch's seed, one of fifty".
The mechanism
The node sets OUTPUT_IS_LIST = (True, False). That flag is the whole trick - it tells the engine to hand the downstream chain one list element at a time instead of the list itself, so a KSampler wired to this node samples once per seed rather than once with a bigger batch. Not exotic machinery: it's what wildcard and iterative packs use too. It's just rarely applied to seeds, which is the value people most want to sweep.
The seeds themselves are built deliberately:
seed- the base. The node's own tooltips are worth reading, and this one says the actual seed gets written back into the widget after it's mapped into[min_seed, max_seed]. That's the anti-control_after_generatedesign. ComfyUI's stock seed widget fires after the run by default, which is how beginners lose the good seed they just found; here the widget, the node's live "Used Seed" line, andseed[0]all show the same number.mode-fixedrepeats the base every iteration,increment/decrementstep by the iteration index,randomizekeeps iteration 0 as the base and hashes the rest. Default israndomize, and read that one twice: it's a deterministic hash of the base, not a fresh random draw.offset- added to the base before range mapping. Handy for jumping to a new neighbourhood of seeds while keeping the base you liked written down.count- how many generations in the cycle. Default 1, and it goes up to 100000, which is a dare, not a feature.min_seed/max_seed- the allowed range, and the reason this node can do something stock nodes can't: negatives are legal, and the modulo wrap is negative-safe. Bounds swap themselves if you enter them backwards.
Outputs are just two: seed (the INT list) and seed_str, the same cycle as one comma-separated string. Wire seed into the KSampler - right-click its seed widget and "Convert widget to input", or drag a wire off it - and wire seed_str into whatever takes a name, so a run's files carry their whole cycle in the filename.
Install
ComfyUI Manager, search comfyui-AGSoft, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Art-xmaster/comfyui-AGSoft
then restart. The pack's requirements.txt pulls numpy, opencv-python and translators - none of which this particular node needs (random does the work), but you'll want them for the image and Translate nodes. The loader scans the folder and imports each file independently, logging failures instead of aborting, so one broken dependency doesn't take the seed node down with it.
Where people get bitten
randomize with a fixed base reproduces the same cycle forever. That's a feature - same base, same ten seeds, every time - but it surprises people who read "randomize" the way the stock dropdown means it. Want genuine variety between queued jobs? Press the frontend's 🎲 Randomize button (it rolls a new base) or bump offset.
Count larger than the range wraps. Set min_seed 0 and max_seed 9 with count 30 and you get three passes over the same ten seeds, because every seed is wrapped into range. If your sweep looks suspiciously repetitive, that's why.
Count multiplies with batch size. count 20 fed into an Empty Latent with batch_size 4 is eighty images. Pick one knob.
And the honest comparison: if you only need one seed and a readable record of it, rgthree's Seed node is lighter - it parks the last-used seed in the title bar. Reach for AGSoft Seed when you want the cycle itself: N seeds, N full runs, names and metadata intact.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| seed | INT | 0-9007199254740991–9007199254740991 | Base seed of the cycle (float64-safe bounds). The actual seed is written back here after mapping into [min_seed, max_seed]. --- Базовый сид цикла (float64-безопасные границы). После отображения в [min_seed, max_seed] сюда пишется фактический сид. |
| mode | COMBO | randomize | How cycle seeds vary: fixed repeats the base, increment/decrement shift by the iteration index, randomize hashes iterations > 0. --- Как меняются сиды цикла: fixed повторяет базу, increment/decrement сдвигают на индекс итерации, randomize хэширует итерации > 0. |
| offsetopt | INT | 0 | Value added to the base seed before range mapping. --- Значение, добавляемое к базовому сиду до отображения в диапазон. |
| countopt | INT | 11–100000 | Number of generations in the cycle (one run per seed). --- Число генераций в цикле (один запуск на сид). |
| min_seedopt | INT | -9007199254740991-9007199254740991–0 | Lower allowed bound for cycle seeds; may be negative. Bounds are auto-swapped if min > max. --- Нижняя допустимая граница сидов цикла; может быть отрицательной. Границы меняются местами, если min > max. |
| max_seedopt | INT | 90071992547409910–9007199254740991 | Upper allowed bound for cycle seeds. Bounds are auto-swapped if min > max. --- Верхняя допустимая граница сидов цикла. Границы меняются местами, если min > max. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| seed | INT | List of cycle seeds: downstream runs once per seed. First element equals the mapped base seed. --- Список сидов цикла: даунстрим выполняется по одному сиду. Первый элемент равен отображённой базе. |
| seed_str | STRING | The same cycle as a comma-separated string for filenames. --- Тот же цикл строкой через запятую для имён файлов. |