Skip to main content

#!/usr/bin/env python3 """ Prompt Optimizer for Claude Opus 4.5

Optimizes prompts by replacing aggressive language that may cause overtriggering in Opus 4.5. Based on Claude Operating Preferences v6.0.

Usage: python prompt-optimizer.py "Your MUST ALWAYS prompt" python prompt-optimizer.py --file system-prompt.md python prompt-optimizer.py --batch prompts/ python prompt-optimizer.py --report "CRITICAL: NEVER skip" """

import argparse import json import re import sys from dataclasses import dataclass, field from pathlib import Path from typing import List, Tuple, Dict, Optional

Aggressive language replacements

AGGRESSIVE_REPLACEMENTS = { # Imperatives "MUST": "Please", "ALWAYS": "Prefer to", "NEVER": "Avoid", "CRITICAL": "Important", "ABSOLUTELY": "", "REQUIRED": "Recommended", "MANDATORY": "Suggested",

# Emphasis
"VERY IMPORTANT": "Note",
"EXTREMELY": "Quite",
"ESSENTIAL": "Helpful",
"CRUCIAL": "Useful",

# Threats/Warnings
"UNDER NO CIRCUMSTANCES": "Generally avoid",
"YOU MUST NOT": "Please avoid",
"FAILURE TO": "If you don't",
"YOU WILL BE": "You may be",

}

Thinking word replacements (for when thinking is disabled)

THINK_REPLACEMENTS = { "think about": "consider", "think through": "work through", "think carefully": "review carefully", "think step by step": "proceed step by step", "think hard": "focus on", }

@dataclass class OptimizationChange: """Record of a single optimization change""" original: str replacement: str reason: str line_number: Optional[int] = None

@dataclass class OptimizationResult: """Result of prompt optimization""" original: str optimized: str changes: List[OptimizationChange] = field(default_factory=list)

@property
def change_count(self) -> int:
return len(self.changes)

@property
def reduction_percent(self) -> float:
if not self.original:
return 0
return (1 - len(self.optimized) / len(self.original)) * 100

def to_dict(self) -> Dict:
return {
"original_length": len(self.original),
"optimized_length": len(self.optimized),
"changes_made": self.change_count,
"reduction_percent": round(self.reduction_percent, 1),
"changes": [
{
"original": c.original,
"replacement": c.replacement,
"reason": c.reason,
"line": c.line_number
}
for c in self.changes
]
}

def optimize_prompt( text: str, no_thinking: bool = False, track_lines: bool = False ) -> OptimizationResult: """ Optimize prompt for Opus 4.5.

Args:
text: Input prompt text
no_thinking: Also replace "think" words
track_lines: Track line numbers for changes

