cd /news/ai-tools/how-to-humanize-ai-text-without-losi… · home › topics › ai-tools › article
[ARTICLE · art-151992] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=· neutral

How to Humanize AI Text Without Losing the Content: A Diff-Based Review Workflow

A developer published a diff-based review workflow for humanizing AI-drafted technical text while verifying that meaning is preserved. The approach commits the AI draft to git, rewrites it section by section, reviews changes with `git diff --word-diff=color`, and runs a short Python script built on `difflib.ndiff` that flags any altered protected tokens such as numbers, versions, code identifiers, URLs and modal verbs like must and never. A non-zero exit code from the script signals that a section needs manual review before the change is committed.

by read3 min views2 publishedOct 17, 2026

Any rewrite tool, whether it's a humanizer, a paraphraser or "ChatGPT, make this sound natural," has the same failure mode: it improves the voice and quietly changes the meaning. A version number becomes "the latest version." "Must" becomes "should." A three-step process becomes two.

For docs, release notes, support macros or anything technical, that's a bug. Here's the workflow I use to humanize AI-drafted text and prove nothing important changed, using tools you already have: git diff, Python's difflib and a short checklist.

You'd never merge a refactor without reviewing the diff. A humanizing pass is a refactor of prose: same behaviour (meaning), different implementation (wording). So:

mkdir humanize-review && cd humanize-review
git init
cp ~/drafts/release-notes.md .
git add release-notes.md
git commit -m "AI draft, before humanizing"

Now any change shows up in review.

Rewriting a whole document in one pass gives the tool more room to drift. Work section by section, ideally a few hundred words at a time. Keep headings, code blocks and tables out of the rewrite. Those should never change.

I use UnAIMyText for this step because it rewrites at the sentence level and is designed to keep meaning while changing rhythm and phrasing. The free tier takes up to 500 words per input, which fits the section-by-section approach. The workflow below works with any tool, including your own LLM prompt.

Paste the result back over the section in the file.

Line diffs are useless for prose because one edit marks a whole paragraph as changed. Use word-level diffs instead:

git diff --word-diff=color

--word-diff is documented in the git diff reference. It shows insertions and deletions inline, so you can see exactly which words moved.

Some tokens should almost never change in a humanizing pass: numbers, versions, code identifiers, URLs, product names and modal verbs like must, never and only. A small script can catch them.

import re, sys, difflib

PROTECTED = re.compile(
    r"\b\d[\d.,:%]*\b"          # numbers, versions, times, percentages
    r"|`[^`]+`"                 # inline code
    r"|https?://\S+"            # URLs
    r"|\b(must|never|only|always|required|not)\b",  # meaning-critical words
    re.IGNORECASE,
)

def tokens(text):
    return [m.group(0).lower() for m in PROTECTED.finditer(text)]

before = open(sys.argv[1], encoding="utf-8").read()
after = open(sys.argv[2], encoding="utf-8").read()

diff = list(difflib.ndiff(tokens(before), tokens(after)))
changes = [d for d in diff if d.startswith(("- ", "+ "))]

if changes:
    print("Protected tokens changed:")
    for c in changes:
        print("  ", c)
    sys.exit(1)
print("No protected tokens changed.")

Run it against the committed version:

git show HEAD:release-notes.md > /tmp/before.md
python check_meaning.py /tmp/before.md release-notes.md

difflib.ndiff comes from Python's standard library (difflib docs), so there's nothing to install. A non-zero exit code means you need to look at that section again.

The script catches the mechanical stuff. For the rest, read the word diff and ask:

Revert those hunks by hand. Keep the rhythm and phrasing improvements.

git commit -am "Humanize release notes: rhythm and phrasing only, protected tokens unchanged"

If someone questions a sentence later, you have both versions and the reasoning.

The regex above is a starting point. Adjust it to what carries meaning in your docs:

--[a-z-]+ and HTTP verbs such as GET, POST and DELETE. Keep the list short enough that a failure means something. If the script flags every run, people stop reading its output. Start with numbers, code and a few modal verbs, then add patterns only when a real regression slips through. Over time the list becomes a record of the mistakes your rewrite step has actually made, which is the most useful kind of check.

For a team, put check_meaning.py in a pre-commit hook for your docs/ folder. Anyone can humanize AI drafts however they like. The hook just makes sure the facts survive.

Humanizing is safe when you can see exactly what changed. Commit first, rewrite in sections, review a word-level diff, and let a ten-line script guard the tokens that carry meaning. The voice gets better and the content stays the same.

── more in #ai-tools 4 stories · sorted by recency
── more on @unaimytext 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-humanize-ai-t…] indexed:0 read:3min 2026-10-17 · —