이 블로그에는 글이 빠르게 늘고 있다. 코딩 스탠다드(여러 프로젝트에서 코드를 같은 방식으로 짜기 위해 정해 둔 규칙을 설명한 글)가 53편, 그 규칙이 맞는지 작은 프로그램을 만들어 실제로 실행해 본 증명 글이 19편이다. 이 글들은 대부분 AI 프로그램이 나와 대화하며 함께 쓰고 고친다. 그런데 글이 늘수록 이상한 일이 생겼다. AI는 이 글들을 잘 읽고 잘 고치는데, 사람이 읽으면 무슨 말인지 모르겠다는 것이다.

이 글은 그 문제를 어떻게 풀기로 했는지, 그리고 그 결정에 이르기까지 무엇을 버렸는지를 남긴다.

이 결정은 둘이 대화하며 정했다. 글에서 「나」는 이 블로그의 주인인 나(사람)이고, Claude는 나와 함께 여러 해결 방법을 비교한 AI 프로그램이다. 누가 무엇을 제안했는지가 결정의 흐름에서 중요해서 둘을 구분해 적는다. 글에 자주 나오는 「안」은 「제안」의 줄임말로, 문제를 푸는 방법 하나를 말한다. 안이 여럿이면 「안 A」, 「안 B」처럼 이름을 붙여 비교한다. 「대가」는 어떤 안을 골랐을 때 대신 잃는 것이다.


사람이 읽을 수 없는 글은 이렇게 생겼다

예를 하나 보자. 이 블로그의 Domain 영속화 표준 글에 실제로 있는 문장이다. 이 표준은 주문 같은 데이터를 DB(데이터베이스. 데이터를 표 모양으로 오래 보관하는 프로그램)에 저장하는 방법을 정한 글이고, 영속화는 데이터를 DB에 저장해 프로그램이 꺼져도 남게 하는 일을 말한다. 표준 글은 규칙을 「원칙 1」, 「원칙 2」처럼 번호 붙은 덩어리로 나눠 적는데, 아래는 원칙 1에 있는 문장이다. Domain은 이 프로젝트에서 주문 같은 업무 데이터를 담는 자바 객체를 부르는 이름이다.

Domain은 POJO라 toEntity()가 만드는 Entity는 항상 분리(detached) 상태다. 그대로 save()하면 merge가 되고, merge는 분리 인스턴스의 모든 필드를 복사하므로 Domain이 나르지 않는 컬럼이 null로 덮인다.

(이 글을 읽는 데 이 문장의 뜻을 알 필요는 없다. 오히려 뜻을 몰라서 막히는 그 느낌이 이 글이 다루는 문제다.)

이 문장 하나에 뜻을 모르면 막히는 말이 줄줄이 들어 있다. POJO, toEntity(), Entity, 분리(detached) 상태, save(), merge, 필드 복사, 컬럼, null이다. 나는 이 문장을 쓸 때 이미 그 뜻을 다 알고 있었고, 이 글을 읽는 AI도 안다. 그래서 둘에게는 충분하다.

하지만 자바 문법을 막 배운 고등학생이 이 문장을 읽는다고 해 보자. 첫 단어인 POJO에서 막히고, 그 뒤는 읽어도 머리에 남지 않는다. 문장은 짧고 정확한데, 이해하는 데 필요한 중간 단계가 전부 빠져 있다. 이런 글이 수십 편 쌓이고 있었다.


먼저 알아 둘 것 — 이 글에서 여러 번 쓰는 말들

뒤의 결정들이 여러 번 기대는 말만 여기서 한 번씩 푼다. 한 번만 나오는 말은 나오는 자리에서 푼다.

글은 파일이고, 파일은 저장소에 모여 있다

이 블로그의 글 한 편은 마크다운 파일 하나다. 마크다운은 글자에 몇 가지 기호를 섞어 모양을 정하는 글 형식이고, 파일 이름이 .md로 끝난다. 줄 앞에 ##를 붙이면 그 줄이 큰 제목이 된다. 이 글에서 섹션## 제목 하나와 그 아래 다음 제목 전까지의 덩어리를 말한다.

이 파일들은 저장소에 모여 있다. 저장소는 GitHub라는 서비스에 있는, 파일들과 그 파일들이 언제 어떻게 바뀌었는지의 기록을 함께 보관하는 공간이다. 글 파일은 저장소 안의 _posts/ 폴더에 둔다. 글 파일 맨 위에는 제목, 카테고리(글의 분류 이름), 마지막으로 고친 날짜(last_modified_at) 같은 정보를 적는 설정 줄이 있고, 화면에는 본문으로 보이지 않는다.

커밋, 푸시, 사이트 게시

파일을 고치면 먼저 커밋한다. 바뀐 파일들을 한 묶음으로 저장소 기록에 남기는 일이다. 그다음 GitHub에 올리면(푸시) GitHub가 자동으로 마크다운 파일들을 웹 페이지로 바꿔 인터넷에 내건다. 이 글에서는 이걸 사이트 게시라고 부른다.

글의 인터넷 주소는 설정 줄의 카테고리와 파일 이름으로 만들어진다. 카테고리는 소문자가 되고, 파일 이름에서는 앞의 날짜와 끝의 .md가 빠진다. 예를 들어 카테고리가 Plan이고 파일 이름이 2026-09-17-writing-by-reader.md면 주소는 /post/plan/writing-by-reader다. 그래서 카테고리나 파일 이름이 바뀌면 주소가 바뀌고, 옛 주소로 들어오면 「페이지를 찾을 수 없다」는 404 오류가 난다.

에이전트와 글쓰기 규칙 문서

에이전트는 사람 대신 파일을 읽고, 코드를 짜고, 글을 고치는 AI 프로그램이다. 이 저장소에서는 Claude(Anthropic이라는 회사의 AI)와 Codex(OpenAI라는 회사의 AI)를 쓴다.

에이전트는 이 저장소에서 일을 시작할 때 글쓰기 규칙 문서를 먼저 읽는다. Claude는 저장소 맨 위 폴더의 CLAUDE.md를, Codex는 같은 자리의 AGENTS.md를 읽는다. 글을 어떻게 써야 하는지가 여기에 적혀 있다. 이 둘은 이 블로그 저장소에서만 쓰는 문서다.

토큰

AI가 글을 읽고 쓰는 양은 토큰이라는 단위로 센다. 이 블로그 저장소의 도구 프로그램은 한글 한 글자를 약 1.1토큰으로 어림한다. AI를 쓰는 요금과 답이 나오는 시간은 읽고 쓰는 양이 많을수록 대략 늘어난다(정확한 요금 계산 방식까지는 이 글에서 다루지 않는다). 그래서 에이전트가 필요 없는 부분까지 읽지 않게 하는 것이 이 저장소에서 중요한 일이었다.

코딩 스탠다드는 표준 글과 규칙 파일이 한 짝이다

코딩 스탠다드 하나는 두 파일로 되어 있다.

  • 표준 글 — 블로그에 올라가는 글이다. 여러 안을 비교하고 이렇게 정했는지를 적는다
  • 규칙 파일(SKILL.md) — 에이전트가 코드를 짤 때 읽는 파일이다. 「이렇게 한다」처럼 무엇을 할지만 짧은 명령문으로 적는다

규칙 파일은 블로그 저장소 안의 coding-standards/ 폴더에 있다. 이 폴더가 바뀐 채 푸시하면, GitHub의 자동 작업이 이 폴더만 담아 두는 배포용 저장소(coding-standards라는 이름의 별도 저장소)로 복사한다. 그리고 내가 만드는 다른 자바 프로젝트들은 거기서 규칙을 받아 설치한다. 이 글에서는 이걸 규칙 배포라고 부른다. 사이트 게시와는 다른 일이다.

증명 글과 인용 줄

표준 글에는 「이렇게 하면 이런 일이 생긴다」 같은 주장이 들어 있다. 증명 글은 그 주장이 맞는지 작은 프로그램을 실제로 실행해 보고 결과를 적은 글이다. 표준 글은 증명 결과를 인용 줄 한 줄로 가져온다.

> 실측(supported): 결과 요약 — [증명](링크)

「실측」은 직접 재 본 결과라는 뜻이고, supported는 「주장이 맞았다」는 판정이다. [증명](링크)는 「증명」이라는 글자를 누르면 증명 글로 가는 링크다.

검사 프로그램은 언제 도는가

이 저장소에는 규칙이 지켜졌는지 확인하는 검사 프로그램들이 있다. 예를 들어 짝 검사는 「규칙 파일마다 짝이 되는 표준 글이 있는가」를 파일 이름으로 맞춰 본다.

  1. 커밋할 때 자동으로 돈다. 걸리면 터미널(명령을 입력하고 결과를 글자로 보는 창)에 경고를 찍지만, 커밋은 그대로 된다
  2. 규칙 배포 직전에 한 번 더 돈다. 여기서는 하나라도 실패하면 규칙 배포가 멈춘다. 이 검사는 규칙 배포 작업의 첫 단계다. 그래서 coding-standards/ 폴더가 바뀐 푸시에만 돈다. 글만 고친 푸시에서는 사이트 게시만 일어나고, 이 검사는 돌지 않는다

검사가 없어서 틀린 상태가 그대로 나가 버리는 것을 이 저장소에서는 「새어 나갔다」고 부른다.


처음 생각한 원인은 섹션 길이 제한이었다

CLAUDE.md에는 「섹션 하나가 너무 길어지면 쪼갠다」는 규칙이 있다.

이 규칙이 생긴 이유가 있다. 코딩 스탠다드의 표준 글은 에이전트가 코드를 짜다가 「이 규칙은 왜 이렇게 정했지?」 하고 찾아 읽는 글이다. 이때 에이전트는 파일을 처음부터 열지 않는다. 표준 글이 53편이라 어느 파일 어느 줄에 답이 있는지 모르고 열면, 그걸 찾는 동안 훨씬 많이 읽게 된다. 그래서 저장소에는 섹션 색인이 있다. 글마다 어느 줄부터 어느 줄까지가 어떤 제목의 섹션인지 프로그램이 자동으로 뽑아 둔 목록이다. 에이전트는 색인에서 제목으로 필요한 섹션을 찾고 그 줄만 읽는다. 섹션이 길면 필요한 한 가지를 알려고 긴 덩어리를 통째로 읽게 되어 토큰이 많이 든다. 그래서 섹션을 작게 유지하라는 규칙이 생겼다.

처음에 나는 「섹션을 1,000자 안에 넣으라는 규칙 때문에 글이 짧게 줄어들었다」고 생각했다. 글자 수가 모자라니 설명을 줄였을 것이라는 추측이었다.


재 보니 원인은 길이 제한이 아니었다

추측으로 규칙을 고치기 전에 Claude가 두 가지를 확인했다.

첫째, 규칙 원문을 다시 읽었다. 규칙은 1,000자가 아니라 1,000 토큰이었고, 괄호 안에 「한글 약 700자 + 코드 예시 1~2개」라고 적혀 있었다. 섹션에는 코드 예시도 들어가니 그 몫을 빼고 한글을 약 700자로 어림한 것이다. 크기로 보면 내가 기억한 1,000자와 크게 다르지 않았다.

둘째, 실제 글의 섹션이 몇 글자인지 카테고리별로 셌다. 규칙은 토큰으로 세지만, 사람이 감을 잡기 쉽게 여기서는 글자 수(공백 제외, 코드 포함)로 셌다.

카테고리 전체 섹션 수 섹션 글자 수 중앙값 1,000자를 넘는 섹션
coding-standard (표준 글) 587개 663 158개
proof (증명 글) 133개 281 1개
plan (생각 정리 글) 52개 465 3개
spring (Spring 기술 설명 글) 49개 582 19개
java (자바 기술 설명 글) 30개 1,079 16개

