AI 이용 정책을 ai.txt로 적어 둔 곳은 700곳에서 알바천국 한 곳이었어요 — robots.txt는 382곳, llms.txt는 61곳이에요
Tranco 목록에서 기계적으로 자른 도메인 700곳에 robots.txt 와 llms.txt 와 ai.txt 를 요청해 봤어요. robots 문법으로 읽힌 382곳 가운데 AI 크롤러를 이름으로 적은 곳이 140곳, llms.txt 는 61곳, ai.txt 는 1곳이었어요.
AI 기술을 누구나 쉽게 활용할 수 있도록 실전 가이드를 작성합니다. ChatGPT, Claude, AI 자동화, SEO 분야를 전문으로 다룹니다.
AI API 요금표는 대체로 한 줄이에요. 100만 토큰당 얼마. 그런데 그 토큰이 무엇을 세는지는 요금표에 안 적혀 있어요. GPT 토크나이저가 들고 있는 어휘 사전에 어떤 글자가 몇 칸이나 들어 있느냐로 정해지거든요.
그래서 이번에는 설명글을 읽는 대신 사전 파일을 직접 받아서 열어 봤어요. OpenAI 가 공개한 o200k_base 사전 파일은 199,998칸이에요. 그중 알파벳만으로 이루어진 칸은 105,898칸, 한글만으로 이루어진 칸은 2,338칸이었어요. 전체에서 차지하는 비율로는 52.95% 대 1.17%예요.
그 배분이 실제로 어떻게 나타나는지 보려고, 유니코드 완성형 한글 음절 11,172자를 하나씩 단독으로 사전에 넣어 봤어요. 한 토큰으로 끝나는 글자는 677자였어요. 같은 방식으로 알파벳 a 부터 z 까지 26자를 넣으면 26자가 전부 1토큰이고요.
먼저 하나 갈라 둘게요. 「GPT 토큰 사전」은 하나가 아니에요. 같은 회사의 같은 계열인데 답이 셋으로 갈려요. r50k_base 에서는 0자, cl100k_base 에서는 129자, o200k_base 에서는 677자예요. 그리고 가장 널리 알려진 GPT-4 는 677이 아니라 129 쪽이에요. 제목의 677은 tiktoken 저장소 표에서 GPT-4o 와 gpt-5 접두에 연결된 사전의 값이라는 뜻이에요.
조회 조건도 적어 둘게요. 이 조사는 API 를 한 번도 부르지 않았고 키도 쓰지 않았어요. 공개된 사전 파일만 받아서 셌고, 파일을 받은 시각은 2026년 9월 16일 오후 2시 27분부터 41분까지, 한국 시각이에요.
![]()
숫자보다 분모가 먼저예요. 이 글의 수치는 전부 아래 파일에서 나왔어요.
| 파일 | 크기 | 서버가 밝힌 수정 시각 |
|---|---|---|
o200k_base.tiktoken | 3,613,922바이트 | 2024년 5월 13일 17시 GMT |
cl100k_base.tiktoken | 1,681,126바이트 | 2022년 12월 14일 23시 22분 53초 GMT |
r50k_base.tiktoken | 835,554바이트 | 2022년 12월 15일 0시 29분 19초 GMT |
tiktoken 저장소 openai_public.py | 5,613바이트 | main 브랜치 |
tiktoken 저장소 model.py | 3,909바이트 | main 브랜치 |
HuggingFace 공개 tokenizer.json | 6종 | 아래 6절 |
| OpenAI 요금 문서 | 580,923바이트 | 조회 당일 |
| Anthropic 요금 문서 | 915,533바이트 | 조회 당일 |
내려받은 파일이 진짜 그 사전인지부터 확인해야 했어요. 다행히 tiktoken 저장소의 소스코드 안에 각 사전의 sha256 값이 expected_hash 라는 이름으로 박혀 있어요. 받은 파일 셋의 해시를 64자리 전부 대조했더니 전부 완전히 일치했어요. o200k_base 의 값은 446a9538 으로 시작하는 그 문자열이에요.
이 대조가 이 조사에서 제일 중요한 부분이에요. 숫자가 맞다 틀리다 이전에, 내가 센 파일이 남이 받을 파일과 같은 파일이라는 게 먼저 정해져야 하니까요.
두 가지를 각각 다르게 셌어요. 칸을 세는 일과 글자를 넣어 보는 일은 별개거든요.
칸을 셀 때는 각 칸을 UTF-8 로 풀어서, 맨 앞 공백 하나만 떼고(토큰은 보통 앞에 공백을 달고 있어요) 남은 글자가 전부 한 문자 종류일 때만 그 종류로 셌어요. 종류가 섞인 칸은 어느 쪽에도 안 넣었고요. 그래서 종류별 칸을 다 더해도 전체 칸이 되지 않아요. o200k_base 는 1,562칸이 UTF-8 로 풀리지도 않아요. 글자가 아니라 바이트 조각인 칸이에요.
글자를 넣어 볼 때는 각 사전의 실제 병합 규칙을 그대로 돌렸어요. 분모는 유니코드 완성형 한글 음절 11,172자 전수예요. 표본이 아니라 전부고, 옛한글 자모와 호환 자모는 뺐어요.
각도도 한 줄 갈라 둘게요. 토큰을 줄이는 요령 쪽은 GPT 새 토크나이저 토큰 절감 팁에 이미 정리해 뒀어요. 그 글은 마지막에 「정확한 값은 tiktoken 으로 본인 텍스트를 직접 재보는 게 가장 확실하다」고 적어 뒀는데, 이 글이 그걸 대신 해 본 관측이에요.
제목이 약속한 677부터 갈라 놓을게요. OpenAI 가 공개한 사전은 셋이고, 같은 한글 11,172자를 넣어도 답이 이렇게 달라요.
| 사전 | 매핑된 모델 접두 | 전체 칸 | 1토큰 | 2토큰 | 3토큰 | 낱글자 평균 |
|---|---|---|---|---|---|---|
r50k_base | GPT-3 초기 모델(davinci, curie, babbage, ada) | 50,256 | 0 | 266 | 10,906 | 2.9762 |
cl100k_base | gpt-4- 접두, gpt-3.5-turbo- 접두 | 100,256 | 129 | 4,263 | 6,780 | 2.5953 |
o200k_base | gpt-4o- 접두, gpt-4.1- 접두, gpt-5 접두 | 199,998 | 677 | 7,135 | 3,360 | 2.2402 |
세 줄 모두 1토큰과 2토큰과 3토큰을 더하면 11,172가 돼요. 이 세 사전에서 4토큰 이상으로 떨어지는 한글 낱글자는 없었어요.
비율로 옮기면 r50k_base 는 0.00%, cl100k_base 는 1.15%, o200k_base 는 6.06%예요. 사전 칸이 두 배로 늘어나는 동안 한 토큰으로 끝나는 한글은 129자에서 677자로 늘었어요.
이 매핑은 제가 지어낸 게 아니라 tiktoken 저장소의 model.py 에 그대로 적혀 있어요. 표에서 여섯 줄만 축자로 옮기면 이래요.
"gpt-5": "o200k_base",
"gpt-4.1-": "o200k_base",
"gpt-4o-": "o200k_base",
"gpt-4-": "cl100k_base",
"gpt-3.5-turbo-": "cl100k_base",
"gpt-oss-": "o200k_harmony",
같은 파일의 99행부터 100행까지가 매칭 방식을 정해요. 모델 이름이 저 접두로 시작하는지를 보는 접두 일치예요. 그래서 gpt-5.5 도 gpt-5 접두에 걸려 o200k_base 로 가요.
여기서 두 가지를 더 갈라 둘게요.
첫째, 이건 tiktoken 저장소가 적어 둔 표예요. OpenAI 가 실제 서비스에서 어떤 사전을 쓰는지를 이 표가 확정해 주지는 않아요. 이 글은 「표에는 이렇게 적혀 있다」까지만 주장해요.
둘째, 이 표를 「최신 GPT 전부」로 넓히면 틀려요. OpenAI 요금 문서 원문에는 gpt-6-astra 같은 이름이 이미 올라와 있는데, gpt-6 은 위 접두 어디에도 걸리지 않아요. 표에 적힌 접두까지만 읽는 게 맞아요.
셋째로 하나 더. r50k_base 를 「davinci 계열」이라고 뭉뚱그리면 안 돼요. 같은 파일 안에서 davinci 와 curie 와 babbage 와 ada 는 r50k_base 지만, text-davinci-002 와 text-davinci-003 은 p50k_base 고, davinci-002 는 cl100k_base 예요. 이름 한 마디가 사전 세 개에 걸쳐 있어요.
낱글자 성적이 왜 저렇게 갈리는지는 칸 배분을 보면 짐작이 가요. 아래는 각 사전의 칸을 문자 종류로 나눠 센 값이에요.
| 사전 | 전체 칸 | 한글 칸 | 알파벳 칸 | 가나 | 한자 | 키릴 |
|---|---|---|---|---|---|---|
o200k_base | 199,998 | 2,338 | 105,898 | 693 | 7,080 | 14,068 |
cl100k_base | 100,256 | 281 | 68,695 | 160 | 832 | 729 |
r50k_base | 50,256 | 0 | 46,893 | 126 | 42 | 17 |
| Qwen3-8B | 151,643 | 3,473 | 68,923 | 1,518 | 25,061 | 4,122 |
| DeepSeek-V3 | 128,000 | 1,120 | 63,925 | 730 | 35,185 | 5,251 |
| EXAONE-3.5 | 102,400 | 34,039 | 59,439 | 712 | 2,098 | 468 |
| kanana-nano | 128,000 | 2,236 | 71,202 | 913 | 4,132 | 6,423 |
r50k_base 의 한글 칸이 0이라는 게 눈에 띄어요. 낱글자 1토큰이 0자였던 이유가 이거예요. 한글이 통째로 들어간 칸이 아예 없으니 모든 한글 글자가 바이트 조각으로만 표현돼요.
o200k_base 안에서 제일 선명한 대비는 이 자리예요. 키릴 문자만으로 된 칸이 14,068개인데 한글만으로 된 칸은 2,338개예요. 배수로 6.0배(정확히는 6.017배)고, 한자 칸 7,080개와 비교해도 한글이 3.0배 적어요.
왜 이렇게 배분됐는지는 이 조사가 모르는 부분이에요. 학습 데이터 비중 때문이라는 설명이 흔하지만 제가 확인한 건 아니에요. 확인된 건 칸이 몇 개냐까지예요.
다만 그 자리에 대한 언급이 사전을 정의한 파일 안에 남아 있긴 해요. openai_public.py 의 101행부터 103행까지, o200k_base 정의 안쪽, 사전분할 정규식 바로 위에 이런 주석이 붙어 있어요. 「이 정규식은 더 효율적으로 만들 수 있었다」로 시작해서 「언어들 사이에 토큰을 더 효율적으로 배분할 수 있다고 생각한다」로 끝나요.
이건 회사 공식 입장문이 아니라 저장소 안의 코드 주석이에요. 그 차이는 지켜서 읽어야 해요.
표에서 튀는 줄은 EXAONE-3.5 예요. 사전 102,400칸 중 34,039칸을 한글에 줘요. 비율로 33.24%니까 사전의 3분의 1이에요.
그런데 낱글자 성적으로 가면 순위가 뒤집혀요. 한글 낱글자를 1토큰으로 끝내는 글자 수는 Qwen3-8B 가 2,512자로 EXAONE-3.5 의 1,399자보다 많아요. 칸 수 1위와 낱글자 1위가 다른 모델이에요.
이유는 칸의 길이에 있어요. 같은 사전 안에서 한 칸에 들어가는 글자 수를 재 보면 이래요.
| 사전 | 한글 칸 평균 글자수 | 한글 칸 최장 | 알파벳 칸 평균 글자수 | 알파벳 칸 최장 |
|---|---|---|---|---|
o200k_base | 1.62 | 7 | 5.77 | 26 |
cl100k_base | 1.25 | 3 | 6.02 | 36 |
| Qwen3-8B | 1.27 | 5 | 6.02 | 36 |
| EXAONE-3.5 | 2.26 | 7 | 5.98 | 21 |
| kanana-nano | 1.62 | 5 | 5.98 | 36 |
EXAONE-3.5 의 한글 칸은 평균 2.26글자예요. 낱글자보다 낱말 통째에 칸을 썼다는 뜻이에요. 그래서 낱글자를 하나씩 넣는 이 시험에서는 Qwen3-8B 에 밀리고, 뒤에 나올 낱말 시험에서는 앞서요. 두 지표를 같은 줄로 읽으면 틀려요.
그리고 어느 표에서도 확인하지 않은 게 하나 있어요. 답변 품질이에요. 토큰이 적게 든다는 사실과 한국어를 잘 다룬다는 평가는 다른 이야기고, 이 조사는 뒤쪽을 전혀 재지 않았어요.
이 절이 677이라는 숫자가 어디서 나오는지를 보여 주는 자리예요. 한글 칸 2,338개를 글자 수로 나누면 이렇게 돼요.
| 글자 수 | 앞 공백 없는 칸 | 앞 공백 붙은 칸 | 합 |
|---|---|---|---|
| 1글자 | 677 | 443 | 1,120 |
| 2글자 | 387 | 646 | 1,033 |
| 3글자 | 41 | 106 | 147 |
| 4글자 | 12 | 20 | 32 |
| 5글자 | 2 | 3 | 5 |
| 7글자 | 0 | 1 | 1 |
| 합 | 1,119 | 1,219 | 2,338 |
맨 윗줄 왼쪽 칸의 677이 제목의 677이에요. 앞에 공백이 붙지 않은 한글 한 글자짜리 칸이 677개라서, 그 677자를 단독으로 넣으면 1토큰으로 끝나요.
표본을 조금만 보이면 이런 글자들이에요.
가각간갈감갑값강같개객거건걸검겁것게겠겨격견결겼경계고곡곤골곳공과관광괴교구국군굴궁권귀규균그극근글금급기긴길김
까깔깨꺼께껴꽃꾸꿈끄끌끔끝끼낌나난날남납났내낸낼냈냐냥너널넘네넷녀녁년념녕노논놀농높놓누눈뉴느는늘능니닉닌님닝
표에서 4글자와 5글자와 7글자 칸을 다 더하면 38개예요. 전수로 옮기면 이게 전부예요.
가나다라마바사 가능합니다 감사합니다 같습니다 개인정보 것입니다 겠습니다 녕하세요 다운로드
대상으로 대한민국 데이터를 되었습니다 드립니다 때문이다 라마바사 바랍니다 사람들이 사용하는
서비스를 않습니다 았습니다 업데이트 없습니다 었습니다 였습니다 예정이다 오프화이트 있습니다
제공합니다 출장안마 프로그램 프로젝트 프화이트 하십시오 해주세요 했습니다 홈페이지
이 목록을 보면 사전이 어떻게 만들어졌는지가 조금 보여요. 출장안마 같은 스팸 낚시 문구가 한 칸을 차지하고 있고, 오프화이트 는 의류 브랜드 이름이에요. 그리고 프화이트 와 라마바사 와 녕하세요 는 온전한 낱말이 아니라 잘린 조각이에요. 사람이 골라 넣은 목록이 아니라 자료에서 자주 붙어 다닌 조각이 올라온 결과라는 뜻이에요.
앞 공백이 붙은 형태와 안 붙은 형태를 둘 다 뒤졌는데, 다음 낱말들은 o200k_base 안에 한 칸으로 들어 있지 않았어요.
인공지능 · 안녕 · 블로그 · 한국어
출장안마 는 공백 없는 형태로 사전에 있는데 인공지능 은 어느 형태로도 없어요. 이 대비가 칸 배분이 사람의 판단이 아니라는 걸 가장 잘 보여 주는 자리라고 봐요.

