Structured Output
Stop begging the LLM for JSON — force it to return exactly one value
- model
- STRING
Prompting an LLM to "return a number" and getting a paragraph back is a rite of passage. This node exists so you stop playing that game. StructuredOutput pins the model to a single, typed value - an int, a float, a bool, a category you define - and guarantees it comes back as exactly that. It's the difference between "the model probably did what I asked" and "the model has no choice but to comply."
What it is
It's the pack's answer to getting structured data out of a GGUF LLM reliably, and it's one of the features the README leads with. The author's framing is blunt: structured outputs are hard to get through prompt engineering alone, so this node does it at the mechanism level. Use it to extract entities, pull numbers, classify prompts against a list of classes you define, or emit one specific prompt - the examples in the README, verbatim.
The inputs that matter
- prompt - the input text you're analyzing: a caption, an image description, whatever you want to extract from.
- model - CUSTOM, the GGUF LLM from the pack's loader.
- attribute_name - the name of the value you want back, e.g.
ageorstyle. The model returns it labeled with this. - attribute_type - the big one. A dropdown:
str,int,float,bool, orCategory. This is what forces the response into the shape you want. - attribute_description - a hint describing the field, so the model knows what it's extracting. Filling this well is the difference between accurate extractions and confident guesses.
- categories - comma-separated values, used only when
attribute_typeisCategory. This is your classification target list - e.g.anime, photo, painting. - temperature - default 0.15. Keep it low for extraction and classification; you want the same answer every time.
Output is a single STRING, but it's the string of the typed value - the clean int, float, or category you asked for, not a JSON blob.
How it works
Under the hood it runs a structured chat: the pack builds a JSON schema from your attribute settings and instructs the model to return only that object. The generation is constrained to follow the schema - that's why you get a number back instead of an essay. Because the schema is built from your attribute_name and attribute_type, the node is genuinely general: flip attribute_type to Category, fill in categories, and the same setup becomes a classifier.
Install
Pack-level install:
cd ComfyUI/custom_nodes
git clone https://github.com/gokayfem/ComfyUI_VLM_nodes
Restart ComfyUI (or Manager → "VLM Nodes"). Python 3.9+ and the llama.cpp stack. You need a GGUF in models/LLavacheckpoints; LLaVa 1.5/1.6 are the README's recommended models for the pack's generation family, so if the model has a vision projector, pair it correctly.
Troubleshooting
Beyond the pack's usual llama-cpp-python install pain, the interesting failure here is semantic: if your extraction is wrong, it's almost never the mechanism - it's your attribute_description being vague, or the prompt being ambiguous. Tighten those first. And if Category returns junk, your categories list is probably too loose; give the model fewer, sharper options.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| model | CUSTOM | — | |
| temperature | FLOAT | 0.150–2 | — |
| attribute_name | STRING | result | — |
| attribute_type | COMBO | str | 5 options: str, int, float, bool, Category |
| attribute_description | STRING | — | |
| categories | STRING | Comma-separated values for Category. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |