Systems Library / Marketing Automation / How to Build a Content Tone Analyzer
Marketing Automation content marketing

How to Build a Content Tone Analyzer

Analyze content tone to ensure consistency with your brand voice guidelines.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Every brand has a voice document nobody reads. The ai content tone analyzer brand voice system makes your voice guidelines enforceable instead of aspirational. You define your brand voice once in structured parameters, then run any piece of content through the analyzer before it gets published. It scores the content against your actual standards and flags exactly what needs to change.

I built this after a client published twelve articles over three months that all sounded like different companies wrote them. The analyzer would have caught every single one. Consistent tone is a conversion factor. Readers who trust your voice buy more from you.

What You Need Before Starting

Step 1: Build Your Brand Voice Profile

Define your brand voice with enough precision that it can be scored against. Vague attributes like "friendly" are useless. Quantifiable dimensions work:

# voice_profile.py

VOICE_PROFILES = {
    "direct_expert": {
        "name": "Direct Expert",
        "description": "Authoritative practitioner. Leads with the answer. No hedge words. Treats the reader as a capable adult.",
        "dimensions": {
            "formality": {
                "target": 4,         # 1=very casual, 10=very formal
                "tolerance": 2,      # how much variance is acceptable
                "description": "Professional but not stuffy. You talk to people, not at them."
            },
            "confidence": {
                "target": 8,
                "tolerance": 1,
                "description": "States things directly. No 'might', 'could potentially', 'it is possible that'."
            },
            "technicality": {
                "target": 6,
                "tolerance": 2,
                "description": "Uses technical terms when accurate. Explains when needed. Does not dumb down."
            },
            "warmth": {
                "target": 5,
                "tolerance": 2,
                "description": "Human and approachable. Not cold. Not overly warm."
            },
            "urgency": {
                "target": 6,
                "tolerance": 2,
                "description": "Moves with purpose. Gets to the point. Does not meander."
            }
        },
        "banned_phrases": [
            "it is important to note",
            "in conclusion",
            "as we can see",
            "it goes without saying",
            "needless to say",
            "at the end of the day",
            "moving forward",
            "leverage",
            "synergy",
            "holistic approach"
        ],
        "required_characteristics": [
            "first person voice where appropriate",
            "active verbs over passive constructions",
            "concrete examples over abstract claims",
            "short sentences under 25 words on average"
        ],
        "reading_level_target": "Grade 6-7"
    }
}

Step 2: Build the Analyzer

import os
import json
import anthropic
from dotenv import load_dotenv
from voice_profile import VOICE_PROFILES

load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

def analyze_tone(content: str, profile_key: str = "direct_expert") -> dict:
    profile = VOICE_PROFILES[profile_key]
    dimensions_str = json.dumps(profile["dimensions"], indent=2)
    banned_str = "\n".join(f"- {p}" for p in profile["banned_phrases"])
    required_str = "\n".join(f"- {r}" for r in profile["required_characteristics"])
    
    prompt = f"""Analyze this content against the brand voice profile below. Return JSON only.

BRAND VOICE: {profile['name']}
DESCRIPTION: {profile['description']}

SCORING DIMENSIONS (target score 1-10, tolerance is acceptable variance):
{dimensions_str}

BANNED PHRASES:
{banned_str}

REQUIRED CHARACTERISTICS:
{required_str}

TARGET READING LEVEL: {profile['reading_level_target']}

CONTENT TO ANALYZE:
---
{content}
---

Return this JSON structure:
{{
  "overall_score": 0,
  "grade": "A/B/C/D/F",
  "on_brand": true/false,
  "dimensions": {{
    "formality": {{"score": 0, "delta": 0, "note": ""}},
    "confidence": {{"score": 0, "delta": 0, "note": ""}},
    "technicality": {{"score": 0, "delta": 0, "note": ""}},
    "warmth": {{"score": 0, "delta": 0, "note": ""}},
    "urgency": {{"score": 0, "delta": 0, "note": ""}}
  }},
  "banned_phrases_found": [],
  "missing_characteristics": [],
  "estimated_reading_level": "",
  "top_issues": [],
  "specific_rewrites": [
    {{"original": "", "suggested": "", "reason": ""}}
  ],
  "summary": ""
}}

For specific_rewrites: find the 2-3 sentences most off-brand and suggest exact replacements."""

    message = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2000,
        messages=[{"role": "user", "content": prompt}]
    )
    
    raw = message.content[0].text.strip()
    if raw.startswith("```"):
        raw = raw.split("```")[1]
        if raw.startswith("json"):
            raw = raw[4:]
    
    return json.loads(raw)

Step 3: Print a Readable Report

def print_analysis_report(analysis: dict, profile_key: str = "direct_expert"):
    profile = VOICE_PROFILES[profile_key]
    
    grade = analysis["grade"]
    score = analysis["overall_score"]
    on_brand = "PASS" if analysis["on_brand"] else "FAIL"
    
    print(f"\n{'='*50}")
    print(f"TONE ANALYSIS REPORT")
    print(f"Profile: {profile['name']}")
    print(f"{'='*50}")
    print(f"Overall Score: {score}/100  |  Grade: {grade}  |  Status: {on_brand}")
    print(f"\nSUMMARY: {analysis['summary']}")
    
    print(f"\nDIMENSION SCORES:")
    for dim, data in analysis["dimensions"].items():
        target = profile["dimensions"][dim]["target"]
        delta = data["delta"]
        indicator = "OK" if abs(delta) <= profile["dimensions"][dim]["tolerance"] else "OFF"
        print(f"  {dim.upper():15} Score: {data['score']:2}/10  Target: {target}  [{indicator}]  {data['note']}")
    
    if analysis["banned_phrases_found"]:
        print(f"\nBANNED PHRASES FOUND:")
        for phrase in analysis["banned_phrases_found"]:
            print(f"  - '{phrase}'")
    
    if analysis["missing_characteristics"]:
        print(f"\nMISSING CHARACTERISTICS:")
        for char in analysis["missing_characteristics"]:
            print(f"  - {char}")
    
    if analysis["specific_rewrites"]:
        print(f"\nSUGGESTED REWRITES:")
        for i, rw in enumerate(analysis["specific_rewrites"], 1):
            print(f"\n  {i}. ORIGINAL: {rw['original']}")
            print(f"     SUGGESTED: {rw['suggested']}")
            print(f"     REASON: {rw['reason']}")

Step 4: Run It

if __name__ == "__main__":
    sample_content = """
    In today's rapidly evolving digital landscape, it is important to note that content marketing 
    has become increasingly crucial for businesses looking to leverage their online presence. 
    Moving forward, organizations that fail to implement a holistic approach to content strategy 
    may find themselves at a competitive disadvantage. Needless to say, the synergies between 
    quality content and SEO cannot be overstated.
    """
    
    print("Analyzing content...")
    analysis = analyze_tone(sample_content, profile_key="direct_expert")
    print_analysis_report(analysis, profile_key="direct_expert")

What to Build Next

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems