visualtoprompt.com

A ComfyUI prompt from an image: one text box, two weight parsers

The generated line carries no brackets at all, so the node reads 336 characters as one unweighted chunk — and six of nineteen bracket forms mean something different to the node than they do to this site’s checker.

One input box on the left, its line forking into two different measuring tools on the right.
One input box on the left, its line forking into two different measuring tools on the right.

A ComfyUI prompt from an image goes into one field: text on a CLIPTextEncode node. That node has two inputs, text and clip, and neither of them is a weight — every weight has to be written inside the string itself. A prompt generated from a picture arrives as a comma list with zero bracket characters anywhere in it, so the node’s parser hands the whole line to the tokenizer as one chunk at weight 1.0: 336 characters, 45 words, 16 commas, one chunk.

The number that matters is not 336. It is that this site’s checker calls the same line 17 separate weighted terms, and the node calls it one. Both counts are correct for their own parser, and the two parsers are not the same parser. Nineteen bracket forms were put through both; thirteen read identically, six do not.

Where the text actually goes

ComfyUI ships a default text-to-image workflow in its repository as an API-format JSON. Eight nodes, ids 3 to 9, and the prompt lives in exactly two of them:

The two prompt nodes in the shipped default workflow, with their fields as written in the repository’s own example file.
Node idclass_typeInputsValue in the shipped example
6CLIPTextEncodetext, clip"masterpiece best quality girl" — and clip is ["4", 1]
7CLIPTextEncodetext, clip"bad hands" — and clip is ["4", 1]

Both nodes take the same input: ["4", 1], which means the output at slot 1 of node 4. Node 4 is CheckpointLoaderSimple, and it returns three things in a fixed order — MODEL at slot 0, CLIP at slot 1, VAE at slot 2. So the positive box and the negative box are wired to the same CLIP, and slot 2 is what the decoder at node 8 gets instead. The node itself is thin: encode() tokenises the string and hands the tokens on. Nothing in the node interprets your brackets.

Look at the text the example ships with. masterpiece best quality girl is 29 characters, four words, zero commas and zero brackets. The line this site writes for the same node is 336 characters, 45 words, 16 commas and still zero brackets. The comma list is a shape the node has never been asked to read in its own documentation.

One line, two rulers

Nine lines were generated from the three sample pictures this site keeps for testing, at all three length settings, and each one was fed to both parsers. The line that comes out of the generator has no brackets in any of the nine — and that single fact is the whole result on the node side.

The same nine generated lines, counted by both parsers. The site splits on commas; the node splits on parentheses only.
PictureLengthLine (chars)WordsCommasBracket charsSite termsNode chunks
night-fireworksshort18023110121
night-fireworksmedium28438140151
night-fireworkslong33645160171
strong-backlightshort17522110121
strong-backlightmedium25634140151
strong-backlightlong30841160171
text-screenshotshort18423100111
text-screenshotmedium25233150161
text-screenshotlong28337160171

Why there are no brackets is a one-line fact about the composer rather than a guess. src/compose.js contains 47 string literals and not one of them contains a bracket character — not a round one, not a square one, not a curly one. There is no code path that could emit a weight marker, so the output is always plain text at weight 1.0 everywhere. On the node side that is harmless: an unweighted line is a legal line. It just means nothing in the line is emphasised, and the site’s own seventeen-term count is a reading of comma positions that the node never performs.

The four shapes through the other parser

The generator writes four different shapes for the same picture. All four reach the node as a single chunk, because none of the four contains a bracket either — but one of them carries something else the node will happily tokenise:

One picture, longest setting, four output shapes, through both parsers.
ShapeCharsWordsSite termsSite: out of rangeNode chunksFlag reaches the tokenizer?
midjourney319441511yes — --ar 16:9 is inside the chunk
sd336451701no
flux27339701no
dalle219311001no

