
“고전적” 머신러닝을 이용한 LLM 생성 텍스트 탐지
요약
전통적인 머신러닝 기법을 활용하여 LLM이 생성한 텍스트를 탐지하는 방법론을 소개합니다. 텍스트의 당혹도(Perplexity)를 분석하여 단어의 예측 확률을 기반으로 인간의 글과 AI 생성 콘텐츠를 구별하는 원리를 다룹니다.
핵심 포인트
- 전통적 머신러닝 모델로도 LLM 생성 텍스트의 통계적 패턴 탐지 가능
- 텍스트 당혹도(Perplexity)를 활용한 단어 예측 확률 기반 탐지 원리
- 테스트 세트 기준 단일 문장 탐지 정확도 약 85% 달성
- 범용 데이터 학습 없이도 효과적인 AI 생성 콘텐츠 식별 가능
이 글은 현재 실험적인 기계 번역 상태이며 오류가 포함될 수 있습니다. 불분명한 점이 있다면 원문인 중국어 버전을 참조해 주세요. 번역 품질을 개선하기 위해 지속적으로 노력하고 있습니다.
2026년 초 기준으로, 주류 LLM (Large Language Model) 생성 텍스트는 전통적인 머신러닝 (Machine Learning) 모델을 사용하여 인간이 작성한 콘텐츠와 효과적으로 구별할 수 있는 강력한 통계적 패턴을 보입니다. 저는 이것이 소위 “AI 표절 검사기”들이 실제로 내부에서 작동하는 방식이라고 추측합니다.
온라인 데모: https://lyc8503.github.io/AITextDetector/
이 데모에 사용된 모델은 범용 데이터로 학습되지 않았으며, 엄격한 최적화나 반복 과정을 거치지 않았습니다. 테스트 세트에서의 단일 문장 탐지 정확도는 약 85%입니다. 사용하기 전에 잠재적인 한계를 이해하기 위해 이 글을 끝까지 읽어주시기 바랍니다.
핵심 코드(초안) 및 학습된 모델 파일은 GitHub에서 확인할 수 있습니다: lyc8503/AITextDetector
반년 전 제가 학교에서 논문을 쓰던 시절에도, 이미 AIGC (AI-generated content, AI 생성 콘텐츠) 논문 검사에 대한 소문이 돌고 있었습니다. 저는 CNKI, Wanfang, 그리고 몇몇 제3자 AIGC 탐지 서비스들을 테스트해 보았고, 이들이 제가 직접 쓴 텍스트와 LLM 생성 텍스트를 상당히 괜찮은 정확도로 구별해낼 수 있다는 것을 발견했습니다.
그것은 AIGC 탐지가 실제로 어떻게 작동하는지~~(그리고 어떻게 우회하는지)~~에 대한 저의 호기심을 자극했습니다.
하지만 당시 저는 라디오, 마인크래프트 (Minecraft), 동방 프로젝트 (Touhou) 등에 빠져 너무 많은 일을 병행하고 있었고, 몇 번의 실패 끝에 그 아이디어를 덮어두었습니다.
결국 저는 논문을 어떻게든 통과시켰고, 삶은 흘러갔습니다. 하지만 최근 Lofter를 둘러보던 중, 저품질의, 캐릭터 해석이 완전히 잘못된 AI 생성 팬픽션(fanfics)이 넘쳐나는 태그들을 발견했습니다.
한눈에 그것들이 AI라는 것을 어떻게 알 수 있을까요? 글쎄요, 어떤 사람들은 게시하기 전에 Markdown 포맷팅이나 AI가 생성한 섹션 헤더를 정리하는 수고조차 하지 않으며—그러고는 글의 절반을 유료 결제창 뒤에 숨겨버리곤 합니다 😓
하지만 대부분의 AI 생성 텍스트는 찾아내기가 더 어렵습니다. 다양한 글쓰기 스타일과 다채로운 프롬프트(Prompt) 사이에 묻혀 있어 즉각적으로 눈에 띄지 않기 때문입니다. 무언가 이상하다는 것을 깨달았을 때는 이미 너무 늦은 상태입니다. 어떤 텍스트들은 AI가 작성했다는 것을 증명하는 것이 거의 불가능에 가까워 저를 편집증적으로 만들기도 했습니다. 너무 많은 AI 생성 쓰레기들을 삼키고 난 후, 저는 마침내 참을 만큼 참았다고 느꼈습니다. Lofter 서핑은 여기서 끝내고—이제 VS Code를 열 시간입니다!
네, 그렇게 저는 주말 프로젝트 아이디어를 다시 살리게 되었습니다. 바로 AI 생성 텍스트 탐지기(AI-generated text detector)를 만드는 것이었죠...
현재 인터넷에서 AIGC(AI-Generated Content) 탐지를 검색하면 거의 전부 광고로 오염되어 있습니다. 모든 결과가 그저 또 다른 AI 글쓰기 재작성 서비스일 뿐입니다. 예전에 저는 그 소음 속을 파헤쳐 '텍스트 퍼플렉시티(Text Perplexity, 텍스트 당혹도)'라고 불리는 것을 찾아냈습니다.
아이디어는 간단합니다. 기존의 LLM(Large Language Model)을 사용하여 주어진 문장에서 각 단어가 나타날 확률을 추정하는 것입니다. 만약 거의 모든 단어가 LLM의 예측 순위에서 높게 나타난다면(Top-N), 그 문장은 AI가 생성했을 가능성이 높습니다. 반대로, 많은 단어가 예상치 못한 것이라면 사람이 작성했을 가능성이 더 높습니다.
유망해 보이지 않나요? 저는 이 방법을 시도하는 데 시간을 좀 보냈지만, 결과는 실망스러웠습니다. 수많은 거짓 양성(False Positives)과 거짓 음성(False Negatives)이 발생했고, 합리적인 임계값(Threshold)을 설정할 수도 없었습니다. 게다가 실질적인 문제들도 있었습니다. 높은 추론 비용(Inference cost), 낮은 교차 모델 일반화(Cross-model generalization) 성능, 대규모 모델을 로컬에 배포하는 것의 어려움, 그리고 폐쇄형 가중치 모델(Closed-weight models)을 통합하기 어렵다는 점 등입니다. 전반적으로 이 접근 방식은 우아하지도, 신뢰할 수 있지도 않았습니다.

