
[4/10] 차원 방향 문제 해결하기: 양수/음수 척도(Positive/Negative Scales)가 실제로 작동하는 방식
요약
모듈형 평가 엔진 구축 과정에서 발생하는 차원 점수의 양수/음수 방향성 문제를 다룹니다. 점수 범위 설정 시 발생하는 논리적 오류와 이를 해결하기 위한 데이터 구조 설계 및 방향성 처리 전략을 설명합니다.
핵심 포인트
- 차원 점수의 방향(positive/negative)에 따른 해석 차이 분석
- 방향 인지 설정 방식의 한계와 AI 모델의 혼동 문제
- 데이터 구조 설계를 통한 점수 범위 반전 오류 해결 방안
시리즈: 모듈형 평가 엔진 구축하기 (4/10)
척도(Scale) 모듈은 설문 답변으로부터 차원 점수(dimension scores)를 계산하고 해석 단계(interpretation tiers)를 할당합니다. 간단해 보이지만, 그렇지 않습니다. 높은 점수가 좋은 것인지 나쁜 것인지를 결정하는 "방향(direction)" 문제는 다른 모든 모듈을 합친 것보다 더 많은 버그를 일으켰습니다.
데이터 구조 (The Data Structure)
세 단계의 계층 구조:
Factor (root)
└── Scale (dimension)
├── id: "workload"
...
[

- format은 점수가 계산되는 방식을 결정합니다:
sum(모든 필드 점수 합산),avg(필드 간 평균),count(특정 옵션 선택 횟수) - direction은 의미론적 의미를 결정합니다:
positive(높음 = 좋음, 예: "회복탄력성(resilience)") 또는negative(높음 = 나쁨, 예: "번아웃(burnout)") - **Data[]**는 라벨과 설명이 포함된 점수 범위입니다.
방향 문제 (The Direction Problem)
여기서 혼란이 발생합니다. 두 가지 차원을 생각해 봅시다:
번아웃 (Burnout, 음수 방향(negative direction), 높음 = 나쁨):
- 점수 5 (낮음) → 좋은 상태, 낮은 번아웃
- 점수 25 (높음) → 나쁜 상태, 심각한 번아웃
회복탄력성 (Resilience, 양수 방향(positive direction), 높음 = 좋음):
- 점수 5 (낮음) → 나쁜 상태, 낮은 회복탄력성
- 점수 25 (높음) → 좋은 상태, 높은 회복탄력성
질문: 점수 범위를 설정할 때, 낮은 값에서 높은 값 순서로 작성해야 할까요, 아니면 높은 값에서 낮은 값 순서로 작성해야 할까요? 각 방향에서 "낮은 점수"는 무엇을 의미할까요?
[

시도 1: 방향 인지 설정 (Direction-Aware Configuration)
처음에 SKILL.md는 AI에게 방향에 따라 범위를 다르게 설정하도록 지시했습니다:
positive(양수) 차원의 경우: 낮은 점수 = 최악, 높은 점수 = 최상negative(음수) 차원의 경우: 낮은 점수 = 최상, 높은 점수 = 최악
이는 논리적이었으나 실제 적용 시에는 혼란을 야기했습니다. AI는 어떤 방향이 무엇을 의미하는지 자주 혼동하곤 했으며, 특히 일부 차원은 양수이고 다른 차원은 음수인 혼합 유형 평가(mixed-type assessments)에서 이러한 문제가 두드러졌습니다.
결과: 생성된 앱의 약 30%에서 적어도 하나의 차원이 반전된 범위(inverted ranges)를 가졌습니다. 심각한 번아웃을 겪고 있는 사용자가 범위가 뒤집혀 있는 탓에 "당신의 번아웃은 경미합니다"라는 메시지를 보게 되는 상황이 발생했습니다.
시도 2: 저장 시점의 역전 (Storage-Time Reversal)
마침내 효과를 본 해결책은 다음과 같습니다: 설정 컨벤션(configuration convention)을 통일하고, 엔진이 저장 시점에 역전 처리를 수행하도록 하는 것입니다.
이제 AI를 위한 규칙은 매우 단순합니다:
항상 범위를 가장 낮은 점수(최악의 상태)에서 가장 높은 점수(최상의 상태) 순으로 설정하십시오.
시스템이 내부적으로 방향 역전(direction reversal)을 자동으로 처리합니다.
# Burnout (음수 방향) — 범위가 양수 차원과 동일해 보임
assess scale add --id burnout --name "Burnout" \
--format sum --direction negative
...
잠깐 — "심각함(Severe)"이 낮은 점수 쪽에 있다고? 낮은 점수가 괜찮다는 것을 의미하는 번아웃(burnout) 상황에서는 말이 되지 않습니다.
여기에 비결이 있습니다: 시스템은 음수 방향(negative-direction) 차원을 저장할 때 범위 레이블(range labels)을 역전시킵니다. 따라서 저장된 데이터는 다음과 같이 변합니다:
저장됨 (역전 후):
5-10: 경미함 (low score = 음수 방향에서 좋은 상태)
11-18: 보통
...
AI는 이에 대해 고민할 필요가 없습니다. AI는 모든 차원에 대해 동일한 방식으로 범위를 작성합니다: 낮은 점수 = 최악의 레이블, 높은 점수 = 최상의 레이블. 엔진이 음수 차원에 대해 이를 뒤집어 줍니다.
이것이 작동하는 이유
- 단일한 멘탈 모델 (One mental model). AI는 항상 "낮음 = 최악, 높음 = 최상"이라고 작성합니다. 방향에 따른 조건부 로직은 사용하지 않습니다.
- 방향은 설정 로직이 아닌 메타데이터입니다.
--direction negative는 엔진에 "이것은 증상 척도(symptom scale)입니다"라고 알려주는 역할을 합니다. 이는 레이블 반전(label reversal) 및 보고서 해석 방향을 위해 사용될 뿐, 범위 설정(range configuration)을 위한 것이 아닙니다. - 원시 점수(raw score)는 항상 저장된 범위와 일치합니다. 반전 과정을 거친 후, 번아웃(burnout) 점수가 25점(높음)인 사용자는 "심각(Severe)" 단계에 정확히 도달하게 됩니다. 왜냐하면 저장된 범위에서 "심각"이 높은 쪽 끝에 위치하기 때문입니다.
direction 우선순위 규칙
AI는 특정 차원이 양수인지 음수인지 어떻게 결정할까요? 우선순위는 다음과 같습니다:
- 질문 문구 (최우선 순위): "나는 기진맥진함을 느낀다" (증상, 높음 = 악화) → 음수(negative). "나는 스트레스를 대처할 수 있다" (능력, 높음 = 개선) → 양수(positive).
- 계획 선언 (차순위): 질문 문구가 모호할 때만 적용됩니다.
이것이 중요한 이유는 계획 에이전트(plan agent)가 특정 차원을 음수로 선언하더라도, 실제 질문이 긍정적인 구성 개념("나는 유능하다고 느낀다")을 측정한다면 방향은 양수여야 하기 때문입니다. SKILL.md에는 다음과 같이 명시되어 있습니다: 지식 선언(knowledge declaration)과 질문 의미론(question semantics)이 충돌할 경우, 질문의 의미론이 우선한다.
범위 연속성 버그 (The Ranges Continuity Bug)
점수 범위는 반드시 연속적이고 중복되지 않아야(continuous and non-overlapping) 합니다:
✅ 올바른 예: 3-6, 7-8, 9-999 (7 = 6+1, 9 = 8+1)
❌ 중복 예: 3-6, 3-8, 9-999 (두 번째 범위가 3에서 시작하여 중복됨)
❌ 공백 예: 3-6, 9-999 (7-8 구간이 누락되어 해당 범위의 사용자는 아무것도 받지 못함)
중복 버그는 흔하게 발생했습니다. AI가 값을 증가시키는 대신 첫 번째 범위의 min 값을 두 번째 범위의 min으로 그대로 복사하곤 했습니다:
# 잘못된 예 — 두 번째 범위가 3에서 시작함 (첫 번째 범위의 min을 복사함)
assess scale data add --scale workload \
--ranges "3-6:Severe,3-8:Moderate,9-999:Mild"
...
이제 엔진은 범위의 연속성을 검증하며, 중복되는 범위가 있을 경우 명확한 에러 메시지와 함께 이를 거부합니다.
도달 불가능한 범위 버그 (The Unreachable Range Bug)
또 다른 전형적인 사례는 실제 가능한 점수가 아닌 이론적인 점수에 기반한 범위 설정입니다.
지식(Knowledge)에는 다음과 같이 정의되어 있습니다: "0-2 = 중증(Severe), 3-4 = 중등도(Moderate), 5-6 = 경증(Mild)"
하지만 양식 필드(form fields)의 최소값(min)이 1(0이 아님)로 설정되어 있어, 실제 최소 점수는 3이 됩니다.
→ "0-2: 중증(Severe)" 범위에는 절대 도달할 수 없습니다.
...
해결책: 범위를 설정하기 전에, 척도 기술(scale skill)은 양식 필드로부터 실제 --min 및 --max 값을 읽어와 실제 점수 범위를 계산해야 합니다.
// 척도 검증 로직(scale validation logic) 내에서
int actualMin = 0;
int actualMax = 0;
...
이제 SKILL.md에는 P0 규칙이 추가되었습니다:
범위는 반드시 실제 필드 점수(field scores)를 기반으로 해야 합니다.
form-fields참조에서--options:score값을 읽어 실제 최소/최대값(min/max)을 계산하십시오. 지식(knowledge)에 명시된 이론적 점수를 절대 사용하지 마십시오.
센티널 값 (The Sentinel Value)
가장 높은 범위는 항상 999를 최대값으로 사용합니다:
5-10:중증(Severe),11-18:중등도(Moderate),19-999:경증(Mild)
왜 실제 최대값을 사용하지 않을까요? 부동 소수점 반올림(floating-point rounding) 및 예외 케이스(edge cases) 때문입니다. 평균 형식(avg format)을 통해 18.5점을 받은 사용자는 최대 경계값인 18과 일치하지 않을 수 있습니다. 센티널(sentinel)로서의 999는 가장 높은 단계가 자신의 최소값보다 큰 모든 값을 항상 포착할 수 있도록 보장합니다.
엔진은 999를 특별하게 취급합니다. 즉, 이론적 최대값과 대조하여 검증하는 것이 아니라, 단순히 "이 최소값보다 큰 모든 것"을 의미합니다.
count 형식의 함정 (The count Format Trap)
대부분의 차원(dimensions)은 sum(합계) 또는 avg(평균)를 사용합니다. 하지만 count(개수)는 특정 옵션이 선택된 횟수를 세는 특정한 사용 사례가 있습니다.
# 체크리스트에서 "예(Yes)"라고 답한 횟수 계산
assess scale add --id compliance --name "Compliance" \
--format count --direction positive
...
함정: count는 점수를 합산하지 않습니다. 대신 0이 아닌 필드의 개수를 셉니다. 따라서 어떤 필드의 --score가 5라면, count는 이를 5가 아닌 1(0이 아님)로 취급합니다. 이는 이진 체크리스트(binary checklists)를 위해 의도된 설계이지만, AI가 일반적인 점수 기반 질문에 count를 사용하여 잘못된 총계를 산출하는 경우가 종종 발생했습니다.
규칙: count는 이진(yes/no) 통계에만 사용하십시오. 일반적인 점수 산정에는 항상 sum을 사용하십시오.
교훈 (Lessons Learned)
-
설정 관례를 통일하십시오 (Unify the configuration convention). 양수(positive)와 음수(negative)에 대해 AI가 서로 다르게 생각하도록 만들지 마십시오. 엔진이 반전(reversal)을 처리하도록 두십시오.
-
이론적인 선언이 아닌 실제 데이터에 기반하여 검증하십시오 (Validate against actual data, not theoretical declarations). 플랜 에이전트(plan agent)가 "점수 범위는 0-6"이라고 말할 수도 있지만, 실제 양식 필드(form fields)는 3-18을 생성할 수 있습니다. 항상 소스(source)를 직접 읽으십시오.
-
범위 연속성(Range continuity)은 AI의 문제가 아니라 검증(validation)의 문제입니다. AI가 매번
min = previous_max + 1을 정확하게 수행할 것이라고 믿지 마십시오. 검증하고 거부하십시오. -
방향(Direction)은 메타데이터(metadata)입니다. 방향은 엔진에 점수를 어떻게 해석할지를 알려주는 것이지, 범위를 어떻게 설정할지를 알려주는 것이 아닙니다. 이를 범위 설정 로직(range configuration logic)과 분리하여 유지하십시오.
다음: [Connect Module — AI 기반 표지 및 시각적 스타일]
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기