GPT Chat
Vision Prompts and the Preamble Problem
- images
- history
- provider
- text
- thought
- history
GPT Chat is the OpenAI half of the pack's text nodes, and it does the two jobs people actually use a chat model for in a graph: turn a rough idea into a structured prompt, and read an image and write about it. Captioning a LoRA set, seeding an img2img pass from an existing render, generating dialogue for a video clip - same node each time.
Use the API here and not a local model when the job genuinely needs frontier-level language, and accept the two costs: per-call pricing, and a filter you cannot abliterate because there are no weights (the KB's llm-in-comfyui.md covers the local-vs-API split properly). For prompt enhancement specifically, a small uncensored local model is usually the better tool; for a five-hundred-image captioning pass where you want consistency, paying for GPT is defensible.
The inputs
- prompt - the user turn, multiline. With images connected, this is your instruction ("describe this in one paragraph, natural language, no bullet points").
- model - dynamic dropdown across the GPT line including the reasoning variants. The parameters below change with the version - reasoning versions expose
reasoning_effort, older ones exposetemperatureandtop_p.Custom modelis there for anything newer than the pack. - seed -
0= API's choice; non-zero is sent where supported and changing it forces a re-run. - image_detail -
autoby default. This is the knob that decides how hard the vision model looks, and it's the one people forget exists. Be aware that a heavier setting means the image is tokenised more expensively. - images - autogrow input, up to 16, batches expanded into individual slots.
- system_prompt - the single most important field on the node for prompt work. Be surgical: "Output only the prompt. No preamble, no explanation, no quotation marks."
- history - previous turns; feed a node's
historyoutput back in to continue a conversation. - extra - JSON merged into the request, for anything not exposed.
- retry_count - total attempts, ~3s apart. Keep at 1 while testing.
Outputs: text, thought, history. Here thought carries the reasoning stream from models that emit one - on non-reasoning models it's just empty.
Install and keys
cd ComfyUI/custom_nodes
git clone https://github.com/yogurt7771/ComfyUI-YogurtNodes
cd ComfyUI-YogurtNodes
pip install -r requirements.txt
With no provider wired, this node uses the official OpenAI API, reading openai from custom_nodes/ComfyUI-YogurtNodes/yogurt_nodes/llm/api_key.json or OPENAI_API_KEY:
{ "openai": "sk-...", "openai_base_url": "https://api.openai.com/v1" }
openai_base_url is optional and is honoured as the fallback base URL by the official provider too, which is how people quietly route this node at Azure, a local Ollama, or LM Studio without adding a provider node. It works. It's also opaque six months later - if you're doing that, use Provider: OpenAI Compatible instead and make it visible in the graph.
Common issues
Your prompt has a preamble in it. The classic. A chat model's default output is chat. Two defences, use both: a hard system_prompt and a regex node downstream that strips anything before the payload. An enhancer that hands you "Here is your improved prompt:" as literal conditioning text is worse than no enhancer at all.
Refusals on benign-looking creative work. The API filters follow the model, not the node. You can't tune it, and OpenAI's own history here is a couple of years of shifting sand. When you're hit, the answer is a different model, not a different parameter.
Reasoning models leaking scratch-work. If text reads like a monologue, the model is deliberating into the visible channel. Turn reasoning_effort down where the version allows it. The KB's llm-in-comfyui.md is blunt about this: reasoning models are the wrong choice for structured rewriting, and the job wants small-and-obedient instead.
Cost creep. Every text change in your graph re-runs the node. Iterating on a workflow with an LLM in it is not free, and retry_count above 1 multiplies a failure into several billed attempts.
Vision slots. Batches expand one-for-one against a 16-image ceiling. A batch of 20 images fails; nothing silently drops.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Prompt sent to the model. | |
| model | COMBO | Model version; the inputs below change with the selected model. | |
| seed | INT | 00–2147483647 | Sent to the API when the model supports it; changing it also forces a re-run. 0 lets the API pick a random seed. |
| image_detail | COMBO | auto | Image detail level for vision. |
| extra | STRING | Optional JSON object merged into the request (for parameters not exposed as inputs). | |
| images | COMFY_AUTOGROW_V3 | Optional reference image(s); batches are expanded. Up to 16. | |
| retry_count | INT | 11–10 | Total attempts on failure. |
| system_promptopt | STRING | System instruction sent with the request. | |
| historyopt | HISTORY | Previous turns. | |
| provideropt | YOGURT_LLM_PROVIDER | Provider node. When unconnected, the official API is used with keys from api_key.json or environment variables. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| thought | STRING | — |
| history | HISTORY | — |