Nodes/ComfyUI-LLM-Session/LLM Dialogue Cycle
ComfyUI Node

LLM Dialogue Cycle

LLM Dialogue Cycle makes models argue productively

By kantan-kanto·Created 7 months ago·Updated 15 days ago· 32
LLM Dialogue Cycle
    • transcript_text
    initial_user_text
    session_iddefault
    cycles1
    modelA(No GGUF models found in models/LLM/)
    mmprojA(Auto-detect)
    modelB(No GGUF models found in models/LLM/)
    mmprojB(Auto-detect)
    system_promptYou are a helpful assistant.
    system_prompt_A
    system_prompt_B
    max_tokens512
    temperature0.70
    top_p0.90
    n_gpu_layers0
    n_ctx4096
    max_turns12
    summarize_old_historytrue
    summary_chunk_turns3
    max_tokens_summary128
    summary_max_chars1500
    dynamic_max_tokenstrue
    min_generation_tokens96
    safety_margin_tokens64
    persistent_cacheoff
    runtime_cacheLlamaTrieCache
    repeat_penalty1.12
    repeat_last_n256
    rewrite_continuetrue
    log_leveltiming
    suppress_backend_logstrue
    history_dir
    reset_sessionfalse
    stream_to_consolefalse
    enable_thinkingfalse

    You've probably seen the trick where you paste model A's answer into model B and ask it to rip it apart. LLM Dialogue Cycle automates that loop inside a single ComfyUI node - two local GGUF models talk to each other, no copy-paste, no API keys, no external runtime. The reason you'd reach for it over wiring up two chat nodes with a cyclic graph is that ComfyUI is genuinely bad at cycles. This node runs the whole A→B→A→B exchange in one call, so your workflow stays a straight line.

    It's the same engine as LLM Session Chat (llama-cpp-python running GGUF weights out of models/LLM/), but aimed at a different job: critique-and-revise loops, red-teaming a prompt, or simulating a conversation to check whether your role settings actually behave before you set them loose on a real user. It ships with the pack's own opinion baked in - initial_user_text goes to Model A only, and from there each model's output feeds the other's next turn.

    How it works

    The cycles input is the turn counter: 1 means A then B - a single round trip. Bump it and the ball keeps bouncing, up to 50. Each role gets its own persistent history, so session_id is really a base: A's history lives at {id}_A, B's at {id}_B, and the full transcript is appended to {id}.txt on disk. The node returns the whole transcript as a string out of transcript_text, which is the output you'd wire into a text preview or a save node.

    Because the models run inside one execution, the pack keeps both model managers loaded when runtime_cache is KV_cache or LlamaTrieCache (the defaults), so the dialogue doesn't reload weights between turns. That's also why the newer Unload LLM Model node exists - after a big two-model run you can free the VRAM without restarting ComfyUI.

    The inputs that matter

    You mostly set four things and ignore the rest:

    • modelA / modelB - dropdowns populated from GGUF files in ComfyUI/models/LLM/. If they read (No GGUF models found in models/LLM/), that's your problem right there.
    • system_prompt_A / system_prompt_B - role definitions. A shared system_prompt applies to both unless the per-role one is filled in, which overrides it.
    • cycles - how many round trips before it stops.
    • n_gpu_layers - 0 is pure CPU (slow for anything past a few billion params), -1 offloads everything.

    The mmprojA / mmprojB projector slots exist for future image-capable dialogue; dialogue is currently text-only, so set both to (Not required) and move on. Everything else - temperature, top_p, max_tokens, n_ctx, the summarization and cache knobs - is standard sampling and history management, and the defaults are sane.

    Installing it

    The usual two paths. Via ComfyUI Manager, search for ComfyUI-LLM-Session. Or clone it manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/kantan-kanto/ComfyUI-LLM-Session.git
    pip install pillow numpy
    pip install llama-cpp-python
    

    Then restart ComfyUI. Drop your GGUF files into ComfyUI/models/LLM/. Plain PyPI llama-cpp-python works for most text-only models; the newer multimodal families (Qwen3-VL, Gemma 4) need a recent JamePeng build matching your OS, Python version, and GPU backend - the README's COMPATIBILITY.md walks through it.

    Where people get burned

    Two local models means two sets of weights. A 12B GGUF on an 8GB card is already a squeeze; running A and B back-to-back is where you'll first feel the VRAM ceiling. Keep the quant ladder honest - Q4_K_M or so per model, and lean on n_gpu_layers for partial offload. And remember the histories persist: rerun with the same session_id and the models keep talking where they left off. That's a feature for testing prompts, but a trap if you expected a clean slate - flip reset_session when you want one.

    CategoryLLM/Session

    Inputs (34)

    NameTypeDefaultDescription
    initial_user_textSTRINGInitial user message (sent to Model A only)
    session_idSTRINGdefaultBase session id. A uses {id}_A, B uses {id}_B, transcript uses {id}.txt
    cyclesINT11–50Number of round trips. 1 = A then B.
    modelACOMBO(No GGUF models found in models/LLM/)GGUF model for role A
    mmprojACOMBO(Auto-detect)Projector reserved for image-capable dialogue workflows. For current text-only dialogue, use (Not required).
    modelBCOMBO(No GGUF models found in models/LLM/)GGUF model for role B
    mmprojBCOMBO(Auto-detect)Projector reserved for image-capable dialogue workflows. For current text-only dialogue, use (Not required).
    system_promptSTRINGYou are a helpful assistant.Shared system prompt for both roles
    system_prompt_ASTRINGRole-specific system prompt for model A (overrides shared prompt if set)
    system_prompt_BSTRINGRole-specific system prompt for model B (overrides shared prompt if set)
    max_tokensINT5121–32768
    temperatureFLOAT0.700–2
    top_pFLOAT0.900.05–1
    n_gpu_layersINT0-1–200
    n_ctxINT4096512–131072
    max_turnsoptINT120–200
    summarize_old_historyoptBOOLEANtrue
    summary_chunk_turnsoptINT31–50
    max_tokens_summaryoptINT12816–2048
    summary_max_charsoptINT1500200–20000
    dynamic_max_tokensoptBOOLEANtrue
    min_generation_tokensoptINT961–4096
    safety_margin_tokensoptINT640–2048
    persistent_cacheoptCOMBOoffPersistent cache backend. LlamaDiskCache stores cache data under separate cache directories for each session id.
    runtime_cacheoptCOMBOLlamaTrieCache4 options: KV_cache, LlamaRAMCache, LlamaTrieCache, off
    repeat_penaltyoptFLOAT1.121–2
    repeat_last_noptINT2560–4096
    rewrite_continueoptBOOLEANtrue
    log_leveloptCOMBOtiming3 options: minimal, timing, debug
    suppress_backend_logsoptBOOLEANtrue
    history_diroptSTRINGOptional history directory. Empty => output/llm_session_sessions/. Disk caches are also stored there, separated by session id.
    reset_sessionoptBOOLEANfalseIf true, resets both {id}_A and {id}_B histories (transcript file is not deleted). Session disk caches are kept.
    stream_to_consoleoptBOOLEANfalseStream tokens to console while generating.
    enable_thinkingoptBOOLEANfalseEnable model thinking/reasoning output for supported chat formats.

    Outputs (1)

    NameTypeDescription
    transcript_textSTRING