Skip to main content
ClaudeWave
Skill5.2k repo starsupdated 7d ago

humanize-korean

AI(ChatGPT·Claude·Gemini 등)가 쓴 한글 텍스트를 "사람이 쓴 글처럼" 윤문해주는 오케스트레이터 스킬. 번역투·영어 인용 과다·기계적 병렬·관용구·피동태 남용·접속사 남발·리듬 균일성·이모지/불릿 과다 등 10대 카테고리 70개 AI 티 패턴을 탐지·분류해 내용은 한 글자도 건드리지 않고 문체·리듬·표현만 자연스러운 한국어로 재작성한다. shim의 route_hint(light|standard|heavy)로 경로를 정해 잘 쓴 글은 1콜, 표준은 2콜, 중증·장문만 3+콜(진단→겨냥 윤문→finalize)로 처리한다. 트리거 — "AI 티 없애줘", "AI 같은 글 자연스럽게", "GPT/ChatGPT 문체", "AI 번역투 고쳐", "사람이 쓴 것처럼 윤문", "AI 윤문", "ChatGPT 티 제거", "한글 AI 탐지·윤문", "AI 글 사람처럼", "번역투 제거", "영어 인용 많은 글 윤문", "AI 글 티 안 나게", "휴머나이저", "humanize Korean", "AI detector bypass 한글". 후속 작업 — "특정 카테고리만 다시", "윤문 강도 조정", "장르 바꿔서", "이 문단만", "2차 윤문" 도 모두 이 스킬. 단순 맞춤법·오탈자 교정은 직접 처리, 번역은 번역 스킬, 내용 추가·삭제를 동반한 재작성은 별도 집필 스킬.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/epoko77-ai/im-not-ai /tmp/humanize-korean && cp -r /tmp/humanize-korean/skills/humanize-korean ~/.claude/skills/humanize-korean
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Humanize Korean — AI 한글 티 제거 오케스트레이터 (v2.3)

> **v2.3.2** — 플러그인 스킬을 관례 위치(루트 `skills/`)로 이동. 마켓플레이스 설치에서 shim·진단이 조용히 누락되던 경로 문제 해소.
> **v2.3.1** — 경로 해석·런타임 경계·계약 정합 수정 회차(외부 제보 반영). 기능 변경 없음.
> **v2.3.0** — 구조 수렴 게이트(`verify_gates.py` 4축: 목표달성·대구 전멸·수치·golden) + 진단 슬림 인덱스(`diagnosis-rules.md`, taxonomy 83%↓). (v2.2: route_hint 3경로 + 단일 콜 우선)
> 버전 히스토리·실측 근거·테스트 시나리오: [`${CLAUDE_SKILL_DIR}/references/design-notes.md`](references/design-notes.md)

## Phase 0: 컨텍스트 확인 및 경로 결정

작업 시작 시 가장 먼저 다음 한 줄을 사용자에게 출력한다.

```
humanize-korean v2.3 — 경로: {light|standard|heavy} ({route_hint|사용자 지정}) / run_id: {YYYY-MM-DD-NNN}
```

(경로는 Phase 1의 shim 실행 후에 확정되므로, 이 상태 줄은 shim 직후 출력한다.)

### 전 경로 공통 의미 앵커

- 윤문 전에 문장별 **핵심 내용 명사·개념어**를 내부 목록으로 잡는다. 주어·목적어·보어에서 원문의 주장을 구성하는 어휘가 대상이다.
- 조사·어미는 바꿀 수 있지만, 내용 앵커의 원형 어휘는 결과에 최소 한 번 그대로 남긴다. 동의어 치환이나 문장 병합을 이유로 삭제하지 않는다.
- AI 관용구·추상어를 덜어낼 때는 수식어와 형식명사만 걷어낸다. 내용 앵커까지 함께 사라질 것 같으면 해당 문장을 롤백한다.
- 출력 직전 원문과 윤문본을 다시 대조한다. 내용 앵커 하나라도 빠졌으면 자연성보다 의미 보존을 우선해 복원한다.

### 경로 결정 규칙
1. **사용자 명시가 최우선.** `--strict`·"정밀 모드"·"정밀하게"·"제대로" → **heavy 고정**. "가볍게"·"빠르게만" → **light 고정**. 명시가 있으면 route_hint는 무시한다.
2. 명시가 없으면 shim이 `00_metrics.json`에 쓴 **`route_hint`**(`light`|`standard`|`heavy`)를 디폴트 경로로 따른다.
3. `route_hint` 필드가 없거나 shim이 graceful degrade로 점수 산출에 실패한 경우 → **standard**로 간주.
4. light/standard 결과가 등급 C/D → 사용자에게 "heavy(정밀) 재실행 권고" 안내(자동 전환 아님 — 사용자 opt-in).
5. **입력 길이는 경로를 바꾸지 않는다.** 1만자급도 단일 콜로 처리한다(§설계 노트의 실측 근거 참조). 길이·중증도 판단은 shim의 route_hint에 위임한다.