온라인 리소스가 쓸모없었기에, 다시 옛날 방식의 연금술로 돌아갑니다.
Scikit-learn, 가동!
해당 라이브러리의 로드맵(Roadmap)을 따라, 우리는 분류(Classification) 작업을 위한 좋은 시작점으로 Linear SVC와 Naive Bayes(나이브 베이즈)를 직접 선택할 수 있습니다.
(속삭임: 이것은 제 직감과도 일치했습니다. LLM은 탐지 가능한 단어 선택 패턴을 가지고 있으며, Naive Bayes 분류기조차 이를 잡아낼 수 있을 것이라는 직감 말이죠. 다만 신호(Signal)가 이렇게 강할 줄은 몰랐을 뿐입니다.)
옛날 방식의 연금술 전통적인 분류기(Classifiers)는 레이블이 지정된 데이터(Labeled data)가 필요합니다. 따라서 학습을 위해 사람이 작성한 텍스트와 확인된 LLM 생성 텍스트가 필요합니다.
나의 접근 방식: 나는 2023년에 특정 Ford-like 및 River-like 플랫폼에서 스크래핑한 데이터를 가져와, 2010~2022년(ChatGPT 이전) 사이에 게시된 기사들로 필터링했습니다. 참여도가 극도로 낮거나 매우 짧은 글들만 제외한 후, 수천 자 이상의 텍스트 중 약 10,000개를 무작위로 샘플링하여 사람이 작성한 샘플(human-written samples)로 삼았습니다.
그 다음, LLM을 사용하여 이 텍스트들의 챕터 요약(chapter summaries)을 생성했고, 그 요약본을 다시 LLM에 입력하여 전체 기사를 재생성하도록 했습니다. 이를 통해 장르가 다양하고 원본 인간 콘텐츠와 밀접하게 일치하는, 대략적으로 동일한 수의 LLM 생성 샘플을 확보할 수 있었습니다.
이론상으로는 말입니다. 하지만 LLM API는 비용이 많이 들며, 나는 주말 프로젝트를 위해 수천 달러를 쓸 생각이 없었습니다. 그래서 나는 창의적인 방법을 사용했습니다—그리고 규칙을 우회하여 여러 저비용 또는 무료 API 채널을 활용했습니다:
Gemini: CLIProxyAPI를 사용하여 Antigravity/Gemini CLI 할당량(quota)을 API 액세스로 변환했습니다—AI Pro 계정에 약 $20만 지불하면 됩니다.
Qwen: qwen-code를 사용하면 Qwen Plus API를 역공학(reverse-engineer)할 수 있습니다—무료입니다.
GLM-5: 운이 좋았습니다—OpenRouter에서 GLM-5 퍼블릭 베타(Pony Alpha)를 무료로 제공하고 있었습니다.
Kimi, Deepseek, Doubao, GLM-4.7: 프로모션 코딩 플랜 기간에 가입했습니다—첫 달 $8.9로 API 액세스가 해제되었습니다.
면책 조항: 이것은 권장 사항이 아닙. 이러한 행위는 플랫폼의 이용 약관(ToS)을 위반하며 계정이 정지될 수 있습니다. 하지만 플랫폼들은 마케팅 홍보에 너무 바빠서 신경 쓰지 않을 것이고, 나는 정가를 지불할 생각이 없었습니다.
많은 프로그래밍 중심의 LLM API들은 이상하게도 호출(call)당 비용을 부과하지만, 우리는 작업을 거대한 입력값으로 배치(batching)하여 LLM이 호출당 더 많은 콘텐츠를 생성하도록 강제함으로써 이를 남용 최적화할 수 있습니다. 그래서...