The Midjourney row is the one to read carefully. This site’s checker flags it, because the trailing --ar 16:9 looks to a comma-and-colon parser exactly like an explicit weight of 9. The node’s parser does not flag it and does not strip it: the flag stays in the chunk as ordinary characters and goes to the tokenizer with everything else. So an aspect flag pasted into a ComfyUI text box does not set an aspect ratio and does not raise an error — it becomes words the model reads. Aspect in ComfyUI is set by the width and height fields on EmptyLatentImage, which is a different node entirely.

Nineteen forms, two answers

Both parsers were given the same nineteen strings. Thirteen came back with the same number; six did not.

One term, nineteen spellings, both parsers. “Site” is this repository’s parsePrompt(); “node” is the weight parser from ComfyUI’s comfy/sd1_clip.py, copied verbatim and run locally.
Written asSite readsNode reads
dog1.01.0same
(dog)1.11.1same
((dog))1.211.21same
(((dog)))1.331.33same
(dog:1.3)1.31.3same
((dog:1.3))1.431.3differs
(((dog:1.3)))1.571.3differs
[dog]0.911.0 — text is [dog]differs
[[dog]]0.831.0 — text is [[dog]]differs
[dog:1.3]1.31.0 — text is [dog:1.3]differs
{dog}unknown1.0 — text is {dog}differs
(dog:1.9)1.91.9same value
(dog:0.1)0.10.1same value
(dog:5.0)5.05.0same value
(dog:abc)1.11.1same
\(dog\)1.0, text (dog)1.0, text (dog)same
(a:1.3:1.5)1.5, text a:1.31.5, text a:1.3same
(dog 16:9)9.0, text dog 169.0, text dog 16same
(16:9 dog)1.11.1same

Read the same rows and a pattern shows up. Every disagreement involves a square bracket, a curly brace, or a round bracket sitting directly outside an explicit weight. Plain nesting, explicit weights, escapes, malformed weights and ratio-shaped text all behave identically on both sides — including two cases that are wrong in the same way on both sides, where (dog 16:9) becomes a weight of 9 with the text truncated to dog 16 and (16:9 dog) becomes an ordinary 1.1.

The six that differ, and why

A bracket outside an explicit weight compounds on this site and is overwritten by the node. When the node’s parser meets a bracket group, it multiplies the incoming weight by 1.1, then looks for the last colon inside the group and, if the text after it parses as a number, assigns that number instead of multiplying by it. One bracket around dog:1.3 therefore lands on 1.3, not 1.43 — and a second bracket does not change it either. This site’s parser instead multiplies the explicit weight by every bracket that encloses it, so the two counts pull apart as the nesting deepens: 1.3, then 1.43, then 1.57.

Nesting depth, both parsers. The round-bracket column is identical all the way down; the square-bracket column is not.
DepthSite: (((…)))Node: (((…)))Site: [[[…]]]Node: [[[…]]]
11.11.10.911.0
21.211.210.831.0
31.331.330.751.0
41.461.460.681.0
51.611.610.621.0
61.771.770.561.0

Square brackets are not weight syntax to the node at all. This site’s parser divides by 1.1 per level, so [dog] is 0.91 and six levels of them take a term down to 0.56. The node’s parser only ever looks at round brackets; a square one is an ordinary character that stays in the text and is tokenised along with the word. That is why the node column is a flat 1.0 for all six depths — and why pasting [blurry] into a ComfyUI text box does not de-emphasise the word, it feeds the model a token for the bracket itself.

Braces are the one place where this site refuses to answer and the node answers anyway. Curly braces belong to a different engine whose per-level multiplier this repository does not reproduce, so its parser returns unknown rather than inventing a number, and its range check skips such terms. The node’s parser has no brace rule either, so it reports 1.0 and leaves {dog} in the text. Both parsers are declining to interpret braces; only one of them says so.

The node’s own documentation lists three things its text box understands beyond plain words: an embedding:name reference to a file in models/embeddings, bracket weights, and a random-pick form written {day|night|morning}. The generated line uses none of the three, and the parser function above does not expand the braces — it passes them through. Whichever layer handles the random pick, it is not the weight parser.

