-
책 한 권을 AI 스킬로 컴파일할 때 성패는 정규식 한 줄이 정한다 — 한국어 '제N장'이 들어가기까지IT 2026. 8. 14. 21:00

▶ 동영상 개요 — 한국어 '제N장'이 들어가기까지
5분 53초 — 챕터 감지가 왜 이 도구의 급소인지 훑는다 — NotebookLM 동영상 개요로 생성 기술서 PDF 한 권을 코딩 에이전트가 곧바로 참조할 수 있는 스킬(skill)로 바꿔 주는 오픈소스가 있다. 스킬은 에이전트에게 "이런 상황에는 이렇게 하라"고 알려 주는 지침 파일 묶음이다. 2026년 5월 1일에 공개된 이 도구는 석 달 만에 별 15,007개, 포크 1,617개를 모았다(2026년 8월 2일 기준). 나도 서가에 꽂힌 한글 기술서를 하나 넣어 볼 생각으로 저장소를 열었다가 그 자리에서 멈칫했다.
이 도구가 한국어 책의 "제3장"을 챕터로 알아볼까? 국내에 올라온 소개 글들은 대부분 5월 버전을 다루고 있어서 답이 없었다. 저장소의 커밋을 거슬러 올라가 보니 답은 의외로 최근에 생겨 있었다 — 한국어 챕터 감지는 2026년 7월 30일 릴리스에 들어갔다. 그리고 그 한 줄짜리 정규식을 들여다보면서, 나는 이 도구의 진짜 급소가 어디인지 알게 됐다.
이 도구가 하는 일 — 검색이 아니라 컴파일이다
다이어그램 설명. 책 한 권이 스킬로 바뀌는 전 과정이다. "기술서 PDF·EPUB"에서 출발해 텍스트를 뽑고, 챕터 경계를 찾고, 그 단위로 내용을 증류해 두 종류의 파일로 떨어뜨린다. 핵심은 마지막 두 상자의 관계다 — "SKILL.md"는 책의 지도에 해당해서 에이전트가 항상 들고 있고, "chapters/"의 개별 파일은 그 주제를 실제로 물어봤을 때만 읽힌다. 이 구조가 이 도구의 존재 이유다. 400쪽짜리 책을 통째로 대화창에 붙이면 20만 토큰이 매 턴 소모되지만, 이렇게 쪼개 두면 지도 4천 토큰에 필요한 챕터 하나 천 토큰만 얹으면 된다. 제작자는 이 차이를 "질문 하나당 24~51배 절감"으로 표현했는데, 다만 이 수치는 한 번의 탐색 과정을 모델링한 값이지 여러 세션에 걸친 실측이 아니라고 저장소 스스로 밝혀 두었다. 눈여겨볼 대목은 따로 있다. 이 방식은 질문이 들어올 때 문서를 뒤지는 검색(RAG)이 아니라, 미리 한 번 깊게 읽어서 구조로 굳혀 두는 컴파일에 가깝다.
그래서 챕터 감지가 급소다
위 그림에서 "챕터 감지" 상자는 가운데 낀 평범한 전처리 단계처럼 보인다. 실제로는 이 상자가 결과물의 골격을 통째로 결정한다. 챕터 경계가 곧 파일 분할 단위이고, 파일 분할 단위가 곧 on-demand 로딩 단위이기 때문이다. 여기서 경계를 잘못 그으면 아래 두 단계가 아무리 정확해도 쓸모없는 스킬이 나온다.
이 도구는 챕터를 찾을 때
Chapter 1,Kapitel 3같은 명시적 heading 정규식을 먼저 돌린다. 그게 하나도 안 걸리면 문서 구조를 어림잡는 추정 로직으로 넘어간다. 이 이중 구조가 실패의 방향을 둘로 갈라놓는다.다이어그램 설명. 정규식이 걸리느냐 아니냐가 결과를 가른다. "걸림" 쪽으로 가면 책의 실제 챕터 수가 그대로 나오지만, "안 걸림" 쪽으로 빠지면 추정 로직이 대신 판단하면서 두 갈래의 사고가 일어난다. 흥미로운 건 정규식이 못 잡은 대가가 반드시 "적게 잡음"으로 나타나지는 않는다는 점이다. 오히려 과다검출로 폭발하는 경우가 흔하다 — 명시적 매처가 침묵하면 fallback이 문서의 모든 소제목을 챕터 후보로 세기 시작하기 때문이다. 함정은 여기다. 두 실패 모두 에러를 내지 않는다. 파이프라인은 조용히 끝까지 돌고, 이상한 스킬이 나온 뒤에야 알아차리게 된다.
실제로 터진 두 사고
추상적인 이야기가 아니다. 이 저장소의 이슈 트래커에 두 방향의 사고가 각각 재현 리포트와 함께 올라와 있다.
과다검출 쪽. 한 사용자가 535쪽짜리 기술서를 같은 도구에 두 가지 모드로 넣고 비교한 결과를 올렸다. 표·코드 블록을 보존하는 정밀 추출 모드에서 챕터가 355개로 잡혔다. 실제 챕터는 10개였고, 빠른 텍스트 모드에서는 정확히 10개가 나왔다. 원인은 허무할 만큼 단순했다. 정밀 모드는 추출 결과를 마크다운으로 내놓기 때문에 heading이
## Chapter 1형태가 되는데, 정규식이 줄 시작(^)에chapter를 기대하고 있어서 앞에 붙은##두 글자에 전부 빗나간 것이다. 목차를 찾는 별도 정규식도 같은 이유로## Table of Contents를 놓쳤다.과소검출 쪽. 이건 더 얄궂다. 여러 파일을 한 스킬로 묶을 때 추출기가 파일 경계마다
SOURCE:배너를 스스로 끼워 넣는데, 그 배너 줄이 마크다운 문법상 제목 밑줄(setext heading)로 오인돼 챕터로 계산됐다. 파일 하나에서 다섯 챕터를 정확히 찾아 놓고도, 전체 집계에서는 2개로 뭉개졌다. 자기가 만든 텍스트를 자기가 읽고 오판한 셈이다.두 사고를 나란히 놓으면 공통점이 보인다. 둘 다 책이 이상해서가 아니라, 파이프라인 자신이 만든 텍스트나 자신이 고른 추출 모드 때문에 생겼다. 문서 파서를 만들 때 가장 조심해야 할 입력은 외부 문서가 아니라 내가 중간에 끼워 넣은 문자열이라는 이야기다.
한국어가 어려운 이유 — '장'은 너무 흔한 글자다
이제 원래 질문으로 돌아온다. 한국어 챕터를 잡으려면 어떤 정규식을 써야 할까? 순진하게 접근하면
N장을 찾으면 될 것 같다. 그런데 이 패턴은 한국어에서 재앙에 가깝다.본문에 나올 법한 문장 N장으로 잡으면실제 의미 사진 3장을 첨부했다 챕터 3 시작! 종이·사진의 수량 단위 카드 2장이 남았다 챕터 2 시작! 수량 단위 제3장 트랜잭션 챕터 3 시작 진짜 챕터 '장'은 챕터를 뜻하는 한자어이면서 동시에 종이를 세는 가장 흔한 수량 단위다. 영어의
chapter가 문장 한가운데 등장할 일이 드문 것과는 사정이 완전히 다르다. 그래서 이 도구가 택한 해법은제접두사를 선택이 아니라 필수로 거는 것이었다.제N장·제N절·제N편, 그리고 법령 문서에서 쓰는의N형태까지를 인정하되, 앞에제가 없으면 아예 후보로 보지 않는다. 릴리스 노트는 이 패턴을 실제 문헌 묶음으로 검증해 정밀도 0.999, 재현율 1.000을 얻었다고 적고 있다.이 숫자 조합이 이 설계의 성격을 그대로 드러낸다. 재현율(찾아야 할 것을 놓치지 않는 비율)이 1.000이라는 건, 한국어 책이 챕터를 표기하는 방식이
제N장으로 사실상 통일돼 있다는 뜻이다. 정밀도(잡은 것이 진짜인 비율) 0.999는 그럼에도 천 개에 하나꼴로 오탐이 남는다는 뜻이다. 여기서제를 선택 사항으로 풀었다면 재현율은 그대로인데 정밀도만 무너졌을 것이다 — 얻는 것 없이 잃기만 하는 교환이다. 같은 릴리스에 태국어(บทที่ N)와 로마 숫자(Chapter I.)도 함께 들어갔는데, 로마 숫자 지원 덕에 어느 고전 문헌은 가짜 챕터 2개에서 진짜 13개로 바로잡혔다.정리 — anchor를 어디에 걸지가 곧 설계다
이 도구를 뜯어보며 남은 교훈은 정작 AI와 별 상관이 없다. LLM이 책을 얼마나 잘 요약하는가는 이 파이프라인에서 가장 덜 위험한 부분이었다. 진짜 위험은 그 앞단, 한 줄짜리 정규식이 어디에 anchor를 거느냐에 있었다.
^를 너무 빡빡하게 걸면##두 글자에 355개가 터지고,제를 느슨하게 풀면 사진 3장이 챕터가 된다.그래서 나는 이 도구에 한글 기술서를 넣기 전에 할 일을 하나 정했다. 변환이 끝나면 생성된
chapters/폴더의 파일 개수부터 세어 보는 것이다. 목차의 챕터 수와 맞지 않으면 그 스킬은 내용을 읽어 볼 필요도 없이 다시 만들어야 한다. 정규식은 조용히 실패하기 때문에, 조용히 지나가지 않게 만드는 건 결국 쓰는 사람 몫이다.
참고한 공개 자료:
- book-to-skill 저장소 — github.com/virgiliojr94/book-to-skill
- v1.3.0 릴리스 노트 (한국어·태국어·로마 숫자 챕터 감지) — releases/tag/v1.3.0
- 이슈 #91 — 마크다운 프리픽스 heading 미감지로 인한 챕터 355개 과다검출 — issues/91
- 이슈 #81 — 추출기 자체 배너가 제목으로 오인돼 챕터 2개로 붕괴 — issues/81
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
스타 12만 개짜리 프롬프트 뭉치 — gstack 논쟁이 실제로 드러낸 것 (0) 2026.08.15 웹을 읽는 에이전트에 방어막을 씌운다는 것 — 프롬프트 인젝션 6겹 해부 (0) 2026.08.15 gstack을 석 달 방치했더니 — 1.26과 1.60 사이에 늘어난 스킬 9개 (0) 2026.08.15 책을 미리 증류할까, 그때그때 찾을까 — 벡터 DB를 직접 굴려 본 사람이 본 '스킬 컴파일'의 자리 (0) 2026.08.14 책을 스킬로 만드는 순간 PDF는 데이터가 아니라 지시문이 된다 — 문서에서 에이전트로 이어지는 새 공격면 (0) 2026.08.14 RAG를 직접 지을까, 빌릴까 — 자체 벡터 DB 파이프라인과 NotebookLM 백엔드의 트레이드오프 (0) 2026.08.13 API 없는 최고의 RAG — NotebookLM을 코딩 에이전트의 외부 장기로 이식하기 (0) 2026.08.13 '의도대로 만들어졌나'를 자동으로 검증할 수 있을까 — 학계가 디자인 의도를 직접 판정하지 않고 '우회'하는 이유 (0) 2026.08.12 디자인 린트는 무엇을 검증하고 무엇을 놓치나 — 토큰 표준이 안정판에 도달한 뒤에도 남은 것 (0) 2026.08.12 웹은 실행 중인 화면을 열어 볼 수 있다 — '실제 적용된 값'을 대조하는 세 가지 창구 (0) 2026.08.12