ervin-mo/humanizar-es

Local AI text humanizer for Spanish & English, built on controlled experiments: a base model without chat training rewrites, a fidelity guard keeps every concept and quote, the rhythm is rebuilt, and flagged paragraphs are re-sampled and selected. 0% in Grammarly, ZeroGPT and GPTZero. No API · Humanizador IA local.

Python

4

18 commits

updated Oct 8, 2026

See the code

See what people are saying

SourceMessageScoreDate

humanizar-es: a local base model (Qwen3-4B + HIP LoRA, CPU) that takes AI text from 45% to 0% in Grammarly, GPTZero and ZeroGPT, with every measurement in the repo (r/coolgithubprojects)

Detectors mostly catch chat training, not "AI": a base model paraphrasing reads human. Then each detector wants something different (Grammarly reads rhythm, ZeroGPT scores sentence by sentence), so the pipeline rebuilds rhythm and samples candidates until all three pass. CPU only, no API, MIT.…

1

Oct 8, 2026

I spent a week taking apart AI detectors with controlled experiments, then open-sourced the tool: a local model that takes text from 45% to 0% in Grammarly, GPTZero and ZeroGPT (r/SideProject)

**TL;DR:** detectors mostly catch *chat training*, not "AI". A base model paraphrasing reads human. Then each detector wants something different, and the fix for one breaks another. Open source pipeline + every measurement in the repo. **Setup:** one 1,990-word AI essay (Spanish), one change at a…

5

Oct 8, 2026

I built a Claude Code skill that takes AI text from 45% to 0% in Grammarly, GPTZero and ZeroGPT, with a local base model. Here's what controlled experiments taught me about detectors (r/ClaudeAI)

**TL;DR:** detectors mostly catch *chat training*, not "AI". A base model paraphrasing reads human. Then each detector wants something different, and the fix for one breaks another. Open source pipeline + every measurement in the repo. **Setup:** one 1,990-word AI essay (Spanish), one change at a…

0

Oct 8, 2026

README

humanizar-es · Local AI text humanizer for Spanish and English

tests license: MIT macOS · Linux · Windows Español · English

English · Español

humanizar-es: make AI text read as human, on your own computer, for free

humanizar-es takes a text written with ChatGPT, Claude, Gemini or DeepSeek and gives it back saying the same thing, in prose that the three detectors we measured read as human: 0% in Grammarly, 0% in ZeroGPT and 0% AI / 98% human in GPTZero, on the same 1,990-word essay that started at 45%. It runs on your own computer with an open model: no API, no keys, no per-word fees, and your text never leaves your machine. Use it by hand or as a skill for your coding agent (Claude Code, Codex, OpenCode, Antigravity).

It is not a synonym spinner, a "rewrite it in a human tone" prompt, or a typo generator. It is a four-stage pipeline, and every stage exists because a controlled experiment showed what a detector actually measures: one variable at a time, the same text in every condition, and a human-written control and the AI original in every session.


Results

AI-generated essayGrammarlyZeroGPTGPTZero
Aristotle: act and potency · 1,990 words · before45%45.3%37% AI
Aristotle: act and potency · after0% and 0%0%0% AI · 98% human
Tourism and AI in Chiapas · 1,150 words77% → 0%——
An AI classification model · 690 words→ 0%——
Dragon Ball and its generation · 910 words84% → 10%——
🇬🇧 Remote work (English) · 601 words—100% → 0%—
🇬🇧 Electric vehicles (English) · 673 words—100% → 0%—

October 2026. The first essay keeps 24 of 24 key names, terms and figures, and its two quotations of Aristotle word for word. Grammarly reads ~1,400 words, so it was measured in halves. The Dragon Ball essay ran on an earlier version of the pipeline.


The method

 original ─► 1. rewrite ──► 2. fidelity ──► 3. rhythm ──► 4. selection ──► final
             base model     concepts,       blocks of      candidates,
             without chat   quotes, copy,   uneven         measured in the
             training       ≤3-word fixes   length         whole document

What the detectors measure

Three detectors, three different signals. The pipeline exists because each one was taken apart with experiments:

DetectorWhat it reacts toWhat does not move it
GPTZerothe fingerprint of chat training; its newer English model (4.1o) also reads base-model text, our next milestone—
Grammarlyrhythm: sentences of even length, each closed by its own perioddouble spaces (typos do move it, but leave visible errors)
ZeroGPTindividual sentences that read like a textbook; it scores sentence by sentence and weighs by wordsjoining sentences of a human text (Unamuno joined: 0%)

