How to Build a Content Tone Analyzer
Analyze content tone to ensure consistency with your brand voice guidelines.
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
- Python 3.10 or higher
- Anthropic API key
- A written brand voice guide or enough examples to define the parameters
pip install anthropic python-dotenv
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
- Build a pre-publish checklist that blocks content from being approved in your CMS until it passes the tone analyzer
- Create a writer onboarding tool that analyzes sample writing from new hires against your brand profile and gives them personalized feedback
- Add a historical tone tracker that measures whether your brand voice has drifted over the past 12 months
Related Reading
- How to Build an AI Blog Post Generator - Generate content that is already calibrated to your brand voice
- How to Create Automated Content Performance Reports - Correlate tone scores with traffic and conversion performance
- How to Create an AI-Powered FAQ Generator - Ensure FAQ content matches your brand voice before publishing
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