# im-not-ai: a Claude skill that rewrites Korean AI text into human Korean

> im-not-ai targets the tells that show up in Korean text produced by ChatGPT, Claude or Gemini, and rewrites them while holding the original meaning fixed. It installs as a skill into Claude Code, Copilot CLI, Codex CLI or Gemini CLI, and it is only useful if your draft is in Korean.

**epoko77-ai/im-not-ai** — AI가 쓴 한글을 사람 글처럼 윤문하는 Claude 스킬 — Korean AI-text humanizer: detects and rewrites translationese, mechanical parallelism, and 71 other AI tells

- Repository: https://github.com/epoko77-ai/im-not-ai
- Website: https://imnotai.kr
- Stars: 5,791 · Forks: 639
- Language: Python
- License: MIT
- Published: 2026-09-09 · Updated: 2026-09-09 · Language: en
- Canonical page: https://hysenlabs.com/projects/epoko77-ai-im-not-ai

## What im-not-ai actually targets, and who it is not for

The README states the goal plainly: take Korean text written by an AI and restore natural style, rhythm and phrasing without touching the content. That last clause is the whole design constraint. The tool is not a paraphraser and not a detector score chaser. It is a rewrite pass with a fixed taxonomy of what makes Korean read as machine output.

The premise is that Korean AI tells are mostly translationese inherited from English. The README gives four examples: "AI 기술을 통해 효율을 높일 수 있다" becomes "AI로 효율을 높인다"; "이에 있어서 중요한 점은" becomes "여기서 중요한 건"; "~에 의해 생성된" becomes "~가 만든"; and "결론적으로, 이는 시사하는 바가 크다" is deleted outright. Those are not stylistic preferences. They are the residue of English syntax carried into Korean, and generic English humanizers such as QuillBot, Hix or Undetectable AI do not model them.

The audience is narrow on purpose: people who publish Korean and whose first draft came from a model. If you write in English, the taxonomy is irrelevant to you. If you write Korean from scratch, the tool has little to detect in the light path and will often exit early with a message that the text is already fine.

## The 10 x 70 taxonomy and its S1/S2/S3 severity split

The classification scheme is the core asset. Ten top-level categories (A through J) cover translationese, excess English quotation, structural AI patterns, AI idioms, rhythm uniformity, modifier redundancy, hedging, connective overuse, formal nouns and visual decoration. The README counts 70 sub-patterns plus one on hold pending verification.

Category A is the most specific to Korean. Beyond the familiar "~를 통해" and "~에 대해", it names double passives ("~되어진다"), "가지고 있다", an insistence on 그/그녀 (A-16), left-branching relative clauses (A-18) and doubled particles such as "~에서의" and "~에로의" (A-19). Category C includes mechanical 첫째/둘째/셋째 sequencing, bullet and emoji overuse, and a comma after a connective ending (C-11). Category E covers low sentence-length variance, repeated identical endings, and loss of addressee honorific consistency (E-7). Category J flags bold text, scare quotes and dashes.

Severity drives the decision. S1 is decisive: one occurrence is enough to mark the text, so it is always removed. S2 tolerates one or two instances but triggers removal at three or more. S3 only matters when it overlaps another pattern. After rewriting, output is graded A through D, where C means a second pass and D means a human should look at it. That grading is what makes the taxonomy operational rather than descriptive.

## How route_hint decides between one, two and three model calls

The v2.2 architecture is a routing system. A shim, prepare_monolith_input.py, scores the input first and deterministically derives a route_hint of light, standard or heavy. The state of the draft picks the route, and the route picks the call count.

light is a single call: diagnosis and finalize are skipped, one conservative rewrite runs, and if there is almost nothing to fix the tool exits early. standard is two calls: one diagnostic pass, then one targeted rewrite that can handle ten thousand characters without chunking. heavy is three or more calls: diagnose, rewrite (chunked in parallel only when the shim produced two or more chunks), then finalize. If the shim fails, the pipeline degrades gracefully to standard without a score.