1. Remove the chat-training fingerprint

Xu et al. (2026), Base Models Look Human To AI Detectors, showed that text from a base model scores 97–99% human on GPTZero and Pangram, and the same model after chat training 17–30%. Our tests agree: every rewrite we tried with a chat model stayed between 64% and 100% in Grammarly. rewrite.py paraphrases with Qwen3-4B-Base plus the paper's HIP adapter, through llama.cpp, on your CPU.

2. Keep it faithful, without putting the fingerprint back

Each paragraph gets one pass, and a try is rejected and retried when it:

  • loses a concept you listed (names, terms, figures, key negations);
  • changes a quotation of the original or adds a reference the original never had (on a test essay the model wrote «(De Anima, libro i, cap. vi)», which does not exist);
  • copies the original: more than 60% of its words in runs of 8+ identical words;
  • comes out truncated or runs away.

check.py then compares concepts and negations, and a person fixes one to three words at most. Anything bigger is regenerated by the model (--only), never written by hand and never pasted back from the original: hand fixes of four or more words kept half an essay at 3% in Grammarly; regenerating those paragraphs brought it to 0%.

3. Rebuild the rhythm

People write in bursts, some sentences long, some short. join.py --pauses 2 leaves two or three periods per paragraph, in blocks of uneven length of at least two sentences, cutting first where a sentence already opens with a discourse marker («Sin embargo», "For example", «Segundo»). Inside a block it links with "and" or ";". No content word is touched.

4. Select by measurement

The base model is a sampler: the same paragraph comes out differently every time, and a detector can score two samples 0% and 100%. So the paragraphs a detector still flags are regenerated several times (--candidates), each candidate is joined and measured inside the whole document (context changes the score), and the one that passes is adopted (--take). All candidates come from the same base model, so selection adds no chat fingerprint. Two findings made this work:

  • The opening words matter. To keep writing in Spanish, the model starts each paragraph with the original's first two words. When those are a stock opening («Uno de los problemas más importantes…», «Aristóteles distingue…»), the model rebuilds the stock sentence and ZeroGPT flags it. Starting with other words (--lead "Desde la") fixed it: 22 candidates of one paragraph with the original opening scored 100%; with another opening, 0%.
  • Every edit is measured again. ZeroGPT is deterministic but brittle: a one-word fix took a paragraph from 0% to 62%.

The experiments behind each stage

Same essay, one change at a time.

Grammarly
Rewritten by the base model only84%
… plus random double spaces84%
… removing ~35% of the commas60%
… joining ~60% of the sentences40%
… joining every sentence of each paragraph8%
The original, without the base model, joining every sentence57%
Rewriting with a chat model (four different recipes)64–100%
Pauses, with a sentence left alone between two periods6%
Pauses, blocks of two or more sentences0% and 0%
ZeroGPT (deterministic: the same text always gives the same score)
The AI original34.3%
Rewritten by the base model, sentences unjoined33.9%
… all sentences joined44.0%
… with pauses52.4%
A human text (Unamuno, 1914), joined the same way0%
After selection: candidates measured in the whole document0%

The tension is real: Grammarly wants long sentences, ZeroGPT punishes a long sentence that contains one textbook clause. Rhythm alone cannot satisfy both; rhythm plus selection does. Every measurement: references/evidence.md.

How we measure

  • Two controls in every session: a human text must come out human, and the AI original must come out as AI. A detector that fails either one does not count: QuillBot scored the AI original 100% human, and GPTZero, after many scans from one browser, scored a 1914 text 100% AI.
  • The reference is re-measured in the same session, never compared with a number from hours before.
  • The final format is the one measured: with headings and bibliography, ZeroGPT can give a different score than for the bare text.

Install

With your agent (easiest)

git clone https://github.com/ervin-mo/humanizar-es.git
cd humanizar-es
python3 install.py          # on Windows: python install.py

Open a new session and ask: "humanize this text" (or «humaniza este texto»). The skill walks the agent through every stage: install what's missing (it asks before downloading the model), list with you what must not be lost, rewrite, show you every change, rebuild the rhythm, and select candidates for whatever your detector still flags.