The two extremes, on a real line

Weighting in the node happens where you put the bracket, and a chunk ends only at a round bracket — never at a comma. That makes the two obvious edits behave very differently from what a comma-counting habit predicts:

The 336-character line, wrapped two ways.
EditCharsSite termsNode chunksNode chunks carrying a weight
one pair of brackets around the whole line33817, all at 1.111 — the entire line
seventeen pairs, one per comma-separated term37017, all at 1.13317 — plus 16 leftovers

Wrap the whole line once and the node sees one chunk at 1.1, which raises everything uniformly — the same outcome the site describes, arriving through a completely different bookkeeping. Wrap all seventeen terms separately and the node reports 33 chunks, because the comma-and-space between each pair of bracket groups becomes a chunk of its own with nothing to weight. Sixteen of those thirty-three carry no weight at all; they are punctuation. Nothing breaks, but a phrase-level weight and a term-level weight are not the same edit in the node, and the site’s term count is not a list of the places you can put one.

The other place ComfyUI keeps a weight

The text box is only half the story. In the node inventory of the shipped build, 18 of 65 nodes carry a field whose job is a weight — strength, multiplier, strength_model, strength_clip, conditioning_to_strength, blend_factor, scale_by, cfg, denoise. The cleanest of them is ConditioningSetAreaStrength, whose entire input list is conditioning and strength: a node that exists to multiply a conditioning, with no text involved anywhere.

So there are two independent weight systems in the same graph. One lives inside the string and is parsed by the code above. The other lives on the nodes and is a number in a field. A line generated from a picture feeds the first one and, because it contains no brackets, arrives with every term at 1.0. It never touches the second one at all — there is no field in it that says strength. Before you hand that string to a render, it is worth knowing what it is actually carrying: how much of a generated line is measured off your file, and what the generator has to supply instead.

What this means when you paste

Four questions from the node side

Four questions, captured on 2026-10-02 — three People also ask boxes and one paired suggestion. Each answer is either a count from the nine lines above or a field name read out of the node source.

How to prompt for ComfyUI?

Write into the text field of a CLIPTextEncode node, and put the weighting inside that string — the node has no weight input to use instead. From a picture, generate the Stable Diffusion shape and paste it whole: 336 characters, 45 words, 16 commas, no brackets, and the node reads it as one chunk at weight 1.0. Then wrap only the phrase you want to move, remembering that a chunk ends at a bracket and not at a comma.

How to get prompt from ComfyUI image?

Not from the graph — the graph stores the text you typed, not a description of the picture. To go the other way, measure the image: this tool reads the file on a 192 × 192 grid in your browser and writes a prompt back, in four shapes. That prompt is the thing you paste into node 6, and it is the reason the text box in the shipped example is four words long while a generated line is forty-five.

Can you provide some examples of prompts for ComfyUI?

The same fireworks frame, pasted into the text field with nothing changed: masterpiece, best quality, widescreen 16:9 composition, dark, low-key lighting, dominant palette of navy, grey, slate, silver, vivid, saturated colour, cool blue colour temperature, medium contrast, highly detailed with intricate texture, light falling on the centre with darker edges, brighter upper half, moody and dramatic atmosphere — 336 characters, seventeen comma-separated terms to this site’s parser, one unweighted chunk to the node’s.

What are the top 10 AI prompts?

There is no top ten that survives a change of picture, because the wording here is arithmetic on the file rather than a house style. What is worth memorising is the shape: a comma list of measured phrases, two fixed quality tags at the front, no brackets anywhere, and the subject noun — the one thing no measurement can supply — placed first. That shape pastes into any of the four targets, and in a ComfyUI text box it arrives at weight 1.0 throughout.

On this site’s side of the fence the arithmetic is on how to weight a prompt and write a negative; the shape most ComfyUI checkpoints were trained on is where the weights go in a Stable Diffusion prompt; the two shapes that end in sentences rather than commas are the Flux prompt and the ChatGPT image prompt; and which images it handles badly is where measuring fails before any of this matters.