
Avoid Ai Writing
- 1.3k installs
- 2.8k repo stars
- Updated August 4, 2026
- conorbronsdon/avoid-ai-writing
avoid-ai-writing is a documentation agent skill that removes generic, predictable patterns from AI-generated prose before publishing or shipping for developers who want human-sounding technical writing.
About
avoid-ai-writing is a Documentation agent skill from conorbronsdon/avoid-ai-writing with 529 installs on skills.sh that strips generic, predictable phrasing from AI-generated prose before publishing or shipping. The skill guides agents to rewrite technical docs, blog posts, README sections, and release notes so they read naturally instead of repeating common LLM filler patterns. Developers reach for avoid-ai-writing as a final editorial pass when AI-drafted content is functionally correct but sounds templated or obviously machine-written. The skill focuses on diction, rhythm, and pattern removal rather than fact-checking or structural outlining. Use it immediately before merging documentation or publishing external-facing copy that was initially drafted by an AI coding agent.
- Detects and eliminates common AI writing tells such as hedging language, repetitive structures, and overly formal tone.
- Works across blog posts, landing pages, product copy, documentation, and email sequences.
- One-command agent skill that integrates directly into Claude, Cursor, or Codex workflows.
- Preserves your unique voice while making output read as if written by a human.
Avoid Ai Writing by the numbers
- 1,334 all-time installs (skills.sh)
- +160 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #874 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/conorbronsdon/avoid-ai-writing --skill avoid-ai-writingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.3k |
|---|---|
| repo stars | ★ 2.8k |
| Last updated | August 4, 2026 |
| Repository | conorbronsdon/avoid-ai-writing ↗ |
How do you remove obvious AI writing patterns?
Remove generic, predictable patterns from AI-generated prose before publishing or shipping.
Who is it for?
Developers polishing AI-drafted documentation, blog posts, or release notes who need a final pass to remove templated LLM phrasing before publishing.
Skip if: Fact-checking technical accuracy or generating initial content outlines where the primary need is research rather than prose de-AI-ing.
When should I use this skill?
AI-generated prose is ready to publish but reads generic, repetitive, or obviously machine-written and needs a human-tone editorial rewrite.
What you get
Human-sounding revised prose with generic AI filler patterns removed from docs and publish-ready copy.
- human-toned revised prose
By the numbers
- Reports 529 installs on skills.sh
- Ranked 9150 on the skills.sh leaderboard in the bundled metadata
Files
Avoid AI Writing — Audit & Rewrite
You are editing content to remove AI writing patterns ("AI-isms") that make text sound machine-generated.
What this skill is and isn't
This is a writing-quality tool, not a verdict. The patterns flagged here are statistically more common in LLM output, but humans on autopilot — especially writing under deadline pressure, in unfamiliar genres, or in a second language — produce the same shapes. Independent audits of commercial AI detectors have found false-positive rates above 60% on non-native English writers (Liang et al., Stanford, Patterns 2023) and overall misclassification rates above 70% on open-source detectors (Jabarian & Imas, BFI Working Paper 2025-116, 2025). Adversarial paraphrase reduces detection accuracy by ~88% across every method tested (arXiv:2506.07001, 2025).
The patterns are useful as a signal — both for cleaning up your own writing and for assessing whether a piece reads as AI-generated. Just don't make them the sole basis for a consequential decision (academic integrity, hiring, publication, attribution). Several rules here also fire on second-language writing, deadline-pressed humans, and technical genres that compress vocabulary by design. Pair the signal with context: who wrote it, what genre, what the writer's normal voice looks like, what other evidence you have.
In short: signals, not proof. Worth acting on; not worth ruining someone's day over.
Modes
This skill operates in one of three modes:
`rewrite` (default) — Flag AI-isms and rewrite the text to fix them.
`detect` — Flag AI-isms only. No rewriting. Use this mode when:
- The writer wants to see what's flagged and decide what to fix themselves
- The flagged patterns might be intentional (AI patterns aren't always bad — they can be effective in small doses)
- You're auditing text you don't want altered (published content, someone else's writing, reference material)
- You want a quick scan without waiting for a full rewrite
`edit` — Edit a file in place rather than returning rewritten text. Use this when the writer points you at a file ("clean up draft.md", "fix the AI-isms in this file directly") and wants the file changed, not a copy to paste back. Make minimal, targeted edits with the Edit tool — change the flagged spans, not the whole document. Preserve passages that are already human: if a paragraph has no tells, leave it untouched. Don't edit quoted material, code blocks, or text attributed to someone else — flag those instead of rewriting them. For a large file, confirm which section to clean before changing anything. After editing, re-read the file and confirm the flagged patterns are resolved.
Trigger detect mode when the user says "detect," "flag only," "audit only," "just flag," "scan," "what AI patterns are in this," or similar. Trigger edit mode when the user names a file and asks you to fix or clean it in place. Default to rewrite mode if not specified.
Invocation. Natural language is enough ("rewrite this in a blunt voice for LinkedIn," "edit post.md in place," "scan this, don't rewrite"). Power users can also pass explicit options, which map to the sections below: [--mode rewrite|detect|edit], [--voice casual|professional|technical|warm|blunt], [--context linkedin|blog|technical-blog|investor-email|docs|casual], [--file PATH], [--iterate N] (max 2).
Iterate to convergence (optional). Rewrite mode already runs one corrective second pass (see Output format) — that built-in pass is pass 2, so --iterate does not stack on top of it. When the writer asks to "iterate," "keep going until it's clean," or passes --iterate N, repeat the audit→rewrite cycle until no patterns remain or N passes are reached. Cap N at 2: a rewrite plus one corrective pass clears the flagged patterns, and a third pass costs a full regeneration while rarely finding more. Report how many passes it took ("converged in 2 passes").
---
In rewrite mode, your job is to:
1. Audit it: identify every AI-ism present, citing the specific text 2. Rewrite it: return a clean version with all AI-isms removed 3. Show a diff summary: briefly list what you changed and why
In detect mode, your job is to:
1. Audit it: identify every AI-ism present, citing the specific text 2. Assess it: note which flags are clear problems vs. patterns that may be intentional or effective in context
In edit mode, your job is to:
1. Read the file the writer named 2. Edit in place: apply minimal, targeted fixes to the flagged spans with the Edit tool, leaving already-human passages untouched 3. Verify: re-read the file and confirm the flagged patterns are resolved; report what you changed
---
What to remove or fix
Formatting
- Em dashes (— and --): Replace with commas, periods, parentheses, or rewrite as two sentences. Target: zero. Hard max: one per 1,000 words. This applies to headings and section titles too, not just body prose. Catch both the Unicode em dash (—) and the double-hyphen substitute (--).
- Bold overuse: Strip bold from most phrases. One bolded phrase per major section at most, or none. If something's important enough to bold, restructure the sentence to lead with it instead.
- Emoji in headers: Remove entirely. No
## 🚀 What This Means. Exception: social posts may use one or two emoji sparingly — at the end of a line, never mid-sentence. - Excessive bullet lists: Convert bullet-heavy sections into prose paragraphs. Bullets only for genuinely list-like content (feature comparisons, step-by-step instructions, API parameters).
- Curly quotation marks (“ ” ‘ ’) and apostrophes: Curly quotes and apostrophes (U+201C/U+201D, U+2018/U+2019) are a weak paste-from-chat signal — meaningful mainly in plain-text contexts like code comments, commit messages, or plaintext drafts, where nothing auto-curls. Treat as corroborating, never conclusive: Word, Google Docs, macOS, and iOS curl quotes by default, so most human prose contains them too. Don't flag curly apostrophes (U+2019) on their own. Replace with straight quotes in plain-text/code; leave them in finished publications and locale-correct punctuation (French « », German „ “).
Sentence structure
- "It's not X — it's Y" / "This isn't about X, it's about Y": Rewrite as a direct positive statement. Max one per piece, and only if it serves the argument.
- Hollow intensifiers: Cut
genuine/genuinely,real(as in "a real improvement"),truly,quite frankly,to be honest,let's be clear,it's worth noting that. Just state the fact. - Vague endorsement ("worth [verb]ing"): Cut or replace
worth reading,worth paying attention to,worth a look,worth exploring,worth checking out,worth your time. These substitute a generic thumbs-up for a specific reason. Say why something matters instead. - Hedging: Cut
perhaps,could potentially,it's important to note that,to be clear. Make the point directly. - Missing bridge sentences: Each paragraph should connect to the last. If paragraphs could be rearranged without the reader noticing, add connective tissue.
- Compulsive rule of three: Vary groupings. Use two items, four items, or a full sentence instead of triads. Max one "adjective, adjective, and adjective" pattern per piece.
Words and phrases to replace
Words are organized into three tiers based on how reliably they signal AI-generated text. This tiered approach — adapted from brandonwise/humanizer's vocabulary research — reduces false positives on words that are fine in isolation but suspicious in clusters.
- Tier 1 — Always flag. These words appear 5–20x more often in AI text than human text. Replace on sight.
- Tier 2 — Flag in clusters. Individually fine, but two or more in the same paragraph is a strong AI signal. Flag when they appear together.
- Tier 3 — Flag by density. Common words that AI simply overuses. Only flag when they make up a noticeable fraction of the text (roughly 3%+ of total words).
Match inflected forms. Each entry below covers the listed word and its morphological variants — adverb (-ly), gerund/participle (-ing), plural, comparative/superlative, and verb conjugations — unless a variant carries a distinct, legitimate meaning. So genuine also flags genuinely, leverage also flags leveraging / leveraged, delve covers delving, and meticulous covers meticulously. When a variant has a separate honest sense (e.g. real meaning factual, not the intensifier in "a real improvement"), judge by context rather than matching blindly.
Tier 1 — Always replace
| Replace | With |
|---|---|
| delve / delve into | explore, dig into, look at |
| landscape (metaphor) | field, space, industry, world |
| tapestry | (describe the actual complexity) |
| realm | area, field, domain |
| paradigm | model, approach, framework |
| embark | start, begin |
| beacon | (rewrite entirely) |
| testament to | shows, proves, demonstrates |
| robust | strong, reliable, solid |
| comprehensive | thorough, complete, full |
| cutting-edge | latest, newest, advanced |
| leverage (verb) | use |
| pivotal | important, key, critical |
| underscores | highlights, shows |
| meticulous / meticulously | careful, detailed, precise |
| seamless / seamlessly | smooth, easy, without friction |
| game-changer / game-changing | describe what specifically changed and why it matters |
| hit differently / hits different | (say what specifically changed, or cut) |
| utilize | use |
| watershed moment | turning point, shift (or describe what changed) |
| marking a pivotal moment | (state what happened) |
| the future looks bright | (cut — say something specific or nothing) |
| only time will tell | (cut — say something specific or nothing) |
| nestled | is located, sits, is in |
| vibrant | (describe what makes it active, or cut) |
| thriving | growing, active (or cite a number) |
| despite challenges… continues to thrive | (name the challenge and the response, or cut) |
| showcasing | showing, demonstrating (or cut the clause) |
| deep dive / dive into | look at, examine, explore |
| unpack / unpacking | explain, break down, walk through |
| bustling | busy, active (or cite what makes it busy) |
| intricate / intricacies | complex, detailed (or name the specific complexity) |
| complexities | (name the actual complexities, or use "problems" / "details") |
| ever-evolving | changing, growing (or describe how) |
| enduring | lasting, long-running (or cite how long) |
| daunting | hard, difficult, challenging |
| holistic / holistically | complete, full, whole (or describe what's included) |
| actionable | practical, useful, concrete |
| impactful | effective, significant (or describe the impact) |
| learnings | lessons, findings, takeaways |
| thought leader / thought leadership | expert, authority (or describe their actual contribution) |
| best practices | what works, proven methods, standard approach |
| at its core | (cut — just state the thing) |
| synergy / synergies | (describe the actual combined effect) |
| interplay | relationship, connection, interaction |
| in order to | to |
| due to the fact that | because |
| serves as | is |
| features (verb) | has, includes |
| boasts | has |
| presents (inflated) | is, shows, gives |
| commence | start, begin |
| ascertain | find out, determine, learn |
| endeavor | effort, attempt, try |
| keen (as intensifier) | interested, eager, enthusiastic (or cut — just state the interest) |
| genuinely / genuine (as intensifier) | (cut — just state the fact) |
| symphony (metaphor) | (describe the actual coordination or combination) |
| embrace (metaphor) | adopt, accept, use, switch to |
Tier 2 — Flag when 2+ appear in the same paragraph
These words are legitimate on their own. When two or more show up together, the paragraph likely needs a rewrite.
| Replace | With |
|---|---|
| harness | use, take advantage of |
| navigate / navigating | work through, handle, deal with |
| foster | encourage, support, build |
| elevate | improve, raise, strengthen |
| unleash | release, enable, unlock |
| streamline | simplify, speed up |
| empower | enable, let, allow |
| bolster | support, strengthen, back up |
| spearhead | lead, drive, run |
| resonate / resonates with | connect with, appeal to, matter to |
| revolutionize | change, transform, reshape (or describe what changed) |
| facilitate / facilitates | enable, help, allow, run |
| underpin | support, form the basis of |
| nuanced | specific, subtle, detailed (or name the actual nuance) |
| crucial | important, key, necessary |
| multifaceted | (describe the actual facets, or cut) |
| ecosystem (metaphor) | system, community, network, market |
| myriad | many, numerous (or give a number) |
| plethora | many, a lot of (or give a number) |
| encompass | include, cover, span |
| catalyze | start, trigger, accelerate |
| reimagine | rethink, redesign, rebuild |
| galvanize | motivate, rally, push |
| augment | add to, expand, supplement |
| cultivate | build, develop, grow |
| illuminate | clarify, explain, show |
| elucidate | explain, clarify, spell out |
| juxtapose | compare, contrast, set side by side |
| paradigm-shifting | (describe what actually shifted) |
| transformative / transformation | (describe what changed and how) |
| cornerstone | foundation, basis, key part |
| paramount | most important, top priority |
| poised (to) | ready, set, about to |
| burgeoning | growing, emerging (or cite a number) |
| nascent | new, early-stage, emerging |
| quintessential | typical, classic, defining |
| overarching | main, central, broad |
| underpinning / underpinnings | basis, foundation, what supports |
Tier 3 — Flag only at high density
These are normal words. Only flag them when the text is saturated with them — a sign that AI filled space with vague praise instead of specifics.
| Word | What to do |
|---|---|
| significant / significantly | Replace some with specifics: numbers, comparisons, examples |
| innovative / innovation | Describe what's actually new |
| effective / effectively | Say how or cite a metric |
| dynamic / dynamics | Name the actual forces or changes |
| scalable / scalability | Describe what scales and to what |
| compelling | Say why it compels |
| unprecedented | Name the precedent it breaks (or cut) |
| exceptional / exceptionally | Cite what makes it an exception |
| remarkable / remarkably | Say what's worth remarking on |
| sophisticated | Describe the sophistication |
| instrumental | Say what role it played |
| world-class / state-of-the-art / best-in-class | Cite a benchmark or comparison |
Tier 3 phrases — Flag at density or in clusters
Multi-word boilerplate that's individually unobjectionable but stacks heavily in AI-generated content (crypto, web3, DePIN, AI/infra reviews are the worst offenders). Flag at 2+ uses of the same phrase (the per-phrase rule — lower threshold than single-word Tier 3 because a two-word match repeated twice is already stronger evidence than re-using "significant"), plus a cluster rule: three or more distinct phrases from this table in one piece is a strong signal even when each phrase only appears once — that's the shape LLMs take when they vary their own boilerplate to seem less repetitive.
| Phrase | What to do |
|---|---|
| emerging sector / emerging space / emerging category | Name the actual sector or what's emerging about it |
| the integration of (X with Y) | Describe what's being integrated and what changes for the user |
| the intersection of (X and Y) | Pick the specific overlap that matters or cut the framing |
| community-driven | Name what the community does. "Community-driven" alone is filler |
| long-term sustainability | Cite the time horizon and the constraint. "Long-term" is hand-waving |
| user engagement | Name the action. "Engagement" is a wrapper around clicks/comments/retention |
| decentralized compute | Specify the architecture or cut. The phrase has become a category label, not a claim |
| (sustainable) reward emissions | Cite the emission schedule and the sink |
| tokenized incentive structures | Describe the actual mechanism (vesting, gauge, bonded LP, etc.) |
| designed for long-term [X] | Cut "designed for" — either it is or it isn't. Then state the property |
Template phrases (avoid)
These slot-fill constructions signal that a sentence was generated, not written. If a phrase has a blank where a noun or adjective could go and still sound the same, it's too generic.
- "a [adjective] step towards [adjective] AI infrastructure" → describe the specific capability, benchmark, or outcome
- "a [adjective] step forward for [noun]" → same rule: say what actually changed
- "Whether you're [X] or [Y]" → false-breadth construction. Pick the audience you're actually addressing, or cut. "Whether you're a startup founder or an enterprise architect" means nothing — it's just "everyone."
- "I recently had the pleasure of [verb]-ing" → review/social AI pattern. Just say what happened: "I talked to," "I read," "I attended."
Transition phrases to remove or rewrite
- "Moreover" / "Furthermore" / "Additionally" → restructure so the connection is obvious, or use "and," "also," "on top of that"
- "In today's [X]" / "In an era where" → cut or state specific context
- "It's worth noting that" / "Notably" → just state the fact
- "Here's what's interesting" / "Here's what caught my eye" / "Here's what stood out" → reader-steering frames. Let the content signal its own importance. If you need a lead-in, make it specific: "The revenue number matters because..." not "Here's the interesting part."
- "In conclusion" / "In summary" / "To summarize" → your conclusion should be obvious
- "When it comes to" → just talk about the thing directly
- "At the end of the day" → cut
- "That said" / "That being said" → cut or use "but," "yet," or "however." Don't overuse any one of them.
Structural issues
- Uniform paragraph length: Vary deliberately. Include some 1-2 sentence paragraphs and some longer ones. If every paragraph is roughly the same size, fix it.
- Formulaic openings: If the piece opens with broad context before getting to the point ("In the rapidly evolving world of..."), rewrite to lead with the news or the insight. Context can come second.
- Suspiciously clean grammar: Don't sand away all personality. Deliberate fragments, sentences starting with "And" or "But," comma splices for effect: if the natural voice uses them, keep them.
Significance inflation
- Phrases like "marking a pivotal moment in the evolution of..." or "a watershed moment for the industry" inflate routine events into history-making ones. State what happened and let the reader judge significance.
- If the sentence still works after you delete the inflation clause, delete it.
Generic future-narrative closers
- "May become one of the most important narratives of the next market cycle," "could become the defining trend of the coming decade," "is poised to become the next major chapter in [X]." AI defaults to this shape when it needs to land a closing thought without committing to a falsifiable claim. The closer is grammatically a prediction but contains no testable content.
- Pattern: modal (may / could / will / is poised to) + "become" + (one of) the most [adjective] + (narrative / story / trend / theme / chapter / movement / force).
- Fix: pick the falsifiable version. "DePIN compute may exceed AWS spot pricing for embarrassingly parallel workloads by 2027" is a prediction. "The intersection of AI and DePIN may become one of the most important narratives of the next market cycle" is not.
Hedge-stacked predictions
- Stacking a modal with a hedge adverb: "could potentially create," "may eventually unlock," "might ultimately transform." Either word alone is acceptable; the stack is the tell. Each hedge cancels the next, leaving a sentence that asserts nothing while sounding cautious and thoughtful.
- Fix: pick one. If you mean "could create," say that. If you mean "potentially creates," say that. Both together is filler.
"Real/actual" adjective inflation
- "Real on-chain tokenomics," "actual reward sustainability," "genuine utility," "true product-market fit." Using
real/actual/genuine/trueas an empty intensifier on an abstract noun implies the rest of the field is fake or superficial — without naming what makes this instance the real one. Common in crypto/AI/web3 content where the writer wants to signal sophistication. - Distinct from the existing "hollow intensifiers" rule (genuine / truly / quite frankly as sentence-level hedges). This is the noun-modifier form, where the intensifier latches onto an abstract noun to manufacture a contrast that goes unsaid.
- Carve-out — named contrast: if the sentence explicitly names what the fake/superficial version is, leave it. "Real on-chain settlement, not bridged IOUs" or "actual revenue from paying customers, not grants" is honest contrastive writing. The AI tell is the unsaid contrast.
- Fix when no contrast is named: drop the adjective and add the specific claim. "Reward sustainability" → "rewards funded from $X/mo in fees rather than emissions."
Hashtag stuffing
- Long trailing hashtag blocks (6+ hashtags on a single short post) are near-universal in LLM-generated social content and rare in thoughtful human posts. The block usually mixes a project-specific tag with broad category tags (#AI #Crypto #Web3 #Innovation #FutureTech #Technology) — the categorical ones do nothing for discoverability and read as bot output.
- Why 6? Empirical floor. LinkedIn and X organic engagement plateaus or declines past 3-5 tags; human posts that exceed 5 are usually launch posts trading reach for engagement, while LLM-generated posts default to 10-15. Six is the threshold where false positives on legitimate human use start dropping below false negatives on AI output. The detector treats 6+ as a hard flag; the spec treats 5+ as a soft tell worth a second look on
linkedinandinvestor-emailprofiles. - Fix: 2-3 specific tags max, or none. If a hashtag wouldn't help a reader find related work, it's filler.
Bullet lists of bare noun phrases
- A list of 5+ consecutive bullet items where each item is a short (≤6 word) adjective-plus-noun phrase with no verb. "Stable mining efficiency / Reliable pool connectivity / Optimized RandomX performance / Low failed share rates / Effective hardware utilization / Consistent thermal stability." Reads as a marketing one-pager because that's the shape LLMs default to when asked to summarize features.
- The tell is the symmetry: every item is the same grammatical shape, every item is parallel in length, none of them assert anything checkable. A genuine list of observations would have varying length, occasional verbs, and at least one item that doesn't fit the pattern.
- Fix: convert to prose paragraph, or rewrite items as full claims ("Failed shares stayed under 1% across a 12-hour run" beats "Low failed share rates"). If the list is genuinely the right form, vary the items so each carries a different shape of information.
- This rule does not apply to genuine list content (changelog entries, todo lists, parameter docs, ingredient lists) where bare noun phrases are the correct form. The detector keys on absence of finite verbs to separate the two — but in prose audits, ask whether the bullets are summarizing claims (rewrite) or enumerating items (leave).
Copula avoidance
- AI text avoids "is" and "has" by substituting fancier verbs: "serves as," "features," "boasts," "presents," "represents." These sound like a press release.
- Default to "is" or "has" unless a more specific verb genuinely adds meaning.
Synonym cycling
- AI rotates synonyms to avoid repeating a word: "developers… engineers… practitioners… builders" in the same paragraph. Human writers repeat the clearest word.
- If the same noun or verb appears three times in a paragraph and that's the right word, keep all three. Forced variation reads as thesaurus abuse.
Vague attributions
- "Experts believe," "Studies show," "Research suggests," "Industry leaders agree" — without naming the expert, study, or leader. Either cite a specific source or drop the attribution and state the claim directly.
Filler phrases
- Strip mechanical padding that adds words without meaning:
- "It is important to note that" → (just state it)
- "In terms of" → (rewrite)
- "The reality is that" → (cut or just state the claim)
- Note: "In order to," "Due to the fact that," and "At the end of the day" are covered in the word/phrase table and transition sections above — don't duplicate rules.
Generic conclusions
- "The future looks bright," "Only time will tell," "One thing is certain," "As we move forward" — these are filler disguised as conclusions. Cut them. If the piece needs a closing thought, make it specific to the argument.
Chatbot artifacts
- "I hope this helps!", "Certainly!", "Absolutely!", "Great question!", "Feel free to reach out," "Let me know if you need anything else" — these are conversational tics from chat interfaces, not writing. Remove entirely.
- Also watch for: "In this article, we will explore…" or "Let's dive in!" — these are AI-generated meta-narration. Cut or rewrite with a direct opening.
"Let's" constructions
- "Let's explore," "Let's take a look," "Let's break this down," "Let's examine" — AI uses "let's" as a false-collaborative opener to ease into a topic. It's filler that delays the actual point. Just start with the point. "Let's dive in" is covered above under chatbot artifacts, but the pattern is broader than that — flag any "let's + verb" that's functioning as a transition rather than a genuine invitation to act.
Notability name-dropping
- AI text piles on prestigious citations to manufacture credibility: "cited in The New York Times, BBC, Financial Times, and The Hindu." If a source matters, use it with context: "In a 2024 NYT interview, she argued..." One specific reference beats four name-drops.
Superficial -ing analyses
- Strings of present participles used as pseudo-analysis: "symbolizing the region's commitment to progress, reflecting decades of investment, and showcasing a new era of collaboration." These say nothing. Replace with specific facts or cut entirely.
- The same move shows up without the -ing: declarative "meaning-telling" that glosses a mundane subject as if it were profound — "this represents a broader shift," "the decision symbolizes a commitment to excellence," "it speaks to a larger trend in the industry." If the significance is real, show it with a specific consequence; otherwise cut. Adapted from
Aboudjem/humanizer-skillP40.
Promotional language
- AI defaults to tourism-brochure prose: "nestled within the breathtaking foothills," "a vibrant hub of innovation," "a thriving ecosystem." Replace with plain description: "is a town in the Gonder region," "has 12 startups." If you wouldn't say it in conversation, cut it.
Formulaic challenges
- "Despite challenges, [subject] continues to thrive" or "While facing headwinds, the organization remains resilient." This is a non-statement. Name the actual challenge and the actual response, or cut the sentence.
False ranges
- AI creates false breadth by pairing unrelated extremes: "from the Big Bang to dark matter," "from ancient civilizations to modern startups." These sound sweeping but say nothing. List the actual topics or pick the one that matters.
Inline-header lists
- Bullet lists where each item starts with a bold header that repeats itself: "Performance: Performance improved by..." Strip the bold header and write the point directly. If the list items need headers, they should probably be paragraphs.
List-label periods
- In bulleted lists where each item leads with a short label, LLMs end the label with a period and then run the explanation as a separate sentence. A person writing the same list almost always uses a colon instead. Strongest form: bold labels (
**Intros.**,**Content distribution.**,**Developer GTM.**where a human writes**Intros:**). Weaker but still a tell: the same shape without bold (- Intros. Years of conferences and operator network.) — a short noun-phrase label terminated with a period at the start of a bullet, followed by a gloss. The colon reads as "here's what this label means"; the period reads as a sentence that the following clause then contradicts by continuing. Example tell:- **Intros.** Years of conferences and operator network.becomes- **Intros:** years of conferences and operator network.Fix the period to a colon and lowercase the start of the gloss, or drop the label and write the point as a plain sentence. Carve-outs: when the label span is a full sentence on its own (not a label introducing a gloss), the period is correct; and for the unbolded form, only flag when the leading fragment is clearly a label (a 1-4 word noun phrase, no verb) — a short complete sentence opening a bullet is fine.
Title case headings
- AI over-capitalizes headings: "Strategic Negotiations And Key Partnerships" instead of "Strategic negotiations and key partnerships." Use sentence case for subheadings. Title case only for the piece's main title, if at all.
Hyphenated-pair overuse
- AI stacks compound modifiers: "a high-quality, well-architected, future-proof solution." Two distinct problems. First, density — strings of hyphenated adjectives piled on one noun; cut to the modifier that actually matters. Second, the attributive/predicate error: a compound is hyphenated before the noun ("a high-quality report") but not after a linking verb ("the report is high quality," no hyphen). AI frequently hyphenates the predicate form; fix it to two words. Adapted from
blader/humanizerP26.
Cutoff disclaimers
- "While specific details are limited based on available information," "As of my last update," "I don't have access to real-time data." These are model limitations leaking into prose. Either find the information or remove the hedge. Never publish a sentence that admits the writer didn't look something up.
Speculative gap-filling
- When the model lacks a fact, it fills the gap with hedged speculation dressed up as background: "maintains a relatively low public profile," "is believed to have," "likely began his career in," "appears to have studied." These are guesses formatted as statements. Distinct from cutoff disclaimers, which admit the gap — this one hides it behind plausible-sounding filler, which is worse because the reader can't tell what's known from what's invented. Cut the speculation, or replace it with a sourced fact. Adapted from
blader/humanizerP21.
Unfilled placeholders
- Bracketed slot-fillers that were meant to be replaced before publishing:
[Your Name],[INSERT SOURCE URL],[Describe the specific section],2025-XX-XX,<!-- Add citation if available -->. These are near-definitive evidence that AI-generated boilerplate was pasted without editing. Humans use placeholders in templates too, but rarely ship them. Treat any visible placeholder as a publishing bug: fill it in with real content or delete the sentence entirely. - Catch the obvious shapes:
\[(?:Your|Insert|Add|Enter|Describe|Specify|Choose)[^\]]+\],\b\d{4}-XX-XX\b, HTML/Markdown comments with placeholder verbs (add,fill in,todo,insert).
Chatbot citation markup leaks
- Internal citation tokens that leak through when text is copy-pasted from chat UIs:
citeturn0search0,contentReference[oaicite:0]{index=0},oai_citation,[attached_file:1],grok_card. These are not patterns — they are fingerprints. Their presence is essentially proof the text was generated by a specific chat tool and pasted without cleanup. - The fix is mechanical: strip every markup token. If a citation was meaningful, replace it with a real reference. Don't try to humanize the markup — delete it.
- Adapted from
Aboudjem/humanizer-skillP34. Worth catching even when nothing else in the text reads as AI — the token itself is enough.
AI-tool URL parameters
- Tracking parameters that AI tools auto-append to URLs they generate, surviving copy-paste into published content:
utm_source=chatgpt.com,utm_source=copilot.com,utm_source=openai,utm_source=claude.ai,utm_source=perplexity.ai,referrer=grok.com. Same logic as citation markup leaks — the presence of the parameter is the signature, regardless of what the surrounding text reads like. - The fix: strip the parameter from every URL. Keep the URL itself if the link is meaningful; lose the parameter entirely. Adapted from
Aboudjem/humanizer-skillP35.
Novelty inflation
- AI text treats established concepts as if the speaker invented or discovered them: "He introduced a term," "She coined the phrase," "a concept nobody's naming," "a failure mode nobody talks about." In reality, most ideas in a conversation are applications of existing concepts, not inventions.
- Two problems. First, it's factually risky: if the concept already has a Wikipedia page or conference talks from last year, claiming novelty makes the writer look uninformed. Second, it flatters the subject in a way that reads as promotional rather than analytical.
- The fix: describe what the person did with the concept, not that they discovered it. "Michel walked through how context poisoning works in practice" instead of "Michel introduced a term I hadn't heard before: context poisoning." If you're unsure whether something is novel, assume it isn't and frame accordingly.
- Related patterns to flag: "the failure mode nobody's naming," "a problem nobody talks about," "the insight everyone's missing," "what nobody tells you about." These are engagement-bait framings that claim scarcity of knowledge where none exists.
Infomercial engagement hooks
- Punchy fragment-hooks that tee up a reveal: "The catch?", "The kicker?", "Here's the thing.", "But here's the kicker:", "The best part?", "Plot twist:", "The result?". AI uses these to fake momentum and manufacture suspense around ordinary information — the prose equivalent of a late-night infomercial.
- Distinct from rhetorical-question openers (which stall before a point) and chatbot artifacts (which perform helpfulness): these are mid-flow teasers that pad the rhythm. The fix is to delete the hook and state the thing. "The catch? It only works on weekends." becomes "It only works on weekends." Adapted from
Aboudjem/humanizer-skillP41.
Social endorsement closers
- The curatorial sign-off LLMs append to LinkedIn and X posts that share or recommend something — usually a colon teeing up a link: "This one is worth your time:", "This one's a must-read:", "I highly recommend giving this a read.", "Do yourself a favor and read this.", "You won't want to miss this one.", "Save this for later.", "Bookmark this.", "Don't sleep on this one.", "Trust me, you'll want to read this.", "Thank me later."
- Why it's a tell: it performs a recommendation without giving the reader a reason to click. The endorsement is generic and demonstrative-anchored ("THIS one is worth your time") — it could sit under any link, which is exactly why an LLM reaches for it to close a share post.
- Distinct from the bare "worth [verb]ing" word-table entry (a single weak word inside a sentence) and from infomercial engagement hooks (mid-flow teasers like "The catch?"): this is the whole closing line of a social post.
- The fix: say what the thing is and who it's for, then drop the CTA. "This one is worth your time:" becomes "Sarah's breakdown of why context windows leak — the clearest explanation I've found for anyone debugging RAG pipelines." If you can't name a specific reason, the share doesn't need a sign-off at all; let the link stand on its own.
Emotional flatline
- AI claims emotions as a structural crutch without conveying them through the writing: "What surprised me most," "I was fascinated to discover," "What struck me was," "I was excited to learn," "The most interesting part," and the bare section-header variant: "Interesting part of the project:" / "Interesting thing here:" / "Interesting aspect:". The header form drops "the most" but does the same job — pre-announcing significance the writing hasn't earned.
- Two problems. First, it's tell-don't-show: if the thing is genuinely surprising, the reader should feel that from the content, not from the writer announcing it. Second, these phrases are massively overused as list introductions and transitions. They're filler wearing an emotion costume.
- This pattern isn't always AI. It's also a sign of lazy human writing on autopilot. Flag it either way.
- The fix isn't "never say surprised." It's: if you claim an emotion, the writing around it should earn it. Otherwise cut the claim and present the thing directly.
- Related pattern: "hit differently" / "hits different." AI uses trendy colloquialisms as a shortcut to sound relatable without earning the emotional beat. If something genuinely affected you, describe how. Otherwise cut.
False concession structure
- "While X is impressive, Y remains a challenge" or "Although X has made strides, Y is still an open question." AI uses this to sound balanced without actually weighing anything. Both halves are vague. Either make the concession specific (name what's impressive, name the actual challenge) or pick a side and argue it.
Rhetorical question openers
- "But what does this mean for developers?" / "So why should you care?" / "What's next?" — AI uses rhetorical questions to stall before the actual point. If you know the answer, just say it. Rhetorical questions are earned by strong setup, not dropped as section transitions.
Parenthetical hedging
- "(and, increasingly, Z)" / "(or, more precisely, Y)" / "(and perhaps more importantly, W)" — AI inserts parenthetical asides to sound nuanced without committing. If the aside matters, give it its own sentence. If it doesn't, cut it.
Numbered list inflation
- "Three key takeaways" / "Five things to know" / "Here are the top seven" — AI defaults to numbered lists because they're structurally safe. Only use numbered lists when the content genuinely has that many discrete, parallel items. If you're padding to hit a number, the list shouldn't exist.
Reasoning chain artifacts
- "Let me think step by step," "Breaking this down," "To approach this systematically," "Step 1:," "Here's my thought process," "First, let's consider," "Working through this logically" — these are artifacts of chain-of-thought reasoning leaking into published prose. The reader doesn't need to see the scaffolding. State the conclusion, then the evidence.
- Also watch for numbered reasoning steps that read like an internal monologue rather than an argument meant for an audience.
Sycophantic tone
- "Great question!", "Excellent point!", "You're absolutely right!", "That's a really insightful observation" — these are conversational rewards from chat interfaces, not writing. Remove entirely.
- Distinct from chatbot artifacts: sycophancy specifically validates the reader/questioner rather than just performing helpfulness.
Acknowledgment loops
- "You're asking about," "The question of whether," "To answer your question," "That's a great question. The..." — AI restates the prompt before answering. In writing, this is pure filler. The reader knows what they asked. Just answer.
- Related pattern: opening a section by summarizing what the previous section said. If the structure is clear, the reader doesn't need a recap.
Confidence calibration phrases
- "It's worth noting that," "Interestingly," "Surprisingly," "Importantly," "Significantly," "Notably," "Certainly," "Undoubtedly," "Without a doubt" — AI uses these to signal how the reader should feel about a fact instead of letting the fact speak for itself.
- "Here's what's interesting," "Here's the interesting part," "Here are the parts I found interesting" — reader-steering cue that pre-interprets importance. Works when followed by genuinely surprising data; fails when it introduces a restatement of something obvious (which is the AI default).
- One "notably" in a 2,000-word piece is fine. Three in 500 words is AI-style emphasis stacking. Flag by density.
- Related — persuasive-authority tropes: "the real question is," "at its core," "fundamentally," "make no mistake," "the truth is." Same move as the calibration phrases above, but they assert depth or stakes instead of feeling: they announce that what follows is important rather than showing it. Cut the trope and lead with the substance. Adapted from
blader/humanizerP27.
Self-labeling significance
- After listing or describing several items, the writer points back at one and labels it as contrarian / clever / surprising / counterintuitive / key: "That last move is the contrarian one," "This is the interesting part," "That third bullet is the real story," "Here's where it gets clever," "The last bit is the counterintuitive one."
- The label does the work the content was supposed to do. If a move is genuinely contrarian, the reader recognizes it from the description; if it isn't recognizable without the label, the label is unearned. The pattern reads as the writer auditing their own list to flag which item should matter, instead of writing the list so the right item carries the weight on its own.
- Distinct from confidence calibration ("Notably," "Interestingly") which front-loads the cue, and from emotional flatline ("What surprised me most," "The most interesting part") which prefaces a single claim. This pattern back-points after the fact, usually as "[that / this / the Xth / the last] [noun] is the [adjective] one."
- Significance-adjectives that signal the pattern: contrarian, clever, surprising, counterintuitive, interesting, key, important, unusual, smart, brilliant, real, actual.
- Fix: cut the labeling sentence and let the explanation that follows do the work directly. Or restructure so the item you wanted to highlight is positioned first or expanded with specifics, making the label redundant.
- Example. Before: "→ Two separate indexes for tiered storage. That last move is the contrarian one. Co-locating related data usually helps cache locality." After: "→ Two separate indexes for tiered storage. Co-locating related data usually helps cache locality, but splitting the indexes is what makes the hot path cheap." The contrast carries itself; the label is gone.
Excessive structure
- Too many headers in short text: more than 3 headings in under 300 words is almost always AI trying to look organized. Merge sections or use prose transitions instead.
- Too many list items: 8+ bullet points in under 200 words means the content should be a paragraph, not a list.
- Formulaic section headers: "Overview," "Key Points," "Summary," "Conclusion," "Introduction" — these are default AI scaffolding. Use headers that tell the reader something specific about what follows.
Rhythm and uniformity
These aren't individual word or phrase problems — they're patterns in how the text flows as a whole. AI text is metronomic; human text has varied rhythm.
Structure is the #1 detection signal. AI detection tools (including Pangram, which trains a classifier on 28M human documents) weight structural regularity higher than vocabulary. Consistent sentence construction, uniform pacing, and symmetrical phrasing patterns are harder to mask than swapping out a few flagged words. If you fix every word on the Tier 1 list but leave the rhythm untouched, the text still reads as AI-generated.
- Sentence length uniformity: If most sentences are 15–25 words, the text sounds robotic. Mix short punchy sentences (3–8 words) with longer flowing ones (20+). Fragments work. Questions break the monotony.
- Paragraph length uniformity: If every paragraph is 3–5 sentences and roughly the same size, vary deliberately. Some paragraphs should be one sentence. Some should be longer.
- Vocabulary repetition vs. synonym cycling: AI either repeats the same word mechanically or cycles through synonyms conspicuously. Human writers repeat when the word is right and vary when it's natural — there's no formula.
- Read-aloud test: If the text sounds like it could be read by a text-to-speech engine without sounding weird, it's probably too uniform. Human writing has rhythm that resists robotic delivery.
- Missing first-person perspective: Where appropriate, the writer should have opinions, preferences, and reactions. AI is relentlessly neutral. If the piece is supposed to have a voice, the absence of "I think," "in my experience," or a stated preference is itself an AI tell.
- Over-polishing: Aggressively editing out every irregularity can push human writing toward AI statistical profiles. Natural disfluency, idiosyncratic word choices, and uneven pacing are what keep text out of the "AI-generated" classification. Don't sand away all personality in pursuit of clean prose. This skill should make writing sound more human, not less — if you apply every rule at maximum strictness, you risk creating the very uniformity you're trying to avoid.
Vocabulary diversity (stylometric)
In longer pieces (200+ words), look at how much vocabulary the text actually uses. The type-token ratio (TTR) — distinct word types divided by total tokens — is a classical stylometric signal that's easy to read by eye. Human prose at this length usually lands somewhere around 0.50–0.65 in English. AI text trends flatter, sometimes drifting under 0.40 when the model gets locked on a small vocabulary loop.
A very low TTR is not by itself proof of AI authorship — narrow topics, technical reference material, and second-language writing all legitimately compress vocabulary. But on general prose where you'd expect range (essays, articles, social content over ~200 words), a TTR below 0.40 is worth a second look. The fix is rarely to thesaurus the text; it's to broaden the what — name specific things, cite specific cases, replace a re-used abstract noun with the concrete instance behind it.
This is the first of four stylometric signals on the roadmap. The others (sentence-length burstiness as a continuous measure, function-word z-scores against a human-prose reference, POS-bigram log-odds) require either a POS tagger or a reference distribution and aren't implemented as detector categories yet.
Paragraph-reshuffle immunity (structure test)
- A writer-side diagnostic, not a regex: can you swap two body paragraphs without breaking the piece? If the order doesn't matter, you've written a list of points, not an argument that builds. AI prose often fails this — each paragraph is a self-contained module with no load-bearing connection to its neighbors.
- The fix is structural, not lexical: establish a through-line where each paragraph depends on the one before it. If the paragraphs are genuinely independent, decide whether the piece should be an explicit list, or whether it's missing a thesis. Adapted from
Aboudjem/humanizer-skillP38.
Treadmill effect / low information density (content test)
- Another writer-side test: read each paragraph and ask "what's actually new here?" AI prose frequently restates the premise in fresh words instead of advancing it — lots of motion, no distance covered. The tell is that you could cut 40-60% and lose no information.
- The fix: for each paragraph, name the one fact, claim, or turn it contributes. If there isn't one, cut it. If there is, lead with it and drop the throat-clearing. Adapted from
Aboudjem/humanizer-skillP43.
When to rewrite from scratch vs. patch
If the text has 5+ flagged vocabulary hits across multiple categories, 3+ distinct pattern categories triggered, and uniform sentence/paragraph length, patching individual phrases won't fix it — the structure itself is AI-generated. Advise a full rewrite: state the core point in one sentence, then rebuild from there.
---
Severity tiers
Not all AI-isms are equal. When doing a quick pass or triaging a large document, prioritize by tier:
P0 — Credibility killers (fix immediately)
- Cutoff disclaimers ("As of my last update")
- Chatbot artifacts ("I hope this helps!", "Great question!")
- Vague attributions without sources ("Experts believe")
- Significance inflation on routine events
- Hashtag stuffing on
linkedinandinvestor-emailposts (severity varies by profile — same rule, lower priority onblog/technical-blogwhere a launch post may legitimately stack tags; see the context-profile table below)
P1 — Obvious AI smell (fix before publishing)
- Word-list violations (delve, leverage, harness, robust, etc.)
- Template phrases and slot-fill constructions
- "Let's" transition openers
- Synonym cycling within a paragraph
- Formulaic openings ("In the rapidly evolving world of...")
- Bold overuse
- Em dash frequency (above 1 per 1,000 words)
- Generic future-narrative closers ("may become one of the most important narratives…")
- Social endorsement closers ("This one is worth your time:", "thank me later")
- Hedge-stacked predictions ("could potentially," "may eventually")
- Real/actual adjective inflation ("real on-chain tokenomics")
- Bullet lists of bare noun phrases (5+ short adj+noun items, no verbs)
- Tier 3 phrase clustering (≥3 distinct boilerplate phrases in one piece)
P2 — Stylistic polish (fix when time allows)
- Generic conclusions ("The future looks bright")
- Compulsive rule of three
- Uniform paragraph length
- Copula avoidance (serves as, features, boasts)
- Transition phrases (Moreover, Furthermore, Additionally)
- Hashtag stuffing (
blog/technical-blogprofiles) - Tier 3 phrase repetition (single phrase ≥2× — fine in isolation, suspect in stacks)
Use P0+P1 for quick passes. Full audit covers all three tiers.
---
Self-reference escape hatch
When writing about AI writing patterns (blog posts, tutorials, skill documentation like this file), quoted examples are exempt from flagging. Text inside quotation marks, code blocks, or explicitly marked as illustrative ("for example, AI might write...") should not be rewritten. Only flag patterns that appear in the author's own prose, not in cited examples of bad writing.
---
Context profiles
Pass an optional context hint to adjust rule strictness. If no context is specified, auto-detect from content cues (short + hashtags = social, code blocks = technical, salutation = email, default = blog).
Profile definitions
`linkedin` — Short-form social. Punchy fragments, visual formatting matter. `blog` — Default. Standard long-form prose. All rules apply at full strength. `technical-blog` — Long-form with code, architecture, APIs. Technical terms get a pass. `investor-email` — High-trust audience. Tighten everything; promotional language is the biggest risk. `docs` — Documentation, READMEs, guides. Clarity over voice. `casual` — Slack messages, internal notes, quick replies. Only catch the worst offenders.
Tolerance matrix
Rules not listed in the table apply at full strength across all profiles.
| Rule | blog | technical-blog | investor-email | docs | casual | |
|---|---|---|---|---|---|---|
| Em dashes | relaxed (2/post OK) | strict | strict | strict | relaxed | skip |
| Bold overuse | relaxed (bold hooks OK) | strict | strict | strict | relaxed | skip |
| Emoji in headers | relaxed (1-2 end-of-line OK) | strict | strict | strict | skip | skip |
| Excessive bullets | skip (lists work on LinkedIn) | strict | relaxed (technical lists OK) | strict | skip (lists are docs) | skip |
| Hedging | strict | strict | relaxed ("may" is accurate in technical) | strict | relaxed | skip |
| Word table (full list) | strict | strict | partial (see below) | strict | relaxed | P0 only |
| Promotional language | relaxed (some sell is expected) | strict | strict | extra strict | strict | skip |
| Significance inflation | strict | strict | strict | extra strict | relaxed | skip |
| Copula avoidance | skip | strict | relaxed | strict | skip | skip |
| Uniform paragraph length | skip (short-form) | strict | strict | strict | relaxed | skip |
| Numbered list inflation | relaxed | strict | relaxed | strict | skip | skip |
| Rhetorical questions | relaxed (1 as hook OK) | strict | strict | strict | strict | skip |
| Transition phrases | skip (short-form) | strict | strict | strict | relaxed | skip |
| Generic conclusions | skip | strict | strict | extra strict | skip | skip |
| Hashtag stuffing | strict | strict | strict | extra strict | skip (no hashtags in docs) | skip |
| Bullet-NP lists | strict | strict | relaxed (technical option lists OK) | strict | relaxed (parameter lists OK) | skip |
| Tier 3 phrase clustering | strict | strict | strict | extra strict | relaxed | skip |
| Future-narrative closers | strict | strict | strict | extra strict | skip | skip |
| Social endorsement closers | strict (the LinkedIn share-post tell) | strict | strict | strict | skip | relaxed (1 OK in a DM) |
| Hedge-stacked predictions | strict | strict | relaxed ("could" is hedged accuracy) | extra strict | relaxed | skip |
| Real/actual inflation | strict | strict | strict | extra strict | relaxed | skip |
Technical-blog word table exceptions: These terms have legitimate technical meaning and should not be flagged in technical context: robust, comprehensive, seamless, ecosystem, leverage (when discussing actual platform leverage/APIs), facilitate, underpin, streamline. Still flag: delve, tapestry, beacon, embark, testament to, game-changer, harness.
"Extra strict" means: flag even borderline instances. In investor emails, a single "thriving ecosystem" can undermine the whole message.
"Skip" means: don't audit this category for this profile. The rule doesn't apply or isn't worth the edit.
Auto-detection cues
When no context is specified, infer from these signals:
| Signal | Inferred context |
|---|---|
| Under 300 words + hashtags or mentions | linkedin |
| Code blocks, API references, or technical architecture | technical-blog |
| Salutation ("Hi [name]", "Dear") + investor/fundraising language | investor-email |
| Step-by-step instructions, parameter docs, README structure | docs |
| No strong signals | blog (safest default — all rules apply) |
If auto-detection feels wrong, say which profile you're using and why. The user can override.
---
Voice profiles
Context profiles (above) set how strict to be for an audience. Voice profiles set how the prose should sound — the persona. They're independent axes: you can write blunt for a blog or warm for docs. Voice is optional — if the writer doesn't name one, infer it from the input's existing register and don't impose a persona on text that already has one.
Each profile is a set of concrete targets, not a vibe:
`casual` — Contractions throughout; their absence reads stiff. Short sentences (aim for ≤14 words on average); fragments allowed. At least one first-person or concrete-anecdote touch. Near-zero jargon. Keep warm hedges ("honestly," "I think") but cut corporate ones ("it's worth noting"). Blog posts, social, community.
`professional` — Active voice for most sentences. Vary sentence length; avoid three in a row within a few words of each other. One concrete claim per paragraph (a number, a name, a date), never "experts say." Make the ask explicit. Low tolerance for hedging. LinkedIn, investor email, sponsor pitches.
`technical` — Prefer plain copulatives ("X is Y") over inflated substitutes ("serves as," "stands as a testament to"). One idea per sentence; imperative mood for instructions. Jargon is fine, but define it on first use. Tables and lists only where the content is genuinely list-shaped, not for decoration. Docs, technical blog.
`warm` — Address the reader directly ("you") and acknowledge them at least once. Cut intensifiers ("very," "truly," "incredibly") in favor of stronger verbs. No performative-empathy openers ("I completely understand how you feel"). Medium sentences (15–20 words) for an unhurried cadence. Mentorship, onboarding, thank-yous.
`blunt` — Lead with the claim; cut "It's important to note that" windups. Em-dashes are rare here; use periods for emphasis. No padding to hit a rule of three. Near-zero hedging; flag "may / could / potentially" stacks. Short declaratives, with the occasional long sentence for contrast. Decision memos, thought leadership, hard feedback.
Calibrate to a sample (optional). If the writer gives you a sample of their own writing ("match my voice — here's a post"), analyze its sentence-length pattern, contraction rate, paragraph openings, and recurring word choices, then match those instead of a named profile. Don't "upgrade" their vocabulary: if they write "stuff" and "things," keep that register.
How voice composes with context. Voice sets the target; context sets how hard to enforce it. A voice target always applies, even where a context profile would skip that category — technical voice still prefers plain copulatives in a casual context that otherwise ignores copula avoidance. Where both axes govern the same rule and agree, they reinforce: blunt voice wants near-zero em-dashes and a blog context is already strict on them, so it stays a hard edit. Where they disagree, resolve toward the stricter of the two — a warm voice on docs still doesn't get decorative tables. Sensible default pairings: casual↔casual, professional↔linkedin/investor-email, technical↔docs/technical-blog.
---
Output format
Rewrite mode (default)
Return your response in four sections:
1. Issues found A bulleted list of every AI-ism identified, with the offending text quoted.
2. Rewritten version The full rewritten content. Preserve the original structure, intent, and all specific technical details. Only change what the guidelines require.
3. What changed A brief summary of the major edits made. Not every word, just the meaningful changes.
4. Second-pass audit Re-read the rewritten version from section 2. Identify any remaining AI tells that survived the first pass — recycled transitions, lingering inflation, copula avoidance, filler phrases, or anything else from the categories above. Fix them, return the corrected text inline, and note what changed in this pass. If the rewrite is clean, say so.
Detect mode
Return your response in two sections:
1. Issues found A bulleted list of every AI-ism identified, with the offending text quoted. Group by severity (P0, P1, P2).
2. Assessment For each flag, note whether it's a clear problem or a judgment call. Some AI-associated patterns are effective writing techniques — uniform paragraph length is a problem, but a well-placed "however" isn't. Call out which flags the writer should definitely fix vs. which ones are worth a second look but might be fine in context. If the text is clean, say so.
Edit mode
After editing the file in place, return a short report — not the full file:
1. Edits made A bulleted list of the changes, each with the file location and the before → after. Only the spans you touched.
2. Verification Confirm you re-read the file and the flagged patterns are resolved. Note anything you deliberately left alone because it was already human or intentional.
---
Tone calibration
The goal is writing that sounds like a person wrote it. Direct. Specific. The writing should demonstrate confidence, not assert it.
Five principles for human-sounding rewrites: 1. Vary sentence length — mix short with long. Fragments are fine. 2. Be concrete — replace vague claims with numbers, names, dates, or examples. 3. Have a voice — where appropriate, use first person, state preferences, show reactions. 4. Cut the neutrality — humans have opinions. If the piece is supposed to take a position, take it. 5. Earn your emphasis — don't tell the reader something is interesting. Make it interesting.
If the original writing is already strong, say so and make only the necessary cuts. Don't over-edit for the sake of it.
The replacement table provides defaults, not mandates. If a flagged word is clearly the right choice in context, preserve it.
{
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
"name": "conorbronsdon-skills",
"description": "Conor Bronsdon's public Claude Code / Cowork skills.",
"owner": {
"name": "Conor Bronsdon"
},
"plugins": [
{
"name": "avoid-ai-writing",
"source": "./plugins/avoid-ai-writing",
"description": "Audit & rewrite content to remove AI writing patterns (\"AI-isms\"). Supports detect-only and edit-in-place modes, voice profiles, and iterate-to-convergence.",
"category": "productivity",
"keywords": ["writing", "editing", "ai-detection", "humanize"]
}
]
}
*.sh text eol=lf
*.md text eol=lf
Summary
<!-- What does this change and why? -->
Checklist
- [ ]
npm testpasses (engine fixtures +CATEGORIES.mdcontract check) - [ ] If I added a detector
type: it's documented indetector/CATEGORIES.mdand has a fixture indetector/patterns.test.js(a true positive and a must-not-fire case) - [ ] If I added a judgment-only rule: it's listed under "Skill-only" in
detector/CATEGORIES.md - [ ] I considered false positives and added carve-outs for legitimate human writing
- [ ] Any factual claim about how AI or humans write (e.g. "ChatGPT emits X", "humans rarely do Y") cites a source
- [ ] The prose I added passes the skill's own audit (no AI-writing tells, terse bullets, no hollow intensifiers)
- [ ]
CHANGELOG.mdentry added under a dated## [X.Y.Z]heading, andSKILL.mdversion:bumped if a rule changed
name: detector
on:
push:
paths:
- "detector/**"
- "package.json"
- ".github/workflows/detector-test.yml"
pull_request:
paths:
- "detector/**"
- "package.json"
- ".github/workflows/detector-test.yml"
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "20"
- run: npm test
name: plugin-skill-sync
on:
pull_request:
paths:
- "SKILL.md"
- "README.md"
- "plugins/**"
- ".claude-plugin/**"
- "scripts/**"
push:
branches: [main]
paths:
- "SKILL.md"
- "README.md"
- "plugins/**"
- ".claude-plugin/**"
- "scripts/**"
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Validate manifest JSON
run: |
python3 -m json.tool .claude-plugin/marketplace.json > /dev/null
python3 -m json.tool plugins/avoid-ai-writing/.claude-plugin/plugin.json > /dev/null
- name: Check README pattern count matches SKILL.md
run: bash scripts/check-pattern-count.sh
- name: Regenerate bundled skill + check version
run: bash scripts/sync-plugin-skill.sh
- name: Fail if the bundled skill drifted from SKILL.md
run: |
if ! git diff --quiet; then
echo "::error::plugins/avoid-ai-writing/skills/avoid-ai-writing/SKILL.md is out of sync with the root SKILL.md."
echo "Run 'bash scripts/sync-plugin-skill.sh' and commit the result."
git --no-pager diff --stat
exit 1
fi
echo "bundled skill is in sync"
# OS
.DS_Store
Thumbs.db
Desktop.ini
*.swp
*~
# Editors
.vscode/
.idea/
*.sublime-project
*.sublime-workspace
# Environment
.env
.env.local
# Local git worktrees (parallel Claude Code sessions)
.worktrees/
Changelog
All notable changes to this project are documented here.
---
[3.10.0] — 2026-06-10
Added
- List-label periods — in bulleted lists where each item leads with a short label, LLMs end the label with a period and run the gloss as a separate sentence, where a person almost always uses a colon. Strongest with bold labels (
**Intros.**vs**Intros:**); the unbolded shape (- Intros. Years of...) is the same tell, slightly weaker. The colon reads as "here's what this label means"; the period reads as a sentence the next clause then contradicts by continuing. Fix is to swap the period for a colon and lowercase the gloss, or drop the bold label entirely. Distinct from inline-header lists (bold headers that repeat the point): this rule is about the punctuation on the label, not the redundancy. Carve-out: a bold span that is a full standalone sentence keeps its period. Catalog goes from 48 to 49 detection categories. LLM-judgment rule (no detectortype). Closes #31.
---
[3.9.0] — 2026-06-05
Added
- Social endorsement closers — the curatorial sign-off LLMs append to LinkedIn/X share posts, usually a colon teeing up a link: "This one is worth your time:", "This one's a must-read:", "Do yourself a favor and read this," "You won't want to miss this one," "Thank me later," "Bookmark this," "Don't sleep on this one." Performs a recommendation without giving the reader a reason to click. Distinct from the bare "worth [verb]ing" word-table entry (a single weak word inside a sentence) and from infomercial engagement hooks (mid-flow teasers) — this is the whole closing line of a social post. Demonstrative-anchored ("THIS one is worth your time") so it stays off plain human endorsements ("the book is worth reading, but the middle drags"). Catalog goes from 47 to 48 detection categories; the detector engine gains a
social-cta-closertype(43 → 44). Closes #29.
---
[3.8.0] — 2026-05-29
Added
- Self-labeling significance — back-pointing labels that flag which item in a list is supposed to matter ("That last move is the contrarian one," "This is the interesting part," "That third bullet is the real story") instead of writing the list so the right item carries the weight on its own. Distinct from confidence calibration (which front-loads the cue) and emotional flatline (which prefaces a single claim) — this one back-points after the fact. Catalog goes from 46 to 47 detection categories. LLM-judgment rule (no detector
type); documented indetector/CATEGORIES.md§C.
---
[3.7.2] — 2026-05-28
Changed
- Curly quotation marks — recalibrated per review of #15. Reframed from a "strong" tell to a weak, corroborating signal meaningful mainly in plain-text contexts (code comments, commit messages, plaintext drafts), since Word/Google Docs/macOS/iOS auto-curl quotes by default. Curly apostrophes (U+2019) are no longer flagged on their own (they appear in every contraction). Fixes the German low-9 example. Keeps it consistent with the deterministic detector's co-occurrence logic (#16).
---
[3.7.1] — 2026-05-28
Changed
- Curly quotation marks — refined the 3.7.0 "mixed straight/curly punctuation" rule into a single Formatting rule: flag the unexplained presence of Unicode curly quotes (U+201C / U+201D / U+2018 / U+2019) in otherwise plain-ASCII text as a copy-paste-from-chat fingerprint, with carve-outs for deliberate publication typography and locale-correct punctuation (French guillemets, German low-9 quotes).
- Version bump to 3.7.1.
Credit
- Contributed by @augustasas (#15).
---
[3.7.0] — 2026-05-28
Added
- Hyphenated-pair overuse — stacked compound modifiers ("a high-quality, well-architected, future-proof solution") and the attributive/predicate error (hyphenate "a high-quality report" but not "the report is high quality").
- Speculative gap-filling — hedged speculation dressed as background ("maintains a low profile," "is believed to have," "likely began his career") that hides a knowledge gap rather than admitting it. Distinct from cutoff disclaimers.
Changed
- Formatting — added mixed straight/curly punctuation (quote/apostrophe style mixed in one document — a paste-from-chat-UI tell).
- Confidence calibration phrases — extended with persuasive-authority tropes ("the real question is," "at its core," "fundamentally," "make no mistake").
- Version bump to 3.7.0.
Credit
- Patterns adapted from
blader/humanizer(P21, P26, P27) and Wikipedia's "Signs of AI writing," identified in the competitive research tracked in #22.
---
[3.6.0] — 2026-05-28
Added
- Voice profiles — an optional persona axis, independent of the audience context profiles. Five profiles (
casual,professional,technical,warm,blunt), each a set of concrete targets (sentence length, contraction policy, hedging tolerance, jargon level, rhythm) drawn from writing-craft sources (Strunk, Provost, Ogilvy, Handley). Plus optional calibration to a user-supplied writing sample. Includes a composition rule: voice sets the target, context sets enforcement strictness, conflicts resolve toward the stricter. - Edit mode — a third mode alongside
rewriteanddetect. Edits a named file in place via the Edit tool with minimal, targeted changes, preserving already-human passages, then re-reads to verify. Returns an edits-made + verification report, not the full file. - Iterate to convergence — rewrite mode can repeat the audit→rewrite cycle until no patterns remain or N passes (capped at 2). Generalizes the existing built-in second pass.
- Invocation surface — documented optional flags (
--mode,--voice,--context,--file,--iterate N) alongside the existing natural-language triggers.
Changed
- Frontmatter
descriptionupdated to advertise the new modes and voice profiles. - Version bump to 3.6.0.
Notes
- Designed from a competitive feature audit (Aboudjem/humanizer-skill, brandonwise/humanizer, blader/humanizer) plus detection-science and writing-craft research. The
--scorefeature and four additional catalog patterns from that research are tracked separately (#21, #22).
---
[3.5.0] — 2026-05-27
Added
- Infomercial engagement hooks — punchy fragment-hooks that fake momentum around ordinary information: "The catch?", "The kicker?", "Here's the thing.", "Plot twist:", "The best part?". Distinct from rhetorical-question openers (which stall before a point) and chatbot artifacts (which perform helpfulness).
- Paragraph-reshuffle immunity — a writer-side structure test: if you can swap two body paragraphs without breaking the piece, you've written a list of points, not an argument that builds.
- Treadmill effect / low information density — a writer-side content test: each paragraph should contribute one new fact, claim, or turn rather than restate the premise in fresh words. The tell is that you could cut 40-60% and lose no information.
Changed
- Superficial -ing analyses — extended to cover the declarative "meaning-telling" variant ("this represents a broader shift," "speaks to a larger trend") that glosses a mundane subject as profound without the -ing construction.
- Version bump to 3.5.0.
Credit
- Patterns adapted from `Aboudjem/humanizer-skill` (P38, P40, P41, P43), identified during a competitive catalog audit.
---
[3.4.0] — 2026-05-16
Added
- Tier 3 phrases — multi-word boilerplate that's individually unobjectionable but stacks heavily in AI-generated crypto/web3/DePIN/AI-infra content:
emerging sector,the integration of,the intersection of,community-driven,long-term sustainability,user engagement,decentralized compute,sustainable reward emissions,tokenized incentive structures,designed for long-term. Flagged by per-phrase density (≥2 repetitions) or cluster (≥3 distinct phrases in one piece — the LLM-varies-its-own-boilerplate shape). - Generic future-narrative closers — "May become one of the most important narratives of the next market cycle" template family. Modal + "become" + (one of) the most + (narrative / story / trend / theme / chapter / movement).
- Hedge-stacked predictions —
could potentially,may eventually,might ultimately. Modal + hedge adverb stack where each word cancels the next. - "Real/actual" adjective inflation —
real on-chain tokenomics,actual reward sustainability,genuine utility,true product-market fit. The noun-modifier form distinct from the existing sentence-level hollow-intensifier rule. - Hashtag stuffing — trailing blocks of 6+ hashtags on short posts, especially when mixing one project tag with broad category tags (#AI #Crypto #Web3 #Innovation #FutureTech).
- Bullet lists of bare noun phrases — 5+ consecutive bullets where each is a short adj+noun pair with no verb. Detector heuristic excludes genuine list content (verbs in items, ingredient lists, changelog entries).
Changed
- Emotional flatline — extended to cover the bare section-header variant: "Interesting part of the project:" / "Interesting thing here:" — same role as "the most interesting part" but as a header opener.
- Severity tiers — all six new categories wired into P0/P1/P2 ladder (hashtag stuffing varies by profile; the rest are P1, with phrase repetition at P2).
- Context profiles tolerance matrix — added rows for all six new categories so the
linkedinanddocsprofiles don't false-positive on legitimate use (e.g., bullet-NP lists relaxed ontechnical-bloganddocssince technical option lists are correctly bare-NP). - "6+" hashtag threshold — added rationale paragraph explaining the empirical floor.
- "Real/actual" inflation — added named-contrast carve-out so honest contrastive writing ("real on-chain settlement, not bridged IOUs") isn't flagged.
- Version bump to 3.4.0.
Reported by
- A user of the avoid-ai-writing extension flagged two crypto-shill social posts (MineBench reviews) that the v3.3.x wordlist+regex detector scored as "Minimal AI signals" despite being obvious LLM output. Both posts avoided every Tier 1 vocabulary entry by substituting synonyms ("emerging sector," "scalable network contribution," "viability") and used structural shapes (hashtag block, bare-NP bullet lists, hedge stacks, future-narrative templates) the detector had no rule for. v3.4 adds rules for the structures, not just the words.
---
[3.3.0] — 2026-04-01
Added
- "Worth [verb]ing" vague endorsement pattern:
worth reading,worth paying attention to,worth a look,worth exploring,worth checking out,worth your time— broadens existing "it's worth noting that" to the full family - Reader-steering frames:
Here's what's interesting,Here's what caught my eye,Here's what stood out— added to both transition phrases and confidence calibration sections with context on when the pattern is a genuine problem vs. when data-backed usage is acceptable
Changed
- Version bump to 3.3.0
---
[3.2.0] — 2026-03-31
Added
- Detect mode: flag-only mode that identifies AI patterns without rewriting. Trigger with "detect," "flag only," "audit only," "just flag," "scan," or similar. Returns issues grouped by severity (P0/P1/P2) plus an assessment of which flags are clear problems vs. judgment calls. Useful when flagged patterns are intentional, when auditing published or third-party content, or when you want a quick scan without a full rewrite.
Changed
- Output format section now documents both rewrite (default) and detect mode outputs
- Version bump to 3.2.0
---
[3.1.0] — 2026-03-25
Added
- 3 new Tier 1 words from Pangram AI detection research:
keen(as intensifier),symphony(metaphor),embrace(metaphor) - 2 new template phrases: "Whether you're X or Y" (false-breadth), "I recently had the pleasure of" (review/social AI pattern)
- "In summary" added to transition phrases (alongside existing "In conclusion" / "To summarize")
- Structure-priority note in Rhythm section: structural regularity is the #1 signal AI detectors weight, above vocabulary
- Over-polishing warning: aggressive editing can push writing toward AI statistical profiles by removing natural disfluency
Changed
- Total vocabulary: 106 → 109 entries (60 Tier 1 + 38 Tier 2 + 11 Tier 3)
- Template phrases: 2 → 4 entries
Source
- Pangram Labs AI detection research (pangram.com) — decoder-only classifier trained on 28M human documents. Key insight: structural uniformity and pacing consistency are weighted higher than individual word choices.
---
[3.0.0] — 2026-03-20
Added
- Novelty inflation pattern (AI treats established concepts as speaker inventions)
- False concession structure pattern
- Rhetorical question openers pattern
- Parenthetical hedging pattern
- Numbered list inflation pattern
- Severity tiers (P0/P1/P2) for prioritized auditing
- Self-reference escape hatch (exempts quoted examples from flagging)
- Context profiles with tolerance matrix (linkedin, blog, technical-blog, investor-email, docs, casual)
- Auto-detection cues for context inference
- Extended frontmatter: license, compatibility, author, tags, agentskills_spec
Changed
- Pattern count: 30 → 35 categories
---
[2.2.0] — 2026-03-18
Added
- OpenClaw compatibility — added
versionandmetadata.openclawto SKILL.md frontmatter - OpenClaw installation instructions in README (ClawHub and manual)
- Skill now works with both Claude Code and OpenClaw from a single
SKILL.md
Changed
README.md— broadened description to reference both platforms, reorganized installation into Claude Code and OpenClaw sections
---
[2.1.0] — 2026-03-18
Added
- 5 new pattern categories: reasoning chain artifacts, sycophantic tone, acknowledgment loops, confidence calibration phrases, excessive structure
- New "Rhythm and uniformity" section — checks for sentence length uniformity, paragraph length uniformity, missing first-person perspective, and read-aloud test guidance
- New "When to rewrite from scratch vs. patch" threshold — advises full rewrites when AI density is too high for patching
- 5 rewrite principles in tone calibration section (vary length, be concrete, have a voice, cut neutrality, earn emphasis)
- New "Meta Patterns" group in README pattern table
- Expanded credits: OpenClaw humanizer ecosystem (community patterns)
Changed
- Pattern count: 23 → 30 categories
README.md— updated pattern count, added Meta Patterns table, expanded credits with source descriptions- Communication Patterns table in README now includes all communication patterns
---
[2.0.0] — 2026-03-18
Added
- Tiered vocabulary system — words are now organized into three tiers based on AI-signal strength:
- Tier 1 (always flag): 53 entries — dead giveaways that appear 5–20x more often in AI text
- Tier 2 (flag in clusters): 38 entries — legitimate words that signal AI when 2+ appear in the same paragraph
- Tier 3 (flag by density): 11 entries — common words that only flag when the text is saturated with them
- 39 new vocabulary entries across all tiers, including: bustling, intricate, complexities, ever-evolving, daunting, holistic, actionable, impactful, learnings, thought leadership, best practices, synergy, interplay, encompass, catalyze, reimagine, galvanize, augment, cultivate, illuminate, elucidate, juxtapose, paradigm-shifting, transformative, cornerstone, paramount, poised, burgeoning, nascent, quintessential, overarching, underpinning, significant, innovative, dynamic, scalable, compelling, unprecedented, sophisticated, instrumental, world-class
- Credit to brandonwise/humanizer for tiered vocabulary research
Changed
- Word/phrase table reorganized from flat list to tiered structure with usage guidance
- Total vocabulary: 58 → 102 entries (53 Tier 1 + 38 Tier 2 + 11 Tier 3)
README.md— updated replacement table description, pattern table, and credits
---
[1.4.0] — 2026-03-17
Added
- 15 new word/phrase replacements: nuanced, crucial, multifaceted, ecosystem, myriad, plethora, deep dive/dive into, unpack, bolster, spearhead, resonate, revolutionize, facilitate, underpin
- New pattern category: "let's" constructions (false-collaborative openers like "let's explore," "let's break this down")
- Skill now covers 23 pattern categories with 58 word/phrase replacements
Changed
- Deduplicated filler phrases that appeared in both the word table and the filler section
README.md— updated pattern count (22 → 23), replacement table count (43 → 58), added "let's" constructions row to pattern table
---
[1.3.0] — 2026-03-17
Changed
- Em dash detection now catches double-hyphen (
--) in addition to Unicode em dash (—) README.md— updated formatting pattern description to mention--
---
[1.2.0] — 2026-03-06
Added
- New pattern category: emotional flatline (AI claims emotions as structural crutch without conveying them; also flags lazy human writing)
- Skill now covers 22 pattern categories with 43 word/phrase replacements
---
[1.1.0] — 2026-03-06
Added
- 8 new pattern categories: notability name-dropping, superficial -ing analyses, promotional language, formulaic challenges, false ranges, inline-header lists, title case headings, cutoff disclaimers
- 5 new word table entries (nestled, vibrant, thriving, despite challenges, showcasing)
- Skill now covers 21 pattern categories with 43 word/phrase replacements
Changed
README.md— expanded full example (6 paragraphs → 4 clean sentences, 40+ tells flagged); added per-pattern before/after table organized into Content, Language, Structure, Communication groups; updated pattern count and replacement table count throughout
---
[1.0.0] — 2026-03-05
Added
SKILL.md— Claude Code skill with 13 pattern categories: formatting, sentence structure, word/phrase replacements (38 entries), template phrases, transition phrases, structural issues, significance inflation, copula avoidance, synonym cycling, vague attributions, filler phrases, generic conclusions, chatbot artifacts- Four-section output format: issues found, rewritten version, what changed, second-pass audit
README.md— installation guide (3 methods), full pattern reference, usage examplesLICENSE— MIT.gitignore— OS/editor exclusions
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
A single-file writing skill (SKILL.md) that audits and rewrites content to remove AI writing patterns. No build system, no dependencies, no tests — the skill is a markdown file consumed by AI coding assistants.
Repository structure
SKILL.md— the skill itself (v3.7.2). This is the product. All rules, tiers, profiles, and output format live here.README.md— public-facing docs, installation instructions, pattern reference table, full before/after example.CHANGELOG.md— version history with what changed and why.
How to make changes
Edit SKILL.md directly. There's nothing to build or test. When making changes:
- Bump the version in the SKILL.md frontmatter (
version: X.Y.Z) - Add a dated entry to CHANGELOG.md
- Update README.md if the change affects installation, usage, feature list, or pattern count
- The pattern count lives in one place — the README "46 pattern categories" bullet — and is derived from SKILL.md's detection
###entries. Don't restate it elsewhere; CI (scripts/check-pattern-count.sh) fails the build if the README number drifts from SKILL.md, so just add the new###entry and bump the README bullet.
Architecture of the skill
The skill has three modes (rewrite default, detect flag-only, edit in-place) and processes text through this pipeline:
1. Context profile detection — auto-detects or accepts a profile hint (linkedin, blog, technical-blog, investor-email, docs, casual) that adjusts rule strictness via the tolerance matrix 2. Pattern matching — detection categories across content, language, structure, communication, and meta patterns (see SKILL.md for the catalog; the count is in the README bullet) 3. Vocabulary flagging — 3-tier system: Tier 1 (always flag), Tier 2 (flag in clusters), Tier 3 (flag at high density) 4. Severity classification — P0 (credibility killers), P1 (obvious AI smell), P2 (stylistic polish) 5. Output — rewrite mode: 4 sections including a second-pass audit; detect mode: 2 sections with problem vs. judgment-call assessment
Key constraints
- The skill must remain a single
SKILL.mdfile with agentskills.io-compatible frontmatter - Word replacement table entries need specific alternatives, not just "rephrase"
- The self-reference escape hatch (quoted examples exempt from flagging) must be preserved — without it the skill flags its own documentation
- Technical-blog profile has explicit word table exceptions (e.g., "robust" and "ecosystem" are legitimate in technical contexts)
- "Extra strict" and "skip" in the tolerance matrix have specific meanings defined in the file
Compatibility
The skill works with Claude Code, OpenClaw/ClawHub, and any agentskills.io-compatible agent. The frontmatter includes both agentskills_spec and openclaw fields. Changes must not break either format.
Contributing
Thanks for helping improve this skill. It teaches an LLM (and now a deterministic engine) to spot and fix AI-writing tells. Contributions are welcome — a few things keep the project coherent.
How the repo fits together
| Path | What it holds |
|---|---|
SKILL.md | The human-readable catalog of rules. The source of truth for what counts as an AI tell. |
detector/patterns.js | The deterministic engine — the executable subset of the rules. |
detector/CATEGORIES.md | The map between SKILL.md rules and detector types. Keep it current. |
README.md | The pitch and the numbered prose-pattern list. |
cursor-rules/, plugins/ | Editor and tool integrations. |
Adding or changing a rule
First decide which kind of rule it is:
- Regex-detectable (a phrase, a character, a structural shape) → add it to
SKILL.md, add the detection to detector/patterns.js with a new type, and add a row to detector/CATEGORIES.md. Cover it with a fixture in detector/patterns.test.js (both a true positive and a case that must not fire).
- Judgment-only (needs reading for meaning — tone, structure, name-dropping)
→ add it to SKILL.md prose and list it under "Skill-only" in detector/CATEGORIES.md. There is no detector type for these.
If you are unsure which it is, open an issue first and we will sort it out.
Precision over recall
This skill is deliberately biased toward false negatives: a rule that wrongly flags ordinary human writing is worse than one that misses a tell, because false positives erode trust in every other rule. Before proposing a rule, ask who would get flagged by mistake, and add carve-outs for the legitimate cases. A signal that fires on most normal prose is not worth adding.
Cite your sources
If your rule rests on a factual claim about how AI or humans write — "ChatGPT emits curly quotes by default," "most writers rarely do X" — link a source for it. These claims get checked, and some turn out wrong or more nuanced than they first seem (smart quotes, for instance, are a typing-time default on macOS and in Word, not a publication-step artifact). A claim with a citation can be verified; an asserted one can't. Put the links in the PR description or inline in the rule.
Run the tests
npm testThis runs the engine fixtures and the CATEGORIES.md contract check (every detector type must be documented, and every documented type must be real). Both must pass. No dependencies to install; Node 18+ only.
Write clean prose
This repo polices writing quality, so the prose you add has to clear the same bar. Run your additions through the skill itself. Keep rule bullets terse and lead with the directive — match the length and tone of the bullets already in SKILL.md. Drop intensifiers like "strong" or "powerful"; let the rule stand on its own.
Changelog and versioning
Add an entry to CHANGELOG.md under a dated, versioned heading (## [X.Y.Z] — YYYY-MM-DD), matching the existing entries. A new rule is a minor version bump; update the version: field in the SKILL.md frontmatter to match.
Cursor Rule — avoid-ai-writing
Drop-in Cursor rule that ports the `avoid-ai-writing` skill to Cursor's .mdc rule format. Functionally identical to the upstream skill — same tier vocabulary, same context profiles, same detect / rewrite modes.
Install
Copy avoid-ai-writing.mdc into your project's .cursor/rules/ directory:
mkdir -p .cursor/rules
curl -o .cursor/rules/avoid-ai-writing.mdc \
https://raw.githubusercontent.com/conorbronsdon/avoid-ai-writing/main/cursor-rules/avoid-ai-writing.mdcBy default the rule activates on .md, .mdx, .txt, .rst, and .adoc files (via the globs field in the frontmatter). Edit the globs in the rule file if you want it on other file types — or set alwaysApply: true if you want it on every Cursor session.
Trigger phrases
Once installed, ask Cursor:
- "Remove AI-isms from this section."
- "Audit this draft for AI writing patterns."
- "Make this sound less like AI."
- "Run avoid-ai-writing in detect mode." (flag without rewriting)
Old Cursor projects
If you're on a Cursor version that still uses .cursorrules (single file at repo root), you can append avoid-ai-writing.mdc's body (the part below the --- frontmatter) directly to your existing .cursorrules file. Modern Cursor projects should prefer the .cursor/rules/*.mdc layout.
Updating
This file is a copy of `SKILL.md` with Cursor-specific frontmatter. When the upstream skill updates, this file should be re-synced. There's no automated sync between them today — open an issue if drift becomes a problem.
Category map: SKILL.md ↔ detector
This table is the anti-drift contract between the human-readable rules in ../SKILL.md and the executable engine in patterns.js. When you add a rule to the skill, decide here whether it's regex-detectable (give it a detector type) or LLM-only judgment (mark it so). When you add a detector type, point it back at the skill section it enforces.
The engine exposes 44 issue types (see TYPE_LABELS in patterns.js). The skill has more ### sections than that — the gap is not missing coverage, it's rules that are judgment calls a regex can't make. The three groups below account for every entry on both sides.
Three counts coexist on purpose and should not be forced to match: the README's pattern-category count (the human-facing prose catalog, derived from SKILL.md and guarded in CI), the engine's 44 `type`s (which split the vocabulary tiers and add stylometric signals), and SKILL.md's ### sections (which also include writer-side tests with no detectable form). The categories.test.js check enforces only the engine ↔ this-file mapping.
A. Direct mapping (skill rule → detector type)
Detector type | Label | SKILL.md section |
|---|---|---|
tier1 / tier2 / tier3 | AI vocabulary / Word cluster / Overused word | Words and phrases to replace |
transition | AI transition | Transition phrases to remove or rewrite |
template-phrase | Template phrase | Template phrases (avoid) |
tier3-phrase / tier3-phrase-cluster | Boilerplate phrase / cluster | Template phrases (avoid) |
chatbot | Chatbot artifact | Chatbot artifacts |
sycophantic | Sycophantic tone | Sycophantic tone |
acknowledgment-loop | Acknowledgment loop | Acknowledgment loops |
filler | Filler phrase | Filler phrases |
hollow-intensifier | Hollow intensifier | Filler phrases (intensifiers) |
generic-conclusion | Generic conclusion | Generic conclusions |
social-cta-closer | Engagement-bait closer | Social endorsement closers |
future-narrative | Generic future narrative | Generic future-narrative closers |
lets-construction | "Let's" opener | "Let's" constructions |
reasoning-artifact | Reasoning artifact | Reasoning chain artifacts |
significance-inflation | Significance inflation | Significance inflation |
novelty-inflation | Novelty inflation | Novelty inflation |
real-actual-inflation | "Real/actual" inflation | "Real/actual" adjective inflation |
vague-attribution | Vague attribution | Vague attributions |
emotional-flatline | Emotional flatline | Emotional flatline / Superficial -ing analyses |
cutoff-disclaimer | Cutoff disclaimer | Cutoff disclaimers |
false-concession | False concession | False concession structure |
rhetorical-question | Rhetorical question | Rhetorical question openers |
formulaic-opener | Formulaic opener | Formulaic challenges |
confidence-calibration | Confidence stacking | Confidence calibration phrases |
hedge-stack | Hedge-stacked prediction | Hedge-stacked predictions |
parenthetical-hedge | Parenthetical hedge | Parenthetical hedging |
hashtag-stuff | Hashtag stuffing | Hashtag stuffing |
bullet-np-list | Bullet-NP list | Bullet lists of bare noun phrases |
title-case-header | Title Case header | Title case headings |
em-dash / formatting | Em dash overuse / Formatting | Formatting |
uniformity | Rhythm uniformity | Rhythm and uniformity |
low-ttr | Low vocabulary diversity | Vocabulary diversity (stylometric) |
ai-placeholder | Unfilled placeholder | Unfilled placeholders |
ai-citation-markup | Chatbot citation markup leak | Chatbot citation markup leaks |
ai-utm-source | AI-tool URL parameter | AI-tool URL parameters |
smart-punct-signature | Smart-punct signature | Formatting (curly quotation marks) — partial |
Partial map: smart-punct-signature fires only when curly quotes co-occurwith an em-dash, an Oxford comma, and clean typing (≥80 words) — never on curly
punctuation alone. The SKILL.md Formatting rule treats curly quotes as a weak,
corroborating signal in plain-text contexts and excludes apostrophes. The two
agree in spirit (curly punctuation is never conclusive on its own) but differ in
mechanism — so this is a partial map, not 1:1.
B. Detector-only (stylometric / fingerprint — no skill prose)
These extend the skill with signals that work as math over the whole document, not as a phrase a human editor would look up:
Detector type | Label | Why it's engine-only |
|---|---|---|
punct-distribution | Punctuation distribution | Per-paragraph punctuation uniformity |
fnword-trigram-entropy | Grammar repetition | Function-word trigram entropy |
cross-para-burstiness | Cross-paragraph rhythm | Sentence-length variance across paragraphs |
normalization-flag | Bypass-trick chars | Zero-width / homoglyph humanizer-bypass detection |
C. Skill-only (LLM judgment — no detector type)
Rules that require reading for meaning, so they live in the skill prose and are applied by the model, not the regex engine. Listed so future contributors don't mistake their absence for a coverage gap:
- Synonym cycling
- Copula avoidance
- Promotional language
- Structural issues / Excessive structure / Inline-header lists / Numbered list inflation
- False ranges
- Notability name-dropping
- Self-labeling significance
- When to rewrite from scratch vs. patch
- Severity tiers (P0 / P1 / P2)
- Self-reference escape hatch
- Output format
Partial: the skill's **Context profiles / Tolerance matrix / Auto-detection
cues** are partly realized by the engine's options.contextMode(general/technical), which suppresses context-inappropriate flags. Full
profile-based tolerance remains an LLM-side judgment.
/**
* Avoid AI Writing — CATEGORIES.md anti-drift contract test
*
* CATEGORIES.md is the map between SKILL.md rules and detector `type`s. A map
* that nothing checks rots — so this test makes the contract executable:
*
* - every detector `type` (TYPE_LABELS key) must be documented in CATEGORIES.md
* - every detector `type` referenced in the CATEGORIES.md tables must be real
*
* Add a detector type without documenting it → this fails. Rename/remove a type
* and leave a stale row → this fails. Dependency-free; runs on node >= 18.
*/
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const AIDetector = require('./patterns.js');
let failed = 0;
function test(name, fn) {
try {
fn();
console.log(` ✓ ${name}`);
} catch (err) {
failed++;
console.error(` ✗ ${name}`);
console.error(` ${err.message}`);
}
}
const typeKeys = Object.keys(AIDetector.TYPE_LABELS);
const md = fs.readFileSync(path.join(__dirname, 'CATEGORIES.md'), 'utf8');
// Type tokens claimed in the first column of any table row, excluding the
// literal header token `type` and markdown separators. A stray mention in
// prose doesn't count — a type has to land in an actual mapping-table row.
const tableTypes = new Set();
for (const line of md.split('\n')) {
if (!line.startsWith('|')) continue;
const firstCell = line.split('|')[1] || '';
if (/^[\s:-]+$/.test(firstCell)) continue; // separator row
for (const m of firstCell.matchAll(/`([a-z0-9][a-z0-9-]*)`/g)) {
if (m[1] !== 'type') tableTypes.add(m[1]);
}
}
console.log('CATEGORIES.md anti-drift contract');
console.log(` (${typeKeys.length} detector types, ${tableTypes.size} documented in tables)`);
test('every detector type is documented in a CATEGORIES.md table', () => {
const missing = typeKeys.filter((k) => !tableTypes.has(k));
assert.deepEqual(
missing,
[],
`detector types missing from CATEGORIES.md tables: ${missing.join(', ')}`
);
});
test('every type referenced in the tables is a real detector type', () => {
const keySet = new Set(typeKeys);
const stale = [...tableTypes].filter((t) => !keySet.has(t));
assert.deepEqual(
stale,
[],
`CATEGORIES.md references types that no longer exist: ${stale.join(', ')}`
);
});
if (failed > 0) {
console.error(`\n${failed} contract check(s) failed.`);
process.exit(1);
}
console.log('\nCATEGORIES.md contract holds.');
Detector engine
patterns.js is the executable expression of this skill's pattern rules — a zero-dependency, build-step-free detection engine that scores text for AI-writing tells. It runs identically in Node (>=18) and in the browser.
The skill's SKILL.md is the human-readable catalog of rules; this engine is the deterministic, testable implementation of the regex-detectable subset, plus stylometric and AI-tool-fingerprint detectors that don't make sense as prose. See `CATEGORIES.md` for the rule ↔ category mapping that keeps the two in sync.
Run it
npm test # runs detector/patterns.test.js (no deps to install)
# or directly:
node detector/patterns.test.jsconst AIDetector = require("./detector/patterns.js");
const result = AIDetector.analyzeText("Your text here…");
console.log(result.score, result.label, result.issues.length);In the browser, load patterns.js as a plain script — it self-registers as a global AIDetector (the module.exports block is guarded and only runs under CommonJS).
analyzeText(text, options?) → result
| Field | Type | Meaning |
|---|---|---|
score | 0–100 | 0 = clean, 100 = heavy AI |
label | string | Minimal / Some / Strong / Heavy (or Empty / Too short / Text too long) |
issues[] | {type, text, severity, …} | one entry per detected pattern; type keys map to `CATEGORIES.md` |
stats | object | wordCount, per-tier counts, contextMode, denseAIVocab, normalization flags, etc. |
document_classification | string | trinary HUMAN_ONLY / MIXED / AI_ONLY (shape mirrors GPTZero for swap-in) |
class_probabilities | {human, mixed, ai} | sums to exactly 1.0 |
confidence_category | low / medium / high | |
highlight_sentence_for_ai | region[] | sentence spans with byte offsets + per-region score, for UI highlighting |
options.contextMode accepts general (default) or technical; technical mode suppresses flags that are legitimate in code-adjacent prose (e.g. Title Case headers). Invalid modes fall back to general and set stats.contextModeFallback.
Design notes
- FN-biased. False positives damage trust more than false negatives, so
MIXED is wide and AI_ONLY requires multiple corroborating signals.
- Scoring is non-linear. Repeated hits of the same phrase are deduplicated;
category weights live in the ISSUE_WEIGHTS table.
- Length gates. Under ~10 words →
Too short(unscorable); over 10k words →
Text too long.
MIT License
Copyright (c) 2026 Conor Bronsdon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "avoid-ai-writing-detector",
"version": "3.5.0",
"description": "Deterministic detection engine for the Avoid AI Writing skill — 44-category pattern + stylometric analysis of AI-generated text.",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/conorbronsdon/avoid-ai-writing.git"
},
"main": "detector/patterns.js",
"files": [
"detector/patterns.js"
],
"engines": {
"node": ">=18"
},
"scripts": {
"test": "node detector/patterns.test.js && node detector/categories.test.js"
}
}
{
"name": "avoid-ai-writing",
"description": "Audit & rewrite content to remove AI writing patterns (\"AI-isms\"). Supports detect-only and edit-in-place modes, voice profiles, and iterate-to-convergence.",
"version": "3.10.0",
"author": {
"name": "Conor Bronsdon"
},
"homepage": "https://github.com/conorbronsdon/avoid-ai-writing",
"repository": "https://github.com/conorbronsdon/avoid-ai-writing",
"license": "MIT",
"keywords": ["writing", "editing", "ai-detection", "humanize"]
}
<div align="center">
avoid-ai-writing
Audit & rewrite content to remove AI writing patterns. A practical skill for any AI agent. Supports detect-only and edit-in-place modes, plus voice profiles.
  
<img src="docs/demo.gif" alt="The bundled detector engine flagging 13 AI-writing patterns by category in a sample paragraph, then scoring the clean rewrite 0/100" width="800"> </div>
---
A portable writing skill for Claude Code, OpenClaw, Hermes, and any other agentskills.io-compatible agent. Audits and rewrites content to remove AI writing patterns ("AI-isms").
Three modes:
- Rewrite (default) — flags AI patterns and rewrites the text to fix them. A built-in second pass catches patterns that survived the first edit.
- Detect — flags AI patterns without rewriting. Shows which flags are real problems vs. judgment calls. Useful when patterns might be intentional, when auditing content you don't want altered, or when you just want a quick scan.
- Edit — edits a file in place (via the Edit tool) with minimal, targeted changes, preserving passages that are already human. Returns an edits-made + verification report, not the full file.
An optional voice profile (casual / professional / technical / warm / blunt) sets how the prose should sound, independent of the audience context profile.
Quick demo
Input:
Certainly! Acme Analytics, a vibrant startup nestled in the heart of Boulder's thriving tech ecosystem, has secured $40M in Series B funding — marking a watershed moment for the observability landscape. The platform serves as a unified hub, featuring real-time dashboards, boasting sub-second queries, and presenting a seamless integration layer. Moreover, experts believe Acme is poised to disrupt the market. In conclusion, the future looks bright!
Output:
Acme Analytics raised a $40M Series B led by Sequoia. The Boulder-based startup makes an observability platform that runs queries in under a second and plugs into existing monitoring stacks without custom integration work.
What it caught: chatbot opener ("Certainly!"), promotional language ("vibrant," "nestled," "thriving"), significance inflation ("watershed moment"), copula avoidance ("serves as," "featuring," "boasting"), 4 word replacements, vague attribution ("experts believe"), filler ("Moreover"), generic conclusion ("the future looks bright"), over-polished uniformity. 15+ AI tells in one paragraph.
Why a skill, not just a prompt
A one-shot "make this sound human" prompt catches the obvious stuff. This skill is different:
- Structured audit — returns identified issues with quoted text, the rewrite, a change summary, and a second-pass audit in four discrete sections. You see exactly what changed and why.
- Two-pass detection — the second pass re-reads the rewrite and catches patterns that survive the first edit: recycled transitions, lingering inflation, copula swaps that snuck through.
- 109-entry word replacement table across 3 tiers + 10 Tier 3 phrases — not vibes-based. Every flagged word has a specific, plainer alternative. "Leverage" → "use." "Commence" → "start." Tier 1 words always flag, Tier 2 words flag when they cluster, Tier 3 words flag only at high density. Tier 3 phrases (multi-word boilerplate like "the integration of," "decentralized compute") flag on per-phrase repetition or when 3+ distinct phrases stack in one piece — the LLM-self-varies-boilerplate shape.
- 49 pattern categories — representative examples below, each with before/after. Includes structural detection (hashtag stuffing, bare-NP bullet lists, hedge-stacked predictions), AI-tool fingerprints (placeholders, citation markup, UTM params), rhythm/uniformity checks, and writer-side tests. The full catalog lives in `SKILL.md`; this count is enforced against it in CI.
- Detect mode — flag patterns without rewriting. See which flags are real problems vs. judgment calls. Useful when patterns might be intentional or you're auditing content you don't want altered.
- Works across platforms — one
SKILL.mdruns in Claude Code, Cowork (as a plugin), OpenClaw, and Cursor (as a ported rule). See the install paths below.
Installation & Usage
Claude Code
Option 1: Clone into skills directory
git clone https://github.com/conorbronsdon/avoid-ai-writing ~/.claude/skills/avoid-ai-writingOption 2: Copy the file directly
Download SKILL.md and place it in any directory that Claude Code can read. Reference it in your CLAUDE.md:
- Editing for AI patterns → read `path/to/avoid-ai-writing/SKILL.md`Option 3: Use as a slash command
Create a command file (e.g., ~/.claude/commands/clean-ai-writing.md):
---
description: Audit and rewrite content to remove AI writing patterns
---
$ARGUMENTS
Read and follow the instructions in ~/.claude/skills/avoid-ai-writing/SKILL.mdThen use /clean-ai-writing <your text> in Claude Code.
Claude Cowork — install as a plugin
Cowork loads skills only from installed plugins — it doesn't scan ~/.claude/skills/, so a bare clone (the Claude Code steps above) won't be discovered there. This repo doubles as a single-plugin marketplace, so install it as a plugin instead:
/plugin marketplace add conorbronsdon/avoid-ai-writing
/plugin install avoid-ai-writing@conorbronsdon-skills
/reload-plugins # or restart the session, to activate the skillIn the Cowork desktop app, do the same from Customize → Plugins → Add marketplace from GitHub (conorbronsdon/avoid-ai-writing), then install avoid-ai-writing. The skill auto-triggers from phrases like "remove AI-isms." New releases arrive when the plugin's version is bumped — run /plugin marketplace update to pull them.
The same plugin install works in Claude Code if you'd rather have a versioned, updatable plugin than the file clone above.
Prefer not to install a plugin? CopySKILL.mdinto a folder connected to your Cowork session and tell the agent to follow./SKILL.md— works as a one-off, no auto-trigger.
OpenClaw
Option 1: [Install from ClawHub](https://clawhub.ai/conorbronsdon/avoid-ai-writing)
clawhub install avoid-ai-writingOption 2: Clone into skills directory
git clone https://github.com/conorbronsdon/avoid-ai-writing ~/.openclaw/skills/avoid-ai-writingCursor
Drop the ported rule into your project's .cursor/rules/:
mkdir -p .cursor/rules
curl -o .cursor/rules/avoid-ai-writing.mdc \
https://raw.githubusercontent.com/conorbronsdon/avoid-ai-writing/main/cursor-rules/avoid-ai-writing.mdcSee `cursor-rules/README.md` for activation globs and trigger phrases. Functionally identical to the Claude Code skill — same tier vocabulary, same context profiles, same modes.
Hermes
Drop the skill into Hermes's skills directory — it then appears automatically as /avoid-ai-writing, no registration needed:
mkdir -p ~/.hermes/skills/writing/avoid-ai-writing
curl -o ~/.hermes/skills/writing/avoid-ai-writing/SKILL.md \
https://raw.githubusercontent.com/conorbronsdon/avoid-ai-writing/main/SKILL.mdOpenAI Codex
Codex reads Agent Skills in the same SKILL.md format. Put it in .agents/skills/ at the repo root, or ~/.agents/skills/ to use it across all your projects:
mkdir -p .agents/skills/avoid-ai-writing
curl -o .agents/skills/avoid-ai-writing/SKILL.md \
https://raw.githubusercontent.com/conorbronsdon/avoid-ai-writing/main/SKILL.mdOther agents
The same SKILL.md (or the Cursor .mdc port) drops into most tools' rules/skills location:
| Tool | Where to put it |
|---|---|
| Windsurf | .windsurf/rules/avoid-ai-writing.md |
| Cline | .clinerules/avoid-ai-writing.md |
| GitHub Copilot (VS Code) | paste into .github/copilot-instructions.md |
| Claude.ai Projects | paste SKILL.md into the project's custom instructions |
| ChatGPT Custom GPTs | paste SKILL.md into the GPT's Instructions field |
Triggering the skill
Once installed, ask your assistant to clean up AI writing:
- "Remove AI-isms from this post"
- "Audit this draft for AI tells"
- "Make this sound less like AI"
- "Clean up AI writing in this paragraph"
In rewrite mode (default), the skill returns four sections:
1. Issues found — every AI-ism identified, with the text quoted 2. Rewritten version — clean version with all AI-isms removed 3. What changed — summary of the major edits 4. Second-pass audit — re-reads the rewrite and catches any surviving tells
In detect mode, the skill returns two sections:
1. Issues found — every AI-ism identified, grouped by severity (P0/P1/P2) 2. Assessment — which flags are clear problems vs. patterns that may be intentional or effective in context
Trigger detect mode with: "detect," "flag only," "audit only," "just flag," "scan," or similar.
Pattern reference
Representative examples from the catalog — not the exhaustive list (that's `SKILL.md`). The skill's human-facing prose catalog and the detector engine use different counts on purpose: the engine implements 44 type categories because it splits the vocabulary tiers and adds stylometric/fingerprint signals (punctuation distribution, function-word entropy, bypass-trick detection) that work as math over a document rather than as a rule you'd look up. The two are mapped in `detector/CATEGORIES.md`; don't "fix" one count to match the other.Content Patterns
| # | Pattern | Before | After |
|---|---|---|---|
| 1 | Significance inflation | "marking a pivotal moment in the evolution of..." | "was founded in 2019 to solve X" |
| 2 | Notability name-dropping | "cited in NYT, BBC, and Wired" | "In a 2024 NYT interview, she argued..." |
| 3 | Superficial -ing analyses | "symbolizing... reflecting... showcasing..." | Replace with specific facts or cut |
| 4 | Promotional language | "nestled within the breathtaking region" | "is a town in the Gonder region" |
| 5 | Vague attributions | "Experts believe it plays a crucial role" | "according to a 2019 survey by Gartner" |
| 6 | Formulaic challenges | "Despite challenges... continues to thrive" | Name the challenge and the response |
| 7 | Novelty inflation | "He introduced a term I hadn't heard before" | "He walked through how X works in practice" |
Language Patterns
| # | Pattern | Before | After |
|---|---|---|---|
| 8 | Word/phrase replacements (3 tiers) | "leverage... robust... seamless... utilize" | "use... reliable... smooth... use" |
| 9 | Copula avoidance | "serves as... features... boasts" | "is... has" |
| 10 | Synonym cycling | "developers... engineers... practitioners... builders" | "developers" (repeat the clear word) |
| 11 | Template phrases | "a [adj] step towards [adj] infrastructure" | Describe the specific outcome |
| 12 | Filler phrases | "In order to," "Due to the fact that" | "To," "Because" |
| 13 | False ranges | "from the Big Bang to dark matter" | List the actual topics |
| 14 | Parenthetical hedging | "tools (like X and Y)" | Name them directly or cut |
Structure Patterns
| # | Pattern | Before | After |
|---|---|---|---|
| 15 | Formatting | Em dashes (— and --), bold overuse, emoji headers, bullet-heavy | Commas/periods, prose paragraphs |
| 16 | Sentence structure | "It's not X, it's Y" + hollow intensifiers + hedging | Direct positive statements |
| 17 | Structural issues | Uniform paragraphs, formulaic openings, too-clean grammar | Varied length, lead with the point |
| 18 | Transition phrases | "Moreover," "Furthermore," "In today's [X]" | "and," "also," or restructure |
| 19 | Inline-header lists | "Speed: Speed improved by..." | Write the point directly |
| 20 | Title case headings | "Strategic Negotiations And Partnerships" | "Strategic negotiations and partnerships" |
| 21 | Numbered list inflation | "Here are 7 reasons why..." | Cut to the 2-3 that matter |
| 22 | False concession | "While X has limitations, it's still remarkable" | State the real tradeoff |
| 23 | Rhetorical question openers | "What if there were a better way to...?" | Lead with the claim |
Communication Patterns
| # | Pattern | Before | After |
|---|---|---|---|
| 24 | Chatbot artifacts | "I hope this helps! Let me know if..." | Remove entirely |
| 25 | "Let's" constructions | "Let's explore," "Let's break this down" | Just start with the point |
| 26 | Cutoff disclaimers | "While details are limited in available sources..." | Find sources or remove |
| 27 | Generic conclusions | "The future looks bright," "Only time will tell" | Specific closing thought or cut |
| 28 | Emotional flatline | "What surprised me most," "I was fascinated to discover" | Earn the emotion or cut the claim |
| 29 | Reasoning chain artifacts | "Let me think step by step," "Breaking this down" | State conclusion, then evidence |
| 30 | Sycophantic tone | "Great question!", "You're absolutely right!" | Remove entirely |
| 31 | Acknowledgment loops | "You're asking about," "To answer your question" | Just answer directly |
| 32 | Confidence calibration | "It's worth noting," "Interestingly," "Surprisingly" | Let the fact speak for itself |
Meta Patterns
| # | Pattern | Before | After |
|---|---|---|---|
| 33 | Excessive structure | 5 headers in 200 words, "Overview:", "Key Points:" | Merge sections, use specific headers |
| 34 | Rhythm and uniformity | All sentences 15–25 words, all paragraphs same length | Mix short/long, fragments, questions |
| 35 | Over-polishing | Every irregularity sanded away, perfectly uniform prose | Keep natural disfluency, varied rhythm |
| 36 | Rewrite-vs-patch threshold | 5+ vocabulary flags + 3+ pattern categories + uniform rhythm | Advise full rewrite, not patching |
Structural Detection (v3.4)
Added in v3.4 to catch LLM output that sidesteps the vocabulary tables by substituting synonyms but still leans on structural shapes detectors can identify. Crypto/web3/AI-infra content is where these patterns concentrate most heavily, but the rules generalize to any social-length post.
| # | Pattern | Before | After |
|---|---|---|---|
| 37 | Tier 3 phrases (multi-word boilerplate) | "the integration of," "decentralized compute," "community-driven," "long-term sustainability" stacked across a piece | Replace the repeated phrase with a specific claim, or vary genuinely. Flagged per-phrase at ≥2 hits, or as a cluster when ≥3 distinct phrases appear |
| 38 | Future-narrative closers | "may become one of the most important narratives of the next market cycle" | Pick the falsifiable version. "X may exceed Y by 2027" is a prediction; the template form is not |
| 39 | Hedge-stacked predictions | "could potentially create," "may eventually unlock" | Pick one. Each hedge cancels the next |
| 40 | "Real/actual" adjective inflation | "real on-chain tokenomics," "actual reward sustainability" | Drop the empty intensifier and add the specific claim. Carve-out: "real on-chain settlement, not bridged IOUs" is honest contrastive writing — the AI tell is the unsaid contrast |
| 41 | Hashtag stuffing | 15-tag trailing block: #AI #Crypto #Web3 #Innovation #FutureTech… | 2-3 specific tags max, or none. Empirical threshold: 6+ tags is near-universal in LLM social output, rare in thoughtful human posts |
| 42 | Bullet lists of bare noun phrases | * Stable mining efficiency / Reliable pool connectivity / Optimized RandomX performance / Low failed share rates / Effective hardware utilization / Consistent thermal stability | Convert to prose, or rewrite each item as a full claim with a verb and a number. Carve-out: genuine list content (changelogs, parameter docs, ingredient lists) where bare NPs are correct |
AI-tool fingerprints & later additions (v3.5–3.8)
| # | Pattern | Before | After |
|---|---|---|---|
| 43 | Unfilled placeholders | [Your Name], [INSERT SOURCE], 2025-XX-XX | Fill in with real content or delete — shipped placeholders are a near-definitive tell |
| 44 | Chatbot citation markup | citeturn0search0, oai_citation, contentReference[oaicite:0] | Strip the markup token entirely |
| 45 | AI-tool URL parameters | utm_source=chatgpt.com, utm_source=copilot.com | Strip the tracking parameter; keep the URL if the link matters |
| 46 | Speculative gap-filling | "maintains a low profile," "likely began his career" | Cut the guess, or replace with a sourced fact |
| 47 | Hyphenated-pair overuse | "a high-quality, well-architected, future-proof solution" | Cut to the modifier that matters; no hyphen in predicate ("the report is high quality") |
| 48 | Infomercial engagement hooks | "The catch?", "The kicker?", "Here's the thing." | Delete the hook, state the thing |
| 49 | Vocabulary diversity (low TTR) | Narrow, repetitive word range across 200+ words | Broaden the what — name specific things, cite specific cases |
| 50 | Self-labeling significance | "That last move is the contrarian one," "This is the interesting part" | Cut the label; let the explanation carry the weight, or reposition the item so it stands out on its own |
| 51 | List-label periods | - **Intros.** Years of conferences and operator network. (also unbolded: - Intros. Years of...) | Use a colon, not a period, on a list label: - **Intros:** years of conferences and operator network. |
Two writer-side tests round out the catalog (judgment checks, not auto-detected): paragraph-reshuffle immunity (can you swap two body paragraphs without breaking the piece?) and the treadmill effect ("what's actually new in this paragraph?").
Full Example
Before (AI-generated):
Certainly! Here's a comprehensive overview of Acme's Series B.
>
Acme Analytics, a vibrant startup nestled in the heart of Boulder's thriving tech ecosystem, has secured $40M in Series B funding — marking a watershed moment for the company and the observability landscape at large. The round was led by Sequoia, with participation from Andreessen Horowitz, Y Combinator, and Index Ventures, underscoring the robust investor confidence in Acme's vision.
>
The platform serves as a unified hub for engineering teams, featuring real-time dashboards, boasting sub-second query performance, and presenting a seamless integration layer. It's not just another monitoring tool — it's a paradigm shift in how organizations navigate complex distributed systems. Experts believe Acme is poised to disrupt the $15B observability market. Studies show that companies utilizing comprehensive monitoring solutions can ascertain issues 40% faster.
>
- 🚀 Performance: The platform streamlines incident response, empowering engineers to resolve issues faster.
- 💡 Scale: Acme fosters collaboration across teams, from frontend developers to SRE practitioners to platform builders to infrastructure engineers.
- ✅ Adoption: Customer adoption continues to accelerate, reflecting broader industry trends.
>
Moreover, Acme's approach showcases the potential of modern observability — symbolizing a shift toward proactive monitoring, reflecting years of R&D investment, and highlighting the intricate interplay between data collection and actionable intelligence. Despite challenges common in the crowded monitoring space, Acme continues to thrive. In order to fully capitalize on this momentum, the company plans to expand its go-to-market endeavors.
>
In conclusion, the future looks bright for Acme Analytics. Only time will tell how this game-changer will reshape the observability paradigm. Feel free to reach out if you'd like more details!
After (cleaned up):
Acme Analytics raised a $40M Series B led by Sequoia. The Boulder-based startup makes an observability platform that runs queries in under a second and plugs into existing monitoring stacks without custom integration work.
>
The pitch is speed. Their median time-to-resolution is 12 minutes, compared to the 45-minute industry average that Datadog reported in 2024. That gap is why 380 companies are paying for it.
>
They'll use the money to hire sales reps in EMEA and add log management. The monitoring market is crowded, but Acme's bet is that most teams still stitch together three or four tools and lose time switching between them.
What the skill caught: chatbot artifacts (Certainly!, Feel free to reach out), 3 em dashes, promotional language (vibrant, nestled, thriving), significance inflation (watershed moment), copula avoidance (serves as, featuring, boasting, presenting), 10 word replacements (landscape, robust, seamless, paradigm, streamline, empower, foster, utilize, ascertain, endeavor), synonym cycling (developers/practitioners/builders/engineers), negative parallelism (It's not just X, it's Y), notability name-dropping (Sequoia, a16z, YC, Index stacked for credibility), vague attributions (Experts believe, Studies show), filler phrases (In order to, Moreover), inline-header list with emoji, superficial -ing analysis (symbolizing... reflecting... highlighting...), formulaic challenges (Despite challenges... continues to thrive), generic conclusion (the future looks bright, only time will tell), false range implied in the adoption bullet.
That's 35+ AI tells.
Run the detector
The skill ships a deterministic, zero-dependency detection engine in `detector/` — the same 44-category engine the rules above describe, as runnable code. It works in Node (>=18) and the browser with no build step.
It's also the single source of the numeric score: the skill itself (and detect mode) report which patterns are present and how severe (P0/P1/P2), and the engine is what turns those into one computed 0–100 score. There's deliberately no second, prose-estimated score in SKILL.md — one scorer, not two.
npm test # run the detector's fixtures (no deps to install)const AIDetector = require("./detector/patterns.js");
const { score, label, issues } = AIDetector.analyzeText("Your text here…");See `detector/README.md` for the full analyzeText API and `detector/CATEGORIES.md` for the rule ↔ category map that keeps SKILL.md and the engine in sync.
Credits
Pattern research informed by:
- Pangram Labs AI detection research — structural regularity insights, vocabulary flags from a decoder-only classifier trained on 28M human documents
- Wikipedia's Signs of AI-generated text documentation — the canonical reference for AI writing tells, maintained by Wikipedia editors
- blader/humanizer Claude Code skill
- brandonwise/humanizer — tiered vocabulary system, statistical analysis research (burstiness, sentence length variation, trigram repetition), and rewrite philosophy
- OpenClaw humanizer skill ecosystem — community patterns and vocabulary research
Authored by Conor Bronsdon · LinkedIn · Chain of Thought podcast
Community / Multilingual
Things the community has built around this skill:
- [avoid-ai-writing-multilingual](https://github.com/jurigis/avoid-ai-writing-multilingual) by Jürgen Kraus — German (
SKILL-DE.md) and Romanian (SKILL-RO.md) adaptations, grounded in native-language research rather than translated from English. French and Spanish planned. - [$avoid token + burn web app](https://avoid-ai-writing-app.vercel.app) — a community-built Solana token (
$avoid) and token-burn web app around this project (2026), now in maintenance mode.
Built something on top of this skill? Open an issue — happy to link it here.
---
Disclaimer
All views, opinions, and statements expressed on this account are solely my own and are made in my personal capacity. They do not reflect, and should not be construed as reflecting, the views, positions, or policies of Modular. This account is not affiliated with, authorized by, or endorsed by Modular in any way.
License
MIT
Related skills
How it compares
Pick avoid-ai-writing over generic copyediting skills when the source text is AI-drafted and the goal is removing recognizable LLM filler patterns.
FAQ
What does avoid-ai-writing change in a draft?
avoid-ai-writing rewrites AI-generated prose to remove generic, predictable LLM phrasing and templated diction so technical docs and blog copy read naturally before publishing.
How popular is avoid-ai-writing on skills.sh?
avoid-ai-writing from conorbronsdon/avoid-ai-writing reports 529 installs on skills.sh, indicating active community use for pre-publish prose cleanup.