중앙값은 섹션들을 글자 수 순서로 줄 세웠을 때 한가운데 있는 값이다. Spring은 자바로 웹 서버를 만들 때 널리 쓰는 도구 모음이다.

spring과 java 글은 대부분 2026년 1~3월에 썼다. 섹션 크기 규칙은 2026년 8월에 생겼으니, 이 글들은 규칙 없이 자유롭게 쓴 글이다. 그래서 java 글은 섹션 절반이 1,079자를 넘을 만큼 길다.

눈에 띄는 것은 증명 글이다. 증명 글은 모두 2026년 9월, 규칙이 생긴 뒤에 썼는데 섹션의 절반이 281자 이하였고, 1,000자를 넘는 섹션은 133개 중 하나뿐이었다.

그래도 「긴 글을 규칙대로 잘게 쪼개서 섹션이 짧아진 것」일 수 있었다. 그래서 글 전체 양을 봤다. 쪼갰다면 섹션 수만 늘고 글 전체 양은 그대로여야 한다. 그런데 증명 글은 한 편 전체가 평균 약 1,671토큰(한 편에 섹션 약 7개)이었고, 규칙이 생기기 전의 옛 기술 글은 한 편에 3,900~7,800토큰이었다. 글 전체가 짧았다. 그러니 상한에 걸려 쪼갠 것은 아니다.

다만 숫자만으로는 「원래 할 말이 적어서 짧은 것」인지 「할 말을 줄여 써서 짧은 것」인지까지는 가를 수 없다. 증명 글은 작은 프로그램 하나를 돌린 결과라 옛 기술 글보다 다룰 내용이 적을 수 있다. 줄여 썼다고 본 근거는 숫자가 아니라 읽어 본 경험이다. 나는 증명 글을 읽고 이해하지 못했다. 앞에서 본 Domain 영속화 표준의 문장처럼, 처음 보는 말이 풀이 없이 한 문장에 여러 개씩 들어 있었다. 숫자가 보여 준 것은 「상한은 원인이 아니다」까지다.

그러면 왜 짧게 줄였을까. CLAUDE.md에 이런 문장들이 코딩 스탠다드뿐 아니라 모든 글에 똑같이 걸려 있었다.

  • 「근거는 표 하나나 두세 줄로 압축한다」
  • 「하한은 없다. 답이 짧으면 짧은 게 맞다」 — 하한은 「적어도 이만큼은 써야 한다」는 최소 길이다. 최소 길이가 없으니 짧을수록 낫다는 뜻으로 읽혔다
  • 「섹션이 1,000 토큰을 넘으면 쪼갠다」 — 이쪽은 상한, 즉 넘으면 안 되는 최대 길이다

하나하나는 AI가 찾아 읽을 글에 맞는 규칙이다. 그런데 이것들이 합쳐져 사람이 읽을 글까지 전부 짧게 줄이게 만들고 있었다. 그래서 상한 숫자 하나만 없애서는 해결되지 않는다는 결론이 나왔다. 새로 정할 것은 섹션 크기가 아니라 「누가 읽는 글인가에 따라 쓰는 방식 자체를 가른다」였다.


결정 1. AI가 주로 찾아 읽는 글은 코딩 스탠다드 하나뿐이다

먼저 어떤 글이 어느 독자를 위한 글인지 경계를 그었다. 아래 표의 주니어는 개발을 막 시작한, 자바 기초 문법만 아는 사람이다. 정확히 무엇을 알고 무엇을 모르는지는 결정 4에서 정한다.

카테고리 지금 하는 일 독자
coding-standard 규칙의 「왜」가 적힌 표준 글이다. 에이전트가 섹션 색인으로 필요한 섹션만 골라 읽는다 AI
proof 표준의 주장을 실제로 실행해 본 결과다 주니어
plan 생각 정리 글이다 주니어
그 밖 (spring, java 등) 기술 설명 글이다 주니어

증명 글을 사람 쪽에 둔 이유는 이렇다. 표준 글은 증명 글을 인용 줄 한 줄로만 가져간다. 에이전트가 규칙을 확인하면서 증명에서 필요한 것은 그 결과 한 줄뿐이라, 증명 글 본문을 길고 친절하게 풀어 써도 에이전트가 규칙을 확인하려고 읽는 양은 늘지 않는다.

대가도 있다. 에이전트는 코드 규칙을 찾을 때는 표준 글만 보지만, 글을 어떤 틀로 써야 하는지 확인할 때는 plan 글을 열기도 한다. 예를 들어 증명 글을 어떤 모양으로 써야 하는지는 증명 방식을 정한 plan 글에 정해 두었다. 이런 글이 길어지면 에이전트가 그 틀을 확인하러 읽을 때 드는 토큰이 늘어난다. 그래서 제목도 「AI가 주로 찾아 읽는 글」이다.


결정 2. 표준마다 사람을 위한 설명 글을 따로 두고, 결론은 규칙 파일에서 끌어온다

표준 글은 AI용으로 짧게 남긴다. 그러면 사람을 위한 설명은 어딘가 다른 곳에 있어야 한다. 이게 가장 오래 고민한 부분이고, 방향이 한 번 크게 꺾였다.

여기서 설명 글은 표준 글 하나를 주니어가 이해할 수 있게 풀어 쓴 새 글을 말한다. 안들을 비교할 때는 앞에서 본 Domain 영속화 표준 원칙 1을 예로 들었다. 그 원칙이 막으려는 사고는 이런 장면이다 — DB에서 주문을 꺼내 「확정」 상태로만 바꿔 저장했는데, DB를 열어 보니 주문이 만들어진 시각을 적는 칸(created_at)이 비어 있다.

안 A — 표준 글 자체를 쉽게 풀어 쓴다

