Local AI-text humanizer powered by Ollama. Rewrites AI-generated text so it reads naturally, entirely on your own machine.
Project description
mihuman is a small, dependency-light Python library that rewrites AI-generated text so it reads like a human wrote it. Everything runs against a local Ollama server — no external API calls, no data leaves your box.
The library ships two things:
- A
humanize()function that streams a rewrite from Ollama and runs a deterministic post-processing pipeline over the output (em-dash stripping, AI-lexicon substitution, burstiness enforcement, optional error injection). - A
Configdataclass andload_config()helper so you can drive the whole thing from a TOML file instead of threading a dozen keyword arguments through your code.
Install
pip install mihuman
You also need Ollama running locally with at least one model pulled:
ollama pull mistral-nemo:12b # or llama3.1:8b, gemma2:9b, whatever you like
Quick start
from mihuman import humanize
result = humanize(
text="The utilization of innovative paradigms facilitates a robust framework...",
model="llama3.1:8b",
style="stealth",
intensity="aggressive",
)
print(result.text)
Driving it from a config file
Drop a mihuman.toml in your project (or at ~/.config/mihuman/config.toml):
model = "llama3.1:8b"
base_url = "http://localhost:11434"
style = "stealth"
intensity = "aggressive"
burstiness = true
error_level = 0
temperature = 0.85
top_p = 0.97
timeout = 300
# seed = 42
Then load it:
from mihuman import humanize, load_config
cfg = load_config() # auto-discovers
# cfg = load_config("path/to/mihuman.toml") # or pass an explicit path
result = humanize(text=my_text, **cfg.to_kwargs())
print(result.text)
Config search order (first match wins):
- Explicit path passed to
load_config(path=...) $MIHUMAN_CONFIGenv var./mihuman.toml(current working directory)$XDG_CONFIG_HOME/mihuman/config.toml(fallback:~/.config/mihuman/config.toml)
Unknown keys raise ConfigError so typos surface at load time, not months later.
An annotated starter config lives at examples/mihuman.toml.
Options
Styles
| Style | Notes |
|---|---|
stealth |
Anti-detection mode. Prioritizes perplexity and burstiness. |
humanize |
General natural writing. Clear, simple. |
casual |
Friendly, conversational. |
professional |
Executive-level direct prose. |
academic |
Q1-journal register. AWL vocabulary. |
creative |
Sensory, fresh comparisons. |
technical |
Precise but approachable; step-by-step. |
Intensity
| Level | Post-processing passes |
|---|---|
light |
preamble strip → em-dash removal → whitespace cleanup |
medium |
+ AI lexicon substitution → burstiness (optional) |
aggressive |
+ contraction forcing → sentence capitalization → burstiness |
Error injection
| Level | Effect |
|---|---|
0 (off) |
none |
1 (subtle) |
~35% chance to drop Oxford commas |
2 (natural) |
+ missed apostrophes (~1 per 180 words) |
3 (casual) |
+ light typos like "teh", "adn" (~1 per 500 words) |
Pipeline
Input text
│
▼
Smart chunking ~800-word, paragraph-aware chunks
│
▼
Ollama /api/chat streamed rewrite per chunk (system prompt = style overlay)
│
▼
Post-processing preamble strip → em-dash strip → AI-lexicon sub
→ contractions → capitalize → burstiness → whitespace
→ optional human-error injection
│
▼
Output
The LLM does the heavy rewriting; the post-processor cleans up AI-specific tells the model tends to leave behind.
Public API
from mihuman import (
humanize, HumanizeResult, OllamaError, list_models,
Config, load_config, ConfigError,
STYLES, DEFAULT_MODEL, DEFAULT_OLLAMA_URL,
postprocess, make_rng, build_system_prompt,
__version__,
)
humanize(text, *, style, model, intensity, base_url, temperature, top_p, timeout, burstiness, error_level, seed, writing_sample, on_progress, on_token, on_chunk_done) -> HumanizeResultlist_models(base_url=...) -> list[str]— enumerate installed Ollama modelspostprocess(text, intensity, rng, burstiness, error_level) -> str— run just the post-processor on already-rewritten text
Pass callbacks (on_token, on_chunk_done, on_progress) if you want to stream output into a UI.
Requirements
- Python 3.10+
- Ollama running locally (or somewhere reachable)
Runtime deps: none on Python 3.11+; tomli on 3.10 only.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mihuman-0.1.0.tar.gz.
File metadata
- Download URL: mihuman-0.1.0.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d65d6eb986fb21685231802f7b8539afd4caf1c99743bed18fb722f05e6c2c0e
|
|
| MD5 |
c1a94ab4ce7c59dc1d49cc5c4224aff4
|
|
| BLAKE2b-256 |
de6c13c8f566183ead3f9b151ba177738f945da2db0a4ec65bec9fef96b6f92c
|
File details
Details for the file mihuman-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mihuman-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e30c88b24b0d154e60926d30536f77ac4fc3e3c2268bc8a98b059a5837a33030
|
|
| MD5 |
eeb8806da8e384d652d55c1f2202f11f
|
|
| BLAKE2b-256 |
79521dce0a929d2ccf1a44c40a151aac55dca82f8b20cd263ef2fbe8316deadd
|