System One Choice
Let the Model Pick a Branch — With a Chicken-Out Option
- backend
- choice
- confidence
- confident
- report
You write one prompt, and the picture that comes out is anime. You meant watercolor. System One Choice is the node that reads the prompt first and tells the graph what it's actually looking at, so the sampler can be pointed at the right style before it wastes a run.
It's also the cleanest example of the plumbing doc's thesis in a real pack: ComfyUI stops being a pipeline and becomes a small program, and a natural-language judgment is now a value you can wire.
How it works
The node takes your text, your question, and a list of options, and sends the backend a typed choice question - instructions plus a criteria map of label → description. The model answers with one label, a confidence, and a full probability spread over every option. That last part is the useful bit: you get to see, on the node itself, that it thought "anime 0.65, photo 0.20" rather than just being told which one won.
Then the gate: if confidence lands below min_confidence, the node returns your fallback instead and sets confident to false. That's the whole design goal - an unsure model never picks a branch on a coin flip.
One detail from the source that isn't obvious from the README: if you leave fallback empty, an unconfident answer passes through anyway. The fallback only exists if you fill it in.
Inputs and outputs
backend- from System One Backend. Required.state- what the model reads. Usually your prompt. If the text parses as a JSON object or array it gets sent as structured state instead, which is how you'd hand it a dict of shot parameters.instructions- the question. Be specific and narrow; vague questions get vague confidences.options- one per line,label: descriptionor justlabel.min_confidence- 0 to 1, default 0.fallback- the string returned when it isn't confident.
Outputs: choice (STRING), confidence (FLOAT), confident (BOOLEAN), and report (STRING) - JSON with the question, the raw answer, the backend name, and the latency, which is what you want when a run does something weird at 2am.
Wiring it
choice almost never goes straight into a sampler. It goes into a System One Map, which turns the label into prompt text, and that text gets appended to your positive prompt. The confidence output is the one people forget - put it on a Display or a note node while you're tuning, because on Laya it's the number that tells you whether the routing is real.
Want the side-by-side demo from the README? Two Backend nodes, one on laya and one on jev, feeding two Choice nodes with identical settings. Same prompt, two answers, no rewiring when you switch.
The two traps
Option parsing. At least two options, one per line, and the label is everything before the first colon. A label with a colon in it gets silently split at the colon and the tail becomes the description. Duplicate labels raise Duplicate option label: 'photo'. If you see that error, you probably fat-fingered a line break.
Confidence, on Laya. This is the number the whole node hinges on, and the README's own tests are the cautionary tale: on prompts that imply a style through a reference rather than naming it ("in the style of Studio Ghibli", "loose wet-on-wet brushwork"), Laya's top answer was right 7 times out of 8 but came in under 0.5 confidence on four of them. With min_confidence at 0.5 the node routed 3 of 8 to the intended style and sent the rest to photo. Those same 8 prompts went to Jev, which answered all 8 correctly at 0.99+. So: local and free for prompts that say the word "watercolor", hosted when the style is implied. Laya's confidence is also explicitly uncalibrated, so tune min_confidence on your own prompts rather than trusting a magic number from a README.
Also worth knowing: Laya reads at most 512 tokens of your state, and all your option labels share a 192-token budget. Long descriptions of six options will get truncated somewhere you can't see.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/dante01yoon/ComfyUI-SystemOne
pip install -r ComfyUI-SystemOne/requirements.txt
Or search System One in ComfyUI Manager. The requirements file is a single line (laya>=0.3.24); Jev needs TYPESAFE_API_KEY exported in the shell that launches ComfyUI, and Clef needs CLOUDFLARE_ACCOUNT_ID plus CLOUDFLARE_API_TOKEN.
Why you'd actually use this
The README's demo routes style, which is the obvious use. The less obvious ones are all the same shape: which upscaler should this prompt get, is this a photo or an illustration, does this description belong in the "portrait" bucket or the "landscape" bucket, which of five LoRA-trigger styles is being asked for. Anything where you currently eyeball a prompt and adjust a widget by hand is a candidate - with min_confidence set so the model can hand the decision back to a sane default when it doesn't know.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| backend | SYSTEMONE_BACKEND | — | |
| state | STRING | What the model looks at: plain text, or a JSON object/array. | |
| instructions | STRING | The question to answer about the state. | |
| options | STRING | One option per line: 'label: description' or just 'label'. | |
| min_confidence | FLOAT | 0.000–1 | — |
| fallback | STRING | Returned instead of the choice when confidence is below min_confidence. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| choice | STRING | — |
| confidence | FLOAT | — |
| confident | BOOLEAN | — |
| report | STRING | — |