AgentSkills folderCovered by install.py?
Claude Code~/.claude/skillsyes
Codex~/.agents/skillsyes
OpenCode~/.agents/skills, ~/.claude/skillsyes
Antigravity (agy)~/.agents/skillsyes
DeepSeek Harness (dsh)~/.agents/skillsyes
Gemini CLI~/.gemini/skillswith --agent gemini

The model (once, ~4.6 GB)

You need Python 3.9+ (no extra packages) and llama.cpp:

macOS and LinuxWindows
llama.cppbrew install llama.cppwinget install llama.cpp
The modelpython3 scripts/install_model.pypython scripts\install_model.py

The installer checks every file against its sha256 and resumes if the download is cut. It runs on CPU: 8 GB of free RAM is enough, no GPU. On an M4 Mac it takes about 30–60 seconds per paragraph; on a few-years-old PC, 1 to 3 minutes.


Use it by hand

On Windows, type python where it says python3.

1. List what must not be lost in concepts.txt: full proper names, figures, terms. One per line, variants with |, * for prefixes.

Aristotle
act and potency | act and potentiality
self-regulat*

2. Rewrite with the base model:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt

3. Check, and fix one to three words at most. For anything bigger, regenerate that paragraph:

python3 scripts/check.py my-text.txt rewritten.txt --concepts concepts.txt
python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt --only 6,11

Don't ask ChatGPT to fix it: it puts back the fingerprint the base model removed.

4. Rebuild the rhythm (the language is detected automatically):

python3 scripts/join.py rewritten.txt -o final.txt --concepts concepts.txt --pauses 2

5. Measure the final text in your detector, in the format you will hand in, with a human text as control (references/detectors.md).

6. Select, for what is still flagged. Generate candidates of those paragraphs, with other opening words if the paragraph starts with a stock phrase:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt \
        --only 4 --candidates 6 --lead "Desde la" --temperature 1.1

Join each candidate into the full text, measure, adopt the one that passes, and join again:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --take 4=rewritten.txt.candidates/p04-3.txt
python3 scripts/join.py rewritten.txt -o final.txt --concepts concepts.txt --pauses 2

Reread the adopted paragraph against the original: passing a detector is worth nothing if it dropped an idea.

Worked examples, with every hand fix listed, are in examples/.


Languages

RewriteRhythmCheckMeasured
Español✅✅ «y», «;», «pero»…✅✅ four essays, three detectors
English✅ (the HIP adapter was trained in English)✅ "and", ";", "but"…✅✅ ZeroGPT, two essays · GPTZero: next milestone

Other languages: the rewrite may work (the base model is multilingual), but join.py only knows Spanish and English connectors. Adding one is a small dictionary in scripts/join.py; pull requests welcome.

Detectors

DetectorStatus
Grammarly✅ 0% on three of four essays (10% on one run with an older version)
GPTZero✅ 0% AI · 98% human (Spanish) · English: next milestone (what we tried)
ZeroGPT✅ 0% in Spanish and English, with stage 4 (selection) where needed
QuillBotnot usable in Spanish: it scored the AI original 100% human

Each detector runs its own model, so a version that passes one may not pass another; the first essay passes all three at once. Measurements on more detectors and more kinds of text are the contribution we need most.


FAQ

Is it free? Do I need an OpenAI key or any account? Free and keyless. The model downloads once and runs on your computer.

Does it change what my text says? It is built not to: tries that lose a concept, change a quote or invent a reference are rejected, check.py compares concepts and negations, and you reread every paragraph.

Does it add typos on purpose, like other "humanizers"? No. It changes who wrote the sentences and their rhythm, not the spelling.

Are the results consistent? Three of four essays reached 0% in Grammarly, and the latest one passes Grammarly, GPTZero and ZeroGPT at once. The pieces that can be deterministic are (the joining is seeded; ZeroGPT gives the same score for the same text), output that copies the original is refused, and 48 tests run on every change on Ubuntu, macOS and Windows. Detectors drift over time, which is why every session carries controls.

Does the selection step send my text anywhere? The tool never does. Measuring is your step, in your detector, as with any text you check.

Do I need a GPU? No. It runs on CPU, at low priority, so your computer stays usable.