A user instruction overrides the route. Asking for "정밀 모드" or passing --strict pins heavy; asking for "가볍게" pins light. The README is explicit that savings come from fewer calls, not from a cheaper model, and that model selection is left to the user. It also reports one measurement: a ten-thousand-character document run as seven chunks cost 610K tokens against 134K for a single call, a 4.5x difference at equal quality, because each chunk reloads the rulebook and diagnosis. Chunking is therefore documented as heavy-only and discouraged below 15,000 characters.

Four agents do the work. humanize-monolith runs on every path and caps itself at three tool calls. humanize-diagnostician runs on standard and heavy and names three to six dominant patterns with taxonomy IDs. humanize-finalizer runs on heavy and checks fifteen meaning-preservation items against the original. A fourth, korean-ai-tell-taxonomist, is a separate command for maintaining the taxonomy itself. The README also notes that five further agents in agents/ are release-time research tools unrelated to rewriting, and that the older strict five-agent pipeline was retired in v2.1.

## Installing im-not-ai and running a first Korean draft through it

The README supports four hosts: Claude Code, GitHub Copilot CLI, OpenAI Codex CLI and Gemini CLI, with a fuller guide in INSTALL.md. The recommended path needs no clone. For Copilot CLI, the marketplace commands are:

```bash
copilot plugin marketplace add epoko77-ai/im-not-ai
copilot plugin install humanize-korean@im-not-ai
copilot plugin list
```

After that, the README says you can phrase a request like "humanize-korean 스킬로 이 글의 AI 티를 없애줘:" or check loading with /skills list. Updates use copilot plugin update humanize-korean@im-not-ai and removal uses copilot plugin uninstall. Note the compatibility remark in the README: on 1.0.79-5 the direct form copilot plugin install epoko77-ai/im-not-ai still works, but the CLI prints a deprecation warning for repository installs, so it is not the recommended path for new setups.

For Claude Code, the marketplace route is two slash commands:

```
/plugin marketplace add epoko77-ai/im-not-ai
/plugin install humanize-korean@im-not-ai
```

In a new session you then invoke /humanize-korean, or just ask in natural language. If you prefer a clone, the script path covers Claude Code and Codex CLI together:

```bash
git clone https://github.com/epoko77-ai/im-not-ai.git
cd im-not-ai
./install.sh
```

The script detects installed claude and codex binaries and creates global symlinks. Flags --claude-only and --codex-only restrict it to one host, uninstall.sh removes it, and update.sh detects a new version, runs git pull and reinstalls, with --check to detect only. Marketplace installs update through /plugin update instead.

One constraint matters before you start. The README says the multi-call paths (standard with two calls, heavy with three or more, including diagnosis and finalize) are Claude Code only. Copilot CLI and Codex CLI get a single-call path. The README also warns that the skill does not auto-load in the Claude.ai web version or in ordinary ChatGPT. To try it without installing, clone the repository and start claude from inside the im-not-ai folder so the project-local skill loads.

## The 30 percent and 50 percent change-rate gates

Over-rewriting is the failure mode this project takes most seriously, and it is the one place where the guardrail is code rather than prompt. verify_change_rate.py runs on every route and returns a decision as an exit code. If the change rate exceeds 30 percent the pipeline warns; above 50 percent it halts. That is a hard stop, not a suggestion to the model.

The four stated rules around it are: meaning is invariant, so facts, claims, numbers, proper nouns and direct quotations are preserved verbatim; edits are surgical and confined to spans that were actually detected; genre is preserved, so a column does not become literature and a report does not become an essay; and over-rewriting is forbidden. The middle rule is the interesting one, because it means the tool deliberately leaves text alone when nothing fires. A draft with no vocabulary tells will not be polished for the sake of polishing.

Two limits follow. First, the meaning-preservation rule itself is enforced by the finalizer agent on the heavy path and by the monolith's self-check elsewhere, not by a deterministic checker, so on light and standard you are trusting a prompt. Second, the change-rate gate measures how much moved, not whether what moved was correct. A rewrite that stays under 30 percent can still alter a nuance, and the README does not document a rollback mechanism for that case. Keep the original file.

## Where im-not-ai is the wrong tool, and what to use instead

