Text Embeddings Interrogator
Ask how close two prompts really are, in your CLIP model's own terms
- CLIP_1
- CLIP_2
- Output string
Text Embeddings Interrogator is the pack's one genuinely clever node. It takes two (CLIP, text) pairs, encodes both texts, and reports two numbers: the cosine similarity and the Euclidean distance between their pooled embeddings. In plain English: how similar are these two prompts, as judged by the very text encoder your model uses?
That "as judged by the text encoder" part is the whole point. Words like "cat" and "feline" score close even though they share no letters; "cat" and "dog" land further apart even if a human thinks they're both pets. It's a window into what the model actually understands, which makes it a genuinely useful debugging and prompt-tuning tool rather than a party trick.
How it works
The mechanism is grounded in how CLIP encodes text. The node tokenizes each text, runs it through the CLIP model you've wired in, and pulls the pooled attention output - the fixed-length summary vector that represents the whole prompt, rather than the per-token embeddings. Then:
- Cosine similarity = dot product of the two normalized vectors. Ranges from −1 to 1; 1 means identical direction, 0 means unrelated, −1 means opposite. This is the number to quote - it's scale-invariant, so "0.9" means "essentially the same prompt" regardless of how long each string is.
- Euclidean distance = L2 norm of the difference. Unbounded, and it grows with text length, so treat it as a secondary check. Two long prompts about the same thing can still have a big raw distance; cosine is the comparable one.
Results print to the console in yellow (the pack's house style) and come out as a STRING named "Output string", formatted like Cosine Similarity: 0.87, Euclidean Distance: 5.31, so you can feed it into a metadata saver if you're benchmarking prompts across runs.
The inputs that matter
- CLIP_1 / CLIP_2 - two CLIP model inputs. You can split one CLIP with a reroute for a simple comparison, or use two different CLIPs to compare how differently they rate the same text (interesting, though the pooled-output shapes need to match).
- Text_1 / Text_2 - the two prompts, plain strings.
Where it actually helps
- Negative-prompt sanity check. Feed your positive prompt and your negative prompt through the same CLIP. A cosine similarity of 0.8 means your "negative" is semantically hugging your positive - you're fighting yourself. A near-zero or negative value means the negative is pulling somewhere genuinely different.
- Prompt ablation. Testing how much a tag actually changes meaning? Compare
"masterpiece, best quality, cat"against"cat"- the delta quantifies what your quality tag is really contributing (hint: often very little on modern models). - Checking regional prompting. If you're building separate conditioning for regions, this tells you whether two regional prompts are accidentally describing the same thing.
A hard limit you need to know
The README labels this "SDXL & 1.5 only for now." The node reaches into the encoding dict for the pooled_output key, which is a CLIP-era structure. Flux and the other modern T5/Qwen-encoder models don't produce pooled text embeddings the same way - hook a Flux CLIP up and this will error or hand you nonsense. If you're on SD1.5/SDXL (or derivatives like Pony/Illustrious), it's fine. On anything newer, sit tight.
Installing it
Part of the ComfyUI-StringsAndThings pack. ComfyUI Manager: search "ComfyUI-StringsAndThings" → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/PressWagon/ComfyUI-StringsAndThings
No model downloads - you supply the CLIP model from your own checkpoint, as you already do for CLIPTextEncode.
Caveats
- SDXL/1.5 only, as above - the single most likely thing to trip you up.
- It's an output node, so it forces its branch to execute and prints to the console (not the UI) in addition to the string output.
- The numbers only mean something relative to each other, not absolutely. A cosine of 0.6 between prompts in one model is not comparable to 0.6 in another model. Benchmark within one CLIP and don't cross-compare.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| CLIP_1 | CLIP | — | |
| Text_1 | STRING | — | |
| CLIP_2 | CLIP | — | |
| Text_2 | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Output string | STRING | — |