Limits

  1. GPTZero in English is the next milestone. Its newer English model (4.1o) reads base-model text from ~250 words on; three model families were tested (evidence). Emails, marketing and technical writing are not measured yet.
  2. Rereading is not optional. The base model sometimes changes a detail or flips an idea. The pipeline catches lost concepts, changed quotes and invented references; a person catches the rest.
  3. Selection costs time. Each candidate is a model run (30–60 s per paragraph on an M4).
  4. Detectors change. This is a snapshot of October 2026.

Responsible use

Made for text you sign and answer for: brand content, outreach, documentation, emails, drafts written with AI help. Don't use it to hand in graded work as your own where AI is banned or must be disclosed. That problem isn't technical; it's academic honesty.


Project layout

humanizar-es/
├── SKILL.md                 the skill for agents
├── install.py               installs the skill (install.sh: shortcut for macOS/Linux)
├── scripts/
│   ├── install_model.py     downloads the model (once)
│   ├── rewrite.py           stages 1, 2 and 4: rewrite, guard fidelity, candidates
│   ├── check.py             stage 2: concepts and negations, original vs rewrite
│   └── join.py              stage 3: rebuild the rhythm of each paragraph
├── examples/                worked examples in Spanish and English
├── references/              every measurement, and how to measure
└── tests/                   48 tests on Ubuntu, macOS and Windows (no network, no model)

The old script names (hip.py, unir.py, verificar_fidelidad.py, instalar_hip.py) still work.

Contributing

What's missing most is evidence: the pipeline measured on more texts, more languages and more detectors, always with a human control and the AI original. Open an issue or a PR with the numbers in references/evidence.md.

python3 -m unittest discover -s tests -v

Credits and license

Code and docs: MIT, © ervin-mo. The HIP method and adapter are by Xu et al. (2026); the base model is Alibaba's Qwen3-4B-Base. Both are Apache-2.0 and downloaded separately: see THIRD_PARTY.md. If you use this in your work, cite the repo (CITATION.cff) and the HIP paper.

agent-skills
ai-detection
ai-humanizer
ai-text-humanizer
base-models
burstiness
chatgpt
claude-code
codex
espanol
gptzero
grammarly
humanizer
llama-cpp
local-llm
nlp
opencode
qwen3
spanish
zerogpt

ervin-mo/humanizar-es

Local AI text humanizer for Spanish & English, built on controlled experiments: a base model without chat training rewrites, a fidelity guard keeps every concept and quote, the rhythm is rebuilt, and flagged paragraphs are re-sampled and selected. 0% in Grammarly, ZeroGPT and GPTZero. No API · Humanizador IA local.

Python

4

18 commits

updated Oct 8, 2026

See the code

See what people are saying

SourceMessageScoreDate

humanizar-es: a local base model (Qwen3-4B + HIP LoRA, CPU) that takes AI text from 45% to 0% in Grammarly, GPTZero and ZeroGPT, with every measurement in the repo (r/coolgithubprojects)

Detectors mostly catch chat training, not "AI": a base model paraphrasing reads human. Then each detector wants something different (Grammarly reads rhythm, ZeroGPT scores sentence by sentence), so the pipeline rebuilds rhythm and samples candidates until all three pass. CPU only, no API, MIT.…

1

Oct 8, 2026

I spent a week taking apart AI detectors with controlled experiments, then open-sourced the tool: a local model that takes text from 45% to 0% in Grammarly, GPTZero and ZeroGPT (r/SideProject)

**TL;DR:** detectors mostly catch *chat training*, not "AI". A base model paraphrasing reads human. Then each detector wants something different, and the fix for one breaks another. Open source pipeline + every measurement in the repo. **Setup:** one 1,990-word AI essay (Spanish), one change at a…

5

Oct 8, 2026

I built a Claude Code skill that takes AI text from 45% to 0% in Grammarly, GPTZero and ZeroGPT, with a local base model. Here's what controlled experiments taught me about detectors (r/ClaudeAI)

**TL;DR:** detectors mostly catch *chat training*, not "AI". A base model paraphrasing reads human. Then each detector wants something different, and the fix for one breaks another. Open source pipeline + every measurement in the repo. **Setup:** one 1,990-word AI essay (Spanish), one change at a…

0

Oct 8, 2026

README

humanizar-es · Local AI text humanizer for Spanish and English

tests license: MIT macOS · Linux · Windows Español · English

English · Español

humanizar-es: make AI text read as human, on your own computer, for free

