Nodes/comfyui-tag-rag/TagRAG Index
ComfyUI Node

TagRAG Index

The boring node that powers the whole TagRAG pack

By FrostySDXL·Created 2 months ago·Updated 2 months ago· 0
TagRAG Index
    • index_ref
    • summary
    • status
    csv_path
    tag_columntag
    index_namedefault
    rebuildfalse
    retrieval_modelexical
    embedding_backendllama_cpp_python
    embedding_model_path
    embedding_n_ctx2048
    embedding_n_gpu_layers-1
    embedding_base_urlhttp://127.0.0.1:8080
    embedding_model
    embedding_endpoint_styleopenai_compatible
    embedding_timeout_seconds30.0
    allow_remote_embedding_base_urlfalse
    aliases_columnaliases
    category_columncategory
    description_columndescription
    source_columnsource
    weight_columnweight
    test_query
    test_top_k5

    Every TagRAG workflow starts here, and that's not a compliment you'll hear often in a pack full of LLM calls. TagRAG Index reads your tag CSV, normalizes it, optionally builds a semantic index, and hands every other node a JSON index_ref string it can reload from. Nothing flashy happens in the UI - no images, no chat - but without this node the other three are just boxes that return ERROR: csv_path is required forever. It's the foundation, and it's the most solid piece in the pack.

    The whole point of the pack is to build prompts from your tag dataset rather than whatever a generic LLM happens to know. You keep a CSV of tags you actually use - character sheets, your style keywords, the tags your favorite checkpoint genuinely responds to - and Index turns that CSV into something queryable. Think of it as a personal tag library with retrieval bolted on.

    How it works

    The node loads the CSV with an encoding fallback chain (utf-8-sig, utf-8, latin-1) and normalizes each row into a TagRecord with tag, aliases, category, description, source, and weight. Lexical retrieval then scores your query across all of those fields - so blue hair finds the row whose description says "azure colored hair" even if the tag column says something else. Underscores are treated as spaces, so blue_hair and blue hair are the same thing.

    For semantic and hybrid modes it gets fancier: it embeds every row with an embedding-capable GGUF (native llama-cpp-python) or a llama-server /v1/embeddings endpoint, persists a FAISS index in a .tag_rag_indexes/<index_name>/ directory sitting right next to your CSV, and records where everything is. That's the design trick to understand: the index_ref isn't a live connection, it's a serialized recipe. It carries csv_path, the column names, retrieval_mode, and the embedding settings. Downstream nodes parse that JSON and reload the CSV themselves, so you wire the string once and never re-point anything.

    Inputs that matter

    • csv_path - full path to your CSV. The only thing that's actually required.
    • tag_column - which column holds the tag text (default tag).
    • retrieval_mode - lexical (default, needs no model) vs semantic/hybrid, which need an embedding model plus FAISS.
    • rebuild - set this true when creating or refreshing a semantic index.
    • test_query and test_top_k - smoke-test retrieval right in the Index node before you wire anything else up.

    The CSV format is forgiving: a single tag column is the minimum, but the recommended shape adds aliases, category, description, source, weight, with aliases separated by | or ;.

    Outputs

    Three strings: index_ref (the JSON you feed into TagRAG Prompt, Chat, or Image), summary (tag count plus your test query results), and status (OK or an ERROR: message explaining what went wrong).

    Install

    ComfyUI Manager - search the pack title comfyui-tag-rag - or do it manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/FrostySDXL/comfyui-tag-rag
    cd comfyui-tag-rag
    pip install -r requirements.txt
    

    Then restart ComfyUI. That requirements.txt pulls numpy, requests, faiss-cpu, onnxruntime, Pillow, and llama-cpp-python - and note the pack downloads no models itself, so semantic retrieval needs you to supply an embedding GGUF. The author's whole stance is local-first: no cloud, no API key, nothing fetched behind your back.

    Where people get burned

    • ERROR: FAISS unavailable on semantic/hybrid - faiss-cpu isn't installed, or your index_ref came from a lexical-only build (the missing semantic_index_dir variant). Install requirements-rag.txt and rebuild with rebuild=true.
    • ERROR: csv_path is required - the path is blank. It's the one field you can't skip.
    • Your CSV lives somewhere weird. The loader is deliberately sandboxed: 100 MB max, 200k rows, 4096-char cells, and the file must sit under your working directory or a root you add to the COMFYUI_TAG_RAG_CSV_ROOTS environment variable. That env var is the answer if a legitimate path gets refused.

    One honest caveat: this is a pre-alpha pack (version 0.1.0a0, a single-commit repo from mid-2026). Index is the calm, well-tested part, but treat the whole pack as something to poke at rather than infrastructure to bet a production pipeline on.

    CategoryTagRAG

    Inputs (21)

    NameTypeDefaultDescription
    csv_pathoptSTRING
    tag_columnoptSTRINGtag
    index_nameoptSTRINGdefault
    rebuildoptBOOLEANfalse
    retrieval_modeoptCOMBOlexical3 options: lexical, semantic, hybrid
    embedding_backendoptCOMBOllama_cpp_python2 options: llama_cpp_python, llama_server
    embedding_model_pathoptSTRING
    embedding_n_ctxoptINT2048256–262144
    embedding_n_gpu_layersoptINT-1-1–200
    embedding_base_urloptSTRINGhttp://127.0.0.1:8080
    embedding_modeloptSTRING
    embedding_endpoint_styleoptCOMBOopenai_compatible2 options: openai_compatible, llama_cpp_legacy
    embedding_timeout_secondsoptFLOAT30.01–300
    allow_remote_embedding_base_urloptBOOLEANfalse
    aliases_columnoptSTRINGaliases
    category_columnoptSTRINGcategory
    description_columnoptSTRINGdescription
    source_columnoptSTRINGsource
    weight_columnoptSTRINGweight
    test_queryoptSTRING
    test_top_koptINT51–100

    Outputs (3)

    NameTypeDescription
    index_refSTRING
    summarySTRING
    statusSTRING