11 KiB
글의 뼈대 — 관찰 기록
이 문서는 채워 넣을 틀이 아니다. 아래 다섯 편이 실제로 어떤 순서를 썼는지 적어 둔 것이다. 여기 있는 칸을 전부 채우려 들면 문서마다 같은 목차가 나오고, 문장은 한국어인데 글은 보고서 생성기 출력처럼 읽힌다. 실제로 그렇게 됐고, 그래서 이 경고를 맨 앞에 둔다.
쓰는 법: 어떤 수가 있는지 보고, 이 문서에 필요한 것만 source가 정하게 한다. 자료가 말하지 않는 칸은 비우고, 자료가 채울 수 있어도 이 글에 필요 없으면 역시 비운다.
글의 뼈대
우아한형제들 기술블로그 5편의 목차와 도입·마무리를 그대로 읽고 정리한 것이다. 낱낱의 문장이 아니라 글 전체가 어떤 순서로 서는지를 담는다. 인용은 아래 글에서 가져왔고, 브라우저로 페이지를 직접 열어 옮겼다.
- 사람도 AI도 놓친 번역 누락, ESLint 플러그인을 만들어 해결하기 — 이하
26388 - WMS 재고 이관을 위한 분산 락 사용기 —
17416 - 로그 및 SQL 진입점 정보 추가 여정 —
13429 - 검색 성능 개선을 위한 Elasticsearch 인덱스 구조와 쿼리 최적화 —
20161 - 나 4년 차 서버개발자, 배달의민족의 지리 체계를 뒤흔들다 —
11238
이 다섯 편은 scripts/style_profile.mjs가 문체 수치를 재는 기준값이기도 하다. 원문을 다시 받으려면
node scripts/fetch_reference.mjs <디렉터리>를 쓴다. 사이트가 curl과 리더 프록시를 403으로 막으므로
실제 브라우저가 필요하고, playwright-core가 있어야 한다. 받은 뒤
node scripts/style_profile.mjs --baseline <디렉터리>/*.md로 값을 다시 잰다.
1. 다섯 편이 공유하는 순서
| 자리 | 26388 | 17416 | 13429 | 20161 | 11238 |
|---|---|---|---|---|---|
| 왜 이 글인가 | 여는 글 | (첫 문단) | (첫 문단) | (첫 문단) | 포스팅 목적 |
| 말 뜻 정하기 | @lib/i18n과 세 가지 컨벤션 | WMS란? | 진입점이 뭐죠? · MDC를 아시나요? | 성능개선을 돕는 도구 | 공간 (Spatial) 데이터 타입이란? |
| 무슨 일이 있었나 | 험난한 컨벤션 준수의 길 | 할당과 취소를 동시에 요청한다면? | 근데 왜 진입점 정보가 남아야 해요? | 현상 | 프로젝트 배경 |
| 왜 그랬나 | 사람과 AI 검수의 한계 | 동시성 이슈 원인 | — | 문제 원인 분석 및 해결 | 방향성 검토 |
| 어떻게 했나 | 린트로 위반 탐지하고 AI로 교정하기 | 1 단계: 분산 락 추가하기 | 기본 작업 · 추가 작업 | 해결 방안 | 개발 |
| 결과 | 린트 플러그인의 성과 | (단계마다 문제점) | — | 개선 결과 | 결과 · 검증 |
| 닫기 | 맺는 글 | 마무리 | 마무리 | 맺으며 | 회고 |
용어를 정하는 자리가 항상 문제보다 앞에 있다. 다섯 편 예외가 없다. 독자가 모르는 말을 안고 문제 설명을 따라가게 두지 않는다.
2. 첫 문단은 세 가지를 한다
17416의 도입은 세 문장이고, 셋이 각각 다른 일을 한다.
"WMS 재고 이관 과정에서 발생한 동시성 이슈를 분산 락(Distributed Lock)을 사용해 해결한 경험을 공유하는 글입니다. 본 글은 분산 락에 대해 알고 있는 분들을 대상으로 작성되었습니다. 제가 경험한 내용들이 여러분들의 비즈니스에 도움이 되는 글이 되길 바랍니다."
- 이 글이 무엇인가 —
<무엇>에서 <무슨 일>을 <어떻게> 한 <경험/과정>을 공유하는 글입니다 - 누가 읽는 글이고, 무엇을 알고 있어야 하는가
- 바람 한 줄
26388도 같은 자리에 같은 문장을 둔다.
"이 글은 다국어 라이브러리를 사용하거나, 팀의 까다로운 컨벤션 유지를 위해 AI 및 린트를 활용하는 개발자를 대상으로 합니다. 린트 플러그인을 구현한 경험이 없어도 쉽게 읽을 수 있게 정리했습니다."
11238은 독자를 둘로 나눠서 각각에게 읽는 법을 준다.
"취업 준비 중인 분들이라면 프로젝트 과정을 간접적으로 경험해 보시면 좋겠고, 현업에 계신 분들이라면 속한 부서에서 진행하는 방법과 차이를 비교해 보면서 읽으시면 좋겠습니다."
독자와 선수 지식의 바를 도입에서 못 박는다. 이 문장이 있으면 본문에서 어디까지 풀어 써야 하는지가 정해진다. 없으면 글 전체가 흔들린다.
3. 도입 끝에 차례를 알린다
17416— "본 글에서는 WMS 재고를 이관하는 과정에서 마주친 동시성 문제에 대해 살펴보고, 어떤 방법으로 동시성 이슈를 해결해 나갔는지에 대해 공유합니다."
11238— "프로젝트는 다음 순서대로 소개해 보겠습니다. — 프로젝트 배경 / 방향성 검토 / 개발 / 검증 / 회고"
26388— "먼저 문제의 출발점이 된 @lib/i18n 라이브러리와 컨벤션부터 살펴보겠습니다."
한 줄이든 목록이든, 읽는 사람이 지금 어디쯤인지 알 수 있게 한다.
4. 용어 절의 생김새
제목부터 묻는 형태다.
| 제목 | 글 |
|---|---|
WMS란? |
17416 |
진입점이 뭐죠? |
13429 |
MDC를 아시나요? |
13429 |
공간 (Spatial) 데이터 타입이란? |
11238 |
근데 왜 진입점 정보가 남아야 해요? |
13429 |
안에서 하는 일은 셋이다.
- 한 문장 정의 —
WMS(Warehouse Management System, 창고 관리 시스템)는 물류센터에서 반복되는 수기 작업을 시스템화하여 안정적으로 운영될 수 있도록 합니다. - 이 글에서 쓸 말을 직접 정함 —
편의상 "화면에 렌더링되어 사용자에게 노출되는 문자열"을 "문구"라고 하겠습니다.·이들을 모두 묶어서 "번역 API"라고 표현하겠습니다. - 주변 관계를 한 문단으로 —
WMS 재고들은 중앙물류기지라고 불리는 DC(Distribution Center)로 입고되며, DC에 입고된 상품들은 지역 거점 센터인 PPC(Picking Packing Center)로 재고가 이관됩니다.
약어는 나오는 자리에서 전부 편다. WMS(Warehouse Management System, 창고 관리 시스템),
DC(Distribution Center), PPC(Picking Packing Center), MDC(Mapped Diagnostic Context),
AST(Abstract Syntax Tree), 분산 락(Distributed Lock), 보간(Interpolation).
5. 사례 하나를 다루는 작은 틀
20161은 같은 세 칸을 다섯 번 반복한다.
현상 → 문제 원인 분석 및 해결 → 개선 결과
17416은 단계마다 자기 문제를 달고 간다.
1 단계: 분산 락 추가하기 → 해결방법 → 문제점
2 단계: 분산 락 대기하기 → 해결방법 → 문제점
3 단계: 분산 락과 상태 키 함께 사용하기 → 해결방법
고친 방법마다 남은 문제를 같이 적는다. 마지막 단계에 와서야 문제점이 없다. 처음부터 정답을
내놓지 않고, 왜 다음 단계가 필요했는지를 앞 단계의 문제점이 만든다.
6. 독자를 데리고 다니는 문장
이 글들은 독자가 무엇을 궁금해할지 알고 미리 처리한다. 내 스킬이 가장 크게 놓쳤던 부분이다.
| 하는 일 | 문장 |
|---|---|
| 곁길 막기 | "여기서 번역 API의 내부 동작이 궁금할 수 있겠지만 딴 길로 새지 맙시다." |
| 나중으로 미루기 | "그리고 유형별로는 문구의 포맷 차이가 있는데, 나중에 살펴보겠습니다." |
| 초점 잡기 | "중요한 것은 아래 세 가지 컨벤션을 반드시 지켜야 한다는 점입니다." |
| 다음 칸 예고 | "이번에는 그렇게 탄생한 규칙들을 깊게 파보겠습니다." |
| 수치로 넘어가기 | "숫자 없이 복잡한 글만으로는 효능이 마음에 와닿지 않는 듯하니, 제작한 플러그인의 규칙이 적발한 컨벤션 위반 개수를 확인해봅시다." |
| 범위 좁히기 | "전체적인 내용은 기술적인 내용보다는 ~ 전체 과정을 소개하는 데 집중했습니다." |
중요한 것은 ~입니다는 금지어가 아니다. 여기서는 앞에 늘어놓은 것 중 무엇을 들고 갈지 고르는
말이고, 자료에 없는 결론을 만드는 말이 아니다. 금지되는 쓰임과 구분해야 한다.
- 쓴다 — 이 글 안에서 독자의 눈을 어디로 보낼지 정할 때
- 안 쓴다 — 측정값 옆에 붙여 자료가 증명하지 않은 해석을 결론처럼 얹을 때
7. 마무리 절
26388의 맺는 글은 네 걸음이다.
"지금까지 커머스 웹프론트에서 다국어 지원을 위해 도입한 @lib/i18n의 컨벤션 준수 이슈와 그 해결 과정을 살펴봤습니다. 사람은 실수를 하고 AI는 확률론적이다 보니 컨벤션 위반의 미탐과 오탐이 빈번했기 때문에, 결정론적인 린트 규칙을 구현해 탐지하고 교정은 자연어에 능숙한 AI에게 맡기는 하이브리드 접근을 택했습니다. 그 결과 다량의 번역 누락과 오역을 방지하고 코드 복잡도도 낮췄습니다."
"AI는 요술램프가 아닙니다. ... 결정론과 확률론의 경계를 구분하고 적재적소에 일을 맡기는 안목이 더욱 중요해지고 있습니다. 이 글이 비슷한 고민을 하시는 분들에게 도움이 되면 좋겠습니다."
지금까지 ~를 살펴봤습니다— 다룬 범위를 되짚는다[원인]이다 보니 [문제]했기 때문에, [해결]을 택했습니다— 한 문장으로 압축한 줄거리그 결과 ~— 성과- 글쓴이 자신의 생각 + 독자에게 건네는 인사
4번은 마무리 절에만 온다. 본문 문단 끝마다 붙는 교훈과는 다른 것이다. 그리고 이것은 글쓴이가 실제로 가진 생각이라 자료에 있을 때만 옮긴다. 없으면 1~3만 쓰고 끝낸다.
8. 이 저장소에 적용할 때
TechLog 기록은 서로 링크로 이어지고, 우아한형제들 글보다 짧다. 그래도 위 뼈대에서 빼면 안 되는 자리가 있다.
| 자리 | 필수 여부 |
|---|---|
| 이 기록이 무엇을 다루는지 한 문장 | 필수 |
| 독자와 선수 지식의 바 | 필수 |
| 처음 쓰는 말의 정의 (본문 안, 첫 사용 앞) | 필수 |
| 무슨 일이 있었나 · 왜 그랬나 | 필수 |
| 어떻게 했나 · 결과 | 자료에 있으면 필수 |
| 단계마다 남은 문제 | 자료에 있으면 필수 |
| 차례 예고 | 절이 셋 이상이면 |
| 글쓴이의 생각 | 자료에 있을 때만 |
없는 자리를 지어내지 않는다. 자료에 없으면 그 칸은 비운다. 이 문서는 무엇을 채울 수 있는지를 말할 뿐, 채울 내용을 만들어도 된다는 뜻이 아니다.