humanizar-es takes a text written with ChatGPT, Claude, Gemini or DeepSeek and gives it back saying the same thing, in prose that the three detectors we measured read as human: 0% in Grammarly, 0% in ZeroGPT and 0% AI / 98% human in GPTZero, on the same 1,990-word essay that started at 45%. It runs on your own computer with an open model: no API, no keys, no per-word fees, and your text never leaves your machine. Use it by hand or as a skill for your coding agent (Claude Code, Codex, OpenCode, Antigravity).

It is not a synonym spinner, a "rewrite it in a human tone" prompt, or a typo generator. It is a four-stage pipeline, and every stage exists because a controlled experiment showed what a detector actually measures: one variable at a time, the same text in every condition, and a human-written control and the AI original in every session.


Results

AI-generated essayGrammarlyZeroGPTGPTZero
Aristotle: act and potency · 1,990 words · before45%45.3%37% AI
Aristotle: act and potency · after0% and 0%0%0% AI · 98% human
Tourism and AI in Chiapas · 1,150 words77% → 0%——
An AI classification model · 690 words→ 0%——
Dragon Ball and its generation · 910 words84% → 10%——
🇬🇧 Remote work (English) · 601 words—100% → 0%—
🇬🇧 Electric vehicles (English) · 673 words—100% → 0%—

October 2026. The first essay keeps 24 of 24 key names, terms and figures, and its two quotations of Aristotle word for word. Grammarly reads ~1,400 words, so it was measured in halves. The Dragon Ball essay ran on an earlier version of the pipeline.


The method

 original ─► 1. rewrite ──► 2. fidelity ──► 3. rhythm ──► 4. selection ──► final
             base model     concepts,       blocks of      candidates,
             without chat   quotes, copy,   uneven         measured in the
             training       ≤3-word fixes   length         whole document

What the detectors measure

Three detectors, three different signals. The pipeline exists because each one was taken apart with experiments:

DetectorWhat it reacts toWhat does not move it
GPTZerothe fingerprint of chat training; its newer English model (4.1o) also reads base-model text, our next milestone—
Grammarlyrhythm: sentences of even length, each closed by its own perioddouble spaces (typos do move it, but leave visible errors)
ZeroGPTindividual sentences that read like a textbook; it scores sentence by sentence and weighs by wordsjoining sentences of a human text (Unamuno joined: 0%)

1. Remove the chat-training fingerprint

Xu et al. (2026), Base Models Look Human To AI Detectors, showed that text from a base model scores 97–99% human on GPTZero and Pangram, and the same model after chat training 17–30%. Our tests agree: every rewrite we tried with a chat model stayed between 64% and 100% in Grammarly. rewrite.py paraphrases with Qwen3-4B-Base plus the paper's HIP adapter, through llama.cpp, on your CPU.

2. Keep it faithful, without putting the fingerprint back

Each paragraph gets one pass, and a try is rejected and retried when it:

  • loses a concept you listed (names, terms, figures, key negations);
  • changes a quotation of the original or adds a reference the original never had (on a test essay the model wrote «(De Anima, libro i, cap. vi)», which does not exist);
  • copies the original: more than 60% of its words in runs of 8+ identical words;
  • comes out truncated or runs away.

check.py then compares concepts and negations, and a person fixes one to three words at most. Anything bigger is regenerated by the model (--only), never written by hand and never pasted back from the original: hand fixes of four or more words kept half an essay at 3% in Grammarly; regenerating those paragraphs brought it to 0%.

3. Rebuild the rhythm

People write in bursts, some sentences long, some short. join.py --pauses 2 leaves two or three periods per paragraph, in blocks of uneven length of at least two sentences, cutting first where a sentence already opens with a discourse marker («Sin embargo», "For example", «Segundo»). Inside a block it links with "and" or ";". No content word is touched.

4. Select by measurement

The base model is a sampler: the same paragraph comes out differently every time, and a detector can score two samples 0% and 100%. So the paragraphs a detector still flags are regenerated several times (--candidates), each candidate is joined and measured inside the whole document (context changes the score), and the one that passes is adopted (--take). All candidates come from the same base model, so selection adds no chat fingerprint. Two findings made this work:

  • The opening words matter. To keep writing in Spanish, the model starts each paragraph with the original's first two words. When those are a stock opening («Uno de los problemas más importantes…», «Aristóteles distingue…»), the model rebuilds the stock sentence and ZeroGPT flags it. Starting with other words (--lead "Desde la") fixed it: 22 candidates of one paragraph with the original opening scored 100%; with another opening, 0%.
  • Every edit is measured again. ZeroGPT is deterministic but brittle: a one-word fix took a paragraph from 0% to 62%.