낱글자 전수는 분모가 명확하지만 실제로 쓰는 글과는 거리가 있어요. 그래서 낱말과 문장으로도 재 봤는데, 여기서부터는 전수가 아니라 제가 고른 목록이에요. 통계 표본이 아니라는 뜻이에요.
고른 기준은 하나예요. 띄어쓰기가 없는 낱말 하나만 골랐어요. 그래야 분할 규칙이 흔들리지 않거든요.
| 한국어 낱말 | r50k_base | cl100k_base | o200k_base | EXAONE-3.5 |
|---|---|---|---|---|
| 인공지능 | 11 | 4 | 3 | 2 |
| 자동화 | 9 | 3 | 2 | 2 |
| 블로그 | 9 | 3 | 2 | 1 |
| 프롬프트 | 12 | 7 | 4 | 3 |
| 데이터 | 8 | 2 | 2 | 1 |
| 마케팅 | 9 | 7 | 2 | 1 |
| 요금제 | 9 | 4 | 3 | 2 |
| 한국어 | 8 | 4 | 2 | 1 |
| 개발자 | 9 | 4 | 3 | 2 |
| 생산성 | 9 | 3 | 3 | 2 |
| 이미지 | 8 | 3 | 2 | 1 |
| 파이썬 | 8 | 6 | 4 | 2 |
| 크롤러 | 9 | 4 | 3 | 3 |
| 검색엔진 | 12 | 6 | 3 | 2 |
| 수익화 | 8 | 4 | 3 | 3 |
| 콘텐츠 | 9 | 9 | 2 | 2 |
| 사용량 | 8 | 4 | 2 | 2 |
| 안녕하세요 | 14 | 5 | 2 | 3 |
| 감사합니다 | 11 | 4 | 3 | 2 |
| 구독 | 6 | 3 | 2 | 2 |
| 합계(66글자) | 186 | 89 | 52 | 39 |
같은 66글자가 사전에 따라 186토큰에서 39토큰까지 갈려요. 그리고 여기서는 EXAONE-3.5 가 앞서요. 앞 절에서 낱글자로는 Qwen3-8B 에 밀렸는데, 낱말 칸에 투자한 결과가 이 표에서 나타나요.
대조군으로 영어 낱말 20개도 같이 넣었어요. 168글자였고 o200k_base 에서 29토큰이었어요. 대부분 1토큰이고, blog 와 data 와 image 와 python 과 content 와 usage 여섯 개는 이 조사가 연 사전 일곱 곳(r50k_base · cl100k_base · o200k_base · Qwen3-8B · DeepSeek-V3 · EXAONE-3.5 · kanana-nano) 전부에서 1토큰이었어요.
글자당으로 옮기면 o200k_base 기준 한글은 글자당 0.788토큰, 영어는 글자당 0.173토큰이에요. 배수로 4.56배고요.
이 4.56이라는 숫자에는 조건을 두 개 달아야 해요. 첫째, 제가 고른 낱말 목록에서 나온 값이에요. 둘째, 영어 쪽 목록에는 artificialintelligence 처럼 붙여 쓴 말이 세 개 있어요. 자연스러운 영어 문장이 아니라 낱말 대조용으로 만든 목록이라는 뜻이에요.
같은 내용을 담은 문장 한 쌍도 넣어 봤어요. 분할 규칙이 흔들리지 않게 문장부호는 뺐어요.
인공지능 모델에 한국어로 질문하면 같은 내용이라도 토큰이 더 많이 들어갑니다when you ask an artificial intelligence model in korean the same content costs more tokens| 사전 | 한국어 | 영어 | 배수 |
|---|---|---|---|
r50k_base | 93 | 16 | 5.81배 |
cl100k_base | 43 | 16 | 2.69배 |
o200k_base | 22 | 15 | 1.47배 |
글자 수는 영어가 두 배 넘게 많은데 토큰은 한국어가 더 들어가요. 그리고 사전이 커지면서 그 격차가 5.81배에서 1.47배로 줄었어요.
o200k_base 가 저 한국어 문장을 나눈 22개를 그대로 펼치면 이래요. 따옴표는 앞에 공백이 붙은 토큰을 표시한 거예요.
인 / 공지 / 능 / ' 모델' / 에 / ' 한국' / 어 / 로 / ' 질문' / 하면 / ' 같은' /
' 내용' / 이라 / 도 / ' 토' / 큰 / 이 / ' 더' / ' 많이' / ' 들어' / 갑 / 니다
인공지능 이 인 과 공지 와 능 세 조각으로 나뉘고, 토큰 이라는 낱말조차 토 와 큰 으로 쪼개져요. 앞 절에서 본 「인공지능 은 한 칸을 못 받았다」가 문장에서는 이렇게 나타나는 거예요.
한편 Gemini 쪽은 사전 파일이 공개돼 있지 않아서 이 방법으로는 잴 수 없어요. 그 대신 API 응답값으로 잰 기록은 한국어 토큰 수 실측에 따로 적어 뒀어요. 잰 층이 다르니 두 글의 숫자를 섞어 쓰면 안 돼요. 그 글은 API 가 돌려준 값이고, 이 글은 사전 파일 자체예요.
같은 11,172자를 위 세 사전 밖의 사전 6종에도 넣어 봤어요. 파일이 공개돼 있어 승인 없이 받을 수 있는 것만 골랐어요.
| 사전 | 만든 곳 | 전체 칸 | 1토큰 | 2토큰 | 3토큰 | 낱글자 평균 |
|---|---|---|---|---|---|---|
| Qwen3-8B | 알리바바 | 151,643 | 2,512 | 8,596 | 64 | 1.7809 |
| EXAONE-3.5 | LG AI연구원 | 102,400 | 1,399 | 9,068 | 705 | 1.9379 |
| kanana-nano | 카카오 | 128,000 | 599 | 7,218 | 3,355 | 2.2467 |
| DeepSeek-V3 | 딥시크 | 128,000 | 392 | 6,190 | 4,590 | 2.3758 |
| Phi-4 | 마이크로소프트 | 100,352 | 129 | 4,263 | 6,780 | 2.5953 |
| gpt-oss-20b | OpenAI 공개 모델 | 199,998 | 677 | 7,135 | 3,360 | 2.2402 |
아래 두 줄이 이상하지 않으세요. Phi-4 의 네 숫자가 앞에서 본 cl100k_base 와 소수점까지 같고, gpt-oss-20b 는 o200k_base 와 똑같아요. 우연이 아니라서 칸을 바이트 단위로 집합 비교해 봤어요.
| 비교 | 결과 |
|---|---|
o200k_base(199,998칸) 대 gpt-oss-20b(199,998칸) | 양쪽 차집합이 둘 다 0칸. 완전히 같음 |
cl100k_base(100,256칸) 대 Phi-4(100,352칸) | 한쪽 차집합 0칸, 다른 쪽 96칸이고 전부 특수 표식 자리 |
즉 마이크로소프트 Phi-4 의 사전은 cl100k_base 에 특수 표식 96칸을 더 얹은 것이에요. 한글 낱글자 성적이 GPT-4 세대와 소수점까지 같았던 이유가 이거고요.
gpt-oss-20b 쪽은 표현을 한 번 정확히 해야 해요. model.py 의 매핑은 gpt-oss- 접두를 o200k_harmony 로 보내요. o200k_base 와 같은 것은 사전 전체가 아니라 병합표예요. openai_public.py 에서 o200k_harmony 정의를 보면 o200k_base 를 불러서 그 병합표를 그대로 가져다 쓰고, 특수 토큰만 더 얹어요. 그러니까 「같은 사전을 쓴다」가 아니라 「병합표를 그대로 재사용한다」가 맞는 표현이에요.
조사 보고니까 검증 과정도 적을게요. 이 글의 수치는 두 번 흔들어 봤어요.
사전분할로 나뉜 덩어리 안에서, 사전에 있는 조각들로 그 바이트열을 덮는 가장 적은 조각 수를 동적계획법으로 따로 구했어요. 병합 방식은 탐욕적이라 이 최솟값보다 적게 나올 수가 없어요. 둘이 같으면 그 값이 곧 정답이라는 뜻이고요.
| 검증 항목 | 결과 |
|---|---|
한글 11,172자와 r50k_base | 11,172 / 11,172 일치 |
한글 11,172자와 cl100k_base | 11,172 / 11,172 일치 |
한글 11,172자와 o200k_base | 11,172 / 11,172 일치 |
낱말 40개와 cl100k_base | 40 / 40 일치 |
낱말 40개와 o200k_base | 40 / 40 일치 |
| 알파벳 a 부터 z 까지 26자, 사전 9종 | 전부 1토큰 |
여기서 넓히면 틀리는 자리가 하나 있어요. 「병합 방식은 항상 최적이다」로 읽으면 안 돼요. 영어 실문서 한 편을 통째로 넣었더니 o200k_base 기준 조각 2개, cl100k_base 기준 5개가 최솟값보다 많이 나왔어요. 확인된 건 이 글이 잰 낱글자와 낱말에서는 최솟값과 같았다까지예요.
o200k_base 는 tiktoken 형식 파일을 tiktoken 식으로, gpt-oss-20b 는 HuggingFace JSON 을 그쪽 방식으로 돌렸어요. 형식도 코드도 다른데 11,172자 결과가 677과 7,135와 3,360으로 한 자리도 안 틀리고 같았어요.
마지막으로 격리된 가상환경에 공식 라이브러리를 따로 설치해 제3의 정답지로 대조했어요. 677과 7,135와 3,360과 2.2402, cl100k_base 의 129와 2.5953, 낱말 표의 52와 29, 문장의 22와 15가 전부 같았어요.
숨기면 안 되는 자리가 있어요. 교차검증용으로 영어 실문서 한 편을 통째로 넣어 봤는데, 처음 얻은 값이 틀렸어요. 다시 재고 공식 라이브러리로 확인한 값은 o200k_base 기준 2,262토큰, 글자 수로 옮기면 5.02자당 1토큰이에요.
원인은 사전 병합이 아니라 그 앞 단계였어요. 긴 글은 병합 전에 정규식으로 먼저 덩어리를 나누는데, 그 나누기를 직접 구현하면서 앞쪽 공백 처리가 샌 거예요. 같은 파일을 공식 라이브러리에 넣으면 2,262가 나와요.
그런데 이 오류가 이 글의 헤드라인 수치는 건드리지 못해요. 이유가 명확해요. 낱글자 하나와 띄어쓰기 없는 낱말 하나는 어떤 분할 규칙에서도 조각이 1개거든요. 나눌 자리가 없으니 그 앞 단계가 관여할 수 없어요. 677과 2,338과 105,898은 전부 그 층에서 나온 값이라 흔들리지 않아요.
반대로 말하면, 긴 글을 직접 재실 생각이라면 이 앞 단계까지 정확히 맞춰야 해요. 제가 밟은 자리가 거기예요.

