String Function π§
A tiny Python sandbox that writes your prompts for you
- STRING
Prompt engineering in ComfyUI is mostly "type text into a box," and that works fine until you want the text to be generated - randomized, formatted, or assembled from parts. That's the gap this node fills. It runs a snippet of Python and turns whatever the snippet returns into a STRING you can feed straight into a CLIP Text Encode node. If you've ever wanted a prompt that picks a random hair color or builds a sentence from a list, this is the easiest way to get it.
How it works
The python_code input is a chunk of Python that gets wrapped in a function and executed, with the string it returns becoming the output. Three optional inputs - a, b, c - are injected as variables with those names, so you can mix fixed strings (wired from other nodes or typed into the fields) with generated content. The modules random, re, numpy (as np) and json are already imported, so the example from the README works as-is:
colors = ["red", "orange", "yellow", "green", "blue", "purple"]
return "a girl with %s hair and %s eyes wearing %s maid costume" % (
random.choice(colors), random.choice(colors), a
)
Wire a to a prompt fragment and you get a new variation on every execution.
There are guardrails, and you should know exactly what they are. The node strips eval and exec from the builtins it exposes, and it rejects any python_code containing the literal text import. What that does not mean is that it's safe - it's still arbitrary Python execution on your machine, which is why the README carries an explicit warning: if you load a workflow from someone you don't fully trust, review the python_code before running it. This is the same class of risk the whole custom-node ecosystem lives with, and the ComfyUI_LLMVISION malware incident is the canonical reminder of why you take it seriously.
The inputs that matter
python_code- the snippet. Returns the output string.a,b,c- optional string inputs, accessible as variables in the snippet.- Output: a single STRING.
Because the output is a plain STRING, it composes with everything - a CLIP Text Encode node, another String Function, or the pack's OpenAI Translate node if you want a random prompt generated in English from a non-English base.
Installing it
It's in ComfyUI-NegiTools. Use ComfyUI Manager (search "ComfyUI-NegiTools") or:
cd ComfyUI/custom_nodes
git clone https://github.com/natto-maki/ComfyUI-NegiTools
pip install -r ComfyUI-NegiTools/requirements.txt
then restart. No API key needed - this one is fully local.
Where it shines
The author of this pack clearly built it for a specific workflow: natto-maki's own ComfyUI dialogue game chains GPT for scriptwriting and DALL-E3 for art, and prompt assembly like this is exactly the glue that workflow needs. For you, the sweet spot is batch variation - a prompt that randomizes a few attributes per run, or a template that inserts a seed-dependent word to make each generation feel fresh. If that sounds like a niche, it is. But when you need it, it beats building the same logic out of a stack of string-concatenation nodes.
One last note: the node re-executes on every run (it forces a change), so the randomness actually triggers - no caching surprises. If your snippet returns something that isn't a string, you get an empty string rather than a crash, which is lenient but can be confusing; keep your return statements returning text.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| python_code | STRING | return "a text" | β |
| aopt | STRING | β | |
| bopt | STRING | β | |
| copt | STRING | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | β |