The experiments behind each stage

Same essay, one change at a time.

Grammarly
Rewritten by the base model only84%
… plus random double spaces84%
… removing ~35% of the commas60%
… joining ~60% of the sentences40%
… joining every sentence of each paragraph8%
The original, without the base model, joining every sentence57%
Rewriting with a chat model (four different recipes)64–100%
Pauses, with a sentence left alone between two periods6%
Pauses, blocks of two or more sentences0% and 0%
ZeroGPT (deterministic: the same text always gives the same score)
The AI original34.3%
Rewritten by the base model, sentences unjoined33.9%
… all sentences joined44.0%
… with pauses52.4%
A human text (Unamuno, 1914), joined the same way0%
After selection: candidates measured in the whole document0%

The tension is real: Grammarly wants long sentences, ZeroGPT punishes a long sentence that contains one textbook clause. Rhythm alone cannot satisfy both; rhythm plus selection does. Every measurement: references/evidence.md.

How we measure

  • Two controls in every session: a human text must come out human, and the AI original must come out as AI. A detector that fails either one does not count: QuillBot scored the AI original 100% human, and GPTZero, after many scans from one browser, scored a 1914 text 100% AI.
  • The reference is re-measured in the same session, never compared with a number from hours before.
  • The final format is the one measured: with headings and bibliography, ZeroGPT can give a different score than for the bare text.

Install

With your agent (easiest)

git clone https://github.com/ervin-mo/humanizar-es.git
cd humanizar-es
python3 install.py          # on Windows: python install.py

Open a new session and ask: "humanize this text" (or «humaniza este texto»). The skill walks the agent through every stage: install what's missing (it asks before downloading the model), list with you what must not be lost, rewrite, show you every change, rebuild the rhythm, and select candidates for whatever your detector still flags.

AgentSkills folderCovered by install.py?
Claude Code~/.claude/skillsyes
Codex~/.agents/skillsyes
OpenCode~/.agents/skills, ~/.claude/skillsyes
Antigravity (agy)~/.agents/skillsyes
DeepSeek Harness (dsh)~/.agents/skillsyes
Gemini CLI~/.gemini/skillswith --agent gemini

The model (once, ~4.6 GB)

You need Python 3.9+ (no extra packages) and llama.cpp:

macOS and LinuxWindows
llama.cppbrew install llama.cppwinget install llama.cpp
The modelpython3 scripts/install_model.pypython scripts\install_model.py

The installer checks every file against its sha256 and resumes if the download is cut. It runs on CPU: 8 GB of free RAM is enough, no GPU. On an M4 Mac it takes about 30–60 seconds per paragraph; on a few-years-old PC, 1 to 3 minutes.


Use it by hand

On Windows, type python where it says python3.

1. List what must not be lost in concepts.txt: full proper names, figures, terms. One per line, variants with |, * for prefixes.

Aristotle
act and potency | act and potentiality
self-regulat*

2. Rewrite with the base model:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt

3. Check, and fix one to three words at most. For anything bigger, regenerate that paragraph:

python3 scripts/check.py my-text.txt rewritten.txt --concepts concepts.txt
python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt --only 6,11

Don't ask ChatGPT to fix it: it puts back the fingerprint the base model removed.

4. Rebuild the rhythm (the language is detected automatically):

python3 scripts/join.py rewritten.txt -o final.txt --concepts concepts.txt --pauses 2

5. Measure the final text in your detector, in the format you will hand in, with a human text as control (references/detectors.md).

6. Select, for what is still flagged. Generate candidates of those paragraphs, with other opening words if the paragraph starts with a stock phrase:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --concepts concepts.txt \
        --only 4 --candidates 6 --lead "Desde la" --temperature 1.1

Join each candidate into the full text, measure, adopt the one that passes, and join again:

python3 scripts/rewrite.py my-text.txt -o rewritten.txt --take 4=rewritten.txt.candidates/p04-3.txt
python3 scripts/join.py rewritten.txt -o final.txt --concepts concepts.txt --pauses 2