Returns:
OptimizationResult with original, optimized, and changes
"""
result = text
changes: List[OptimizationChange] = []

# Process aggressive replacements
for original, replacement in AGGRESSIVE_REPLACEMENTS.items():
pattern = re.compile(re.escape(original), re.IGNORECASE)
matches = list(pattern.finditer(result))

for match in matches:
line_num = None
if track_lines:
line_num = result[:match.start()].count('\n') + 1

changes.append(OptimizationChange(
original=original,
replacement=replacement,
reason="Aggressive language may overtrigger",
line_number=line_num
))

if matches:
result = pattern.sub(replacement, result)

# Process thinking replacements if requested
if no_thinking:
for original, replacement in THINK_REPLACEMENTS.items():
pattern = re.compile(re.escape(original), re.IGNORECASE)
matches = list(pattern.finditer(result))

for match in matches:
line_num = None
if track_lines:
line_num = result[:match.start()].count('\n') + 1

changes.append(OptimizationChange(
original=original,
replacement=replacement,
reason="Thinking disabled - avoid 'think' words",
line_number=line_num
))

if matches:
result = pattern.sub(replacement, result)

# Remove excessive exclamation marks
excessive_pattern = re.compile(r'!{2,}')
if excessive_pattern.search(result):
changes.append(OptimizationChange(
original="!!+",
replacement="!",
reason="Excessive punctuation"
))
result = excessive_pattern.sub('!', result)

# Remove ALL CAPS words (except likely acronyms)
def lower_non_acronym(match):
word = match.group(0)
if len(word) <= 4: # Likely acronym (API, URL, etc.)
return word
return word.capitalize()

caps_pattern = re.compile(r'\b[A-Z]{5,}\b')
caps_matches = list(caps_pattern.finditer(result))
for match in caps_matches:
word = match.group(0)
changes.append(OptimizationChange(
original=word,
replacement=word.capitalize(),
reason="ALL CAPS may be too aggressive"
))
result = caps_pattern.sub(lower_non_acronym, result)

return OptimizationResult(
original=text,
optimized=result.strip(),
changes=changes
)

def print_report(result: OptimizationResult): """Print detailed optimization report""" print("\n" + "=" * 60) print("OPTIMIZATION REPORT") print("=" * 60)

print(f"\nStatistics:")
print(f" Original length: {len(result.original)} chars")
print(f" Optimized length: {len(result.optimized)} chars")
print(f" Reduction: {result.reduction_percent:.1f}%")
print(f" Changes made: {result.change_count}")

if result.changes:
print(f"\nChanges:")
print("-" * 60)
for i, change in enumerate(result.changes, 1):
line_info = f" (line {change.line_number})" if change.line_number else ""
print(f" {i}. {change.original} → {change.replacement}{line_info}")
print(f" Reason: {change.reason}")

print(f"\n{'Original':^30} | {'Optimized':^30}")
print("-" * 63)

# Show side-by-side comparison (truncated)
orig_lines = result.original.split('\n')[:10]
opt_lines = result.optimized.split('\n')[:10]

for i in range(max(len(orig_lines), len(opt_lines))):
orig = orig_lines[i][:28] if i < len(orig_lines) else ""
opt = opt_lines[i][:28] if i < len(opt_lines) else ""
print(f" {orig:<28} | {opt:<28}")

if len(orig_lines) > 10:
print(" ... (truncated)")

def process_file( filepath: Path, no_thinking: bool = False, dry_run: bool = False, output: Optional[Path] = None ) -> OptimizationResult: """Process a single file""" text = filepath.read_text() result = optimize_prompt(text, no_thinking, track_lines=True)

if not dry_run:
target = output or filepath
target.write_text(result.optimized)

return result

def process_batch( directory: Path, no_thinking: bool = False, dry_run: bool = False, extensions: Tuple[str, ...] = ('.md', '.txt') ) -> List[Tuple[Path, OptimizationResult]]: """Process all files in directory""" results = []

for ext in extensions:
for filepath in directory.glob(f'**/*{ext}'):
result = process_file(filepath, no_thinking, dry_run)
results.append((filepath, result))

return results

def main(): parser = argparse.ArgumentParser( description="Optimize prompts for Claude Opus 4.5" ) parser.add_argument( "prompt", nargs="?", help="Prompt text to optimize" ) parser.add_argument( "--file", type=Path, help="Read prompt from file" ) parser.add_argument( "--batch", type=Path, help="Process all files in directory" ) parser.add_argument( "--no-thinking", action="store_true", help="Also replace 'think' words" ) parser.add_argument( "--report", action="store_true", help="Show detailed optimization report" ) parser.add_argument( "--dry-run", action="store_true", help="Preview changes without modifying files" ) parser.add_argument( "--output", type=Path, help="Write optimized prompt to file" ) parser.add_argument( "--json", action="store_true", help="Output as JSON" )

args = parser.parse_args()

# Batch processing
if args.batch:
if not args.batch.is_dir():
print(f"Error: {args.batch} is not a directory")
sys.exit(1)

results = process_batch(
args.batch,
args.no_thinking,
args.dry_run
)

print(f"\nBatch Processing: {len(results)} files")
print("=" * 60)

total_changes = 0
for filepath, result in results:
if result.change_count > 0:
print(f"\n{filepath}:")
print(f" Changes: {result.change_count}")
print(f" Reduction: {result.reduction_percent:.1f}%")
total_changes += result.change_count

print(f"\n{'=' * 60}")
print(f"Total: {total_changes} changes across {len(results)} files")

if args.dry_run:
print("\n(Dry run - no files modified)")
return

# File processing
if args.file:
if not args.file.exists():
print(f"Error: {args.file} not found")
sys.exit(1)

result = process_file(
args.file,
args.no_thinking,
args.dry_run,
args.output
)

if args.json:
print(json.dumps(result.to_dict(), indent=2))
elif args.report:
print_report(result)
else:
print(result.optimized)

if args.dry_run:
print("\n(Dry run - file not modified)")
elif args.output:
print(f"\nWritten to: {args.output}")
return

# Direct prompt processing
if args.prompt:
result = optimize_prompt(args.prompt, args.no_thinking)

if args.json:
print(json.dumps(result.to_dict(), indent=2))
elif args.report:
print_report(result)
else:
print(result.optimized)

if args.output and not args.dry_run:
args.output.write_text(result.optimized)
print(f"\nWritten to: {args.output}")
return

# No input - show help
parser.print_help()

if name == "main": main()