결과적으로, 나는 gemini-3-flash를 사용하여 요약을 생성했고, 7개의 서로 다른 모델(gemini-3-pro, qwen-coder-plus, glm-5, glm-4.7, kimi-k2.5, doubao-seed-code, deepseek-v3.2)을 사용하여 7세트의 LLM 생성 샘플을 만들었습니다.

데이터 생성이 절반 정도 진행되었을 때, 나는 기다릴 수 없어 바로 학습(training)을 시작했습니다.
나는 Claude에게 분류기(classifier) 코드를 작성해 달라고 요청했고, Claude는 원문 텍스트 전체를 모델에 그대로 쏟아부어 버렸습니다. 그 결과 99.45%라는 의심스러운 정확도를 달성했습니다... 잠깐, 정말인가요?
Claude는 쓸모가 없군요. 직접 하겠습니다. 학습(training)을 위해, 나는 중국어 문장 부호를 사용하여 모든 텍스트를 문장 단위로 나누고, 중국어/영어가 아닌 문자를 제거한 다음, scikit-learn의 TF-IDF를 적용했습니다.
→ LinearSVC
일부 노이즈를 정리한 후에도, 문장 단위 분류(sentence-level classification) 정확도는 여전히 약 85%에 달했습니다!

개별 문장은 제한된 정보만을 담고 있지만, 문장당 85%의 정확도는 더 긴 기사의 경우 그것이 AI에 의해 생성되었는지 판단하는 데 매우 높은 확신을 가질 수 있음을 의미합니다. 이 성능은 내 예상을 훨씬 뛰어넘었습니다. 구식 머신러닝(Old-school ML)은 여전히 강력합니다. 단순히 LLM에게 "이 텍스트가 AI가 생성한 것인가요?"라고 묻는 멍청한 온라인 도구들보다 훨씬 낫습니다.
모든 데이터를 마친 후, 나는 8개 클래스 모델(인간 + 7개의 AI) 학습을 시도했지만, LLM들이 서로 너무 유사하여(아마도 서로로부터 증류(distilled)되었을 것입니다) 분류가 엉망이었고 정확도는 약 50%에 불과했습니다.

