Step 2: Clustering Analysis
Group your prompt phrases by meaning, not spelling
- summary
- cluster_dir
Step 2: Clustering Analysis is where your prompt data stops being a heap of near-duplicate phrases and becomes organized groups. It takes the JSON from Step 1, and for every dimension it embeds the extracted phrases, reduces them, and clusters them with HDBSCAN so "soft film grain texture", "film-like texture with subtle grain", and "natural film grain" all end up in one pile. Then Step 3 turns each pile into a dictionary entry.
If you only use the prompt composition nodes, you never touch this one. It exists purely for people building their own dictionaries - and it's the one node in the pack with real hardware and download requirements, so read this before you run it.
How it works
The pipeline is the classic embedding-clustering stack, straight from the source (tools/step2_clustering.py):
- Each dimension's extracted phrases are deduplicated.
- Every unique phrase is embedded with
BAAI/bge-small-en-v1.5, a small sentence-transformer. On first run it's downloaded from Hugging Face into your ComfyUI models folder if it isn't already there - this is the step that needs network access. - Embeddings are reduced with UMAP (cosine metric), then clustered with HDBSCAN (leaf selection method).
- Whatever HDBSCAN marks as noise gets a second, looser clustering pass if there's enough of it (≥10 noise items) - that's the "noise recluster" toggle.
- Results are written per dimension to
output/step2_clusters/<dim>/<dim>_clusters.json.
Everything runs on your machine - CPU works but it's slow; the code prefers CUDA automatically if torch sees a GPU.
The inputs that matter
- input_json - the path to a Step 1 JSON file. Note the default in the schema points at a bundled
data/02_merged_normal_*.jsonfrom the author's own workflow, so change it to your actual Step 1 output. - enable_noise_recluster - leave it on. Without it, all the oddball phrases HDBSCAN couldn't fit sit in a "noise" bucket and become useless.
- primary_min_cluster_size / primary_min_samples - how big and how dense a cluster has to be to count. Defaults are 6 and 3. If your output is nothing but noise, raise... actually lower
min_cluster_sizeto let smaller groups form; if everything collapses into one blob, raise it. - noise_min_cluster_size / noise_min_samples - the looser settings for that second pass (defaults 4 and 2).
Outputs are summary (a markdown table with per-dimension cluster counts, noise rates, and timings) and cluster_dir, the folder Step 3 reads.
Install and the dependency warning
cd ComfyUI/custom_nodes
git clone https://github.com/jinxishe/ComfyUI-PromptEngine
pip install -r requirements.txt
That requirements.txt is where it gets real. The composition nodes only need openai and tqdm, but Step 2 additionally pulls in sentence-transformers, umap-learn, hdbscan, numpy, and torch. If you already run ComfyUI you have torch; the rest are small. The model download on first run is a few hundred MB.
Gotchas
- First run needs internet to fetch the embedding model; after that it's loaded from
local_files_only. - Small datasets behave oddly: under a size threshold the node gives up and dumps everything into a single cluster rather than forcing splits. If you're clustering a handful of prompts, expect one sad bucket per dimension.
- It's a background job, not a live thing. Large corpora mean minutes of UMAP/HDBSCAN churn with a progress bar, so run it once per batch rather than fiddling live.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| input_json | STRING | data/02_merged_normal_20260211_001-026.json | — |
| enable_noise_reclusteropt | BOOLEAN | true | — |
| primary_min_cluster_sizeopt | INT | 62–20 | — |
| primary_min_samplesopt | INT | 31–20 | — |
| noise_min_cluster_sizeopt | INT | 42–10 | — |
| noise_min_samplesopt | INT | 21–10 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| summary | STRING | — |
| cluster_dir | STRING | — |