Reread the adopted paragraph against the original: passing a detector is worth nothing if it dropped an idea.

Worked examples, with every hand fix listed, are in examples/.


Languages

RewriteRhythmCheckMeasured
Español✅✅ «y», «;», «pero»…✅✅ four essays, three detectors
English✅ (the HIP adapter was trained in English)✅ "and", ";", "but"…✅✅ ZeroGPT, two essays · GPTZero: next milestone

Other languages: the rewrite may work (the base model is multilingual), but join.py only knows Spanish and English connectors. Adding one is a small dictionary in scripts/join.py; pull requests welcome.

Detectors

DetectorStatus
Grammarly✅ 0% on three of four essays (10% on one run with an older version)
GPTZero✅ 0% AI · 98% human (Spanish) · English: next milestone (what we tried)
ZeroGPT✅ 0% in Spanish and English, with stage 4 (selection) where needed
QuillBotnot usable in Spanish: it scored the AI original 100% human

Each detector runs its own model, so a version that passes one may not pass another; the first essay passes all three at once. Measurements on more detectors and more kinds of text are the contribution we need most.


FAQ

Is it free? Do I need an OpenAI key or any account? Free and keyless. The model downloads once and runs on your computer.

Does it change what my text says? It is built not to: tries that lose a concept, change a quote or invent a reference are rejected, check.py compares concepts and negations, and you reread every paragraph.

Does it add typos on purpose, like other "humanizers"? No. It changes who wrote the sentences and their rhythm, not the spelling.

Are the results consistent? Three of four essays reached 0% in Grammarly, and the latest one passes Grammarly, GPTZero and ZeroGPT at once. The pieces that can be deterministic are (the joining is seeded; ZeroGPT gives the same score for the same text), output that copies the original is refused, and 48 tests run on every change on Ubuntu, macOS and Windows. Detectors drift over time, which is why every session carries controls.

Does the selection step send my text anywhere? The tool never does. Measuring is your step, in your detector, as with any text you check.

Do I need a GPU? No. It runs on CPU, at low priority, so your computer stays usable.


Limits

  1. GPTZero in English is the next milestone. Its newer English model (4.1o) reads base-model text from ~250 words on; three model families were tested (evidence). Emails, marketing and technical writing are not measured yet.
  2. Rereading is not optional. The base model sometimes changes a detail or flips an idea. The pipeline catches lost concepts, changed quotes and invented references; a person catches the rest.
  3. Selection costs time. Each candidate is a model run (30–60 s per paragraph on an M4).
  4. Detectors change. This is a snapshot of October 2026.

Responsible use

Made for text you sign and answer for: brand content, outreach, documentation, emails, drafts written with AI help. Don't use it to hand in graded work as your own where AI is banned or must be disclosed. That problem isn't technical; it's academic honesty.


Project layout

humanizar-es/
├── SKILL.md                 the skill for agents
├── install.py               installs the skill (install.sh: shortcut for macOS/Linux)
├── scripts/
│   ├── install_model.py     downloads the model (once)
│   ├── rewrite.py           stages 1, 2 and 4: rewrite, guard fidelity, candidates
│   ├── check.py             stage 2: concepts and negations, original vs rewrite
│   └── join.py              stage 3: rebuild the rhythm of each paragraph
├── examples/                worked examples in Spanish and English
├── references/              every measurement, and how to measure
└── tests/                   48 tests on Ubuntu, macOS and Windows (no network, no model)

The old script names (hip.py, unir.py, verificar_fidelidad.py, instalar_hip.py) still work.

Contributing

What's missing most is evidence: the pipeline measured on more texts, more languages and more detectors, always with a human control and the AI original. Open an issue or a PR with the numbers in references/evidence.md.

python3 -m unittest discover -s tests -v

Credits and license

Code and docs: MIT, © ervin-mo. The HIP method and adapter are by Xu et al. (2026); the base model is Alibaba's Qwen3-4B-Base. Both are Apache-2.0 and downloaded separately: see THIRD_PARTY.md. If you use this in your work, cite the repo (CITATION.cff) and the HIP paper.

agent-skills
ai-detection
ai-humanizer
ai-text-humanizer
base-models
burstiness
chatgpt
claude-code
codex
espanol
gptzero
grammarly
humanizer
llama-cpp
local-llm
nlp
opencode
qwen3
spanish
zerogpt