LLM Node
One rough idea in, an enhanced prompt plus two search queries out
- clip
- cond
- pose_query
- style_query
The LLM Node is the front half of a local RAG experiment, and it's the node with the ideas. You type "female warrior standing on a cliff at sunset" and a local LLM - Ollama running qwen2:7b by default - rewrites that into a proper SD/SDXL prompt, then splits off two separate short search queries: one describing only the pose, one describing only the style. Those queries feed the pack's DB Load Node, which retrieves a pose reference and a style reference to drive ControlNet and IP-Adapter respectively.
That split is the clever part, and it's a genuinely different take on RAG. Most prompt-enhancer nodes (and there are a lot of them now - local LLM prompt enhancement is a mainstream ComfyUI pattern) just rewrite your text into something the encoder likes. This one treats your prompt as a search problem too: instead of one generic retrieval, you get functionally different queries targeting two different reference pools. An LLM writing an instruction for an LLM-based encoder is the standard trick; an LLM decomposing a request into ControlNet-shaped and IP-Adapter-shaped queries is the research-y part.
How it works
Under the hood (services/llm_service.py) it's a single HTTP call:
POST http://localhost:11434/api/generate
with your prompt wrapped in a big system-style instruction that demands JSON - exactly three fields: final_prompt, pose_query, style_query - at temperature 0.2, streaming off, 120-second timeout. The response gets scraped for the JSON object (it strips markdown fences and grabs between the first { and last }), validated, and both queries get truncated to 20 words if the model got chatty.
The node then does something that makes it a drop-in replacement for a CLIP Text Encode: it takes the clip input you wired in, tokenizes final_prompt, and encodes it straight to a CONDITIONING output. No extra encode node needed.
If Ollama is down, it degrades gracefully instead of crashing - the fallback returns your original prompt unchanged and uses it as both queries. You'll see [LLMService] Using fallback result in the console. It keeps the graph running, but with zero enhancement and two identical, generic queries.
The inputs and outputs
user_initial_prompt- multilineSTRING, your rough idea. That's it for the prompt side.clip- aCLIPinput, wired from your checkpoint loader. Its tooltip is plain: "The CLIP model used for encoding the text." This is the encoder for the final prompt's conditioning.
Outputs:
cond(CONDITIONING) → positive input of a KSampler.pose_queryandstyle_query(STRING) → wire both into the DB Load Node.
Installing and running it
Manager search ComfyUiRagCustomNodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Santat2023/ComfyUiRagNodes.git
Restart, find the MyNodes category. Then you need Ollama and the model:
ollama pull qwen2:7b
Where people get burned
- The
config.jsonin the README does nothing. The README walks you through creating a config with Ollama/OpenAI/Yandex providers, but the shipped code never reads it.LLMService()is constructed with hardcoded defaults:http://localhost:11434andqwen2:7b. If you want a different model or endpoint, you're editing the source inservices/llm_service.py, not the config file. The README rots; the code is the truth. - It's a cold API call every run. Each execution waits on a full Ollama generation (up to 120s). A 7B model on a mid GPU is a few seconds, but a bigger model means a real pause before sampling even starts.
- Output quality rides on JSON discipline. Small local models occasionally wrap the JSON in prose; the parser is defensive about it but a bad response can still raise. Watch the
[LLMService]logs if output looks off.
This is a thesis demo, not a tool you'll keep installed - but if you're curious how prompt-splitting RAG could actually look inside a graph, it's the rare pack that shows the whole flow end to end.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| user_initial_prompt | STRING | Enter your prompt here | — |
| clip | CLIP | The CLIP model used for encoding the text. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| cond | CONDITIONING | — |
| pose_query | STRING | — |
| style_query | STRING | — |