무료 모델이 초안을 작성하기 전 문서 섹션 점수 매기기: 적합성 테스트 장치(Fitness Harness)
요약
본 글은 AI가 작성한 문서 초안을 평가할 때 단순히 가독성을 넘어, 섹션별로 반복 가능한 결정론적 검사(fitness harness)를 구축하는 방법을 제시합니다. 파일 전체 대신 섹션을 분리하여 테스트함으로써, 각 섹션의 고유 위험 단위에 맞는 정확한 평가가 가능해집니다. 이는 모델이나 프롬프트 변경 시에도 일관된 비교 기준을 제공합니다.
핵심 포인트
- 문서 페이지는 균일하지 않으므로 파일 전체 검사보다 섹션별 점수 매기기가 우월하다.
- 적합성 테스트 장치(fitness harness)를 통해 반복 가능한 결정론적 검사를 구축해야 한다.
- 소유권 마커(`<!-- owner: ... -->`)를 사용하여 재생성 시 반드시 보존되어야 할 텍스트 범위를 지정한다.
- 공용 식별자 목록과 클레임 레지스트리를 활용하여 사실 관계의 일관성을 유지한다.
모델이 작성한 문서를 평가할 때 유용한 질문은 그 산문이 잘 읽히는지 여부가 아닙니다. 주어진 모델이 팀이 이미 설정해 둔 기준을 낮추지 않으면서 어떤 섹션을 초안으로 작성할 수 있는가입니다. 무료 모델 접근은 이 질문의 비용 측면만 이동시킬 뿐, 정확성 측면은 건드리지 않습니다. 따라서 답은 읽어보는 과정보다는 반복 가능한 검사에서 나와야 합니다. 본 게시물에서는 이러한 검사를 구축했습니다: 섹션당 4가지 결정론적 테스트(deterministic tests), 판정표(verdict table), 그리고 모든 재생성 시 실행되는 CI 게이트입니다.
왜 파일 수준 검사보다 섹션별 점수 매기기가 우월한가
문서 페이지는 균일한 위험 단위가 아닙니다. 용어집 항목은 열거 가능하고(enumerable), 사용 방법 가이드는 실행 가능하며(executable), API 참조는 스키마에 구속되고(schema-bound), 마이그레이션 노트는 판단 의존적입니다(judgment-heavy). 이 중 하나에서 통과하는 모델은 다음 섹션에 대해서는 거의 아무것도 말해주지 못합니다. 파일 수준에서 검토하면 이러한 차이가 숨겨집니다. 왜냐하면 단 하나의 약한 문단이 다른 섹션들은 괜찮았음에도 불구하고 페이지 전체의 재작성을 강요하기 때문입니다.
섹션별 점수 매기기는 재생성 과정에서도 살아남습니다. 모델이 페이지를 다시 작성한 후, 흥미로운 질문은 "이 텍스트가 새로운가"가 아니라 "내가 소유했던 것이 사라진 것은 없는가, 그리고 등록되지 않은 것이 나타난 것은 없는가"입니다. 이 두 가지 모두 스타일을 읽지 않고도 측정할 수 있습니다. 이것이 적합성 테스트 장치(fitness harness)가 채우는 격차이며, 의도적으로 지루한 작업입니다.
마지막으로, 섹션 점수는 이식성이 뛰어납니다. 모델이나 프롬프트 버전을 전환할 때, 동일한 평가 기준을 유지하고 리뷰 스레드에서 취향에 대해 다시 논쟁하는 대신 통과율을 비교할 수 있습니다. 평가 기준이 계약이며(contract), 모델은 변수입니다(variable).
1단계: 초안이 절대 변경해서는 안 되는 범위 표시하기
먼저, 마크다운 내부에서 소유권 경계를 선언하여 파일과 함께 이동하고 변환 과정에서도 살아남도록 합니다. 이 마커들 사이에 있는 모든 내용은 인간이 소유한 텍스트이며, 재생성 시 바이트 단위로 재현되어야 합니다.
<!-- owner: payments-team -->
Refunds settle in the customer's currency, and partial refunds keep the original fee.
<!-- /owner -->
이 마커가 유용하게 유지되는 두 가지 규칙이 있습니다. 첫째, 단지 의도적인 결정으로 작성된 문장에만 적용하고, 모든 단락에 적용해서는 안 됩니다. 그렇지 않으면 검사가 노이즈가 됩니다. 둘째, 생성된 텍스트를 절대 감싸서는 안 됩니다. 왜냐하면 자신의 출력을 재구성하는 모델은 결코 실패하도록 설계되지 않은 검사를 통과하지 못하게 만들기 때문입니다.
단계 2: 섹션이 참조할 수 있는 사실 고정하기
이 검사들을 가능하게 하는 두 가지 작은 아티팩트가 있습니다. 공용 식별자 내보내기 목록(export list of public identifiers)과 안정 ID로 키가 지정된 클레임 레지스트리(claims registry)입니다. 항상 배포되는 API와 일치하도록, 이 내보내기 목록은 수동으로 작성하지 말고 빌드에서 생성해야 합니다.
["createClient", "client.retry", "RetryPolicy", "client.timeout"]
{
"retry-after": {
"value": "60 s"
...
숫자, 제한 또는 기간을 명시하는 문장은 반드시 인라인으로 해당 클레임 ID를 포함해야 합니다. 예를 들어 The header honors a [claim:retry-after] backoff window.와 같습니다. 모델이 태그 없이 숫자를 작성하면 초안은 실패하며, 사람이 소스 라인을 확인한 후에만 태그를 추가합니다.
단계 3: 네 가지 결정론적 검사 실행하기
아래의 하네스(harness)는 단일 의존성 없는 스크립트입니다. 이 스크립트는 보호된 범위(protected spans), 알 수 없는 식별자(unknown identifiers), 등록되지 않은 숫자 클레임(unregistered numeric claims), 그리고 이번 재생성으로 도입된 새로운 식별자를 검사합니다.
#!/usr/bin/env python3
"""docfit.py: deterministic fitness checks for a model-drafted markdown section.
...
이 네 가지 검사 중 세 가지가 차이점(diff)-상대적이기 때문에, 빈 파일에 대해서가 아니라 이전 승인된 버전을 대상으로 실행해야 합니다.
python tools/docfit.py docs/next/retry.md \
--baseline docs/main/retry.md \
--api build/api.json \
...
단계 4: 보고서를 섹션별 판정으로 변환하기
원시 실패 목록은 협상을 유도하므로, 모델 초안이 인간 검토 대상이 되기 전에 통과해야 하는 검사들을 섹션 유형에 매핑합니다. 아래 표는 보편적인 표준이 아닌 시작 정책입니다.
| Section type | protected spans | identifiers | claims | Advisory drift | Draft eligibility |
|---|---|---|---|---|---|
| Glossary entry | not required | required | required if numeric | review names | Model drafts, human edits |
| ... | |||||
| Encode the policy next to the harness so it is reviewable in the same pull request that changes a doc. |
REQUIRED = {
"glossary": {"identifiers", "claims"},
"how-to": {"protected_spans", "identifiers", "claims"},
...
실패하는 섹션은 거부된 아티클이 아닙니다. 그것은 실패 목록(failure list)이 첨부되어 프롬프트로 되돌아가는 섹션입니다. 바로 이 피드백 루프(feedback loop)에서 대부분의 품질 향상이 발생하는데, 모호한 프롬프트 지침이 구체적인 제약 조건으로 변하기 때문입니다.
5단계: CI에서 모든 재생성(regeneration)에 게이트 설정하기
변경된 마크다운 파일 각각에 대해 harness를 실행하고 JSON 보고서를 빌드 아티팩트(build artifacts)로 보관합니다. 검토자는 렌더링된 페이지를 열기 전에 이 보고서를 먼저 확인합니다.
name: docs-fitness
on: [pull_request]
jobs:
...
만약 기준선 파일(baseline file)이 존재하지 않는다면, 해당 실행을 새로운 페이지로 간주하고, 단순히 파일 누락 때문에 작업이 실패하는 잘못된 이유를 허용하기보다는 protected-span 및 drift 검사를 명시적으로 건너뛰어야 합니다.
무료 모델 액세스 및 무료 서버가 실제로 들어가는 곳
섹션별 여러 후보 초안을 생성하는 것이 이 루프에서 비용이 발생하는 부분이며, 또한 저렴한 모델만으로도 충분히 가능한 부분입니다. 왜냐하면 harness는 취향(taste)보다는 준수 여부(conformance)를 필터링하기 때문입니다. 무료 모델 액세스는 거부할 의도가 있는 후보들을 생성하는 데 유용하며, 여러분이 유지하는 것은 생성 자체가 아니라 점수 매기기(scoring)입니다. 고지: 본 문서는 MonkeyCode의 제품 홍보 활동의 일환으로 작성되었습니다.
무료 서버 옵션은 문서 저장소에 유료 러너를 추가할 수 없는 팀에게 중요합니다. 왜냐하면 이 경우 하네스(harness)와 렌더링된 미리보기는 노트북이 아닌 그곳에 존재할 수 있기 때문입니다. 가용성은 운영자가 진술하는 바가 전부입니다. 위 스크립트는 제품 종속성이 없으며 Python이 실행되는 모든 곳에서 작동하므로, 호스팅은 아키텍처라기보다는 편의성으로 간주하십시오.
한계점 및 사용을 건너뛰어야 할 경우
하네스는 진실(truth)이 아닌 적합성(conformance)을 측정합니다. 이 장치는 특정 섹션이 불필요하거나, 설명이 누락되었거나, 문장이 기술적으로 틀렸지만 여전히 레지스트리(registry)와 일치하는지 알려줄 수 없습니다. 이러한 것들은 인간의 책임으로 남아 있으며, 레지스트리는 실제로 각 주장 뒤에 있는 소스 라인을 확인하는 사람이 있을 때만 도움이 됩니다.
유지보수가 진정한 비용입니다. 새로운 숫자 주장을 할 때마다 소유자 및 만료일이 지정된 레지스트리 항목이 추가되며, 오래된 레지스트리는 존재하지 않는 것보다 더 나쁩니다. 왜냐하면 잘못된 자신감을 조성하기 때문입니다. 변경된 섹션당 검토 패스(review pass)를 대략 하나 할당하고, 아무도 그 패스를 소유하지 않는다면 이 접근 방식을 완전히 포기하십시오.
문서 표면이 작고 안정적일 때, 저장소에 연결할 CI가 없을 때, 또는 문서화가 규제되어 자동화된 신호와 관계없이 인증된 검토를 요구하는 경우에는 사용을 건너뛰십시오. 이러한 경우 protected-span 체크만으로도 설정 비용의 일부만으로 대부분의 가치를 포착할 수 있습니다.
첫 주 동안 섹션 유형별로 세 가지 숫자를 기록하십시오: 하네스로부터의 패스율, 주장 ID를 포함하는 숫자 문장의 비율, 그리고 protected-span 실패 횟수입니다. 레지스트리 크기가 평평한 상태에서 패스율이 상승하는 것은 모델이 사용자의 제약 조건을 학습했다는 것을 의미하며, 레지스트리가 축소되면서 패스율이 상승하는 것은 검사가 조용히 완화되었다는 것을 의미할 수 있습니다.
모델 예산이나 빌드 박스를 확정하기 전에 이 루프를 실행하고 싶다면, MonkeyCode의 무료 모델 액세스와 무료 서버 옵션만으로 시작하기에 충분하며, 하네스는 어쨌든 사용자의 저장소에 남아 있게 됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기