결국, 나는 7개의 별도 이진 분류기(binary classifiers)를 학습시킨 후 다수결 투표(majority voting) 방식을 사용했습니다. 즉, 2개 이상의 모델이 탐지하면 해당 문장을 AI로 표시하는 방식입니다.
1 | 8536개 샘플 로드됨 |
모든 모델이 85% 이상의 정확도와 80% 이상의 F1 점수를 달성했습니다. 꽤 탄탄한 결과입니다! 또한 AI가 생성한 텍스트는 종종 여러 모델에 의해 탐지된다는 점을 발견했기에, 투표 방식은 매우 합리적이었습니다.
MultinomialNB와 SGDClassifier도 시도해 보았지만, 정확도가 약간 떨어졌습니다. BERT는 약간의 성능 향상을 주었지만 GPU 시간이 너무 많이 소요되어 제외했습니다. AutoGluon도 테스트해 보았으나, 이진 분류 정확도가 겨우 53%에 그쳤습니다. 이 부분은 깊게 다루지 않겠습니다.
이 시점에서 나는 그냥 리포지토리(repo)를 공개하고 끝낼 수도 있었습니다. 하지만 매번 Python을 실행하는 것은 너무나 불편합니다. Python API를 호스팅할 수도 있었지만, 이는 서버 유지보수를 의미하며, 나의 엄격한 서버리스(Serverless) 철학에 위배됩니다.
나의 원래 계획: 모델을 ONNX로 내보내고, Wasm에서 ONNX Web Runtime을 통해 추론 (Inference)을 실행하는 것이었습니다. 하지만 나의 실리콘 하인(silicon servant)인 Claude에게 도움을 요청했을 때, 내가 명확하게 지정하지 않았고—그 결과 Claude가 대본을 벗어나 모델을 JSON으로 자르고 내보냈습니다... 그러고는 브라우저 추론을 위해 TF-IDF + SVM을 완전히 JavaScript로 구현해 버렸습니다.
음... 사실 나쁘지 않은 아이디어입니다. 100만 자의 텍스트로 테스트해 보았는데, 내 컴퓨터에서 약 10초가 걸렸으며 수용 가능한 수준이었습니다. 일반적인 수천 자 정도의 입력값에 대해서는 즉각적으로 처리됩니다.
좋습니다, 이것은 단순한 데모일 뿐이고, JS 방식이 더 투명하므로 이 약간은 황당한 구현을 그대로 유지하겠습니다. (내 탓이 아니라 Claude 탓입니다.)
정확도에 관해서는: 다양한 피처(Feature) 제한치를 테스트했습니다. 최종적으로 성능을 우선시하여 500k 피처를 유지했습니다. JSON으로 저장하면 107MB로 용량이 커지지만 (서버 측에서 gzip 압축을 하면 약 38MB입니다), 더 작은 버전(50k–80k)은 정확도가 3~4%만 감소했습니다. 하지만 최종 AI 탐지율은 크게 변동되었습니다—특히 인간이 작성한 텍스트에서 ±50%의 상대적 차이가 발생하여 오탐(False Positives)으로 이어졌습니다. 그래서 저는 500k를 고수했습니다.
최종 정확도 하락: 아래에 표시된 바와 같이 약 1%입니다.
1 | ============================================================ |
아래의 모든 테스트는 경량화된 웹 버전을 사용하며, 이는 전체 joblib 모델과 유사하게 작동해야 합니다.
현재 로직: 입력 텍스트를 문장 단위로 나누고, 정제한 뒤 7개의 이진 모델(Binary models)을 모두 사용하여 분류합니다. 만약 2개 이상의 모델이 문장을 플래그(Flag)하면, 해당 문장은 AI 의심 문장으로 표시되고 하이라이트됩니다. 최종 AI 점수는 플래그된 문자의 비율입니다. 분류 기준:
- <50%: 인간 (Human)
- 50–70%: 아마도 인간 (Maybe Human)
-
70%: 아마도 AI (Maybe AI)
먼저, 학습 데이터에 포함되어 있었던 Doubao 및 Deepseek와 같은 일반적인 모델들에 대한 탐지율을 테스트합니다. 프롬프트: 3000단어 분량의 이야기를 써줘


쉽게 탐지되었습니다.
이제 학습되지 않은 모델들을 테스트해 보겠습니다—일반화(Generalization) 성능은 어떨까요?


