{"slug": "how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow", "title": "How to Humanize AI Text Without Losing the Content: A Diff-Based Review Workflow", "summary": "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.", "body_md": "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.\n\nFor 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.\n\nYou'd never merge a refactor without reviewing the diff. A humanizing pass is a refactor of prose: same behaviour (meaning), different implementation (wording). So:\n\n```\nmkdir humanize-review && cd humanize-review\ngit init\ncp ~/drafts/release-notes.md .\ngit add release-notes.md\ngit commit -m \"AI draft, before humanizing\"\n```\n\nNow any change shows up in review.\n\nRewriting 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.\n\nI use [UnAIMyText](https://unaimytext.com/how-unaimytext-works) 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.\n\nPaste the result back over the section in the file.\n\nLine diffs are useless for prose because one edit marks a whole paragraph as changed. Use word-level diffs instead:\n\n```\ngit diff --word-diff=color\n```\n\n`--word-diff` is documented in the [git diff reference](https://git-scm.com/docs/git-diff). It shows insertions and deletions inline, so you can see exactly which words moved.\n\nSome 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.\n\n``` python\n# check_meaning.py\nimport re, sys, difflib\n\nPROTECTED = re.compile(\n    r\"\\b\\d[\\d.,:%]*\\b\"          # numbers, versions, times, percentages\n    r\"|`[^`]+`\"                 # inline code\n    r\"|https?://\\S+\"            # URLs\n    r\"|\\b(must|never|only|always|required|not)\\b\",  # meaning-critical words\n    re.IGNORECASE,\n)\n\ndef tokens(text):\n    return [m.group(0).lower() for m in PROTECTED.finditer(text)]\n\nbefore = open(sys.argv[1], encoding=\"utf-8\").read()\nafter = open(sys.argv[2], encoding=\"utf-8\").read()\n\ndiff = list(difflib.ndiff(tokens(before), tokens(after)))\nchanges = [d for d in diff if d.startswith((\"- \", \"+ \"))]\n\nif changes:\n    print(\"Protected tokens changed:\")\n    for c in changes:\n        print(\"  \", c)\n    sys.exit(1)\nprint(\"No protected tokens changed.\")\n```\n\nRun it against the committed version:\n\n```\ngit show HEAD:release-notes.md > /tmp/before.md\npython check_meaning.py /tmp/before.md release-notes.md\n```\n\n`difflib.ndiff` comes from Python's standard library ([difflib docs](https://docs.python.org/3/library/difflib.html)), so there's nothing to install. A non-zero exit code means you need to look at that section again.\n\nThe script catches the mechanical stuff. For the rest, read the word diff and ask:\n\nRevert those hunks by hand. Keep the rhythm and phrasing improvements.\n\n```\ngit commit -am \"Humanize release notes: rhythm and phrasing only, protected tokens unchanged\"\n```\n\nIf someone questions a sentence later, you have both versions and the reasoning.\n\nThe regex above is a starting point. Adjust it to what carries meaning in your docs:\n\n`--[a-z-]+` and HTTP verbs such as GET, POST and DELETE.\nKeep 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.\n\nFor 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.\n\nHumanizing 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.", "url": "https://wpnews.pro/news/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow", "canonical_source": "https://dev.to/unaimytext_app/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow-2488", "published_at": "2026-10-17 15:26:41+00:00", "updated_at": "2026-10-17 15:34:29.569536+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "natural-language-processing"], "entities": ["UnAIMyText", "git", "Python", "difflib"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow", "markdown": "https://wpnews.pro/news/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow.md", "text": "https://wpnews.pro/news/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow.txt", "jsonld": "https://wpnews.pro/news/how-to-humanize-ai-text-without-losing-the-content-a-diff-based-review-workflow.jsonld"}}