Nodes/Macro Nodes/Prompt Prefix (Macro)
ComfyUI Node

Prompt Prefix (Macro)

Your system prompts as text files, so you stop pasting them

By the-Macro-Man·Created 2 months ago·Updated 15 days ago· 1
Prompt Prefix (Macro)
    • prefix_text
    • source_path
    ◄prefix▾►
    ◄custom_file►
    ◄append►

    Once you have a local LLM in your graph - an Ollama chat node rewriting your rough idea into a structured prompt, or a captioner describing an image - the system prompt becomes the most load-bearing text in the whole workflow. It's also a paragraph you're storing in a widget that lives inside one .json, which means every workflow you build starts with you pasting it in again.

    Prompt Prefix (Macro) turns that paragraph into a file on disk and a dropdown on the node. Pick a file, get its contents out as a STRING, wire it into whatever takes a system prompt. That's the whole node.

    It's one of four in the macronodes pack by the-macroman (MIT) - no models, no dependencies, no network calls, just file reading.

    Why a file, and not a text widget

    Three reasons, and they compound.

    You have more than one. The prefix that makes an 8B local model emit clean booru tags for an anime base isn't the one that makes it write camera language for photorealism, and neither is the captioner's describe-composition-instead-of-style prompt. As files, switching is one click instead of a copy-paste you'll get wrong at 2am.

    Files can be edited in an editor. A multi-paragraph system prompt in a text widget is a scroll bar with a node attached. In a .txt you get a real editor and your own keybindings, and fixing a typo doesn't tempt you into re-saving a working .json.

    The third reason is the quiet one: a file has an mtime. This node's IS_CHANGED returns the file's modification time and size, so editing a prefix invalidates the cache and re-runs the downstream chain while an untouched file doesn't force a re-generation. You get "my edit took effect" without paying for "everything re-runs every time" - the usual trade-off with always-dirty loader nodes.

    How it works, and where it looks

    It scans a short list of directories in priority order:

    1. $MACRONODES_PREFIX_DIR - an absolute path you set yourself.
    2. <models>/prefixes - registered with ComfyUI's folder_paths machinery at import, which means extra_model_paths.yaml and shared model directories get picked up for free.
    3. <ComfyUI>/user/prefixes - the fallback if neither of the above exists.

    Files from all three are merged into one list; on a name clash the earlier directory wins, and the filename minus its extension becomes the dropdown entry. One wrinkle the source has that the README doesn't mention: it accepts .md as well as .txt.

    Three inputs. prefix is the dropdown and the only required one. custom_file takes an absolute path and overrides the dropdown entirely, for a one-off. append is extra text tacked on after the file's contents - the per-run note you deliberately don't want saved into the shared file. The file's contents get whitespace-stripped on read, and append is joined with a blank line.

    Two outputs. prefix_text is the STRING you wire into an LLM node's system input. source_path is the absolute path of the file that was read - more useful than it sounds: send it to a concat or a save node's text and you have a record of which prefix produced a batch.

    Installing it

    cd ComfyUI/custom_nodes
    git clone https://github.com/the-Macro-Man/ComfyUI-MacroNodes
    

    Restart, or install macronodes through ComfyUI Manager (search Macro Nodes). Nothing to pip install - this node imports only os plus folder_paths.

    Then make a folder and drop a .txt in it. Simplest is <ComfyUI>/models/prefixes/, which needs no environment variable at all:

    mkdir -p ComfyUI/models/prefixes
    echo "You are a prompt writer for SDXL. Output one paragraph, no preamble." \
      > ComfyUI/models/prefixes/sdxl_paragraph.txt
    

    Refresh the browser tab and it shows up in the dropdown.

    Where people get burned

    An empty dropdown. The number one issue, and the node handles it well: instead of an empty combo the single entry reads (no .txt files found - set MACRONODES_PREFIX_DIR). It also prints where it looked and how many files it found per directory at startup. Read that before changing anything - it separates the three causes that otherwise look identical: variable never set, set in the wrong process, or folder empty.

    The setx trap. Set MACRONODES_PREFIX_DIR on Windows with setx and then hit Restart in the desktop app and you get the old environment back - the app caches it. Fully quit and reopen. The node's startup message says exactly this, which tells you the author lost time to it too.

    Adding a file vs editing one. Editing an existing prefix takes effect on the next run, no refresh needed, because the file is read every time. Adding or removing one does not - ComfyUI builds a node's dropdown contents when it scans nodes, not when it runs them. Refresh the tab. That asymmetry is ComfyUI behaviour, not a quirk of this pack.

    A bad path doesn't fail quietly. Point custom_file at nothing and the node raises with the path in the message rather than passing an empty string downstream to produce nonsense three nodes later. Right call, even if it means a red node.

    CategoryMacroNodes/utils

    Inputs (3)

    NameTypeDefaultDescription
    prefixCOMBOPick a saved prefix. Files come from $MACRONODES_PREFIX_DIR, <models>/prefixes, or <ComfyUI>/user/prefixes.
    custom_fileoptSTRINGAbsolute path to a .txt file. Overrides the dropdown - useful for a one-off that does not live in the folder.
    appendoptSTRINGExtra text added after the prefix. For a per-run note you do not want saved into the file.

    Outputs (2)

    NameTypeDescription
    prefix_textSTRING—
    source_pathSTRING—