LLM Prompt Tags
Let an LLM write your booru tags — and keep the edits
- positive_prompt
- negative_prompt
- raw_response
You're on an anime SDXL model - Illustrious, NoobAI, WAI, a Pony merge - and you think in sentences, but the checkpoint only really listens to comma-separated Danbooru tags. You could sit there hunting for the right dutch angle variant, or you could hand the whole description to an LLM and let it do the tagging. That's what this node is for.
LLM Prompt Tags (class OpenAICompatiblePromptPair) takes a plain-English scene description, sends it to any OpenAI-compatible chat-completions API, and gets back two ready-to-use tag lists: a positive one and a negative one. Despite the pack name, it never looks at your images - nothing gets tagged visually. It tags prompts. It just saves you the drudgery of translating "silver-haired girl, winter coat, snowy city street at night" into something an anime checkpoint will actually respect.
How it works
The mechanism is small, and knowing it shapes every failure mode. The node POSTs to <api_base_url>/chat/completions (default https://api.deepseek.com/v1) with a system prompt, your user_prompt, and your fixed prefixes, asking for JSON in exactly this shape:
{ "positive": ["1girl", "silver hair", "winter coat", "night"], "negative": ["blurry", "text"] }
It parses the response, prepends your positive_prefix and negative_prefix, removes duplicates (case-insensitively), and hands you the finished strings. Nice detail: the whole thing is written against Python's standard library - urllib, no openai SDK, no requests. Zero Python dependencies to install, which is genuinely rare in this corner of the ecosystem, where LLM nodes usually drag in an SDK that then conflicts with everything else in your environment.
Inputs and outputs
You'll actually touch four things:
api_key- the one real setup step. Any OpenAI-compatible key works; the default endpoint is DeepSeek, so start there. Their API is cheap and a few dollars of credits goes a long way.user_prompt- your natural-language idea. This is the input you'll change between generations.positive_prefix/negative_prefix- fixed quality tags the model is told not to repeat. Note the defaults are Pony vocabulary:score_9, score_8_up, score_7_upmeans something on Pony and does nothing on Illustrious or NoobAI. If you're on those, swap inmasterpiece, best quality, very aesthetic.model- defaults todeepseek-reasoner. Fine, but see the gotcha below.
system_prompt is the author's built-in prompt tuned for anime and illustration models; if you're generating for a general or photoreal model, rewrite it, because the shipped one is designed to output short booru-style tags. temperature (0.2 default), max_tokens (up to 4096), and timeout_seconds are the knobs you'll rarely touch, and print_to_console dumps the prompts to your terminal for debugging.
The outputs are three strings: positive_prompt and negative_prompt wire straight into two CLIPTextEncode nodes, or into any string-processing node - that flexibility is the whole point of this variant over the conditioning one. raw_response is the untouched API reply, for when something smells off.
Install
Two ways, same result:
cd ComfyUI/custom_nodes
git clone https://github.com/longyijdos/ComfyUI-LLM-Prompt-Tagger
then restart ComfyUI. Or search ComfyUI-LLM-Prompt-Tagger in ComfyUI Manager and let it do the clone. There's no requirements.txt and no model download - this needs an API key, not a GPU.
Where people get burned
The default model is a reasoning model, and that's the trap. If max_tokens is set too low, DeepSeek spends the budget on "thinking" and returns nothing but reasoning_content - the node raises exactly that error, so bump max_tokens before you blame anything else. Blank api_key gets you an HTTP 401 from DeepSeek, and a model that ignores json_object and answers in prose gets you the JSON parse error (the message previews the response, so you can see what it actually said). All survivable - this is a small, single-file node, and when something breaks, the error text tells you which of the three it was.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| api_base_url | STRING | https://api.deepseek.com/v1 | — |
| api_key | STRING | — | |
| model | STRING | deepseek-reasoner | — |
| user_prompt | STRING | A silver-haired girl wearing a winter coat stands on a snowy city street at night, shown in an upper-body shot with warm street lights in the background. | — |
| positive_prefix | STRING | score_9, score_8_up, score_7_up, rating_safe | — |
| negative_prefix | STRING | score_4, score_5, score_6, bad anatomy, worst quality, low quality | — |
| system_prompt | STRING | You convert natural-language image requests into Stable Diffusion prompts for anime and illustration models. Return JSON only, with this exact shape: { "positive": ["tag 1", "tag 2"], "negative": ["tag a", "tag b"] } Rules: - Output short English tags only, not prose sentences. - Prefer booru-style tags and tag fragments that work well in image models. - Put subject, clothing, environment, pose, camera angle, and composition in positive. - Put defects and unwanted artifacts in negative. - Add simple count tags when clear, such as 1girl, 1boy, solo. - Prefer camera/view tags like low angle, from below, close-up, upper body, cowboy shot, desk view. - Do not invent expression, lighting, pose, or background details unless the user request clearly implies them. - Do not repeat tags already supplied in the fixed positive_prefix or negative_prefix. - Do not include explanations, markdown, numbering, or extra keys. - The examples below show only the generated tags, not the fixed prefixes. Example 1 User request: A silver-haired girl wearing a winter coat stands on a snowy city street at night, shown in an upper-body shot with warm street lights in the background. Output: { "positive": ["1girl", "solo", "silver hair", "winter coat", "snow", "city street", "night", "upper body", "street lights"], "negative": ["blurry", "watermark", "text"] } Example 2 User request: Draw a blue-haired female mage wearing a large hat, holding a staff, standing in a forest. Output: { "positive": ["1girl", "solo", "blue hair", "mage", "witch hat", "holding staff", "forest", "standing"], "negative": ["blurry", "bad hands", "watermark", "text"] } Example 3 User request: A cyberpunk boy standing on a rainy night street, upper-body shot, neon lights in the background. Output: { "positive": ["1boy", "solo", "cyberpunk", "rainy night", "street", "upper body", "neon lights", "city"], "negative": ["blurry", "extra fingers", "watermark", "text"] } | — |
| temperature | FLOAT | 0.200–2 | — |
| max_tokens | INT | 409664–4096 | — |
| timeout_seconds | INT | 605–600 | — |
| print_to_console | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| positive_prompt | STRING | — |
| negative_prompt | STRING | — |
| raw_response | STRING | — |