글이 하나라 내용이 어긋날 일이 없다는 장점이 있다. 하지만 표준 글은 에이전트가 섹션 단위로 찾아 읽는다. Domain 영속화 표준 원칙 1은 지금 약 400토큰인데, 위의 장면과 용어 풀이를 넣으면 몇 배가 된다. 에이전트가 「주문을 수정할 때 규칙이 뭐였지?」 하고 이 섹션을 가져갈 때마다 사람용 설명까지 같이 딸려 와 토큰이 늘어난다. 결정 1과 부딪혀서 버렸다.

안 B — 설명 글을 두고, 표준 글의 결정 과정까지 쉽게 다시 쓴다

주니어에게는 가장 친절하다. 하지만 같은 결정이 두 곳에 적힌다.

Claude는 이 문제를 처음에 「두 벌이 된다」고만 말했다. 그러자 나는 「두 벌이라는 것이 뭐야?」라고 물었다. Claude는 이렇게 풀었다. 옷 한 벌, 두 벌 할 때의 「벌」이다. 같은 내용을 두 곳에 각각 손으로 적어 둔 상태를 말한다. 적은 날에는 둘이 똑같지만, 내용이 바뀌는 날 한 곳만 고치면 두 곳이 서로 다른 말을 하고, 아무도 모른다. 이 글에서 「두 벌」은 이 뜻으로만 쓴다.

두 벌이 어긋나는 일은 실제로 있었다.

  • 내 다른 자바 프로젝트에 설치되는 코딩 규칙 중에는, Claude·Codex·Copilot(GitHub가 만든, 코드를 쓰는 중에 다음 줄을 제안해 주는 AI) 세 도구가 각자 읽는 「항상 적용」 문서 세 개가 있다. 예전에는 같은 자바 규칙을 이 세 곳에 손으로 적었고, 고칠 때마다 한두 곳을 빠뜨려 같은 규칙이 14줄, 13줄, 12줄로 서로 다른 채 규칙 배포됐다. (이 세 문서는 다른 프로젝트용 코딩 규칙이고, 이 블로그 저장소의 CLAUDE.md·AGENTS.md와는 다른 파일이다.)
  • 이 결정을 하기 바로 전날, 증명 글의 실험 결과 때문에 DB 데이터를 고치는 규칙이 바뀌었다. 원래는 「더티체킹에 맡긴다」(바뀐 값을 JPA라는 도구가 알아서 찾아 나중에 한꺼번에 DB에 반영하게 둔다)였는데, 「저장하는 코드 안에서 flush()까지 부른다」(그 반영을 미루지 말고 바로 그 자리에서 DB에 보낸다)로 바꿨다. 두 방법의 차이는 몰라도 된다. 규칙 문장이 바뀌었다는 것만 보면 된다. 그날 표준 글 4편과 규칙 파일 4개를 고쳤다.

안 B였다면 설명 글에도 「더티체킹에 맡긴다」가 적혀 있었을 것이다. 그걸 빠뜨리면 표준 글은 새 규칙을, 설명 글은 옛 규칙을 말한다. 프로그램이 멈추지도 않고 검사 프로그램이 알려 주지도 않는다. 주니어는 읽기 쉬운 설명 글을 믿고 옛 방식으로 코드를 짠다. 그래서 버렸다.

안 C — 설명 글에는 표준 글에 없는 것만 담는다

설명 글에는 결정을 적지 않고, 결정을 이해하는 데 필요한 바탕만 적는 안이다.

  • 무슨 일이 벌어지는지 보여 주는 구체 장면(주문을 확정했을 뿐인데 created_at이 비었다)
  • 처음 보는 말의 뜻(POJO, 분리 상태)
  • 코드를 한 줄씩 따라가는 설명
  • 결정은 「규칙과 이유는 표준 글에 있다」며 링크로 넘긴다

결정이 바뀌어도 장면과 용어 설명은 그대로 사실이라, 설명 글을 고칠 일이 거의 없다. Claude는 처음에 이 안을 추천했다.

방향이 꺾였다 — 설명 글만 읽고는 무슨 말인지 모른다

Claude가 안 C를 설명하자 나는 이렇게 물었다. 「그럼 설명 글만 보고서는 이게 뭔 말인지 모르는 건가?」

Claude도 맞는 지적이라고 인정했다. 안 C의 설명 글은 끝까지 읽어도 「그래서 어떻게 하라는 건데?」에 답이 없다. 답을 보려면 짧게 줄여 쓴 표준 글로 넘어가야 한다. 주니어가 그 글 하나만 읽고 이해해야 한다는 목표로 보면, 결론을 링크 너머에 두는 것은 실패다. 그래서 Claude가 안 D를 새로 냈다.

골랐다 — 안 D. 결론은 규칙 파일에서 끌어와 보여 주고, 이유는 쉬운 말로 쓴다

설명 글에 결론을 보여 주되, 사람이 손으로 두 번 적지 않는 방법이다. 설명 글의 뼈대는 이렇게 정했다.

  1. 무슨 일이 벌어지나 — 구체 장면
  2. 먼저 알아야 할 말 — 개념 글 링크(결정 5)
  3. 코드를 한 줄씩 따라가기
  4. 그래서 이렇게 한다 — 사람이 적지 않는다
  5. 왜 이렇게 정했나 — 사람이 쉬운 말로 쓴다
  6. 더 보기 — 표준 글과 증명 글 링크

4번은 사이트를 게시할 때 프로그램이 짝이 되는 규칙 파일(SKILL.md)의 본문 전체를 그대로 가져와 그 자리에 채운다. 원본은 규칙 파일 하나다. 전날처럼 flush() 규칙이 바뀌면 규칙 파일만 고치면 되고, 다음 사이트 게시 때 설명 글의 결론도 저절로 바뀐다. 14/13/12줄 문제도 이렇게 풀었다. 세 문서에 손으로 적던 것을, 원본 한 곳만 사람이 고치고 나머지 둘은 프로그램이 원본에서 만들어 내게 바꿨다.

