21 KiB
ClariDoc 설계 근거: 근거를 숨기지 않되, 글쓰기 과정을 독자에게 노출하지 않는 방법
ClariDoc은 문장을 매끄럽게 생성하는 프롬프트 모음이 아니다. 기술 블로그와 기술 문서를 만들 때 다음 세 문제를 동시에 다루는 하네스다.
- 독자가 문제, 선택, 구현, 검증을 끊기지 않고 따라갈 수 있어야 한다.
- 프로젝트의 선택 이유와 경계를 실제 근거 문서에서 회수해야 한다.
- 출처 ID, 저장소 경로, 접근일, 작성 지시문 같은 내부 정보는 독자용 글에 섞이지 않아야 한다.
1. 기존 방식에서 드러난 결함
초기 버전은 근거 추적 가능성을 높이기 위해 본문에 source ID를 직접 쓰도록 했다. 그 결과 다음과 같은 문장이 최종 문서에 나타날 수 있었다.
Retries can increase load on a dependency that is already failing. [S1]
제공된 근거 팩은 다음 사실을 확인 대상으로 제시한다.
예시는 특정 날짜 기준이다.
이 문장들은 사실 검증 과정에는 유용할 수 있지만 독자에게는 불필요하다. 독자는 source-pack의 형식이나 모델이 받은 지시를 알고 싶은 것이 아니라, 문제가 무엇이고 왜 그 선택을 했으며 어떤 비용을 감수했는지 알고 싶다.
더 큰 결함은 근거가 있어도 결정의 이유를 회수하지 못하는 것이었다.
application-core는 Spring DI를 의도적으로 사용한다.
이 문장은 현재 상태만 말한다. 다음 질문에는 답하지 않는다.
- 어떤 문제가 있었는가?
- Spring을 완전히 제거하는 대안은 왜 선택하지 않았는가?
- Spring DI를 허용하면서 어떤 비용을 받아들였는가?
- 허용 범위가 transaction, transport, persistence까지 번지지 않도록 무엇을 막았는가?
- 그 경계가 실제로 지켜지는지는 어떻게 확인하는가?
ClariDoc 0.2.0은 이 두 결함을 각각 출력 경계와 결정 근거 회수 문제로 다룬다.
2. 독자용 글과 내부 provenance를 분리한다
작성 과정에는 출처 식별자가 필요하다. source chunk가 어느 문서의 어느 heading과 line range에서 왔는지 남겨야 이후 검토와 재현이 가능하다. 그러나 그 정보가 최종 글에 그대로 나타날 이유는 없다.
따라서 산출물을 두 층으로 나눈다.
reader-facing layer
└─ document.md
문제, 제약, 대안, 선택 이유, 메커니즘, 검증, 한계만 노출
internal audit layer
├─ provenance.md
├─ evidence-map.json
├─ normalized inputs
├─ raw model responses
└─ manifest.json
source ID, relative path, heading, line range, status, hash 보존
기술 블로그의 기본 citation_style은 hidden이다. 이 모드에서 다음 항목은 독자용 문서에 나타나면 오류다.
[S1]같은 내부 source markerraw/branch-notes/...같은 repository path- source access date
- “제공된 근거”, “근거 팩”, “확인 대상으로 제시” 같은 작성 과정 설명
- planner가 만든 section intent나 prompt tag
공개 링크나 각주가 필요한 문서는 footnote 또는 inline_link를 명시적으로 선택한다. 숨김 정책은 출처를 없애는 것이 아니라 독자용 표현과 감사용 추적을 분리하는 것이다.
3. 프로젝트 문서를 같은 무게로 취급하지 않는다
로컬 저장소에는 현재 상태, 결정 과정, 외부 동작, 선례가 함께 존재할 수 있다. 단어가 겹친다는 이유만으로 모두 같은 근거로 사용하면 현재 구현과 과거 메모가 섞이고, 외부 사례가 프로젝트의 선택 이유로 둔갑한다.
ClariDoc은 source type을 다음처럼 구분한다.
| source type | 답할 수 있는 질문 | 답할 수 없는 질문 |
|---|---|---|
canonical-project |
현재 프로젝트에서 실제로 구현·검증된 것은 무엇인가 | 왜 최초에 그 선택을 했는가가 항상 기록돼 있지는 않다 |
canonical-concept |
재사용 가능한 기술 개념과 일반 동작은 무엇인가 | 특정 프로젝트가 실제 채택했는가 |
branch-note |
어떤 제약, 대안, 이유, 비용으로 결정을 내렸는가 | 최신 canonical과 충돌할 때 현재 상태의 최종 권위가 되지는 않는다 |
official-doc |
프레임워크·프로토콜·제품이 어떻게 동작하는가 | 프로젝트의 의도와 채택 이유 |
company-tech-blog |
다른 조직이 어떤 조건에서 무엇을 시도했는가 | 보편적인 표준 또는 현재 프로젝트의 사실 |
이 계층은 llm-wiki-private의 raw → canonical → external output 흐름과 맞물린다. 공개 글은 canonical의 검증된 현재 상태를 중심으로 삼고, branch-note에서 선택 배경을 회수하며, official docs와 company tech blog는 동작 설명과 선례를 보조한다.
4. 검색의 목표는 관련 문서가 아니라 결정 단위를 찾는 것이다
일반적인 lexical search는 application-core, Spring, DI가 많이 등장하는 문서를 위로 올린다. 하지만 기술 글에 필요한 것은 이름의 공기(共起)가 아니라 다음 요소를 가진 문단이다.
constraint
→ choice
→ reason
→ alternative
→ accepted cost
→ guardrail
→ verification
ClariDoc의 local corpus collector는 Markdown heading 단위로 문서를 나누고 BM25 계열 점수에 다음 가중치를 더한다.
- canonical/project status
- decision, reason, alternative, trade-off, forbidden, verification 같은 용어
- brief의 required topic과 core message
- 한 파일이 결과 전체를 점유하지 않도록 하는 file diversity
검색 결과는 절대 경로가 아닌 repository-relative path와 line range를 가진다. 선택 이유가 없는 chunk는 기술 이름이 일치해도 decision section의 주요 근거로 사용하지 않는다.
application-core 사례
프로젝트의 branch-note에는 다음 결정이 함께 기록돼 있었다.
@Service,@Component는 DI 등록 목적으로 허용한다.- Spring DI까지 제거하면 use case마다
@Configuration에서 bean을 수동 등록해야 해 조립 코드가 늘어난다. - 이 편의를 위해
spring-context,spring-beans의존 비용은 수용한다. - 대신
spring-tx, Spring Web, JPA annotation은 금지한다. - transaction 의미는
TransactionPort로 표현한다. - Gradle과 ArchUnit으로 build graph와 source dependency를 각각 검사한다.
따라서 독자용 설명은 “Spring을 의도적으로 쓴다”에서 멈추지 않고, 수동 조립 비용을 줄이기 위한 제한적 허용과 그 대가를 함께 설명해야 한다.
반대로 SLF4J의 존재만 확인되고 선택 이유가 근거에서 발견되지 않았다면, “의도적으로 사용했다”는 이유를 추정해서는 안 된다. 주장을 제거하거나 확인되지 않은 범위로 남겨야 한다.
5. 기술적 선택은 하나의 완결된 설명 단위여야 한다
좋은 기술 문서는 선택을 제품 이름이나 annotation 이름으로 요약하지 않는다. 독자가 자신의 환경에 판단을 옮길 수 있도록 선택이 성립한 조건을 보여 준다.
ClariDoc의 decision unit은 다음 여섯 항목을 최소 계약으로 사용한다.
- 맥락과 제약: 무엇이 단순한 해법을 막았는가
- 선택: 무엇을 허용하거나 채택했는가
- 이유: 어떤 구체적 비용 또는 실패를 줄이려 했는가
- 대안: 현실적으로 가능한 다른 선택은 무엇이었는가
- 수용 비용: 선택 때문에 새로 생기는 결합·운영·학습 비용은 무엇인가
- 가드레일: 비용이 경계 밖으로 번지면 어떤 검사나 규칙이 실패하는가
운영 또는 설계 글에서는 검증과 적용하지 않을 조건까지 추가한다.
context → constraint → options → decision → mechanism
→ verification → accepted cost → not-applicable condition
RAT001, RAT002, RAT003 lint는 선택 선언 뒤 이유가 없는 문장, 대안·비용·가드레일 누락, 결정 섹션에 rationale evidence가 배치되지 않은 상태를 각각 탐지한다. 휴리스틱이므로 모델 reviewer와 도메인 소유자 검토를 대체하지는 않는다.
6. 우아한형제들 기술 블로그 표본에서 가져온 작성 패턴
우아한형제들의 공식 편집 규정을 확보한 것은 아니다. 공개된 기술 글 8편을 표본으로 읽고 반복되는 전개와 문장 형식을 운영 프로필로 추출했다. 표본은 2017~2025년에 공개된 Backend, Frontend, Data, AI, 장애 회고 글을 포함한다. 출처별 관찰과 일반화 경계는 SOURCE_MATRIX.md에 기록했다.
조사는 다음 두 층을 분리했다.
- 정보 전개 구조: 문제, 제약, 대안, 선택 이유, 구현, 검증이 어떤 순서로 이어지는가
- 문장 형식: 문단을 어떤 문장으로 시작하고, 앞 문장과 어떤 관계를 만들며, 순서·질문·선택 이유를 어떻게 표현하는가
문제 → 제약 → 대안 → 선택 이유는 첫 번째 층의 계약이다. 이 구조를 첫 번째 제약은, 두 번째 제약은, 세 번째 제약은 같은 문장 틀로 출력해야 한다는 뜻은 아니다.
6.1 팀과 시스템의 실제 맥락에서 시작한다
Polars 적용기는 팀이 어떤 크기와 형태의 데이터를 처리하는지 먼저 설명하고 예상 독자를 명시한다. B마트 OMS 글은 고객, 라이더, 현장 작업자의 서로 다른 목표와 물리적 제약을 구체적인 주문 장면으로 보여 준다.
하네스 적용:
- 첫 섹션을 추상적인 정의가 아니라
problem_scene으로 둔다. - 팀, 시스템, 요청 흐름, 장애 증상, 반복 비용 중 최소 하나를 구체적으로 제시한다.
- “이 글에서는 무엇을 다룬다”보다 독자가 왜 이 문제를 읽어야 하는지가 먼저 드러나게 한다.
6.2 문제를 비용과 관측 가능한 증상으로 표현한다
B마트 OMS 글은 피크 시간대에 주문이 몰릴 때 출고 지연, 라이더 대기, 현장 부하가 어떻게 연결되는지 보여 준다. LLMOps 글은 provider 복잡성, 프롬프트 버전 추적, 장애, 비용, 실험 재현성 같은 운영 문제를 각각 구체적인 실패로 분해한다.
하네스 적용:
- “복잡했다”, “비효율적이었다”만 쓰지 않는다.
- 누가 어떤 작업을 반복했는지, 어떤 상태가 관측됐는지, 어느 경계에서 비용이 커졌는지 적는다.
- 근거가 없는 수치는 만들지 않는다. 숫자가 없다면 qualitative cost를 정확히 제한해 쓴다.
6.3 선택지를 보여 준 뒤 선택 이유를 설명한다
LLMOps 글은 Langfuse를 선택하기 전에 여러 후보와 각 후보의 한계를 비교한다. 기술 선택은 “유명해서”가 아니라 현재 조직의 요구와 맞지 않은 지점을 통해 설명된다.
하네스 적용:
options와decision_rationale을 별도 intent로 둔다.- 대안을 허수아비로 만들지 않는다.
- 비교 기준은 brief와 근거에서 회수한다.
- 선택의 장점과 함께 수용한 비용을 쓴다.
6.4 구현은 구성요소 목록이 아니라 흐름으로 설명한다
B마트 OMS 글은 주문, 출고, 배송, 시뮬레이션 시간과 비동기 작업이 어떤 순서로 이어지는지 보여 준다. 독자는 클래스 이름을 외우는 대신 입력이 결과로 변하는 경로를 따라간다.
하네스 적용:
input → decision → state change → dependency call
→ observation → success / stop / recovery
- 메커니즘 섹션에 데이터 또는 제어 흐름을 요구한다.
- component 목록만 나열하면 reviewer가 인과 단절로 지적한다.
6.5 검증 결과와 한계를 같이 둔다
공개 기술 글은 시뮬레이션, 성능 지표, 파일럿 결과, 장애 회고처럼 선택이 실제로 무엇을 바꿨는지 보여 준다. 장애 회고는 시간 순서와 놓친 조건을 드러내고 이후의 리뷰·협업 개선으로 연결한다.
하네스 적용:
- test, build rule, metric, incident timeline 중 실제로 존재하는 검증만 사용한다.
- local verification을 production verification으로 확대하지 않는다.
- 정적 분석의 reflection 우회처럼 자동 검사가 보장하지 못하는 범위를 함께 쓴다.
6.6 개요의 분류명을 문장 머리에 반복하지 않는다
8편에서 첫 번째 제약은이라는 문장 형식은 확인되지 않았다. 순서 표현은 존재했지만 용도가 달랐다. 실제 처리 단계, 두 가지 입력 방법, 여러 레이어, 차트처럼 순서 자체가 내용인 대상을 구분할 때 사용했다. 반면 문제와 제약은 대체로 구체적인 상태와 그 결과를 바로 서술했다.
예를 들어 표본은 다음과 같은 관계를 문장에 드러낸다.
| 문장 역할 | 표본에서 관찰한 형식 | 적용 경계 |
|---|---|---|
| 문제 전환 | 정상적으로 보이던 상태 뒤에 달라진 조건과 비용을 하지만, 문제는, 다만으로 연결 |
접속어 자체를 의무화하지 않고 실제 역접 관계가 있을 때만 사용 |
| 인과 연결 | 앞 문장의 상태를 이 때문에, 그 결과, 그래서, 이에로 다시 받아 선택이나 결과로 연결 |
지시어가 가리키는 원인이 바로 앞 문맥에 명확해야 함 |
| 선택 이유 | 후보나 기준을 먼저 제시하고, 선택 문장에서 현재 조건과 제외 이유를 함께 설명 | 제품 이름이나 장점 목록만으로 선택을 정당화하지 않음 |
| 질문 | 질문형 heading이나 짧은 전환 질문을 두고 바로 사례·설명·결과로 답함 | 답하지 않는 수사 질문을 장식처럼 반복하지 않음 |
| 순서 표현 | 실제 단계, 방법, 레이어, 도표의 순서를 구분 | 추상적인 section intent를 산문으로 읽어 주는 용도로 사용하지 않음 |
| 프로젝트 목소리 | 팀에서는, 저희는, 우리는으로 판단 주체와 적용 범위를 밝힘 |
모든 문장을 1인칭으로 쓰거나 조직의 선택을 보편 법칙으로 확대하지 않음 |
하네스 적용:
- outline의
constraints,options,decision_rationale은 작성자가 충족해야 할 의미 계약이지 독자에게 그대로 읽어 줄 문장 표지가 아니다. - 문단은 가능하면 행위자·상태·변화·영향 중 하나를 바로 제시한다.
- 연속된 병렬 항목이 실제로 필요하면 목록이나 의미 있는 소제목을 사용한다.
첫 번째/두 번째/세 번째 + 추상 분류명으로 문단을 반복 시작하면 deterministic lint가STYLE001warning을 낸다.- editor reviewer는 정보 구조가 문장 템플릿으로 노출됐는지, 질문이 바로 답을 얻는지, 접속어가 실제 논리 관계를 가리키는지 별도로 검사한다.
이 규칙은 우아한형제들의 문장을 복제하기 위한 것이 아니다. 조사 표본에서 확인한 구체성, 관계가 드러나는 전환, 판단 주체, 순서 표현의 제한된 용도를 하네스의 작성·검토 기준으로 번역한 것이다.
7. 우아한테크코스와 Tecoble에서 가져온 학습형 글 패턴
우아한테크코스 조직은 교육 자료와 학습 기록을 공개하고 있으며, Tecoble에는 팀 프로젝트에서 겪은 문제를 출발점으로 단계적 해결 과정을 설명하는 글이 축적돼 있다. 이를 공식 글쓰기 교과과정 전체로 일반화하지 않고, 학습형 기술 글에서 유용한 다음 패턴만 반영했다.
- 자신이 놓였던 프로젝트 상황과 선행지식을 먼저 밝힌다.
- 작은 재현 사례에서 출발해 개념을 확장한다.
- 처음 시도와 실패 이유를 숨기지 않는다.
- 최종 코드만 보여 주지 않고 판단이 바뀐 과정을 설명한다.
- 독자가 따라 할 수 있도록 입력, 결과, 검증 지점을 제공한다.
이 패턴은 tutorial, explanation, 입문자 대상 technical_blog에 적용한다. 숙련 독자를 위한 reference 문서에는 같은 서사 구조를 강제하지 않는다.
8. 일반 기술 문서 원칙과의 결합
우아한형제들 표본의 문제 해결 서사만으로 모든 문서 유형을 설계할 수는 없다. 다음 공식·표준 자료를 함께 사용한다.
- Google Technical Writing: 독자, 범위, 문단 중심점, outline, 점진적 상세화
- GitHub Docs content design: 사용자 목표, 콘텐츠 유형, 결론 우선, 의미 있는 heading
- Diátaxis: tutorial, how-to, explanation, reference의 목적 분리
- OASIS DITA: concept, task, reference, troubleshooting의 정보 구조
- Kubernetes documentation types: task와 tutorial의 선행 조건, 단계, 검증
이를 바탕으로 ClariDoc은 일곱 문서 유형을 분리한다.
| 유형 | 독자가 끝내려는 일 | 핵심 질문 사슬 |
|---|---|---|
technical_blog |
문제와 설계 판단 이해 | 문제 → 제약 → 대안 → 이유 → 구현 → 검증 → 비용 → 판단 |
tutorial |
안내받으며 결과와 개념 학습 | 결과 → 준비 → 전체 경로 → 단계 → 체크포인트 → 검증 → 다음 학습 |
how_to |
특정 작업 완료 | 적용 조건 → 사전 조건 → 절차 → 확인 → 롤백 → 문제 해결 |
explanation |
개념과 인과 모델 이해 | 질문/답 → 기준점 → 모델 → 메커니즘 → 예시 → 대안 → 한계 |
reference |
정확한 사실 조회 | 범위 → 구문 → 필드 → 동작 → 오류 → 최소 예시 → 관련 항목 |
troubleshooting |
증상에서 원인과 복구로 이동 | 증상 → 영향 → 안전 → 진단 → 분기 → 조치 → 복구 → 예방 |
design_doc |
대안을 비교하고 결정 | 요약 → 문제 → 목표 → 제약 → 대안 → 결정 → 구조 → 실패 → 배포 → 관측 → 위험 |
9. 모델 역할을 분리한다
하나의 모델이 작성과 자기검토를 모두 수행하면 같은 전제와 누락을 반복하기 쉽다. ClariDoc은 역할을 분리하고 자유 형식 감상이 아니라 JSON 계약으로 리뷰를 받는다.
| 역할 | 기본 provider | 검사 대상 |
|---|---|---|
| planner | Codex | 구조, reader question, evidence allocation |
| writer | Claude | 자연스러운 reader-facing prose |
| logic reviewer | Codex | 전제, 인과, 결론 |
| decision reviewer | Codex | 이유, 대안, 비용, 가드레일 |
| reader reviewer | Claude | 독자 맥락, 인지 부하, 정보 누락 |
| editor reviewer | Claude | 도입, 문단 초점, 전환, 반복, 상투 문구 |
| evidence reviewer | Antigravity | source fit, status, 과장, provenance 누출 |
| operations reviewer | Antigravity | 안전, 검증, 롤백, 실패 경로 |
| reviser | Claude | blocker와 error 수정 |
모델을 다르게 배치해도 진실이 자동으로 보장되는 것은 아니다. 결정적 lint, source hierarchy, manifest, 사람 검토가 함께 필요하다.
10. 품질 게이트가 증명하는 것과 증명하지 않는 것
품질 게이트는 다음을 재현 가능하게 확인한다.
- 문서 유형의 필수 섹션이 존재하고 순서를 지키는가
- 작성 과정의 메타 문장이 독자용 글에 누출됐는가
- 선택 선언에 이유, 대안, 비용, 가드레일이 있는가
- 절차에 사전 조건, 검증, 중단, 복구가 있는가
- provider 응답이 계약 형식을 지켰는가
- 산출물과 provenance의 hash가 일치하는가
다음은 증명하지 않는다.
- source 문장이 현실 세계에서 참이라는 것
- 모델 reviewer의 합의가 도메인 정답이라는 것
- 코드와 명령이 대상 시스템에서 안전하게 실행된다는 것
- local test 결과가 production 효과를 보장한다는 것
- 표본에서 추출한 글쓰기 패턴이 우아한형제들의 공식 규정이라는 것
Mock provider PASS는 파이프라인 배선과 검사기의 동작만 검증한다. 실제 문서 품질 점수로 사용하지 않는다.
11. 최종 작성 원칙
ClariDoc이 기술 글에 요구하는 핵심은 다음 한 문장으로 정리할 수 있다.
독자에게는 문제와 판단의 흐름만 보이고, 검토자에게는 그 판단이 어디에서 왔는지 끝까지 추적되어야 한다.
이를 위해 최종 글은 다음 순서를 지향한다.
실제 문제 장면
→ 단순한 해결을 막은 제약
→ 현실적인 대안과 실패 지점
→ 선택과 선택 이유
→ 받아들인 비용과 지킨 경계
→ 코드·데이터·제어 흐름
→ 검증 결과와 검증하지 못한 범위
→ 다른 환경에 적용할 판단 기준
이 구조는 미문을 보장하지 않는다. 대신 독자가 “무엇을 했는가”뿐 아니라 “왜 그랬고, 어디까지 믿어도 되는가”를 판단할 수 있는 최소 조건을 만든다.