TagRAG Prompt
Type an idea, get a ComfyUI prompt — built from your own tag library
- positive_prompt
- negative_prompt
- retrieved_tags
- status
This is the node that makes the TagRAG pack worth installing. You type a rough idea like nekomimi blue portrait, and TagRAG Prompt retrieves matching tags from your CSV, stuffs them into a one-shot prompt, runs a local LLM, and hands back a positive_prompt you can wire straight into a CLIP Text Encode node - plus a negative_prompt and the raw retrieved tags.
Prompt enhancement by local LLM is an old idea by now; the community has been doing it for years (the "prompt enhancer" pattern went from 12 mentions in 2023 to 253 in the first half of 2026, per our KB). What's different here is where the tags come from. Most enhancers ask the model to invent detail. This one retrieves detail from a dataset you curate, which means the output stays anchored to tags your checkpoint actually responds to instead of the model's generic idea of what looks good.
How it works
It's a pipeline in one node. Give it an index_ref from TagRAG Index and it reloads the CSV itself, retrieves top_k tags (default 10) using lexical, semantic, or hybrid search, then formats everything into the pack's one-shot template: "Retrieve relevant tags from the provided tag dataset and combine them into a detailed, coherent prompt. Output the positive prompt first, then a negative prompt if applicable."
The detail that makes it usable is the label splitting. A raw chat LLM will happily wrap your prompt in "Here is your enhanced prompt:" or role markers - and all of that scaffolding would land in your conditioning if nothing stripped it, which is the classic failure mode of LLM prompt nodes. TagRAG Prompt tells the model to emit positive prompt: and negative prompt: labels and then splits the reply on them. The chat habits get cut before they touch your sampler.
Backends matter: generation_backend defaults to llama_cpp_python, which loads a local GGUF (your model_path) in-process. If you already run a llama.cpp server, switch to llama_server and set base_url (default http://127.0.0.1:8080) - it avoids loading a second copy of the model. Either way, no cloud and no API key. The name might sound like it calls some hosted RAG service; it doesn't.
Inputs that matter
- idea - your rough prompt idea. This is the whole job.
- index_ref - the JSON string from TagRAG Index.
- model_path - a local GGUF, required for native generation.
- top_k - how many tags to retrieve (default 10).
- generation_backend -
llama_cpp_python(default) orllama_server. - max_tokens / temperature - defaults of 512 and 0.7 are fine to start.
Outputs
positive_prompt (wire into your positive conditioning), negative_prompt, retrieved_tags (what got pulled from your CSV), and status - which conveniently includes the retrieval mode, how many tags matched, and a short raw-response snippet for debugging. Read the status string before touching anything else when something looks off.
Install
ComfyUI Manager - search comfyui-tag-rag - or:
cd ComfyUI/custom_nodes
git clone https://github.com/FrostySDXL/comfyui-tag-rag
cd comfyui-tag-rag
pip install -r requirements.txt
Restart after installing. The heavy one in requirements.txt is llama-cpp-python: its wheels are platform/CUDA-specific and installs fail on some setups, which is exactly why the llama-server path exists as an escape hatch. Nothing downloads a model - you supply the GGUF. A blank or missing model_path returns an error status, not a silent fetch.
Where people get burned
ERROR: llama-server request failed- the server isn't reachable atbase_url, or the model isn't loaded in it. Use the base URL only (http://127.0.0.1:8080), not the full endpoint.model_patherrors -llama-cpp-pythonisn't installed or the path doesn't point to a readable GGUF. Install it for your platform or switch backends.- The negative prompt does nothing. Not the node's fault - a negative only has effect when your checkpoint runs CFG above 1. On guidance-distilled models at CFG 1 it's discarded entirely, so don't blame the splitter.
- Thin CSV, thin prompt. The retrieval is only as good as your dataset. The LLM here is a formatter working from your tags, not a tag encyclopedia.
It's pre-alpha (0.1.0a0, one-commit repo), so expect rough edges - but this one node is the reason to have the pack at all.
Inputs (27)
| Name | Type | Default | Description |
|---|---|---|---|
| ideaopt | STRING | — | |
| index_refopt | STRING | — | |
| base_urlopt | STRING | http://127.0.0.1:8080 | — |
| allow_remote_base_urlopt | BOOLEAN | false | — |
| retrieval_modeopt | COMBO | from_index | 4 options: from_index, lexical, semantic, hybrid |
| embedding_backendopt | COMBO | from_index | 3 options: from_index, llama_cpp_python, llama_server |
| embedding_model_pathopt | STRING | — | |
| embedding_n_ctxopt | INT | 2048256–262144 | — |
| embedding_n_gpu_layersopt | INT | -1-1–200 | — |
| embedding_base_urlopt | STRING | — | |
| embedding_modelopt | STRING | — | |
| embedding_endpoint_styleopt | COMBO | from_index | 3 options: from_index, openai_compatible, llama_cpp_legacy |
| generation_backendopt | COMBO | llama_cpp_python | 2 options: llama_cpp_python, llama_server |
| modelopt | STRING | — | |
| model_pathopt | STRING | — | |
| chat_formatopt | STRING | llama-2 | — |
| n_ctxopt | INT | 2048256–262144 | — |
| n_gpu_layersopt | INT | -1-1–200 | — |
| top_kopt | INT | 101–100 | — |
| max_tokensopt | INT | 5121–4096 | — |
| temperatureopt | FLOAT | 0.700–2 | — |
| top_popt | FLOAT | 0.950–1 | — |
| top_k_samplingopt | INT | 400–400 | — |
| repeat_penaltyopt | FLOAT | 1.101–5 | — |
| seedopt | INT | -1-1–2147483647 | — |
| timeout_secondsopt | FLOAT | 301–300 | — |
| system_prompt_overrideopt | STRING | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| positive_prompt | STRING | — |
| negative_prompt | STRING | — |
| retrieved_tags | STRING | — |
| status | STRING | — |