5번은 끌어올 수 없다. 표준 글의 이유는 짧게 줄인 문장이라, 그대로 가져오면 다시 읽히지 않는다. 그래서 이 부분만은 사람이 쉬운 말로 다시 쓴다. 즉 이유는 여전히 두 벌이다.

이걸 보완하려고 낡음 경고를 두었다. 표준 글과 설명 글은 각자 설정 줄에 마지막으로 고친 날짜(last_modified_at)를 적는다. 짝 검사가 두 날짜를 비교해, 표준 글이 설명 글보다 나중에 고쳐졌으면 터미널에 「설명 글의 이유 부분을 다시 읽어라」는 경고를 찍는다. 설명 글을 다시 읽고 나면, 고칠 것이 없더라도 설명 글의 날짜를 갱신한다. 그러면 경고가 꺼진다. 날짜 갱신을 잊으면 경고가 계속 남는다.

정리하면 안 D는 안 A가 못 지키는 AI의 읽기 비용을 지키고, 안 B처럼 가장 자주 바뀌는 결론을 두 벌로 만들지 않으며, 안 C와 달리 설명 글 하나로 장면·용어·결론·이유가 다 끝난다.

대가는 세 가지다. 이유 부분은 여전히 두 벌이라 경고는 알려 줄 뿐 막지는 못한다. 규칙 파일을 가져오는 프로그램과 경고를 새로 만들어야 한다. 가져온 결론은 규칙 파일의 명령문 그대로라 딱딱하다.


결정 3. 새 표준을 만들면 설명 글을 반드시 같이 쓴다

안 A — 필요할 때만 쓴다는 표준 하나를 정하는 비용이 늘지 않는다. 하지만 「필요할 때」를 누가 판단하는지가 비어 있다. 이 저장소에서는 「규칙 파일은 있는데 표준 글이 없는」 표준이, 그걸 잡는 검사가 없어서 실제로 두 번 새어 나갔다. 누군가 기억해야만 지켜지는 규칙은 결국 새기 때문에 버렸다.

골랐다 — 안 B. 새 표준을 만들 때 설명 글을 같은 커밋에 넣고, 짝 검사가 확인한다. 짝 검사에 「표준 글은 있는데 설명 글이 없다」를 잡는 기능을 더한다. 빠뜨리면 커밋할 때는 경고만 뜬다. 실제로 막는 곳은 규칙 배포 직전이다. 새 표준은 규칙 파일도 함께 새로 생기므로 그 푸시에서 규칙 배포가 시작되고, 설명 글이 없으면 거기서 규칙 배포가 멈춘다.

대가는 표준 하나를 정할 때마다 긴 글이 한 편 더 늘어, 표준을 만드는 속도가 느려진다는 것이다.


결정 4. 기준 독자는 자바 기초 문법만 아는 주니어다

「주니어도 이해할 수 있게」라고만 하면 무엇을 풀어 써야 할지 사람마다 다르다. 기준이 비어 있으면 글쓴이가 「이 정도면 알겠지」 하고 넘어가는 순간 짧게 줄인 글이 다시 나온다. 그래서 독자가 무엇을 이미 알고 무엇을 모르는지를 정했다.

기준을 너무 낮게 잡으면(프로그래밍 자체가 처음) 글마다 클래스와 변수부터 설명하게 되어 정작 본론에 닿지 못한다. 너무 높게 잡으면(Spring 실무 1~2년차) 지금 증명 글처럼 「더티체킹」 같은 JPA 용어를 설명 없이 쓰게 된다. JPA는 자바 객체와 DB 표를 이어 주는 도구다.

그래서 이렇게 정했다.

  • 이미 안다: 자바 기초 문법이다. 클래스, 객체, 메서드, 반환값, iffor, 예외 처리(try/catch), 리스트 같은 컬렉션
  • 처음 본다: 그 밖의 모든 것이다. Spring, JPA, SQL(DB에 데이터를 넣고 꺼내라고 명령하는 언어)과 DB, HTTP, JSON, 트랜잭션, 테스트 도구, Git, Docker

이 블로그의 글은 대부분 Spring, JPA, DB 이야기다. 자바 기초까지 설명하면 본론에 닿지 못하고, Spring부터를 모르는 것으로 두면 막 시작한 고등학생이 가장 먼저 막히는 곳에서 설명이 시작된다.


결정 5. 여러 글에 반복되는 개념은 개념 글 한 편에 쓰고 링크한다

기준 독자를 정하고 나니 새 문제가 보였다. Claude는 처음에 트랜잭션(여러 DB 작업을 하나로 묶어, 전부 성공하거나 전부 없던 일로 되돌리는 단위) 같은 말이 나올 때마다 글마다 다시 풀어 쓰자고 했다. 나는 그러면 같은 설명이 여러 곳에 반복되어 중복이 많아진다고 지적했다.

안 A — 글마다 처음 나올 때 풀어 쓴다

글 하나만 읽고 이해할 수 있다. 하지만 트랜잭션 설명이 글 20편에 따로 적혀 있다가 한 편만 고쳐지면, 결정 2의 두 벌 문제가 여러 벌로 생긴다. 내 지적대로 버렸다.

안 B — 용어 사전을 한 곳에 두고, 글에는 한 줄 정의를 자동으로 끌어와 보여 준다

용어 사전 파일 한 곳에 「트랜잭션: 여러 DB 작업을 하나로 묶어 전부 성공하거나 전부 되돌리는 단위」처럼 뜻을 적고, 글에서 처음 나올 때 그 한 줄을 자동으로 괄호 안에 넣어 보여 주는 안이다. 뜻은 한 곳에만 있고, 독자는 읽다가 다른 페이지로 넘어가지 않아도 된다. Claude가 이 안을 내면서 대가도 함께 짚었다 — 한 줄짜리 정의라 어려운 개념은 결국 사전 페이지까지 가서 읽어야 한다.