### run_id 결정
- 모든 경로는 **cwd 기준**. 새 폴더 생성도 cwd 기준 `_workspace/{YYYY-MM-DD-NNN}/`에 만든다.
- 기존 시퀀스 확인은 **`Glob` 도구**로 표지 파일을 매칭해 간접 조회.
  올바른 사용법: `Glob(pattern="_workspace/YYYY-MM-DD-*/01_input.txt")` → 결과에서 폴더명 추출 후 NNN 최댓값 + 1.
  주의: Glob은 디렉토리 자체는 매칭하지 못한다. 반드시 그 안의 표지 파일(`01_input.txt`)을 매칭할 것.
  `Bash ls`는 OS·셸 환경에 따라 경로 해석이 달라지므로 사용 금지.
- 당일 폴더가 없으면 NNN = 001. 있으면 마지막 NNN + 1.
- 부분 재실행 신호("이 카테고리만 다시"·"2차 윤문")일 경우 기존 run_id 재사용 + heavy 경로로 자동 승급.

## 스크립트 경로 규칙 (`${SKILL_ROOT}`)

**스크립트는 절대경로로 부른다. cwd 기준 상대경로로 부르면 안 된다.**

`references/*` 는 **스킬 디렉터리** 기준이라 `${CLAUDE_SKILL_DIR}` 를 쓴다 — `${SKILL_ROOT}` 와 기준이 다르니 섞지 않는다. 룰북·taxonomy 경로도 맨앞 접두어 없이 쓰면 cwd 로 풀려 `No such file or directory` 가 난다.

`scripts/*.py`는 설치 루트에 있고 cwd 는 사용자 작업 디렉터리다. 마켓플레이스 설치에서 둘은 **절대 일치하지 않는다.** 반면 `_workspace/` 같은 데이터 경로는 cwd 기준이다(run_id 규칙 참조). 두 기준이 한 명령줄에 섞이므로 스크립트 쪽만 절대경로로 고정한다.

Phase 1 시작 전에 한 번 정한다.

```bash
SKILL_ROOT="$(d="$(cd -P "${CLAUDE_SKILL_DIR}" && pwd)"; \
  while [ "$d" != / ] && [ ! -d "$d/.claude-plugin" ]; do d="$(dirname "$d")"; done; echo "$d")"
```

`.claude-plugin/` 디렉터리를 만날 때까지 거슬러 올라간다. **고정된 횟수로 올라가지 않는 이유**는 스킬 위치가 배포 방식마다 다를 수 있어서다 — 고정 깊이는 레이아웃이 바뀌면 조용히 엉뚱한 곳을 가리킨다.

**`cd -P` 가 핵심이다.** 심링크 설치(`install.sh` 기본)에서는 스킬 디렉터리가 저장소를 가리키는 심링크라, 그냥 `cd` 하면 셸이 논리 경로를 유지해 엉뚱한 곳(홈 디렉터리)으로 올라간다. `-P` 로 물리 경로를 먼저 푼 뒤 올라가야 심링크·플러그인 양쪽에서 같은 답이 나온다. 이후 모든 스크립트 호출에 `${SKILL_ROOT}/scripts/...` 를 쓴다.

**확인**: `ls "${SKILL_ROOT}/scripts/prepare_monolith_input.py"` 가 실패하면 경로 유도가 틀린 것이다. 이 경우 스크립트를 찾을 때까지 임의로 추측하지 말고, 정량 shim·게이트 없이 진행한다고 **사용자에게 알린 뒤** 계속한다. 조용히 건너뛰면 route_hint 와 철칙 #4 게이트가 사라진 것을 아무도 모른다.

