> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/primeintellect-ai/verifiers/llms.txt
> Use this file to discover all available pages before exploring further.

# MaybeThinkParser

> Parser that handles responses with or without <think>...</think> tags

## Overview

`MaybeThinkParser` is a flexible parser that extracts content after `</think>` tags if present, or returns the text unchanged if no think tags exist. This makes it suitable for models that may optionally include reasoning tags.

## Class Signature

```python theme={null}
class MaybeThinkParser(Parser):
    def __init__(self, extract_fn: Callable[[str], str] = lambda x: x)
```

## Parameters

<ParamField path="extract_fn" type="Callable[[str], str]" default="lambda x: x">
  Optional extraction function to further process the parsed text. For example, you can use this to extract boxed answers from math problems.
</ParamField>

## Methods

### parse

Extracts content after the last `</think>` tag, or returns the text unchanged.

```python theme={null}
def parse(self, text: str) -> str
```

<ParamField path="text" type="str" required>
  The text to parse, potentially containing `<think>...</think>` tags
</ParamField>

**Returns:** The content after the last `</think>` tag if present, otherwise the original text. The result is passed through `extract_fn` if provided.

**Behavior:**

* If `</think>` is found: Returns everything after the last `</think>` tag (stripped)
* If `</think>` is NOT found: Returns the original text unchanged (stripped)
* Always applies the `extract_fn` to the result

## Usage Examples

### Basic Usage with Think Tags

```python theme={null}
import verifiers as vf

parser = vf.MaybeThinkParser()

# Parse text with think tags
text = "<think>This is a test string with thinking tags</think> This is the final answer"
result = parser.parse(text)
print(result)  # "This is the final answer"
```

### Basic Usage without Think Tags

```python theme={null}
import verifiers as vf

parser = vf.MaybeThinkParser()

# Parse text without think tags
text = "This is a test string without thinking tags"
result = parser.parse(text)
print(result)  # "This is a test string without thinking tags"
```

### With Custom Extraction Function

```python theme={null}
import re
import verifiers as vf

def extract_boxed(text: str) -> str:
    """Extract content from \boxed{...}"""
    match = re.search(r'\\boxed\{([^}]+)\}', text)
    return match.group(1) if match else text

parser = vf.MaybeThinkParser(extract_fn=extract_boxed)

# With think tags
text1 = "<think>Reasoning here</think>The answer is \\boxed{42}"
result1 = parser.parse(text1)
print(result1)  # "42"

# Without think tags
text2 = "The answer is \\boxed{42}"
result2 = parser.parse(text2)
print(result2)  # "42"
```

### Parsing Message Completions

```python theme={null}
import verifiers as vf

parser = vf.MaybeThinkParser()

# With think tags
messages_with_think = [
    {"role": "user", "content": "What is 2+2?"},
    {
        "role": "assistant",
        "content": "<think>This is a test string with thinking tags</think>The answer is 4",
    },
]
result = parser.parse_answer(messages_with_think)
print(result)  # "The answer is 4"

# Without think tags
messages_without_think = [
    {"role": "user", "content": "What is 2+2?"},
    {"role": "assistant", "content": "The answer is 4"},
]
result = parser.parse_answer(messages_without_think)
print(result)  # "The answer is 4"
```

### In a Math Rubric

```python theme={null}
import re
import verifiers as vf

def extract_boxed_answer(text: str) -> str:
    """Extract the final answer from \boxed{...}"""
    match = re.search(r'\\boxed\{([^}]+)\}', text)
    return match.group(1) if match else text

def check_math_correctness(completion, answer, parser, **kwargs):
    """Check if the parsed mathematical answer is correct"""
    parsed = parser.parse_answer(completion)
    return 1.0 if parsed == str(answer) else 0.0

parser = vf.MaybeThinkParser(extract_fn=extract_boxed_answer)

rubric = vf.Rubric(
    funcs=[check_math_correctness],
    weights=[1.0],
    parser=parser
)
```

### Handling Edge Cases

```python theme={null}
import verifiers as vf

parser = vf.MaybeThinkParser()

# Empty content after think tag
text1 = "<think>Some thinking</think>"
result1 = parser.parse(text1)
print(result1)  # "" (empty string)

# Multiple think blocks
text2 = "<think>First</think>Middle<think>Second</think>Final"
result2 = parser.parse(text2)
print(result2)  # "Final" (after last </think>)

# Whitespace handling
text3 = "<think>Thinking</think>   Answer with spaces   "
result3 = parser.parse(text3)
print(result3)  # "Answer with spaces" (stripped)
```

## When to Use MaybeThinkParser

Use `MaybeThinkParser` when:

* Your model may or may not include `<think>...</think>` tags
* You want flexible parsing that works with both reasoning and non-reasoning models
* You're working with models that sometimes generate think tags (e.g., during fine-tuning)
* You need graceful handling when think tags are absent

**Key Differences from ThinkParser:**

| Feature            | MaybeThinkParser      | ThinkParser                |
| ------------------ | --------------------- | -------------------------- |
| Missing think tags | Returns original text | Returns empty string       |
| Enforcement        | Permissive            | Strict                     |
| Use case           | Optional reasoning    | Required reasoning         |
| Format validation  | Not provided          | `get_format_reward_func()` |

## Common Use Cases

### Math Problem Solving

`MaybeThinkParser` is commonly used with math rubrics since it can handle both reasoning and direct answers:

```python theme={null}
import verifiers as vf
from verifiers.utils.math_utils import extract_boxed_answer

parser = vf.MaybeThinkParser(extract_fn=extract_boxed_answer)

# Works with reasoning
text1 = "<think>Let me solve this</think>The answer is \\boxed{42}"
print(parser.parse(text1))  # "42"

# Works without reasoning
text2 = "The answer is \\boxed{42}"
print(parser.parse(text2))  # "42"
```

### Fine-tuning Scenarios

During fine-tuning, models may transition from always using think tags to using them selectively:

```python theme={null}
import verifiers as vf

parser = vf.MaybeThinkParser()

# Early in training: includes think tags
early_response = "<think>Reasoning step by step</think>Answer"
print(parser.parse(early_response))  # "Answer"

# Later in training: may skip think tags for simple questions
later_response = "Answer"
print(parser.parse(later_response))  # "Answer"
```

## See Also

* [ThinkParser](/api/think-parser) - For strict think tag enforcement
* [Parser](/api/parser) - Base parser class
* [MathRubric](/api/math-rubric) - Uses MaybeThinkParser by default
* [XMLParser](/api/xml-parser) - For XML-formatted responses