방향이 꺾였다 — 소개 페이지를 따로 만들어 링크로 거는 게 낫다

그러자 나는 이렇게 제안했다. 「해당 내용을 소개하는 페이지를 따로 만들어서 링크로 표시하는 건 어때?」

Claude가 두 안을 비교해 보니 이쪽이 나았다. 사전 안의 장점은 「읽다가 넘어가지 않는다」였는데, 바로 위에서 짚은 대가가 그 장점을 깎는다. 한 줄만 읽고는 그 개념이 지금 읽는 글의 문제와 어떻게 이어지는지까지 알기 어렵다. 결국 넘어가서 읽어야 한다면 처음부터 제대로 된 설명 페이지로 보내는 게 맞다.

게다가 사전 안은 한 줄 정의를 끌어오는 프로그램, 사전 페이지, 「사전에 없는 용어를 불렀다」는 검사를 새로 만들어야 한다. 소개 페이지 안은 평범한 링크 하나로 끝난다. 이 저장소에는 글 사이 링크를 모아 관계 그림을 그리는 프로그램과, 한 글을 고칠 때 그 글을 링크한 다른 글을 찾아 주는 프로그램이 이미 있다. 그래서 개념 글을 고치면 그 글에 기대는 글 목록이 따로 적어 두지 않아도 나온다.

골랐다 — 안 C. 개념 글 한 편을 쓰고, 처음 나올 때 링크한다

  • 트랜잭션, 영속성 컨텍스트(JPA가 DB에서 꺼낸 객체들을 기억해 두는 공간), HTTP 상태 코드처럼 여러 글에 반복되는 개념은 개념 글 한 편으로 쓴다. 주니어용이라 길이 제한이 없다
  • 이미 그 역할을 하는 글이 있으면 그 글을 쓴다
  • 다른 글은 그 개념이 처음 나올 때 링크만 걸고, 「이 글에서 그 개념이 왜 문제인가」만 본문에 적는다

대가는 세 가지다. 모르는 독자는 읽다가 한 번 넘어갔다 와야 해서 흐름이 끊긴다. 링크를 걸기 전에 개념 글이 먼저 있어야 한다(없는 글에 링크를 걸면 404가 난다). 처음에는 개념 글이 한 편도 없어서, 설명 글 한 편을 쓰려면 개념 글 몇 편을 먼저 써야 할 수 있다. 이 글도 아직 개념 글이 없어서, 필요한 말을 「먼저 알아 둘 것」에서 직접 풀었다.


결정 6. 사람을 위한 글에서는 길이와 압축에 관한 규칙만 푼다

압축의 원인은 규칙 하나가 아니라 여러 규칙의 합이었다. 그래서 CLAUDE.md의 규칙을 하나씩 보고, 사람을 위한 글에서 풀 것과 남길 것을 갈랐다.

지금 규칙 사람을 위한 글에서 이유
섹션 1,000 토큰 상한(넘으면 섹션 색인 프로그램이 경고를 찍는다) 푼다. 경고도 표준 글에만 찍는다 필요한 설명을 다 넣으면 길어질 수밖에 없다. 길이를 맞추려고 설명을 빼면 다시 읽을 수 없는 글이 된다
근거는 표 하나나 두세 줄로 압축한다 푼다 짧게 줄인 직접 원인이다
하한은 없다, 짧으면 짧은 게 맞다 푼다. 대신 「이해에 필요한 장면·용어·단계를 빼지 않는다」로 바꾼다 이 문장이 짧게 쓰는 것을 정당화해 왔다
제목은 이름표가 아니라 문장으로 쓴다 남긴다 사람도 목차만 보고 내용을 짐작할 수 있다
한 섹션은 한 질문에만 답한다 남긴다 길이 제한이 없어져도 섹션이 무엇을 말하는지는 분명해야 한다
코드 블록 앞뒤에 설명을 붙인다 남기고 강화한다. 코드를 한 줄씩 따라가는 설명을 붙인다 주니어가 가장 막히는 곳이다
문장을 「~다」로 끝내고, 1인칭 「나」를 쓰고, 이모지를 쓰지 않는다 남긴다 모든 글의 말투를 통일한다
섹션 색인에 싣는다 계속 싣는다 아래 설명

「제목은 이름표가 아니라 문장으로」는 이런 차이다.

// 이름표 제목 — 여러 글에 똑같이 있어서 이 섹션이 무엇을 말하는지 모른다
## 설계 의도

// 문장 제목 — 제목만 읽어도 이 섹션의 결론이 보인다
## 원칙 1. 모든 필드에 설명과 예시를 붙인다

섹션 색인에 계속 싣는 이유는 이렇다. 에이전트는 색인에서 필요한 섹션만 골라 읽는다. 사람을 위한 글의 섹션이 길어져도, 에이전트가 그 섹션을 고르지 않으면 읽지 않는다. 그러니 비용은 그 섹션을 실제로 골라 읽을 때만 든다. 색인에서 빼 버리면 에이전트가 증명 과정을 찾아볼 길이 아예 사라진다.

표준 글에는 지금 규칙이 그대로 걸린다.

대가는 에이전트가 증명 글이나 plan 글의 섹션을 골라 읽을 때 한 번에 가져오는 양이 지금보다 늘어난다는 것이다. 결정 1에서 plan 글에 대해 짚은 비용이 사람을 위한 글 전체로 넓어진다.


결정 7. 설명 글과 개념 글은 정해진 자리와 이름으로 둔다

짝 검사가 설명 글을 찾으려면 이름 규칙이 먼저 있어야 한다.

설명 글  _posts/explain/YYYY-MM-DD-<표준 슬러그>-explained.md   (카테고리 Explain)
개념 글  _posts/concept/YYYY-MM-DD-<개념 슬러그>.md             (카테고리 Concept)