이 절이 이 글에서 제일 중요한 부분일 수도 있어요. 위 숫자를 어디까지 들고 갈 수 있는지가 여기서 정해지거든요.
요금표는 이 조사의 출발점이었지만 도착점은 아니에요. 확인한 것과 확인하지 못한 것을 갈라 둘게요.
확인한 건 요금 단위예요. Anthropic 요금 문서의 표는 입력과 출력, 캐시 쓰기와 캐시 적중을 열로 나눠 두었고 단위가 전부 100만 토큰이에요. OpenAI 요금 문서에도 100만 토큰 단위라는 문장이 그대로 있어요. 두 요금표 어디에도 언어를 가르는 칸은 없어요.
확인하지 못한 건 실제 청구액이에요. 「토큰이 몇 배면 요금도 몇 배」는 입력 토큰만 놓고 하는 산술이고, 출력과 캐시와 컨텍스트 구간은 이 조사가 보지 않았어요. 같은 질문에 모델이 내놓는 답변 길이도 안 쟀고요.
Claude 쪽은 한 칸도 재지 못했어요. Anthropic 은 토크나이저 파일을 공개하지 않아서 이 방법이 통하지 않거든요. 예전에 Claude 토크나이저와 비용에서 「어휘 사전이 영어 위주로 짜이면 한국어는 토큰이 늘어나는 쪽으로 기운다」고 적어 둔 적이 있는데, 그 문장에 숫자를 붙일 수 있는 범위는 파일이 공개된 사전까지예요.
o200k_base 파일의 서버 표기 수정 시각은 2024년 5월 13일이고, 확인한 건 tiktoken 저장소의 매핑 표가 그렇게 적어 뒀다는 것까지예요.낱글자는 유니코드 완성형 한글 음절 11,172자 전수고, 칸 수는 파일에 실제로 들어 있는 줄 수예요. 문자 종류별 칸은 앞 공백 하나만 떼고 나머지가 전부 그 종류일 때만 셌기 때문에 종류별 칸을 다 더해도 전체 칸이 되지 않아요.
그리고 낱말 20쌍과 문장 한 쌍은 제가 고른 목록이에요. 이 둘에서 나온 4.56배와 1.47배는 목록이 바뀌면 값도 바뀌어요. 전수로 셌다고 말할 수 있는 건 낱글자 11,172자와 사전 칸 배분, 이 두 가지뿐이에요.
사전마다 달라서 하나로 답할 수 없어요. 이 글이 잰 조건은 한글 낱글자를 다른 글자 없이 단독으로 넣었을 때예요. 그 조건에서 o200k_base 는 평균 2.2402토큰, cl100k_base 는 2.5953토큰, r50k_base 는 2.9762토큰이었어요. 조건이 바뀌면 값도 바뀌어요. 낱글자가 아니라 낱말로 넣으면 같은 o200k_base 에서도 글자당 0.788토큰으로 떨어지니, 낱글자 평균을 글 전체 길이에 곱하면 과장이 돼요.
아니에요. 677자는 o200k_base 사전에서만 나오는 값이에요. tiktoken 저장소의 매핑 표를 기준으로 하면 이 사전은 gpt-4o 와 gpt-4.1 접두, gpt-5 접두, o1 과 o3 과 o4-mini 에 연결돼 있어요. 반면 gpt-4 접두와 gpt-3.5-turbo 접두는 cl100k_base 로 연결되고 거기서는 129자예요. 그러니까 가장 널리 알려진 GPT-4 에서는 677이 아니라 129예요. 이 글이 제목에 사전 세대를 적어 둔 이유가 그거예요.
이 조사가 연 사전 9종에서는 그랬어요. 조건은 소문자 a 부터 z 까지 26자를 각각 단독으로 넣었을 때예요. 스크립트 안에서 assert 로 검사했고 9종 전부 통과했어요. 다만 대문자나 특수문자, 낱글자가 아닌 조합까지 확인한 것은 아니에요. 그리고 이 조사가 열지 못한 사전이 따로 있어요. 승인 절차가 걸린 저장소 세 곳은 파일을 받지 않았어요.
이 조사는 실제 청구액을 재지 않았어요. 확인한 것은 두 가지까지예요. 하나는 토큰으로 값을 매기는 모델의 단위가 100만 토큰 하나이고 언어를 가르는 칸이 없다는 것, 다른 하나는 같은 내용을 담은 문장 한 쌍에서 한국어가 22토큰, 영어가 15토큰이었다는 것이에요. 입력 토큰만 놓고 산술하면 그 비율만큼 차이가 나겠지만, 출력과 캐시와 컨텍스트 구간은 이 조사가 보지 않았어요.
한 칸도 재지 못했어요. 두 회사 모두 토크나이저 파일을 공개하지 않기 때문이에요. 이 조사가 연 것은 파일이 공개된 사전 9종뿐이에요. Anthropic 쪽에서 확인한 것은 요금표의 단위가 100만 토큰이라는 표기까지이고, Gemini 쪽은 별도의 API 로 토큰을 세는 방식이라 그 층은 다른 글에서 따로 다뤘어요. 이 글의 수치를 두 회사 모델에 옮겨 쓰면 근거가 없는 주장이 돼요.
그렇게 읽으면 두 가지가 섞여요. 확인된 것은 사전 칸 배분과 낱글자 토큰 수까지예요. 칸 수로는 EXAONE-3.5 가 102,400칸 중 34,039칸을 한글에 줘서 1위지만, 낱글자를 1토큰으로 끝내는 글자 수로는 Qwen3-8B 가 2,512자로 더 많아요. 두 지표가 같은 방향이 아니라는 뜻이에요. 그리고 답변 품질은 이 조사가 전혀 재지 않았으니, 토큰이 적게 든다는 사실을 좋은 모델이라는 결론으로 옮기면 안 돼요.
거기까지는 확인하지 못했어요. 확인한 것은 두 가지예요. 하나는 tiktoken 저장소의 매핑 표에 어떤 모델 접두가 어떤 사전에 연결된다고 적혀 있는지이고, 다른 하나는 내려받은 사전 파일의 서버 표기 수정 시각이 2024년 5월 13일이라는 점이에요. 저장소가 그렇게 적어 뒀다는 것과 회사가 실제 서비스에서 그 파일을 쓴다는 것은 다른 주장이라, 이 글은 앞쪽까지만 적어요.
사전 파일 자체를 받아도 되고 공식 라이브러리를 써도 돼요. 이 조사는 API 키 없이 공개된 사전 파일만 내려받아 셌고, 검증 단계에서만 격리된 가상환경에 공식 tiktoken 을 설치해 대조했어요. 다만 조건을 하나 붙여야 해요. 낱글자와 띄어쓰기 없는 낱말은 어떤 구현에서도 결과가 같지만, 띄어쓰기와 문장부호가 섞인 긴 글은 사전분할 규칙까지 정확히 맞춰야 값이 맞아요. 이 글의 조사에서도 그 자리에서 한 번 값이 틀어졌어요.