detect-ai-text-cl-op
AI text detection and humanization. Two modes — Detection (full report) or Humanization (rewrite only, no detection output).
SKILL.md.claude/skills/detect-ai-text-humanize/SKILL.md
GitHubAI Text Detection & Humanization Skill
Two-mode skill for AI-generated text:
- Detection mode — analyze text to determine whether it was likely generated by an AI model (Claude Opus 4.6, GPT-5.*, Gemini, etc.) with detailed reasoning, passage-level highlighting, and statistical backing.
- Humanization mode — rewrite AI-sounding text to read as human, using detection internally as a diagnostic but without surfacing any detection results to the user.
In Detection mode, after completing analysis, always offer to humanize the text (which then switches to Humanization mode for the rewrite).
Mode Selection
Decide which mode you are in before producing any output.
Detection mode (default) — triggers:
- "check this for AI", "detect AI", "is this AI-written", "AI detection"
- The user pastes text and asks for analysis without specifying a rewrite
- The user uploads a document and asks generically about it
→ Run the full pipeline (Steps 0–5) and produce the detection report.
Humanization mode — triggers:
- "humanize this", "humanize", "make this sound human", "make this less AI-ish"
- "rewrite as human", "de-AI this", "remove the AI tells"
- After a detection report, the user follows up with "now humanize it" or similar
→ Run Steps 0–4 internally as a diagnostic only. Do NOT output the detection report (skip Step 5). Use the identified tells as a targeted rewrite checklist (see "Humanization Workflow" below).
Hard rule for Humanization mode: No probability scores, no verdict, no statistical numbers, no "Top Indicators" list, no pattern citations, no model guess, no per-section breakdown in the output. The user asked for humanized text, not a detection write-up. A brief "Key changes" note (1–3 sentences, category names only) is allowed and useful.
If the user starts in Detection mode and then asks to humanize, switch modes — do not repeat the detection report.
Important Caveats (Always Communicate These — Detection mode only)
In Detection mode, always tell the user:
- No detector achieves 100% accuracy. This is pattern-matching, not proof.
- Heavily human-edited AI text will score lower (correctly — it's now mixed-origin).
- Highly formal human writing (academic, legal, medical) can trigger false positives.
- Non-native English writers sometimes produce patterns that overlap with AI tells.
- Self-detection paradox: Claude analyzing Claude has both advantages (deep pattern familiarity) and blind spots (systematic biases Claude can't introspect on).
Frame all Detection-mode outputs as "indicators" and "likelihood", never as "proof" or "certainty."
In Humanization mode, do NOT recite these caveats in the output — they are detection-result framing. Internally they still apply (don't over-claim a "fully de-AI'd" rewrite), but suppress them from the deliverable.
Detection Pipeline
When given text, follow these steps in order.
- In Detection mode, run all of Steps 0–5 and output the report.
- In Humanization mode, run Steps 0–4 silently (do not narrate progress, do not show intermediate numbers) and then jump to the Humanization Workflow section. Skip Step 5.
Step 0: Preprocess Markup (if applicable)
If the input is in a markup format (LaTeX, HTML, Markdown, etc.) rather than plain text, extract the prose before running statistical or pattern analysis. Markup commands, comments, tables, and float environments add noise that skews statistical metrics (TTR, burstiness) and triggers false pattern matches.
LaTeX: Run scripts/extract_latex.py on the .tex file:
# Whole-document prose extraction (feed output to analyze.py)
python scripts/extract_latex.py document.tex -o prose.txt
# Per-section extraction (JSON, for passage-level analysis)
python scripts/extract_latex.py document.tex --per-section -o sections.json
# Strip project-specific \todo-style author commands
python scripts/extract_latex.py document.tex --todo-authors "alice,bob,carol"
extract_latex.py handles:
- Preamble removal (everything before
\begin{document}) - LaTeX comments (full-line and inline)
- Custom
\authorname{...}todo-note macros (via--todo-authors) - Standard
\todo[...]{...}from the todonotes package - Float environments: table, figure, tikzpicture, lstlisting, verbatim, minted, algorithm, algorithmic, tabular/tabularx
- Inline commands: preserves text content of
\textbf,\emph,\gls, etc. - Cross-references and citations: strips
\Cref,\cite,\url, etc. - Section headings: preserves title text
- List environments and
\itemmarkers - Catch-all for remaining
\command{arg}patterns
The --per-section mode splits on \chapter, \section, \subsection,
\subsubsection, \paragraph, and \subparagraph headings, returning a JSON
array of {"heading", "word_count", "prose"} objects. Sections below --min-words
(default 30) are dropped. This output is useful for Step 4 (passage-level analysis).
HTML: Strip tags with a simple regex or BeautifulSoup if available. Remove
<script>, <style>, <nav>, <footer> blocks before extraction.
Markdown: Generally usable as-is for detection. Strip YAML front matter and code fences if they dominate the word count.
If the input is already plain text, skip this step.
Step 1: Compute Statistical Features
Read and run scripts/analyze.py on the input text (or on the prose extracted in
Step 0). If the script is unavailable or the environment doesn't support it, compute
these mentally and approximate:
- Burstiness: Standard deviation of sentence lengths. Claude tends toward low burstiness (sentences are rhythmically uniform). Human writing is "bursty" — short punchy fragments mixed with long complex clauses.
- Lexical diversity: Type-token ratio (TTR). Claude tends toward moderate TTR with synonym cycling (using different words for the same concept across paragraphs).
- Sentence length variance: Claude paragraphs tend to have sentences within a narrow length band. Humans vary more wildly.
- Function/content word ratio: Claude uses slightly more function words (determiners, prepositions, auxiliaries) than typical human writing.
Note on TTR for technical documents: Domain-specific text that repeats terminology heavily (e.g. "CTS", "System", "MPC") will have artificially low TTR. Weight TTR less heavily in such cases and rely more on burstiness and pattern analysis.
Step 2: Scan for AI Model Patterns
Read references/claude-opus-patterns.md for the Claude pattern library, and references/detection-heuristics.md for general AI patterns. Check the text against every category. The major pattern families are:
Non-Claude AI tells (GPT-5, Gemini, etc.):
- OpenAI GPT-5.*: frequent use of "certainly", "of course", "absolutely"; tendency to mirror the user's question structure in the opening sentence; over-affirmative tone
- Gemini: slightly more verbose hedging; "it's important to note"; structured enumeration with transitional summaries
- Llama/Mistral (instruction-tuned): more literal compliance with prompts; less nuanced caveating; occasionally awkward connectives
- General LLM tell: extremely smooth logical flow with no tangents, digressions, or genuine uncertainty — human writing wanders; AI writing doesn't
Claude-specific tells:
Structural tells:
- Balanced paragraph architecture (intro → points → synthesis → caveat)
- "Sandwich" pattern: positive framing → honest content → constructive reframe
- Numbered or parallel structures even when not requested
- Consistent paragraph lengths (Claude rarely writes a 1-sentence paragraph followed by a 10-sentence one)
Vocabulary tells (Claude Opus 4.6 specific):
- Hedging cluster: "it's worth noting", "that said", "to be fair", "it's important to recognize"
- Connective tissue: "let me", "here's the thing", "the key insight is"
- Qualification reflex: "tends to", "generally", "in many cases", "typically"
- Warmth markers: "great question", "I appreciate", "happy to help"
- Avoidance vocabulary: Claude avoids "genuinely", "honestly", "straightforward" (by instruction) — the absence of these common English words in otherwise fluent text is itself a tell
Formatting tells:
- Em-dash overuse (—) where commas or parentheses would be more natural
- Bold emphasis on key phrases within paragraphs
- Headers/subheaders even for relatively short content
- Consistent use of ":" to introduce explanations
- Bullet points with 1-2 sentence explanations each
Reasoning tells:
- Preemptive objection handling ("you might wonder...", "one concern is...")
- Explicit epistemic calibration ("I'm fairly confident", "I'm less sure about")
- Multi-perspective presentation even when one view clearly dominates
- "Both sides" framing on topics where humans would just state their position
- Caveats and disclaimers appended to otherwise clear statements
Code/technical writing tells:
- Overly thorough commenting (explaining obvious operations)
- Consistent code style within a single response (humans drift)
- Variable names that are descriptively perfect (rarely single-letter or abbreviations)
- Error handling that's suspiciously comprehensive for a first draft
- "Here's what this does" explanatory blocks before/after code
Step 3: Apply the Five Cue Families
From the 2026 detection literature (see references), cross-check using:
- Surface cues: Lexical diversity, POS distributions, readability scores, punctuation patterns
- Discourse/Pragmatic cues: Metadiscourse markers, rhetorical organization, stance expressions
- Epistemic/Content cues: How claims are grounded, evidentiality, plausibility of specifics
- Predictability cues: Perplexity proxy (how "expected" each word choice is), entropy patterns
- Provenance cues: Formatting artifacts, citation style, structural templates
Step 4: Passage-Level Analysis
Don't just give an overall score — analyze the text section by section.
Automated scoring: Run scripts/score_sections.py to score and rank sections:
# From pre-extracted JSON (preferred — output of extract_latex.py --per-section):
python scripts/score_sections.py sections.json --top 10
# Directly from a .tex file (runs extract_latex.py internally):
python scripts/score_sections.py document.tex --todo-authors "alice,bob"
# With domain jargon as human counter-indicators:
python scripts/score_sections.py sections.json --domain-jargon "etcd,SecreC,SPDZ"
# Machine-readable JSON output (includes per-section stats from analyze.py):
python scripts/score_sections.py sections.json --json
The script checks ~40 regex patterns across five categories (vocabulary, structure, formatting, reasoning, meta-commentary), applies human counter-indicators (colloquial language, Claude-avoided words, unexplained domain jargon), and scores sentence-level uniformity and paragraph-level uniformity. Scores are normalized by word count so short and long sections are comparable.
When analyze.py is co-located in the same scripts/ folder, score_sections.py
automatically imports it to attach per-section statistical features (burstiness,
TTR, sentence variance) to the JSON output.
Cross-section template parallelism: The script also flags structural patterns across the document: repeated headings (e.g. 5x "Acceptance criteria"), shared opening-sentence skeletons, and stock phrases appearing in 3+ sections. These are strong structural tells — AI-generated documents tend to stamp the same template across parallel sections, while human authors introduce more variation even when writing to a shared outline.
If score_sections.py is unavailable, apply these checks manually:
- Break the input into logical sections (paragraphs or thematic blocks)
- For each section, note which specific patterns triggered and why
- Flag individual sentences or phrases that are strong indicators
- Identify any sections that break the AI pattern (possible human edits)
- Sections shorter than ~30 words are unreliable — flag but don't rank them
Step 5: Produce the Report (Detection mode ONLY — skip in Humanization mode)
In Humanization mode, do not produce this report at all. Jump to the Humanization Workflow section instead.
Output this structure (adapt formatting to context — formal report vs. quick chat):
## Detection Analysis
**Overall AI Probability**: [0-100]%
**Confidence**: High / Medium / Low
**Verdict**: Likely Claude | Likely GPT-5.* | Likely Gemini | Likely Other AI | Likely Human | Mixed/Edited | Uncertain
**Model Guess**: Claude Opus 4.6 / Claude Sonnet 4.5 / Other Claude / GPT-5.* / Gemini / Unknown AI / Human
### Statistical Summary
- Burstiness: [value] (human baseline: X, AI baseline: Y)
- Lexical diversity (TTR): [value]
- Sentence length std dev: [value]
- [other computed metrics]
### Top Indicators
1. [Specific pattern] — "[quoted passage]" — [explanation citing which pattern family]
2. [...]
3. [...]
### Passage-Level Breakdown
**Section 1** (lines/paragraphs X-Y): [score]% AI probability
- [specific findings]
[...]
### Counter-indicators (signs pointing toward human)
- [any human-like patterns found]
### Confidence Factors
- [what makes this assessment more/less reliable for this specific text]
### Caveats
- [relevant warnings for this text type — e.g., academic text, non-native speaker, etc.]
Handling Edge Cases
Highly formal human writing (academic, legal): Raise the evidence threshold. Professional documentation naturally has low burstiness and formal vocabulary. Look harder for model-specific vocabulary tells rather than general AI tells.
Non-native English speakers: "Correct but simple" grammar overlaps with AI patterns. Weight structural and vocabulary tells more heavily than surface-level fluency markers. Look for cultural idioms, non-standard logic flow, and "awkward-but-human" phrasing as human markers.
Humanized AI text (passed through paraphrasing tools or lightly edited): Focus on paragraph-level coherence. Even when individual sentences are humanized, the logical architecture between paragraphs often remains "too structured." Also check for inconsistent style — human edits create style breaks that pure AI text doesn't have.
Mixed-origin text (human draft + AI expansion, or AI draft + human editing): Report this honestly as "Mixed." Identify which sections appear AI-generated vs. human. Style breaks, tonal shifts, and inconsistent formatting are strong indicators of mixed authorship.
LaTeX / markup documents:
Always preprocess with Step 0 before analysis. Raw LaTeX commands inflate word counts,
suppress TTR, and create false pattern matches on structural commands. The --per-section
mode is particularly useful for these documents since section headings provide natural
analysis boundaries. Be aware that LaTeX-specific conventions (e.g. w.r.t, i.e.,
tilde-spaces) can confuse sentence splitting after extraction.
Domain-Specific Adjustments
Long-form articles/reports: Weight structural patterns heavily. Claude's "intro → body → synthesis → caveats" architecture is distinctive. Check for the characteristic "balanced treatment" even of topics where a human author would clearly take a side.
Technical/code writing:
Check for over-documentation, suspiciously complete error handling, perfectly consistent
style, and explanatory scaffolding that's more thorough than developers typically write
in first drafts. Also check for characteristic Claude code patterns: preferring const over
let, comprehensive destructuring, async/await preference, explicit return types.
EU / institutional technical deliverables: These are a specific edge case. The formal register, repetitive terminology, and mandated document structure (scope, audience, methodology, results) overlap heavily with AI tells. Reduce confidence by 10-15% for this genre. Focus on: template parallelism across parallel sections (a strong tell even here), preemptive justification of limitations, and synonym cycling for verbs in roadmap sentences (defines/describes/explains/covers).
Humanization Workflow (Humanization mode ONLY)
This section is used when the skill is in Humanization mode. The goal is to rewrite the text so it no longer pattern-matches as AI, while preserving the user's intended meaning, technical accuracy, and any required terminology.
Hard rules:
- Do NOT produce a detection report.
- Do NOT output probability scores, verdicts, statistical numbers, pattern lists, or per-section breakdowns.
- Do NOT recite the "Important Caveats" section in the output.
- DO use Steps 0–4 silently as a diagnostic to build a per-text list of which tells are actually present, so the rewrite targets the right things instead of applying a generic checklist.
Internal diagnostic (silent)
Before rewriting, internally answer:
- Which vocabulary tells are present? (hedging clusters, warmth markers, qualification reflexes, missing common words)
- Which structural tells are present? (sandwich architecture, uniform paragraph lengths, parallel lists)
- Which formatting tells are present? (em-dashes, mid-paragraph bolding, unnecessary headers, ":"-introductions)
- Which reasoning tells are present? (preemptive objection handling, explicit epistemic calibration, both-sides framing, appended caveats)
- What is the burstiness like? Are sentences uniformly mid-length?
- Is there required domain terminology that must be preserved as-is? (legal, medical, EU institutional, technical jargon)
This list is for your own use. Do not output it.
Targeted rewrites by tell category
For each tell category actually present in this text, apply these transformations:
Vocabulary tells:
- Remove hedging clusters ("it's worth noting", "that said", "to be fair", "it's important to recognize") — usually they add nothing; cut them.
- Cut warmth markers ("great question", "happy to help", "I appreciate") entirely.
- Break qualification reflexes ("tends to", "generally", "in many cases") — commit to a specific claim where defensible, or remove the qualified sentence.
- Reintroduce common English words Claude avoids ("honestly", "genuinely", "straightforward") where natural — their absence is itself a tell.
Structural tells:
- Break the "intro → points → synthesis → caveat" sandwich. Drop the synthesis OR the caveat (often both — humans rarely tie a bow on everything).
- Vary paragraph lengths. Insert at least one short (1–2 sentence) paragraph and one longer, less tidy one.
- Where the AI produced 3–5 parallel items, a human might write 2 and trail off, or list 7 with a throwaway at the end. Disrupt the parallel rhythm.
Formatting tells:
- Convert em-dashes (—) to commas, parentheses, or periods, except where the em-dash genuinely fits the rhythm.
- Remove bold emphasis within paragraphs unless the user explicitly wants it.
- Remove headers from short content (under ~300 words) unless the structure requires them.
- Replace ":"-introductions ("Here's the thing: …") with natural transitions ("So,", "Anyway,", "Look,", or just nothing).
Reasoning tells:
- Cut preemptive objection handling ("you might wonder…", "one concern is…").
- Drop explicit epistemic calibration ("I'm fairly confident", "I'm less sure about") — humans rarely flag their own confidence levels in prose.
- Take a side. If the AI wrote "both X and Y have merit", pick one and say so.
- Cut hedged caveats appended to clear statements.
Burstiness fix (apply last):
- After rewriting, eyeball sentence-length variance. If sentences still feel uniform, deliberately rewrite some as short fragments and combine others into longer, looser sentences. Humans cluster sentence lengths unevenly.
Domain-aware constraints
- Required terminology (legal, medical, EU institutional, specific technical jargon): preserve verbatim. Humanize the structural/rhetorical envelope, not the terminology.
- Code/technical writing: don't strip useful comments just because they're "too thorough" — keep them if they're load-bearing. Focus on the prose around code, and on inconsistent style drift (humans drift; AI doesn't).
- Quoted material, citations, named entities: leave untouched.
What NOT to do
- Don't introduce factual errors, fake confidence, or new claims. The rewrite is stylistic, not substantive.
- Don't add slang, typos, or obvious mistakes just to sound human — that overcorrects and reads as performative.
- Don't strip information the user needs.
- Don't change the language. If the source is in Estonian, rewrite in Estonian.
Output format (Humanization mode)
Produce only:
- The humanized text, formatted the same way as the input (markdown stays markdown, plain text stays plain text, LaTeX stays LaTeX with original commands preserved around the rewritten prose).
- After a
---separator, a Key changes note: 1–3 sentences naming the categories of edits applied (e.g. "Removed hedging clusters and warmth markers, broke the sandwich structure in §2, varied sentence lengths throughout."). No scores. No probabilities. No pattern citations. - If the rewrite required substantial restructuring (e.g., a section was cut, a claim was simplified), add a one-line note so the user can verify nothing essential was lost.
That's the entire output. Nothing else.
Reference Files
references/claude-opus-patterns.md— Comprehensive pattern library for Claude Opus 4.6. Read this file for the full detection checklist. (~200 items organized by category)references/detection-heuristics.md— General AI detection heuristics from the literature, applicable across models. Read when the text might be from a non-Claude AI.scripts/analyze.py— Whole-document statistical features (burstiness, TTR, sentence variance, hedge density, AI vocabulary scan). Run on plain text in Step 1. Also imported byscore_sections.pyfor per-section stats.scripts/extract_latex.py— Extract readable prose from LaTeX source files. Supports whole-document and per-section (JSON) modes. Run in Step 0 when the input is a.texfile. Also imported byscore_sections.pyfor direct.texinput.scripts/score_sections.py— Per-section AI pattern scoring. Checks ~40 regex patterns across vocabulary / structure / formatting / reasoning categories, applies human counter-indicators, detects cross-section template parallelism, and ranks sections by normalized score. Run in Step 4. Accepts.json(fromextract_latex.py --per-section),.tex, or.txtinput.