이 두 줄을 읽는 법은 이렇다.

  • _posts/explain/은 글 파일을 두는 _posts 폴더 안의 explain 폴더다
  • YYYY-MM-DD는 글을 쓴 날짜를 넣는 자리다. 예: 2026-09-17
  • < >로 감싼 부분은 실제 이름으로 바꿔 넣는 자리다
  • 슬러그는 파일 이름에서 날짜와 .md를 뺀 영어 이름이다. 예를 들어 2026-07-31-domain-persistence-standard.md의 슬러그는 domain-persistence-standard다. 그래서 이 표준의 설명 글 파일 이름은 2026-09-17-domain-persistence-standard-explained.md 같은 모양이 된다
  • 괄호 안의 카테고리는 설정 줄에 적는 분류 이름이다. 폴더는 저장소 안에서 파일을 정리하는 자리이고, 카테고리는 사이트 화면과 인터넷 주소에 쓰이는 이름이라 둘을 각각 적는다

설명 글은 이름으로 짝을 찾는다. 표준 슬러그 뒤에 -explained를 붙인다. 이 저장소는 이미 「짝은 이름으로 짓는다」고 정했다. 짝을 따로 표에 적어 두는 방법은 「그 줄을 빼먹으면 검사가 조용히 통과한다」는 이유로 전에 버렸다.

설명 글의 슬러그를 표준과 똑같이 쓰지 않는 이유도 있다. 결정 5에서 말한 관계 그림 프로그램과 링크한 글을 찾아 주는 프로그램이 모두 슬러그로 글을 구별한다. 두 글이 같은 슬러그를 쓰면 프로그램이 둘을 같은 글로 보고 섞어 버린다.

개념 글은 짝이 없는 독립된 글이다. 이미 그 역할을 하는 옛 글은 새 카테고리로 옮기지 않고 그 자리에서 링크한다. 옮기면 주소가 바뀌어 옛 링크가 404가 된다.

대가는 사이트의 카테고리 목록 페이지에 분류가 둘 늘고, 설명 글 주소가 /post/explain/domain-persistence-standard-explained처럼 길어진다는 것이다.


결정 8. 이미 있는 표준은 날짜로 가르고 조금씩 옮긴다

설명 글이 없는 표준이 이미 53편이다. 결정 3의 짝 검사 기능을 켜면, 즉 검사 프로그램에 넣어 실제로 돌게 하면 53건이 한꺼번에 걸린다. 그러면 규칙 파일을 하나 고칠 때마다 규칙 배포가 멈춘다. 그래서 옮기는 방법을 정해야 했다.

안 A — 한 번에 모두 다시 쓴다는 기준이 바로 통일된다. 하지만 설명 글 53편을 새로 쓰고, 결정 1에서 주니어용으로 정한 증명 글 19편도 짧게 줄인 채 남아 있으니 함께 다시 써야 한다. 다른 작업이 한동안 다 멈추고, 필요한 개념 글도 한 편도 없어서 버렸다.

안 B — 규칙을 켜기 전 표준을 예외 목록에 적어 둔다는 검사를 바로 켤 수 있다. 하지만 그 목록은 사람이 손으로 적는 짝 표다. 설명 글을 쓰고 목록에서 빼는 것을 잊으면 조용히 어긋나서 버렸다.

골랐다 — 안 C. 날짜로 가른다.

  • 표준 글 파일 이름의 날짜가 2026-09-17 이상(그날 포함)인 표준에만 설명 글을 강제한다. 그 전 53편은 막지 않고, 검사를 돌릴 때 터미널에 「설명 글이 없는 표준」 경고 목록으로만 찍는다. 파일 이름에 이미 날짜가 있어서 따로 적을 목록이 없다
  • 다른 글에서 많이 링크하는 표준부터 설명 글을 쓴다. 설명 글의 「더 보기」에는 증명 글 링크가 들어가는데, 그 증명 글이 짧게 줄인 채면 주니어가 거기서 다시 막힌다. 그래서 설명 글을 쓸 때 그 표준에 연결된 증명 글도 함께 풀어 쓴다
  • 개념 글은 설명 글을 쓰다가 필요해지는 만큼만 쓴다

안 A처럼 모든 작업을 멈추지 않고, 안 B처럼 손으로 적는 목록을 만들지 않는다.

대가는 한동안 주니어가 읽을 수 없는 표준과 증명 글이 섞여 남는다는 것이다. 경고 목록이 빌 때까지 이 결정은 반쯤 끝난 상태다.


결정 9. 다른 에이전트가 주니어 역할로 읽고 막힌 곳을 찾는다

기준 독자를 정해도 확인하는 수단이 없으면, 글을 쓴 쪽이 「충분히 풀어 썼다」고 믿는 순간 짧게 줄인 글이 다시 나온다. 글쓴이는 이미 내용을 알아서 자기 글의 빈틈이 보이지 않는다.

안 A — 글쓴이가 점검표로 스스로 확인한다는 추가 비용이 없다. 점검표는 「처음 나온 말에 풀이나 링크가 있는가」, 「구체 장면이 먼저 나오는가」, 「코드를 한 줄씩 따라가는가」 같은 질문 목록이다. 하지만 CLAUDE.md에는 원래 「6개월 뒤의 내가 이 글을 읽고 왜 이렇게 정했는지 떠올릴 수 있는가」라는 점검 문항이 있었는데도 증명 글은 짧게 줄여졌다. 글쓴이가 스스로 점검해서는 자기 빈틈을 못 본다고 보고 버렸다.

안 B — 기계 검사로 막는다(문장 길이, 전문 용어 수 같은 숫자로 판정)는 사람이 판단하지 않아도 된다는 장점이 있다. 하지만 「이해되는가」를 숫자로 잴 방법을 정하지 못했다. 문장이 짧아도 설명을 건너뛴 글은 통과한다. 그래서 버렸다.

