NAME
Langertha::Role::ThinkTag - Configurable think tag filtering for reasoning models
VERSION
version 0.202
SYNOPSIS
# Think tag filter is enabled by default on all engines.
# <think> tags are automatically stripped and thinking preserved:
my $response = $engine->simple_chat('Explain quantum computing');
say $response; # clean answer text
say $response->thinking; # chain-of-thought (if any)
# For APIs with native reasoning (DeepSeek, Anthropic, Gemini),
# thinking is extracted from the API response automatically —
# no tag filtering needed.
# Custom tag name (e.g. for models using <reasoning> tags):
my $engine = Langertha::Engine::vLLM->new(
url => $vllm_url,
model => 'my-reasoning-model',
think_tag => 'reasoning',
);
# Disable filtering if you want raw output:
my $engine = Langertha::Engine::OpenAI->new(
api_key => $key,
think_tag_filter => 0,
);
DESCRIPTION
This role provides automatic filtering of <think> tags from LLM responses. Many reasoning models (DeepSeek R1, QwQ, Hermes with reasoning enabled) emit chain-of-thought reasoning wrapped in <think> tags inline with their response text. This role strips those tags and preserves the thinking content on the "thinking" in Langertha::Response attribute.
Composed into Langertha::Role::Chat, so every engine gets it automatically. The filter handles both closed pairs (<think>...</think>) and unclosed tags where the model stopped mid-thought.
For APIs that provide reasoning content natively (DeepSeek reasoning_content, Anthropic thinking blocks, Gemini thought parts), the thinking is extracted directly from the API response — no tag filtering needed.
think_tag
The XML tag name used for thinking content. Defaults to think. Some models may use different tag names (e.g. reasoning).
think_tag_filter
When true, <think>...</think> blocks are stripped from response text. The thinking content is preserved on the "thinking" in Langertha::Response attribute for inspection. Defaults to 1 (enabled). Set to 0 to pass think tags through unmodified.
filter_think_content
my ($filtered_text, $thinking) = $engine->filter_think_content($text);
Strips <think>...</think> blocks from $text. Handles both closed pairs and unclosed tags (where the model stopped mid-thought). Returns the filtered text and the extracted thinking content (or undef if none). Returns the original text unchanged when "think_tag_filter" is false.
SEE ALSO
Langertha::Response - Response object with
thinkingattributeLangertha::Role::Chat - Chat role that composes this role
Langertha::Engine::NousResearch - Engine with
reasoningattribute for Hermes models
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudss.us/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.