Think Remover (UTK)
Strip the <think> block out of a reasoning model's output
- cleared_content
- think_content
Reasoning-capable LLMs - DeepSeek R1, the Qwen3 line, GLM and friends - wrap their chain-of-thought in <think>...</think> tags, and the tags are only meant for the model, not for you. If you're piping one of those models into a prompt builder, a captioner, or a text-to-speech node, the raw output comes with paragraphs of "let me reason through this" garbage attached. Think Remover exists for exactly that moment: it splits the <think> block out from the actual answer, so you can feed the clean response downstream and keep the reasoning for inspection if you want it.
How it works
It searches the input for the closing </think> tag, case-insensitively. Everything up to and including that closing tag goes into think_content; everything after it becomes cleared_content. Both are stripped of leading/trailing whitespace.
The key implementation detail is that it keys on the closing tag only. That means the opening <think> stays attached to the reasoning half - think_content is the complete block with both tags intact, and cleared_content is what came after. If no </think> is found at all, the node is a no-op: both outputs return the full input text unchanged. That's a deliberate safe default, not a bug - a model that didn't reason doesn't get mangled.
The input and outputs
text- the raw string to split. Wire it from an LLM node's output.cleared_content- the answer, with the thinking block removed. This is the one you usually feed into a prompt encoder or a text consumer.think_content- the reasoning block, tags included. Wire it to a display node (Show Any works) if you want to audit what the model was "thinking."
Installing it
Standard pack install - ComfyUI Manager, search "ComfyUI-UniversalToolkit", install and restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/whmc76/ComfyUI-UniversalToolkit
pip install -r requirements.txt
Pure Python string handling; no dependencies beyond stock ComfyUI.
Where people get burned
- It only handles the first
</think>. If a model emits multiple think blocks - which some of the newer reasoning models do when they "check their work" - only the first one is stripped, and the second block's reasoning stays incleared_content. For a single-block response, which is the common case, you're fine. - No tags = no change. If the model skipped reasoning (or you're feeding it a plain prompt), both outputs equal the input. If you expected one of them to be empty, that's why it isn't.
- The tags are case-insensitive, but the node doesn't trim inside the block -
think_contentkeeps whatever formatting the model produced.
It's a small, single-purpose node, and it's the difference between a caption pipeline that emits "I need to carefully consider..." and one that emits the actual caption.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| cleared_content | STRING | — |
| think_content | STRING | — |