LazyPrompt — Prompt Engineer
Let an LLM write your prompt so you don't have to
- clip
- first_frame
- image
- last_frame
- reference_image_1
- reference_image_2
- reference_image_3
- reference_image_4
- reference_image_5
- reference_audio
- model_high
- clip_high
- model_low
- clip_low
- lora_model
- lora_clip
- PROMPT
- PREVIEW
- NEG_PROMPT
- selector_Out
- first_frame
- last_frame
- reference_image_1
- reference_image_2
- reference_image_3
- reference_image_4
- reference_image_5
- reference_audio
- model_high
- model_low
- clip_high
- clip_low
- lora_model
- lora_clip
Type a rough idea into LazyPrompt - Prompt Engineer and it runs a local LLM that turns it into a full prompt shaped for whatever model you're actually sampling. "A woman walks through a rain-soaked city street at night" becomes a proper cinematic block for LTX, or a tag-dense paragraph for Pony, depending on the target_model you pick. If you've ever stared at a blank prompt box before a Wan render, this is the node that fixes that.
Why this exists: in 2026 prompting is model-specific in a way it wasn't in the SD 1.5 era. A booru tag list that sings on Pony is garbage on Z-Image, and an instruction-style sentence that works on LTX gets mangled into Flux. The whole trick of LazyPrompt is that it doesn't just expand text - it swaps in a different system prompt template per target model, so the same rough idea gets rewritten in the right dialect for LTX 2.3, Wan 2.2, Flux, SDXL, Pony, or SD 1.5. That per-model templating is genuinely the hard part, and it's what most ad-hoc "prompt enhancer" nodes get wrong.
How it works
Three backends, all local:
- LM Studio (API) - the default. This is the one people trip on: the name sounds like a hosted service, but there's no key and no cloud. It talks to a model you run yourself in LM Studio over its native
/api/v1/chatendpoint, with an OpenAI-compatible fallback for older versions. Setlm_studio_modelto the exact model id as shown in LM Studio - that field is required and it's the #1 "nothing comes back" cause. - Local Hugging Face - two small abliterated models, NeuralDaredevil 8B and Llama-3.2 3B, downloaded automatically on first run. Fine for text, but they're text-only: the
imageinput is ignored on this backend. - Bypass - flip the
bypasstoggle and the LLM is skipped entirely; your text passes straight through. Great for testing whether the LLM is the problem or the fix.
Beyond the system template, you get environment - 73 presets like Beach - golden hour or Night sky - open field that inject location, lighting, and (for video) sound into the expansion. creativity is the temperature: 0.7 stays literal, 1.1 gets artistic. For video targets, video_length and fps feed pacing hints so the LLM writes to a real duration instead of guessing.
The inputs and outputs that matter
The three you'll actually touch on day one: user_input (your rough idea), target_model (which template/pacing rules), and model + lm_studio_model (the backend). After that: seed (-1 = random), max_output_tokens (default 900; the pacing hint asks for roughly a third of it, so raise both together for long cinematic prompts), and keep_model_loaded - leave it off unless you hate the reload time, because a resident 8B LLM eats VRAM you may want back.
Worth wiring from elsewhere in this pack: character (subject description, so your character file always reaches the LLM), scene_context (from Vision Describe), and prompt_override_input - when connected it replaces user_input entirely, which is how the Lazy-subject-and-scene-automation node's prompt_override takes over the LLM's marching orders.
Outputs are three strings: PROMPT (the expanded positive - wire this to CLIP Text Encode), PREVIEW, and NEG_PROMPT. There's no model/tensor output; this node is purely the text half of your graph.
Install
Install the whole pack once: in ComfyUI Manager, search vsaan212/Vsaan212-workflow-utilities and install, or
cd ComfyUI/custom_nodes
git clone https://github.com/vsaan212/Vsaan212-workflow-utilities
then restart. The heavy lifting is in the pack's requirements.txt - transformers, accelerate, torch, qwen-vl-utils - and the first run against a local HF model downloads several GB of weights. With LM Studio you skip that entirely.
Where people get burned
lm_studio_modelempty or wrong id → silent nothing. LM Studio has to be running with its server up (default port 1234).- Output is your input, unchanged →
bypassis on, orprompt_override_inputis wired and empty-ish. - The
imageinput did nothing → you're on the local HF text backend. Feed frames through LazyPrompt - Vision Describe →scene_contextinstead;imageonly works with a vision model loaded in LM Studio. - VRAM won't come back → you left
keep_model_loadedon. Turn it off or drop the LazyPrompt - Unload local model node into the graph.
System prompt templates live in lazyprompt/system_prompts.json and you can edit them; press R (or restart) to reload after changes.
Inputs (41)
| Name | Type | Default | Description |
|---|---|---|---|
| bypass | BOOLEAN | false | When ON, skips the LLM entirely and sends your text straight through. Use for manual prompts or testing. |
| user_input | STRING | a woman walks through a rain-soaked city street at night | Prompt to be enhanced — short idea, sentence, or numbered steps. The LLM expands it for the selected skill. |
| target_model | COMBO | 🎬 LTX 2.3 — Video; Cinematic Arc + Audio | Skill / output format for the LLM system prompt. "None" = no Model_Skills template (empty system unless override). Skills load from lazyprompt/Model_Skills/*.md (restart ComfyUI or press R after edits). |
| environment | COMBO | None — LLM decides | Injects location, lighting, and (for video) sound. Random uses env_seed. |
| creativity | FLOAT | 0.90.1–1 | Sampling temperature (0.1–1.0, step 0.1) for local HF models and LM Studio. Values above 1.0 are not supported by LM Studio. |
| seed | INT | -1-1–2147483647 | LLM seed. -1 = random each run. |
| keep_model_loaded | BOOLEAN | false | Keep the local HF model in VRAM between runs. Off frees VRAM after each run. |
| offline_mode | BOOLEAN | false | ON = no HuggingFace network; local cache / paths only. |
| video_length | FLOAT | 8.000.25–300 | Video duration in seconds. Filled into the skill's ***VideoLength*** slot for video skills. Image skills strip that slot. If SAS [video_length] is in the user/override text, that value is used instead (and kept in the user message). Timing rules live in the skill MD. |
| env_seed | INT | 00–2147483647 | Seed when environment is Random. 0 = different pick each run. |
| model | COMBO | LM Studio (API) | Backend: local HF checkpoints, LM Studio REST API, or Comfy core TextGenerate via a wired CLIP/LLM (Qwen etc.). TextGenerate requires the optional clip input. |
| local_path_8b | STRING | Optional local snapshot path for the 8B model. | |
| local_path_3b | STRING | Optional local snapshot path for the 3B model. | |
| lm_studio_model | STRING | Required when model is LM Studio (API). LM Studio 0.4+ uses /api/v1/chat; older versions fall back to /v1/chat/completions. | |
| lm_studio_ttl | INT | 50–3600 | LM Studio JIT unload: when > 0, unloads the model immediately after each run via /api/v1/models/unload (v1 chat). On OpenAI fallback only, also sends idle TTL in the request body. 0 = leave loaded. |
| max_output_tokens | INT | 90096–16000 | Hard cap on completion length (HF max_new_tokens / LM Studio max_tokens / TextGenerate max_length). Raise this for longer cinematic prompts. |
| system_prompt | STRING | Optional full system override. Empty = selected skill's Model_Skills/*.md prompt. Does not merge with the MD body. When target is None and this field has text, only that text is used as system prompt and the user message is scene + idea only (no auto augmentation). Skills load from lazyprompt/Model_Skills/*.md (restart ComfyUI or press R after edits). | |
| textgenerate_thinking | BOOLEAN | false | TextGenerate (CLIP) only: enable thinking mode when the wired LLM supports it. |
| clipopt | CLIP | Required for TextGenerate (CLIP) backend. Wire CLIPLoader with an LLM-capable encoder (e.g. Qwen, type minimax / qwen). Plain SD CLIP will fail — needs .generate(). | |
| scene_contextopt | STRING | Authoritative scene/subject text from the vision node or manual paste. | |
| lora_triggersopt | STRING | Injected so the model places these words at the very start of the output. | |
| characteropt | STRING | Subject / character description — always prepended to the LLM user message (including minimal mode and when prompt_override_input is set). Wire from Lazy-subject-and-scene-automation subject_description. | |
| first_frameopt | IMAGE | Image2video First frame. Vision for LM Studio or TextGenerate (CLIP) when gated on. Also accepted via legacy `image` input. | |
| imageopt | IMAGE | Legacy alias for Image2video First frame. Prefer first_frame. | |
| last_frameopt | IMAGE | Image2video Last frame (FL2V). | |
| reference_image_1opt | IMAGE | Reference Image 1 (R2V). | |
| reference_image_2opt | IMAGE | Reference Image 2 (R2V). | |
| reference_image_3opt | IMAGE | Reference Image 3 (R2V). | |
| reference_image_4opt | IMAGE | Reference Image 4 (R2V). | |
| reference_image_5opt | IMAGE | Reference Image 5 (R2V). | |
| reference_audioopt | AUDIO | Reference audio passthrough (R2V). Switchable by global selector. | |
| global_selector_inputopt | STRING | From Lazy Global Selector (T2V/I2V/FL2V/R2V). Gates image/audio sockets. | |
| SAS_automation_selector_inputopt | STRING | From Lazy-subject-and-scene-automation selector. Mode tags always apply. Disk [ReferenceImageN] / [AudioReference] overlay matching slots only (typically reference_image_1 and reference_audio). Other wired reference_image_2..5 stay. Workflow-only blobs keep all sockets. | |
| prompt_override_inputopt | STRING | When connected/non-empty, replaces user_input for the LLM request (LM Studio API and local HF). Wire from Lazy-subject-and-scene-automation prompt_override. | |
| user_instructionsopt | STRING | Optional temporary instructions. When non-empty: filled into ***UserPrompt*** / ***UserPromptEnd*** in the skill (or override), and copied into the user message as locked scene facts. Empty = that skill section is omitted. | |
| model_highopt | MODEL | Optional high stack (after SAS / checkpoint). Prompt [LoraH]path[/LoraH] blocks load here after the LLM, then are stripped from PROMPT. | |
| clip_highopt | CLIP | CLIP paired with model_high for Prompt [LoraH] loads. Separate from the TextGenerate clip input. | |
| model_lowopt | MODEL | Optional low stack. Prompt [LoraL]path[/LoraL] blocks load here after the LLM (Wan-style dual noise / low branch). | |
| clip_lowopt | CLIP | CLIP paired with model_low for Prompt [LoraL] loads. If unwired, LoraL still patches model_low using clip_high. | |
| lora_modelopt | MODEL | Singular model for Prompt [Lora1]–[Lora5] (MiniMax / LTX / Flux / SDXL). Wire SAS minimax_model, video_model, or image_model here. Wan dual-stack keeps using model_high / model_low + LoraH / LoraL. | |
| lora_clipopt | CLIP | CLIP paired with lora_model for [Lora1]–[Lora5]. If unwired, clip_high is used as the companion (same as SAS). |
Outputs (18)
| Name | Type | Description |
|---|---|---|
| PROMPT | STRING | — |
| PREVIEW | STRING | — |
| NEG_PROMPT | STRING | — |
| selector_Out | STRING | — |
| first_frame | IMAGE | — |
| last_frame | IMAGE | — |
| reference_image_1 | IMAGE | — |
| reference_image_2 | IMAGE | — |
| reference_image_3 | IMAGE | — |
| reference_image_4 | IMAGE | — |
| reference_image_5 | IMAGE | — |
| reference_audio | AUDIO | — |
| model_high | MODEL | — |
| model_low | MODEL | — |
| clip_high | CLIP | — |
| clip_low | CLIP | — |
| lora_model | MODEL | — |
| lora_clip | CLIP | — |