텍스트 요약기, 한국어에서는 왜 제대로 작동하지 않는가
"텍스트를 붙여넣으면 핵심 문장만 뽑아준다"는 요약 도구를 한국어 글에 써보면 결과가 이상하다고 느낀 사람이 많습니다. 문장이 골라지긴 골라지는데 왜 하필 그 문장인지 알 수 없고, 핵심 키워드 칸은 텅 비어 있기도 합니다. 이 글은 모두의 툴 텍스트 요약기의 실제 자바스크립트 소스코드를 직접 열어, 한국어 입력에서 무슨 일이 벌어지는지를 추측이 아니라 코드 그대로 확인한 결과입니다.
1. 추출 요약 알고리즘은 애초에 "단어 경계"를 전제로 만들어졌다
이 도구가 쓰는 방식은 생성형 AI 요약이 아니라 단어 빈도 기반 추출 요약입니다. 전체 글에서 각 단어가 몇 번 나오는지 센 뒤, 자주 등장하는 단어를 많이 포함한 문장일수록 점수를 높게 매기고, 점수가 높은 문장 몇 개를 원문 그대로 골라내는 방식입니다. 이 방식이 성립하려면 "단어가 어디서 시작해 어디서 끝나는지"를 정확히 잘라낼 수 있어야 합니다. 영어는 단어 사이에 공백이 있고 굴절이 단순해서 이 경계를 정규식 하나로도 비교적 쉽게 잡아낼 수 있습니다.
2. 한국어는 왜 같은 방식으로 단어를 자르기 어려운가
한국어는 교착어라서 하나의 명사 뒤에 조사가, 하나의 동사·형용사 어간 뒤에 어미가 계속 붙습니다. "회사"라는 같은 단어도 문장에 따라 "회사는", "회사가", "회사를", "회사에서" 처럼 형태가 계속 바뀌고, 이걸 하나의 단어로 묶어 세려면 조사·어미를 떼어내는 형태소 분석이 필요합니다. 영어처럼 공백과 문장부호만 기준으로 잘라서는 "회사는"과 "회사가"가 서로 다른 단어로 취급되어 빈도가 흩어지거나, 아예 정규식 설계 자체가 한글을 고려하지 않으면 다음 절에서 보듯 단어 자체가 통째로 사라지는 문제까지 생깁니다.
3. 실제 코드를 열어보니 — tokenize()의 정규식
text-summarizer.html의 tokenize() 함수는 다음과 같이 정의돼 있습니다.
function tokenize(text){return text.toLowerCase().replace(/[^\w\s]/g,' ').split(/\s+/).filter(w=>w.length>1&&!STOP.has(w));}
핵심은 replace(/[^\w\s]/g,' ') 부분입니다. 이 정규식은 "단어 문자(\w)도 아니고 공백(\s)도 아닌 문자"를 전부 공백으로 바꿉니다. 그런데 JavaScript 정규식의 \w는 [A-Za-z0-9_], 즉 영문자·숫자·밑줄만을 의미하며 한글 음절(가-힣)은 포함하지 않습니다. 그 말은 "한국어" 같은 글자를 넣으면 각 글자가 전부 \w도 \s도 아닌 문자로 판정되어 공백으로 치환된다는 뜻입니다. 뒤이은 split(/\s+/)는 그 공백들을 기준으로 문자열을 나누므로, 순수 한국어 문장은 이 단계에서 인식 가능한 단어 토큰을 단 하나도 남기지 못하고 사실상 빈 배열이 됩니다.
4. 그 결과 실제 요약 결과는 어떻게 나오는가
summarize() 함수를 계속 따라가 보면, 각 문장의 점수는 words.reduce((acc,w)=>acc+(freqMap[w]||0),0)/Math.max(words.length,1)로 계산됩니다. 한국어 문장은 words(tokenize 결과)가 빈 배열이므로 분자는 0, 분모는 Math.max(0,1)=1이 되어 점수는 정확히 0이 됩니다. 위치 기반 모드를 선택해도 이 0점에 첫 문장·마지막 문장 가중치를 곱할 뿐이라 0에 무엇을 곱해도 0으로 남습니다. 결과적으로 모든 문장이 동점 0점이 되고, 실제로 어떤 문장이 요약으로 뽑히는지는 자바스크립트 Array.sort의 동점 처리(정렬 안정성)에 좌우될 뿐, 그 글에서 실제로 중요한 문장을 골라낸 결과가 아닙니다. 핵심 키워드 태그 칸이 한국어 입력에서 비어 보이는 이유도 같은 원인입니다 — 빈도 집계(freqMap) 자체에 한글 단어가 하나도 들어가지 않으므로 상위 키워드로 보여줄 항목이 없는 것입니다.
5. 그래서 한국어 텍스트에는 어떻게 대응해야 하는가
이 도구가 "고장"난 것은 아닙니다. 영어 텍스트를 넣으면 \w가 영문자·숫자를 정상적으로 잡아내므로 빈도 계산과 문장 선택이 설계된 그대로 작동합니다. 다만 한국어 입력에서는 요약 결과가 나오더라도 그것이 실제 핵심 문장이라는 보장이 없다는 점을 알고 써야 합니다. 한국어 문서를 요약해야 한다면, 문단별로 직접 핵심 문장을 표시해두거나, 형태소 분석과 언어 이해를 전제로 하는 별도의 한국어 요약 서비스를 쓰는 편이 실제 결과 품질 면에서 더 안전합니다.
자주 묻는 질문
Q. 왜 한국어 문장은 요약기에서 모두 같은 점수를 받나요?
A. 단어 빈도를 세는 tokenize() 함수가 정규식 [^\w\s]로 단어가 아닌 문자를 공백으로 바꾸는데, JavaScript의 \w는 영문자·숫자·밑줄만 의미하고 한글(가-힣)은 포함하지 않습니다. 그 결과 한국어 문장을 넣으면 인식되는 단어 토큰이 하나도 남지 않아 모든 문장의 점수가 정확히 0이 됩니다.
Q. 위치 기반 모드로 바꾸면 한국어에서도 나아지나요?
A. 아니요. 위치 기반 모드는 문장의 기본 빈도 점수에 첫 문장·마지막 문장 가중치를 곱하는 구조인데, 한국어 문장의 기본 점수가 이미 0이므로 어떤 배율을 곱해도 여전히 0입니다.
Q. 그럼 한국어 텍스트에는 이 도구를 아예 쓸 수 없나요?
A. 요약 결과 자체는 나오지만 점수가 전부 0으로 동점 처리되기 때문에 어떤 문장이 선택되는지는 사실상 정렬 안정성에 따른 우연에 가깝습니다. 즉 결과가 나온다고 해서 실제로 핵심 문장을 골라낸 것은 아니므로, 한국어 요약이 필요하다면 이 도구보다 문장을 직접 읽고 고르거나 언어 모델 기반 요약 서비스를 쓰는 편이 낫습니다.
Q. 영어 텍스트에서는 정상적으로 작동하나요?
A. 네. tokenize()의 \w 정규식은 영문자·숫자를 정상적으로 단어로 인식하므로, 영어 텍스트에서는 단어 빈도가 실제로 집계되고 그 빈도를 기반으로 문장 점수가 매겨져 핵심 문장이 골라집니다.