Skip to content

Commit 26a18df

Browse files
committed
Add reasoning tag cleanup to DeepResearch plugin
Introduces a `clean_reasoning_tags` function to remove reasoning tags (e.g., <think>, <reflection>) from model responses for professional output. Updates DeepResearcher to apply this cleanup at key response stages and documents compatibility and cleanup behavior in the README.
1 parent 813824f commit 26a18df

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

optillm/plugins/deep_research/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ response = client.chat.completions.create(
165165
- **Token Usage**: 1,000-5,000 tokens per iteration
166166
- **Memory Requirements**: Scales with content volume and context size
167167

168+
## Reasoning Model Compatibility
169+
170+
The plugin is fully compatible with reasoning models that include internal thinking processes:
171+
172+
- **Automatic Cleanup**: Removes `<think>`, `<thinking>`, `<reasoning>`, `<reflection>` tags from all responses
173+
- **Professional Output**: Ensures final reports contain only clean, formatted content
174+
- **Seamless Integration**: Works transparently with any model type
175+
- **Supported Tags**: `<think>`, `<thinking>`, `<reasoning>`, `<thought>`, `<reflect>`, `<reflection>`
176+
177+
Example cleanup:
178+
```
179+
Input: "<think>Let me analyze this</think>\n\n# Research Report\nContent here..."
180+
Output: "# Research Report\nContent here..."
181+
```
182+
168183
## Error Handling
169184

170185
The plugin includes comprehensive error handling:
@@ -183,6 +198,7 @@ The implementation follows the TTD-DR paper's quality criteria:
183198
- **Citation Accuracy** - Proper attribution for all claims and findings
184199
- **Academic Rigor** - Maintains objectivity and scholarly tone
185200
- **Iterative Refinement** - Continuously improves research quality
201+
- **Clean Output** - Automatically removes reasoning tags (`<think>`, `<thinking>`, etc.) for professional reports
186202

187203
## Comparison to Simple Search
188204

optillm/plugins/deep_research/research_engine.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,48 @@
1919
from optillm.plugins.memory_plugin import run as memory_run
2020

2121

22+
def clean_reasoning_tags(text: str) -> str:
23+
"""
24+
Remove reasoning tags from model responses for clean final output.
25+
26+
Removes common reasoning tags like:
27+
- <think></think>
28+
- <thinking></thinking>
29+
- <reasoning></reasoning>
30+
- <thought></thought>
31+
32+
Args:
33+
text: Raw model response text
34+
35+
Returns:
36+
Cleaned text with reasoning tags removed
37+
"""
38+
if not text:
39+
return text
40+
41+
# List of reasoning tag patterns to remove
42+
reasoning_patterns = [
43+
r'<think>.*?</think>',
44+
r'<thinking>.*?</thinking>',
45+
r'<reasoning>.*?</reasoning>',
46+
r'<thought>.*?</thought>',
47+
r'<reflect>.*?</reflect>',
48+
r'<reflection>.*?</reflection>',
49+
]
50+
51+
cleaned_text = text
52+
for pattern in reasoning_patterns:
53+
# Use DOTALL flag to match across newlines
54+
cleaned_text = re.sub(pattern, '', cleaned_text, flags=re.DOTALL | re.IGNORECASE)
55+
56+
# Clean up any extra whitespace left behind, but preserve markdown formatting
57+
cleaned_text = re.sub(r'\n\s*\n\s*\n+', '\n\n', cleaned_text) # Multiple empty lines to double
58+
cleaned_text = re.sub(r' +', ' ', cleaned_text) # Multiple spaces to single space (but preserve intentional double spaces)
59+
cleaned_text = cleaned_text.strip()
60+
61+
return cleaned_text
62+
63+
2264
class DeepResearcher:
2365
"""
2466
Implementation of Test-Time Diffusion Deep Researcher (TTD-DR) algorithm
@@ -77,6 +119,8 @@ def decompose_query(self, system_prompt: str, initial_query: str) -> List[str]:
77119
)
78120

79121
content = response.choices[0].message.content.strip()
122+
# Clean reasoning tags from query decomposition response
123+
content = clean_reasoning_tags(content)
80124
self.total_tokens += response.usage.completion_tokens
81125

82126
# Extract numbered queries
@@ -217,6 +261,8 @@ def synthesize_with_memory(self, system_prompt: str, query: str, content: str, s
217261

218262
try:
219263
synthesis, tokens = memory_run(system_prompt, memory_input, self.client, self.model)
264+
# Clean reasoning tags from synthesis response
265+
synthesis = clean_reasoning_tags(synthesis)
220266
return synthesis, tokens
221267
except Exception as e:
222268
return f"Memory synthesis failed: {str(e)}", 0
@@ -254,6 +300,8 @@ def evaluate_completeness(self, system_prompt: str, query: str, current_synthesi
254300
)
255301

256302
content = response.choices[0].message.content.strip()
303+
# Clean reasoning tags from completeness evaluation response
304+
content = clean_reasoning_tags(content)
257305
self.total_tokens += response.usage.completion_tokens
258306

259307
# Parse response
@@ -352,6 +400,8 @@ def generate_structured_report(self, system_prompt: str, original_query: str, sy
352400
)
353401

354402
report_content = response.choices[0].message.content.strip()
403+
# Clean reasoning tags from final report response
404+
report_content = clean_reasoning_tags(report_content)
355405
self.total_tokens += response.usage.completion_tokens
356406

357407
# Add references section with proper formatting

0 commit comments

Comments
 (0)