The clearest boundary is language. The entire taxonomy is Korean-specific. Category A's double particles and left-branching relatives have no English analogue, and the README's own framing is that English-language humanizers are weak on Korean. That cuts both ways: im-not-ai is weak on English, and running it on an English draft would leave it with almost nothing to detect and a light-path early exit.

The second boundary is host capability. If you work in Copilot CLI or Codex CLI, you get the single-call path only. The diagnostic pass that names three to six dominant patterns, and the finalizer that checks fifteen meaning-preservation items against the original, are Claude Code features. For a heavily degraded draft where you want the diagnosis output as evidence, that difference is the reason to choose the host rather than the tool.

The third boundary is the model itself. The README states outright that model selection is the user's responsibility. im-not-ai does not ship a model, does not train one, and its cost profile is a function of the call count you trigger. If your complaint is that your LLM writes bad Korean, this tool repairs the output; it does not change the generator.

As an alternative, a general-purpose humanizer such as QuillBot or Undetectable AI takes a different approach: it rewrites toward a statistical profile of human text, usually tuned on English, with no published taxonomy of Korean-specific tells and no per-span severity model. The practical difference is that im-not-ai can tell you which pattern it found and at what severity, and it can refuse to touch a span it did not detect. A general humanizer rewrites broadly and gives you no such accounting.

## Licence, maintenance and what an upgrade actually costs

The repository is MIT licensed, which permits commercial use and modification provided the copyright notice and permission notice are retained. That is the licence text's effect, not advice about your situation; if you redistribute a modified taxonomy you should read the LICENSE file rather than this paragraph.

The repository is not archived, and the last push was on 2026-09-06, so it is current as of this writing. Recent releases are v2.3.2 (plugin skill path correction), v2.3.1 (path resolution, runtime boundaries, contract alignment) and v2.3.0 (efficiency plus corpus validation), which suggests a project still correcting its own plumbing rather than one frozen in place. The v2.1 retirement of the old five-agent pipeline is the kind of change that can invalidate a pinned setup.

Upgrade cost depends on how you installed it. Marketplace installs move with /plugin update or copilot plugin update. A clone install uses ./update.sh, which detects a new version, pulls and reinstalls; --check reports without applying. The cheap thing to keep an eye on is the taxonomy file itself, skills/humanize-korean/references/ai-tell-taxonomy.md, because sub-patterns are added and one is currently on hold pending verification. If your workflow depends on a specific pattern ID, a version bump can change what fires. There is no documented migration note for taxonomy changes between v2.3.x releases.

## Conclusion

Adopt it if you publish Korean prose and your drafts come out of an LLM: the taxonomy is the product, and the change-rate gate is the safety net. Do not adopt it for English writing or for text you are not allowed to send to a model at all. Before trusting it, run one real draft through the light path and read the final.md diff yourself, because the meaning-preservation rule is enforced by a prompt, not by code.

## FAQ

### Does im-not-ai work outside Claude Code?

Yes, but with fewer paths. The README lists GitHub Copilot CLI, OpenAI Codex CLI and Gemini CLI as supported hosts, and states that Copilot and Codex provide a single-call path only. The multi-call standard and heavy routes, including diagnosis and finalize, are Claude Code only.

### How much does im-not-ai change my text?

It is bounded by a change-rate gate. verify_change_rate.py runs on every route and warns above 30 percent change; above 50 percent it halts. The README also states that edits are confined to spans that were actually detected, so untouched passages stay untouched.

### Can im-not-ai be used on English text?

It is built for Korean. The README states that Korean AI tells mostly come from English translationese and that English-language humanizers are weak on Korean, so the taxonomy covers Korean-specific patterns such as double particles and left-branching relative clauses. Nothing in the README describes English output.

## Sources

- [epoko77-ai/im-not-ai on GitHub](https://github.com/epoko77-ai/im-not-ai)
- [License: MIT](https://github.com/epoko77-ai/im-not-ai/blob/main/LICENSE)
- [Project website](https://imnotai.kr)
- [README](https://github.com/epoko77-ai/im-not-ai/blob/main/README.md)
- [Releases](https://github.com/epoko77-ai/im-not-ai/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/epoko77-ai-im-not-ai