> `CLAUDE_PLUGIN_ROOT` 는 Bash 도구 안에서 비어 있는 경우가 확인됐다(#84). 이 변수에 의존하지 않는다.

## Phase 1: 입력 저장 + 정량 사전 점수 (input shim — 전 경로 공통)

1. cwd 기준 `_workspace/{run_id}/` 생성
2. 입력 텍스트를 `01_input.txt`에 저장
   - **챗봇 잔재 위생 (v2.6)**: 저장 전에 챗봇 프레임 문장이 섞여 있으면 벗겨낸다 — 머리("물론입니다!", "다음은 ~입니다:", "요청하신 내용을 정리하면"), 꼬리("도움이 되셨길 바랍니다", "추가 질문이 있으시면"), 지식 한계 면책("제 지식은 ~까지입니다"). 실사용자는 챗봇 출력을 그대로 붙여넣는 일이 많고, 이 문장들은 본문이 아니므로 제거해도 의미 손실이 0이다. 본문 안에 자연스럽게 녹아 있는 유사 표현은 건드리지 않는다.
3. 첫 300자로 장르 자동 추정 (사용자 명시 시 우선)
4. 사전 처리 shim을 Bash로 1회 실행:
   ```
   python3 ${SKILL_ROOT}/scripts/prepare_monolith_input.py --run-dir _workspace/{run_id} --genre {genre}
   ```
   - `--genre` 값은 영문 키: `essay | column | report | blog | abstract` (생략 시 `essay`). 장르 힌트 매핑: 칼럼→`column`, 리포트→`report`, 블로그→`blog`, 공적/기타→`essay`.
   - `--run-dir`·`--diagnosis`의 상대 경로는 **cwd 기준**으로 해석된다(위 run_id 규칙과 동일 기준). 그 외 인자: `--text`(run-dir 없이 즉석 실행 시 새 run 디렉토리 자동 생성), `--baseline`(baseline JSON 경로 override, 평소 불필요), `--diagnosis`(진단 텍스트 파일을 점수 블록 앞에 prepend — standard·heavy의 진단 결합용).
   - 산출: `00_metrics.json`(정량 점수 + **`route_hint`**) + `01_input_with_metrics.txt`(점수 블록을 원문 앞에 붙인 결합 파일).
   - **graceful degrade 내장**: metrics 계산이 실패하면 shim이 점수 블록 없이 원문만 감싼 결합 파일을 쓰고 `00_metrics.error`를 남긴다. 이 경우 route_hint 없음 → standard 경로.
5. `00_metrics.json`의 `route_hint`를 읽어 Phase 0 규칙대로 경로를 확정하고 상태 줄을 출력한다.

**단일 콜 우선 — 청킹은 여기서 하지 않는다.** `--chunk`는 heavy 경로 전용이며, 그때도 청크 경로를 탈지는 shim이 실제로 청크를 2개 이상 만들었는지로 정한다(heavy 절 참조).

## Light 경로 (1콜) — 잘 쓴 글

어휘 티가 거의 없고 구조 티만 미미한 글. 목표는 **과윤문 방지**이지 많이 고치는 게 아니다.

1. **진단 생략.** `humanize-monolith`를 `Agent` 도구로 1회 호출 — 청킹 없음.
   - 입력: `input_path=01_input_with_metrics.txt`, `quick_rules_path=${CLAUDE_SKILL_DIR}/references/quick-rules.md`, `genre_hint`, 그리고 강도 지시 `보수`(내용 앵커 원형 보존, 원문에 없던 표현 삽입 금지, 확신 없는 구간은 그대로 둔다).
   - 출력: `final.md` (본문 + `<!-- HUMANIZE-SUMMARY -->` 블록).
2. Phase 2.5 변경률 게이트(Bash — LLM 콜 아님).
3. **조기 종료 보고**: monolith 탐지가 거의 없고 게이트 변경률이 5% 미만이면, 결과 전달을 "이미 좋은 글입니다 — 손댄 곳은 {N}곳({요지}) 정도"로 요약한다. 억지로 더 고치지 않는다.
4. 게이트 exit 2(≥50%)일 때만 롤백 재실행 1회(이 경우 총 2콜). light에서 50%가 나오면 과윤문 사고이므로 재실행 지시에 보수 강도를 재강조한다.

**콜 수: 1 (게이트 실패 시 최대 2).**

## Standard 경로 (2콜) — 보통의 AI 초안

1. **진단 1콜**: `humanize-diagnostician`을 `Agent` 도구로 1회 호출.
   - 입력: `input_path=01_input_with_metrics.txt`, `taxonomy_path=${CLAUDE_SKILL_DIR}/references/diagnosis-rules.md` (진단 전용 슬림 인덱스 — 71패턴 전수, taxonomy에서 자동 생성)
   - 출력: `02_diagnosis.md` — 글 전체의 **지배 패턴 3~6개**(본진 ID + 근거 + 처방) + 장르·격식 + 보존 지침.
   - 진단은 span을 세지 않는다. "무엇이 이 글을 지배하는가"를 판단한다(안정적).
2. shim으로 진단을 monolith 입력 앞에 결합 (Bash — LLM 콜 아님):
   ```
   python3 ${SKILL_ROOT}/scripts/prepare_monolith_input.py --run-dir _workspace/{run_id} --genre {genre} --diagnosis _workspace/{run_id}/02_diagnosis.md
   ```
   → `01_input_with_metrics.txt`가 [진단 → 정량 블록 → 원문] 순으로 재생성된다.
3. **윤문 1콜**: `humanize-monolith` 1회 호출 — **청킹 없음. 1만자급도 단일 콜이다.*
humanize-diagnosticianSubagent

정밀(strict) 모드 1단계 진단 에이전트. 글 전체를 한 번에 보고 "가장 지배적인 AI 티 패턴 3~6개"를 taxonomy ID와 함께 진단한다. 불안정한 span 열거(0↔18개로 요동) 대신 "무엇이 이 글을 지배하는가"라는 안정적 판단을 내려, 후속 윤문 콜이 그 진단을 겨냥하게 한다. 산출물은 02_diagnosis.md 1개. 도구 호출 3회 캡(Read 결합입력 + Read taxonomy + Write 진단). 이 진단이 정밀 모드 품질의 결정 변수다.

humanize-finalizerSubagent

정밀(strict) 모드 3단계 마무리 에이전트. 원문과 윤문본을 직접 대조해 ①의미 보존(15항 — 각주·제목·없던 주장 주입 포함) ②자연성(잔존 AI 티 + 과윤문 양방향)을 한 콜로 병합 판정하고, 문제 구간만 국소 보정한다. 전체 재작성 금지 — 의미 드리프트(빈 수사를 없던 주장으로 대체)를 막는 게 존재 이유. 은퇴한 content-fidelity-auditor·naturalness-reviewer 2인을 대체한다. 산출물은 final.md + 09_finalize.json. 도구 호출 4회 캡.

humanize-monolithSubagent

v1.6.1 Fast Path 단일 호출 윤문 에이전트. 한 호출 안에서 탐지·윤문·자체검증을 일괄 수행하여 5,000자 이하 한글 입력을 2~3분 안에 처리한다. 산출물은 final.md 1개(본문 끝에 `<!-- HUMANIZE-SUMMARY -->` HTML 주석 블록으로 메트릭·등급·자체검증 통합). 도구 호출 chain 3회 캡. 깊은 검증이 필요하면 정밀 모드(진단→윤문→finalize 3콜) 사용.

korean-ai-tell-taxonomistSubagent

AI가 생성한 한글 글의 "AI 티" 패턴을 체계적으로 분류·확장·버전 관리하는 도메인 전문가. `references/ai-tell-taxonomy.md`를 단일 진실 원천(SSOT)으로 유지하며, 실제 입력에서 관찰된 신규 패턴을 검증해 v1 → v2로 승격한다.

korean-translation-scholarSubagent

한국 번역학계(이근희·김정우·김도훈·김순영·김혜영·이영옥·곽은주·조의연)와 국제 번역학(Baker·Toury·Laviosa·Chesterman·Toral·Sarti)의 학술 인용 계보를 Humanize KR 본진 SSOT(taxonomy.md)와 외부 references/scholarship.md 양면에 안전하게 안착시키는 학술 정통성 큐레이터. 보고서의 학술 자산을 본진 분류 체계가 검증 가능한 형태로 흡수하되, SSOT 룰북 슬림성을 해치지 않게 메타필드 + 외부 파일로 분리. 본진 패턴에 출처를 박을 때 호출.

post-editese-metric-engineerSubagent

Toral 2019 post-editese 3축(단순화·정규화·간섭)을 한국어 정량 지표로 구체화하고, 보고서 8유형 검출 시그널을 metrics.py에 추가해 회귀 검증 가능 상태로 만드는 정량 엔지니어. 표준 라이브러리만, 형태소 분석은 정규식·접미사 사전으로 근사(konlpy·mecab 금지 — v1.6 정책 보존). monolith 외부 사전 처리(prepare_monolith_input.py)에 결합되어 도구 호출 캡 3회 보존. 신규 metric 추가 또는 metric 회귀 검증 시 호출.

quick-rules-integratorSubagent

신규 분류 체계 v2.0과 metrics·playbook 패치를 quick-rules.md(monolith 전용 슬림 룰북, 126줄 → ≤180줄)에 안착하고 monolith 도구 호출 3회 캡(v1.6.1) 회귀를 검증한 뒤, GitHub PR 초안과 CHANGELOG를 작성하는 통합 엔지니어. 본진 룰북 슬림성·monolith 정의 무수정·v1.x 발행 정책(사용자 명시 승인 후 푸시)을 3대 가드로 삼음. v2.0 변경 묶음을 PR로 발행 직전 단계에서 호출.

taxonomy-gap-analyzerSubagent

Humanize KR 본진 v1.6 분류 체계(10대 카테고리·61+ 패턴)와 외부 학술 보고서 후보 풀(translationese-research-distiller 산출물)을 3-축 매트릭스(이미 본진·보강·신규)로 매핑해 분류학자에게 승격 결정 입력을 제공하는 갭 분석가. 사실 발견만 하고 승격 결정은 하지 않는다 — taxonomist가 최종 판정자. 본진 v1.6 → v2.0 업그레이드 회차 또는 외부 보고서를 본진과 합칠 때 호출.