골랐다 — 안 C. 커밋하기 전에, 그 글을 쓰지 않은 다른 에이전트에게 「자바 기초 문법만 아는 독자로서 이 글을 읽고 막힌 곳을 줄 번호와 함께 적어라」라고 시킨다. 막힌 곳이 0이 될 때까지 고친다. 안 A의 점검표는 그 에이전트에게 주는 기준으로 쓴다.

이 글도 이 방법으로 확인했다. 첫 초안을 다른 에이전트가 읽자 막힌 곳이 46곳 나왔다. 「저장소」, 「배포」, 「규칙 파일」 같은 말을 설명 없이 썼고, 대화에서 누가 무엇을 제안했는지가 섞여 있었다. 「먼저 알아 둘 것」 섹션은 그 결과로 생겼다. 고친 뒤 다시 읽히자 39곳이 더 나왔다. 같은 「배포」가 사이트 게시와 규칙 배포 두 뜻으로 섞여 있었다는 것도 그때 드러났다.

대가는 두 가지다. 사람을 위한 글 한 편마다 에이전트를 한 번 더, 때로는 여러 번 부른다. 그리고 에이전트는 진짜 주니어가 아니다. 이미 JPA를 알고 있어서 모르는 척이 완벽하지 않고, 막힌 곳을 놓칠 수 있다.


결정 10. 이 규칙은 코딩 스탠다드가 아니라 저장소의 글쓰기 규칙이다

이 결정은 다른 프로젝트의 코드가 아니라 이 블로그의 글을 어떻게 쓰는지에 관한 규칙이다.

코딩 스탠다드로 만들면 규칙 파일(SKILL.md)이 생기고, 규칙 배포로 다른 자바 프로젝트에 설치된다. 그 프로젝트들은 블로그 글을 쓰지 않으니 쓸모없는 규칙이 깔린다. 증명 방식을 정했을 때도 같은 이유로 plan 글로 쓰고, 규칙은 CLAUDE.md에만 적었다.

그래서 규칙은 CLAUDE.md에 적고, 결정에 이른 과정은 이 글에 남긴다.

그런데 확정하기 직전에 Claude가 확인해 보니, Codex가 읽는 AGENTS.md는 CLAUDE.md에서 프로그램으로 만든 것이 아니라 사람이 따로 손으로 적은 요약본이었다. 그래서 거기에도 「상한 1,000 토큰」, 「하한은 없다」 같은 옛 규칙이 그대로 적혀 있었다. CLAUDE.md만 고치면 Codex는 옛 규칙대로 계속 짧게 줄인 글을 쓴다. 그래서 이번에 AGENTS.md도 함께 고쳤다. 두 문서가 두 벌이라는 문제 자체는 이 결정의 범위 밖이라, GitHub 저장소의 게시판인 이슈에 따로 적어 두었다. 비슷한 모양의 문제는 표준 동기화 표준에서도 다뤘다.

대가는 이 규칙이 CLAUDE.md와 AGENTS.md 두 곳에 손으로 적혀 있는 상태가, 그 이슈를 풀 때까지 남는다는 것이다.


판단 기준 정리

질문
글이 짧게 줄어든 원인은 섹션 상한이 아니라 압축하라는 규칙들의 합
이 글은 누가 읽나 표준 글이면 AI, 나머지면 주니어
표준을 사람이 이해하려면 설명 글. 결론은 규칙 파일에서 끌어오고 이유는 쉬운 말로
설명 글은 언제 쓰나 새 표준과 같은 커밋. 짝 검사가 규칙 배포 직전에 막는다
기준 독자는 무엇을 아나 자바 기초 문법만
반복되는 개념은 개념 글 한 편에 쓰고 링크
사람을 위한 글에서 푸는 규칙은 길이와 압축에 관한 셋
이미 있는 표준 53편은 날짜로 갈라 경고만, 링크 많은 순서로 옮김
이해되는지 무엇으로 확인하나 다른 에이전트가 주니어 역할로 읽음
이 규칙은 어디에 적나 CLAUDE.md와 AGENTS.md

이 규칙을 정하기까지

원인이 상한이 아니었다. 나는 섹션 1,000자 제한을 풀면 된다고 생각했다. 재 보니 가장 짧게 줄인 증명 글도 섹션이 상한에 한참 못 미쳤고, 글 전체도 옛 글보다 짧았다. 숫자 하나가 아니라 독자에 따라 쓰는 방식을 가르는 문제로 바뀐 순간이다.

「설명 글만 보고는 모르는가」라는 질문이 안 C를 뒤집었다. 결정을 두 곳에 적지 않으려고 설명 글에서 결론을 뺐더니, 정작 주니어가 그 글 하나로 답을 얻지 못했다. 결론을 규칙 파일에서 끌어오는 안 D가 여기서 나왔다.

사전 대신 소개 페이지로 바뀌었다. 한 줄 정의를 자동으로 넣는 사전 안보다, 제대로 된 개념 글에 링크만 거는 쪽이 이해도 되고 새로 만들 것도 없었다.

확정 직전에 AGENTS.md가 걸렸다. 손으로 따로 적은 요약본이라, CLAUDE.md만 고쳤다면 Codex는 옛 규칙대로 계속 썼을 것이다.


정리

  • 글이 짧게 줄어든 원인은 섹션 길이 제한이 아니라 압축하라는 규칙들의 합이었다
  • AI가 주로 찾아 읽는 표준 글만 짧게 두고, 나머지 글은 주니어가 그 글 하나로 이해하게 쓴다
  • 설명 글의 결론은 규칙 파일에서 끌어오고, 이유만 사람이 쉬운 말로 쓴다
  • 이해되는지는 글을 쓰지 않은 에이전트가 주니어 역할로 읽어서 확인한다

자신만의 철학을 만들어가는 중입니다.
최상단으로 이동했습니다!
확대 이미지

댓글남기기