학습 데이터에 없던 다른 모델들(MiMo-V2, Doubao-Seed-2.0, GPT-4o)을 테스트했습니다—모두 약 70%에서 탐지되었으며, 일부는 90%를 넘기도 했습니다. 견고합니다.
또한 더 복잡한 프롬프트 (prompts)도 테스트했습니다. 예를 들어, 사람이 작성한 텍스트 20개 장(chapters)을 입력하고 LLM에게 스타일을 모방하여 내용을 이어 쓰도록 요청하는 방식입니다. 탐지율은 67.8%로 약간 떨어졌습니다 (하지만 우리도 복잡한 프롬프트로 학습했다는 점을 기억하세요). 지면 관계상 결과는 표시하지 않습니다.
그다음, 제 구독 목록에서 완성된 웹소설 10편(2022년 이전 작품)을 선정했습니다. 장르, 작가, 시대가 다양하며 학습 데이터에 포함되지 않았을 가능성이 높습니다.
이들의 AI 탐지율은 22.7%, 24.2%, 25.0%, 24.5%, 19.0%, 13.7%, 29.1%, 4.9%, 27.3%, 19.2%로, 모두 30% 미만이었습니다. 또한 무작위로 Lofter 팬픽(fanfics)을 샘플링했는데, 이들은 더 캐주얼하기 때문에 탐지율이 종종 10% 미만이었습니다. 하지만 제가 AI가 생성했을 것으로 의심되는 텍스트를 입력했을 때는 탐지율이 83.4%로 급증했으며, 이는 공개 없이 LLM을 사용했음을 강력하게 시사합니다.
[2026년 3월 5일 업데이트] 더 엄격한 테스트를 위해, Lofter에서 2022년 이전에 게시된 고참여도(조회수 >5000), 장문(단어 수 >2000) 팬픽 10,000개를 무작위로 샘플링했습니다. 이들의 AI 탐지율 분포는 다음과 같습니다 (7개 모델 투표 방식 사용, 2표 이상 시 탐지):
1 | 0-5%:313 | 5-10%:1945 | 10-15%:3016 | 15-20%:2033 | 20-25%:1355 | 25-30%:594 | 30-35%:492 | 35-40%:123 | 40-45%:34 | 45-50%:62 | 50-55%:24 | 55-60%:5 | 60-65%:3 | 65-70%:1 |
임계값 (threshold)을 60%로 설정 시 → 오탐률 (false positive rate): 0.04%
70%로 설정 시 → 오탐률 (false positive rate): <0.01% (사실상 제로)
60%를 초과한 4개의 텍스트는 모두 실제 이야기가 아닌 컬렉션 인덱스(collection indexes)였으며, 과도한 링크 때문에 플래그가 지정되었습니다.
임계값을 50%로 설정하더라도 오탐률은 단 **0.33%**에 불과합니다.
그 후, Lofter Android의 상위 20개 트렌딩 태그(주간 랭킹)에서 모든 기사를 스크래핑하고 길이에 따라 필터링한 뒤 탐지를 실행했습니다:
1 | 0-5%:27 | 5-10%:138 | 10-15%:231 | 15-20%:245 | 20-25%:238 | 25-30%:137 | 30-35%:112 | 35-40%:87 | 40-45%:116 | 45-50%:112 | 50-55%:118 | 55-60%:157 | 60-65%:118 | 65-70%:109 | 70-75%:75 | 75-80%:56 | 80-85%:28 | 85-90%:15 | 90-95%:10 |
기사의 32.22%가 50% 이상의 AI 점수를 기록했습니다—부분적으로 또는 완전히 AI에 의해 생성되었을 가능성이 높습니다… 인간이 남아있기는 한 걸까요?? 게다가, AI 생성 콘텐츠임을 선제적으로 밝힌 사례는 단 하나도 없었습니다.
“법의 시대가 저물고 있구나, , ,” —그룹 내의 한 친구
좋습니다, 우리는 AIGC (AI Generated Content, AI 생성 콘텐츠) 탐지기를 구축했습니다. 이제 탐지기 방어 도구(anti-detector)를 만들 차례군요.
아니요, 농담입니다. 제가 그렇게 심심하지는 않거든요.
하지만 몇 가지 흔한 anti-AIGC 탐지 기법들을 테스트해 보겠습니다:
Google Translate 왕복 번역 (중국어→영어→중국어): 89.9% → 85.0%
Youdao Translate 왕복 번역 (중국어→영어→중국어): 89.9% → 79.2%
AI 자동 생성 콘텐츠
본 콘텐츠는 HN AI Posts의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기