핵심 요약
통과 · S+A
86/89
96.6% — 담는 데 성공
그중 SUCCESS
33/89
37.1% · 정렬선 하한에 걸림
잔여 FAIL
3
셋 다 도형 겹침
평가 제외
11/100
성적 분모에서 빠짐
무엇을 했나
남는 공간을 재분배한다. 실제 도형 외곽선과 글자 영역으로 크기·간격·위치를 맞추고, 부족할 때만 글자를 줄인다.
무엇이 남았나
통과한 86건 중 53건이 ACCEPTABLE이고 그중 41건이 정렬선 보존율 0.80 하한에 걸렸다. 담기는 했는데 판을 흐트러뜨렸다는 뜻이다 — §12 우선순위 2.
어떻게 읽나
자동 판정 통과율을 디자인 만족도나 상용 성공률로 읽지 않는다. 기계로 잴 수 있는 조건만 통과한 것이다.
2026-08-30 저장 평가 100건 기준 · 최종 After 실측 20:53:11~20:53:39 KST · 저장 문서 재채점 20:54:38 KST. 이 페이지는 그 자료를 아카이브 서식으로 옮긴 것이며 문장·수치는 원본 그대로다.
결과 — 무엇이 달라졌나
시각자료 먼저결과
넘침·겹침·좁은 칼럼은 거의 다 해결.
하지만 그 side effect는 두 가지
— 담기 위해 6건은 글자를 줄였고, 여백을 재분배하며
정렬선이 흐트러짐
유일하게 나빠진 지표가 그것§3.
주지표는 통과율(SUCCESS+ACCEPTABLE) 96.6%다. 넘침·겹침을 남기지 않고 내용을 담아냈다는 뜻이다. SUCCESS 만 보면 37.1%로 뚝 떨어지는데, 이는 실패가 늘어서가 아니라 정렬선 보존율 0.80 하한이 SUCCESS 조건에 들어가 있기 때문이다 — §3에서 정면으로 다룬다. 두 숫자의 의미를 바꿔 쓰지 않는다.
기본 결함과 가독성 관련 전후 지표
| # | 지표 | Before | After | 해석 |
|---|---|---|---|---|
| 1 | 넘침 텍스트 노드 | 85개 | 0개 | 49개 케이스에 있던 넘침이 전부 사라졌다 |
| 2 | 신규 겹침 | 138쌍 | 4쌍 | 약 97.1% 감소했지만 3개 케이스에 잔존 |
| 3 | 좁은 칼럼 | 44개 | 11개 | 75.0% 감소, 8개 케이스에 남음 |
| 4 | 폰트 축소 없는 케이스 | 89/89건 | 83/89건 | 6건에서 축소 사용; 그중 3건은 0.90 이상이라 SUCCESS 조건을 지켰다 |
| 5 | 페이지 밖 텍스트 잘림 | 0개 | 0개 | 이번 코퍼스에서 새 텍스트 잘림 없음 |
| 6 | 정렬선 보존율 평균 | 0.930 | 0.790 | 유일하게 나빠진 지표. 0.80 미만이 11건 → 42건 |
ACCEPTABLE 16건도 원인을 나눠 봅니다. 13건은 유휴 여백 증가, 3건은 10% 초과 폰트 축소 때문이며 이번 결과에서는 두 이유가 겹치지 않습니다. 전자는 공간 활용·균형, 후자는 축소를 대체할 배치 전략을 개선해야 합니다.
Expected는 같은 89건에서 SUCCESS 73 / ACCEPTABLE 15 / FAIL 0입니다. 다만 Expected는 독립적인 완벽한 정답이라는 가정 없이 품질을 계속 감사해야 합니다. 원안은 자기와 비교하므로 항상 SUCCESS가 되는 기준 장입니다.
실제 사례
여기는 눈으로 보는 몫이다
기계로 잴 수 있는 제약(넘침·겹침·폰트·여백)은 §3에서 같은 평가자로 세 방식을 함께 채점했다. 이 절은 그 표가 답하지 못하는 것 — 줄바꿈, 정렬, 균형처럼 사람이 봐야 아는 품질을 실제 렌더 이미지로 확인하는 자리다. 자동 등급이 SUCCESS 인 사례에도 어색한 줄바꿈이 남아 있다.
배경을 넓혀 글자 크기를 지켰다 6447600
SUCCESS글을 줄이기 전에 남는 가로 공간을 쓴다.
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다. 다시 눌러 나란히 볼 수 있습니다.
글자를 15% 줄여 담았다 6134657
ACCEPTABLE구조는 지켰지만 SUCCESS 기준 0.90 에 못 미친다 — 가독성을 양보한 결과.
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다. 다시 눌러 나란히 볼 수 있습니다.
비교 — 같은 입력, 다섯 방법
AI 대비 위치AI와의 비교 — 통과율은 앞서고, 정렬선은 뒤진다
이 표가 답하는 것
통과율과 지연시간
주지표는 통과율 (S+A)/89 — 넘침·겹침을 남기지 않고 내용을 담았는가다.
SUCCESS는 거기에 정렬선·폰트·여백까지 지킨 더 좁은 등급이라 따로 읽는다.
Sol·Opus 는 정답이 아니라 대조군이다
정답(Expected)으로 쓰려고 만든 것이 아니라 비교 baseline으로 생성했다. 세 방식이 만든 After 를 같은 채점기 · 같은 실측 글자 영역 · 같은 Original 좌표계 · 같은 89건 분모로 돌렸다 — 누가 만들었는지는 채점에 들어가지 않는다.
실험 조건
대상
5 방법 × 100건
공통 평가 89건
모델
opus-5 / sol-5.6
추론 강도 high
규칙
짧은 / 긴
해시 고정 · 도중 변경 없음
시도
1회 생성
되돌아가 고치는 반복 없음
“짧은 규칙”과 “긴 규칙”
짧은 규칙
relayout_rules.md
82줄 · 5.4KB — Before 와 After 가 각각 무엇인지만 정의한다.
- 0 · 용어 (컴포넌트 · 컨테이너 · bounding box)
- 1 · 입력과 생성 절차
- 2 · 불변 조건 — 개수·타입·내용·정렬·위상·배율 유지
- 3 · Before — 컨테이너 고정 · 넘침 · 폰트 축소 · 여백 낭비
- 4 · After — 크기·위치만 조정 · 여백 재분배 · 겹침 제거
- 5 · 시각화 관례 (파란 점선 = 컨테이너, 노란 점선 = bounding box)
긴 규칙
before-after-rules.md
1,275줄 · 97.6KB — 정의에 더해 어떻게 푸는지·어떻게 채점하는지까지 담는다.
- 0~1 · 30초 요약 · 문제 정의
- 2 · 불변 조건 — 폰트 동일 · 내접 · 안전 여백 · 정렬선 보존율 1
- 3 · 좌표계 주의
- 4 · 재배치 알고리즘 8절 — 가로 확장 · 넘침 · 겹침 · 유닛 내부 · 그리드 · 데코레이션
- 6~7 · 판정 기준 · 케이스 problems 유형 · 사람 눈 루브릭
- 8 · Expected 제작 스펙 (사람·LLM 공용)
| 대조 항목 | 짧은 규칙 | 긴 규칙 |
|---|---|---|
| 분량 | 82줄 · 5,397B | 1,275줄 · 97,636B (약 18배) |
| 재배치 방법을 알려주나 | 아니오 — 결과 상태만 정의 | 예 — 축별 해법과 순서까지 |
| 판정 기준이 들어 있나 | 아니오 | 예 — 0.90 / 0.70 경계와 지표 정의 |
길이만의 효과로 읽지 않는다. 두 문서는 분량뿐 아니라 내용·구체성이 다르고, 긴 쪽에는 이번 테스트 100건 중 44건의 ID가 과거 사례 설명과 함께 들어 있다.
제약 만족도와 생성 시간 — 최신 100건
| # | 방법 | 통과 (S+A)/89 주지표 |
그중 SUCCESS 정렬선까지 지킨 것 |
S / A / F / 미판정 | After 생성 평균 | 시간 표본 After 생성분 |
결과 없음 |
|---|---|---|---|---|---|---|---|
| 1 | Adaptive Relayout | 96.6% | 37.1% | 33 / 53 / 3 / 0 | 0.16초 | 100/100 | 0 |
| 2 | Opus high · 짧은 규칙 | 82.0% | 55.1% | 49 / 24 / 16 / 0 | 97.27초 | 100/100 | 0 |
| 3 | sol-high · 짧은 규칙 | 79.8% | 43.8% | 39 / 32 / 16 / 2 | 64.91초 | 96/100 | 4 |
| 4 | Opus high · 긴 규칙 | 76.4% | 57.3% | 51 / 17 / 20 / 1 | 171.10초 | 96/100 | 4 |
| 5 | sol-high · 긴 규칙 | 76.4% | 59.6% | 53 / 15 / 15 / 6 | 97.48초 | 86/100 | 14 |
통과율 순으로 정렬했다. 한 줄에 분모가 둘이다 — 시간 표본은 평균 시간을 잰 건수(실제로 After 가 나온 것),
통과·SUCCESS는 평가 가능 89건 고정 분모다. Adaptive 가 100/100 인 것은 평가 제외 11건에도 After 를 만들었기 때문이다.
· sol 두 설정의 미판정에는 Sol 이 baseline 을 못 만든 5546858·5698327 이 들어 있다.
SUCCESS 가 37.1% 인 이유 — 정렬선 보존율
실패가 늘어서가 아니다. SUCCESS 조건에 정렬선 보존율 0.80 하한이 들어가 있고, 재배치가 그 선을 자주 넘어뜨린다. ACCEPTABLE 53건의 사유를 세어 보면 그대로 드러난다.
정렬선 < 0.80
41
ACCEPTABLE 53건 중 · 38건은 사유가 이것 하나뿐
유휴 여백 > 원안
12
공간을 벌려 담은 대가
폰트 < 0.90
3
줄여서 담은 것
한 건이 두 사유에 걸릴 수 있어 합이 53을 넘는다. 사유가 정렬선 하나뿐인 38건의 분포는 최소 0.212 · 중위 0.679 · 최대 0.778 이다 — 넘침·겹침·폰트·여백을 다 지키고 정렬만 못 지킨 결과다.
이건 지표를 낮춰서 풀 문제가 아니다
정렬선 보존율은 디자인 품질을 대신 재는 몇 안 되는 자동 지표다. 하한을 내려 SUCCESS 를 늘리는 대신, 재배치가 정렬선을 제약으로 들고 풀도록 로직을 고치는 쪽으로 잡았다 — §12 우선순위 2 · 정렬선 보존율을 고려한 재배치 로직 추가.
반대로 통과율에서는 코드 방식이 LLM 을 앞선다. 넘침·겹침을 남기지 않는 일은 규칙으로 푸는 편이 확실하고, 정렬을 지키는 일은 아직 못 따라갔다는 것이 이번 비교의 결론이다.
긴 규칙은 통과율에서 두 모델 모두 손해였다
통과율이 Opus 82.0% → 76.4%, sol 79.8% → 76.4%로 떨어졌다. 동시에 시간은 Opus 97.27 → 171.10초, sol 64.91 → 97.48초로 늘었고, 결과를 아예 못 낸 건수도 sol 에서 4 → 14건으로 늘었다. 더 길고 구체적인 문서를 준 쪽이 더 오래 걸리고 더 낮았다. 다만 SUCCESS 만 보면 긴 규칙이 오히려 높다 — 한두 건 차이로 모델·규칙의 일반적 우열을 확정하지 않는다.
측정 경계 — 무엇이 시간에 들어가나
포함
알고리즘 — Before 투입부터 실측 보정 완료 After 반환까지. 반복 글자 측정 포함.
LLM — 호출 시작부터 답변 수신·공통 적용기로 After 를 만든 시점까지. 호출 프로그램의 시작·통신 시간 포함.
제외
입력 준비 · 외곽선 사전 추출 · Before 이미지 생성 · 최종 독립 채점 · 발표용 썸네일.
대기열에서 실행 전 기다린 시간도 제외한다. 따라서 “화면에 After 가 보일 때까지의 총시간”과는 다르다.
| # | 방법 | 전체 요청 평균 | After 중앙값 | After 95백분위 | 글자 실측 |
|---|---|---|---|---|---|
| 1 | Adaptive Relayout | 0.16초 | 0.09초 | 0.60초 | 2.69회 / 생성 |
| 2 | Opus high · 짧은 규칙 | 97.27초 | 67.19초 | 296.89초 | 최종 채점 시 공통 실측 |
| 3 | sol-high · 짧은 규칙 | 64.28초 | 58.35초 | 153.11초 | 최종 채점 시 공통 실측 |
| 4 | Opus high · 긴 규칙 | 166.64초 | 155.74초 | 389.68초 | 최종 채점 시 공통 실측 |
| 5 | sol-high · 긴 규칙 | 88.47초 | 92.71초 | 191.26초 | 최종 채점 시 공통 실측 |
이 표의 해석 범위
LLM 두 규칙은 원안 글자 크기를 요구하고 알고리즘은 정책 하한까지 줄일 수 있다 — 현재 방식 전체의 비교이지 모델의 추론 능력만 분리한 비교가 아니다.
알고리즘의 실측 반복 보정 대 LLM 의 1회 생성을 비교한 것이다. 각 LLM 케이스는 한 번만 실행했고, 네트워크·부하·동시 실행의 영향을 받으므로 평균 시간을 모델 고유 상수나 운영 SLA 로 쓰지 않는다.
Adaptive Relayout 의 실행 경로에는 LLM 호출이 없다. LLM 은 이번 비교의 baseline 생성과, 그와 별개인 개발·평가용 Expected 예시 작성에만 쓴다.
과정과 디테일
10분접근 — 구조를 지키고, 남는 공간을 필요한 곳에 준다
문제 정의는 한 문장으로만 짚습니다. 글은 바뀌었는데 공간 배분이 그대로이기 때문에, 한쪽은 넘치고 다른 쪽은 비어 있습니다. 우리가 바꾸는 것은 내용이 아니라 그 배분입니다.
이번 접근에서 먼저 정한 세 가지
- 변경할 수 있는 것과 없는 것을 나눈다. 텍스트와 배경 도형의 폭·높이·위치·간격을 조정합니다. 내용, 노드 집합, 부모·자식 구조와 그리는 순서는 유지하며 사진·차트 자체를 늘려 문제를 숨기지 않습니다.
- 문제를 축과 관계로 나눈다. 가로 넘침, 세로 넘침, 한 카드 내부 충돌, 카드 사이 충돌은 각각 다른 방법으로 풉니다.
- 후보를 만든 뒤 실제 렌더로 검증한다. 좋아 보이는 숫자만 보고 채택하지 않고, 실제 글자 영역으로 넘침·겹침이 남는지 확인합니다.
예전 tidyLayout에서 배운 점: 모든 요소를 힘으로 동시에 밀고 당기는 방식은 확장·정렬·균형의 목표가 충돌했고, 튜닝을 판정할 기준도 부족했습니다. 현재는 먼저 제약과 지표를 정의하고, 목적별 후보를 제한된 범위에서 적용합니다. 이 설명은 과거 실험 기록이다.
함께 움직일 단위를 먼저 정한다
유닛은 배경 도형과 그 안의 글처럼 함께 움직이는 최소 단위입니다. 같은 줄은 밴드, 같은 열에서 공간을 다투는 단위는 체인, 그 전체를 담는 큰 도형은 프레임으로 다룹니다.
이 관계를 먼저 고정하면, “무엇과 무엇이 한 묶음인가”가 이동 도중 바뀌지 않습니다. 그다음 여백을 나누고 겹치지 않게 배치하되, 가능한 한 원래 자리에서 덜 움직이는 해를 구합니다. 모든 레이아웃을 전역 탐색하는 방식은 아닙니다.
파이프라인 — 크기를 정한 뒤 충돌을 풀고, 축소는 마지막에
현재 UI 의 기본 선택은 Adaptive Relayout(adaptive-relayout)이다.
후보 여덟 개를 가로 넘침 → 세로·가로 재분배 → 유닛 내부 → 유닛 간 → 세로 여백 → 가로 여백 → 폰트 축소 순으로 잇는다.
| 순서 | 함수 | 하는 일 |
|---|---|---|
| 1 | resolveHorizontalOverflow | 가로 넘침을 줄인다 |
| 2 | balanceSlackToFixedPointredistributeVerticalSlack ↔ openHorizontalSlack | 세로 여백 재분배 ↔ 가로 폭 확장을 번갈아 |
| 3 | separateOverlapsWithinUnit | 한 유닛 안의 텍스트 겹침 정리 |
| 4 | separateOverlapsBetweenUnits | 유닛 사이 밴드 분리 |
| 5 | spreadIntoVerticalSlack | 세로 빈 공간으로 펼치기 |
| 6 | escapeIntoHorizontalSlack | 가로 빈 공간으로 빼기 |
| 7 | shrinkFontToReadableFloor | 그래도 안 되면 폰트 축소 |
함수 이름이 번호에서 서술형으로 바뀌었다. 아래 도해의 M1~M8 은 옛 표기이며 개발 식별자일 뿐 실행 순서가 아니다 — 실행 순서는 위 표의 「순서」 칸이다.
예측은 남아 있다
“LLM 호출이 없다”는 맞지만 “예측 계산이 전혀 없다”는 현재 코드와 다르다. 폭 확장(M2)·폭 축소 분기(M3)·폰트 축소(M6)에서 문자폭 계수와 줄바꿈 규칙으로 줄 수를 추정한다.
LLM 추론이 아니라 코드에 고정된 근사 계산이다. 확인일 2026-08-31.
최종 판정은 실측
후보의 크기·위치를 바꾼 뒤 실제 글자 영역으로 다시 확인한다. 정확한 설명은 “기하 규칙과 일부 줄바꿈 예측으로 후보 생성 → 실측 재검증·보정”이다.
반복 종료가 무결함을 보장하지 않는다 — 미해결도 그대로 판정한다.
무엇을 렌더링으로 재검증하는가
| 대상 | 자료를 얻는 방식 | 재배치 중 하는 일 |
|---|---|---|
| 컨테이너·배경 도형 외곽선 | 리소스 SVG·이미지를 사전 래스터화하고 윤곽을 추출해 저장 | 저장된 외곽선을 현재 위치·크기·회전 등에 맞게 변환해 재사용. 반복 루프에서 원본을 다시 렌더해 추출하지 않음 |
| 텍스트 tight bounding box | 실제 폰트와 엔진의 DOM 기반 글자 측정기로 계산 | 후보 적용·내부 충돌 보정·이동·폰트 축소 후 다시 실측. 반복 검증 포트가 반환하는 값은 이 글자 영역 |
| 넘침·겹침·정렬·여백 및 최종 등급 | sheetJson + 위 기하 자료로 코드가 계산 | 별도 종류의 렌더링 측정이 아니라, 같은 좌표와 실측값을 재사용한 검사 |
CLI 의 “렌더 횟수”는 문서 단위 글자 측정 호출 수다 — 페이지 썸네일을 만든 횟수가 아니다. 반복 보정에는 실측 tight 에 글머리 기호를 더한 visual 영역을 쓴다.
측정 — 사각형 프레임이 아니라 실제로 보이는 영역을 잰다
도형의 바깥 사각형 안에 들어왔다고 실제 도형 안에 들어온 것은 아닙니다. 원·캡슐·말풍선의 모서리와 구멍까지 고려합니다. 텍스트도 저장된 박스 대신 엔진이 잰 글자 영역(tight)에 글머리 기호 몫을 더한 visual 영역으로 판정합니다.
기준은 항상 대치 이전 Original입니다. Before는 재배치 입력, After는 알고리즘 결과, Expected는 비교 목표입니다. Expected와 After의 이미지 유사도를 점수로 쓰지 않습니다. 원안과 대치 문서의 좌표·배율을 맞춰 같은 자로 비교합니다.
일곱 가지 관찰 항목과 판정에서의 역할
| # | 항목 | 무엇을 측정하나 | 판정에서의 역할 |
|---|---|---|---|
| 1 | 넘침 | 글자 영역이 자기 컨테이너/페이지를 벗어난 노드 수·면적 | FAIL 게이트 · 원안보다 악화했는가 (면적은 110%까지 봐준다) |
| 2 | 최소 폰트 배율 | 원안 대비 가장 많이 줄어든 텍스트의 비율; 평균이 아님 | FAIL 게이트 0.70 · SUCCESS 조건 0.90 |
| 3 | 정렬선 보존율 | 원안에서 나란했던 노드 쌍이 같은 선 관계를 유지한 비율 | SUCCESS 조건 · 0.80 이상인가 (미달이면 FAIL 이 아니라 ACCEPTABLE) |
| 4 | 유휴 여백 | 콘텐츠가 덮지 않은 페이지 비율; 전면 배경은 제외 | SUCCESS 조건 · 원안 이하인가 |
| 5 | 신규 겹침 | 원안에 없었거나 원안보다 커진 겹침 쌍 | FAIL 게이트 · 의도된 원안 겹침과 구분 |
| 6 | 좁은 칼럼 | 2줄 이상인데 줄당 글자 수가 3자 미만인 텍스트 | 참고 지표 · 가독성 검토 대상 |
| 7 | 페이지 잘림 | 페이지 밖으로 나가 실제 화면에서 잘리는 요소 | 참고 지표 · 절대량; 최종 등급에는 아직 미반영 |
측정의 의미: 겹침 총량과 “새로 늘어난 겹침”은 다릅니다. 디자인에 원래 있던 겹침은 보존하되 대치·재배치가 악화시킨 부분을 검출합니다. 저장 결과는 문서 해시와 연결된 실측 파일로 검증하므로, 다른 문서의 오래된 측정값을 성공 근거로 쓰지 않습니다.
판정 — FAIL 게이트 셋을 먼저 거르고, 통과 결과를 SUCCESS 조건 셋으로 나눈다
이 도해의 정본은 코드다 —
relayout-core/verdict.ts 의
judgeMetrics 와 상수 EXCESSIVE_FONT_SCALE=0.7 · SUCCESS_FONT_SCALE=0.9 ·
SUCCESS_GUIDE_KEPT=0.8 · OVERFLOW_AREA_TOL=0.1 · VERDICT_EPS=5e-4 를 그대로 옮겼다.
같은 파일 머리말 표에는 정렬선 하한이 0.90 으로 적혀 있으나 실제 상수는 0.80 이고 채점도 0.800 으로 돌았다 — 여기서는 코드를 따랐다.
이 페이지의 모든 수치는 커밋 7ebacc1ef · 채점 2026-09-01 11:07 KST 기준이다.
라벨은 다섯 개다 — UNSOLVABLE 과 UNKNOWN 은 다르다
위 도해가 가르는 것은 SUCCESS·ACCEPTABLE·FAIL 셋이다. 나머지 둘은 잰 값으로 가른 결과가 아니다.
UNSOLVABLE 은 알아본 결과 규칙 안에서 답이 없는 것이고,
UNKNOWN 은 아직 못 잰 것(지표가 없거나 견줄 원안이 없다)이다.
「더 볼 것이 없다」와 「아직 안 봤다」를 한 칸에 섞지 않으려고 나눠 둔다.
평가 제외와 실패를 섞지 않는다
수집
100
전체 케이스
평가 가능
89
성적의 분모
평가 제외
11
분모에서 빠짐
UNKNOWN
0
측정 누락 없음
측정 파일 누락·손상이나 기준 부재는 제외로 숨기지 않고 UNKNOWN 으로 남겨 분모에 포함한다 — 현재 0건이다. 전체 수집 기준으로는 통과 86/100, 평가 제외 11/100, 잔여 FAIL 3/100으로 함께 읽어야 한다.
UNSOLVABLE 11건은 왜 빠졌나 — 세 갈래로 나눈다
제외는 알고리즘이 실패한 것이 아니다. 11건 모두 성적 분모 89에서 빠지지만, 빠진 이유는 서로 다르고 고쳐야 할 곳도 다르다 — 앞단(대치)에서 막을 것, 범위를 넓혀 풀 것, 측정 도구를 고칠 것.
| 갈래 | 건수 | 기계 라벨 | 대표 케이스 | 어디를 고쳐야 하나 |
|---|---|---|---|---|
| 대치 오류 | 7 | REPLACEMENT_ERROR | 5694141 | 앞단 — 컴포넌트 선택·슬롯 매핑·용량 검사 |
| 분절형 컨테이너 | 3 | SEGMENTED_CONTAINER | 6858981 | 컨테이너가 한 조각이 아니다 — 합성·중첩 도형 지원 |
| 폰트 없음 | 1 | FONT_UNAVAILABLE | 6885277 | 서체 배포 — 폰트 키가 측정 환경에 없다 |
대치 오류 5694141
REPLACEMENT_ERROR본문이 95.7px 숫자 표식 슬롯에 대치돼 13줄이 됐다. 페이지에 본문용 슬롯이 따로 있는데 긴 설명이 번호 자리에 들어갔다 — 위치·크기로는 못 푼다.
분절형 컨테이너 6858981
SEGMENTED_CONTAINER리소스 polygon 이 3조각이라 외곽선 추출이 unsupported-topology 로 떨어진다. 컨테이너가 한 조각이 아니라 막힌 것이고 — 배치가 불가능해서가 아니다.
라벨을 사유대로 다시 갈랐다 — OUT_OF_CURRENT_SCOPE 는 비었다
「현재 범위가 좁아서」로 묶여 있던 것들이 실은 다 다른 사유였다.
6672017·6370048 은 컨테이너가 분절형이라 막힌 것이고(외곽선으로 빠져 있던 6858981 도 같은 뿌리다),
6553655 는 범위를 넓혀도 문장을 놓을 자리가 없어 대치 오류다.
5546858·5698327 은 알고리즘이 이미 담아내고 있어 평가 대상으로 올렸다 — 분모가 88 에서 89 가 된 이유다.
합계는 7 + 3 + 1 = 11 이다.
제외 11건 전체 — 5108314 · 5694141 · 6138289 · 6370048 · 6553655 · 6577997 · 6672017 · 6780937 · 6805703 · 6858981 · 6885277
남은 FAIL 3건 — 도형 확장 후의 충돌을 마무리한다
유닛 사이 글자 충돌은 최신 보정으로 모두 해결됐다. 남은 것은 셋 다 도형을 확장하거나 옮긴 뒤 생긴 겹침이다 — 6690122 약 3,633px², 5699884 2쌍 약 19,754px², 6248263 약 399px². 도형의 확장 후보를 채택할 때 주변 이미지·도형까지 검사하는 것이 다음 과제다.
케이스별 다음 점검 지점
| 순서 | 문제 유형 | 케이스 ID | 신규 겹침 | 다음 점검 |
|---|---|---|---|---|
| 1 | 도형 확장으로 기존 겹침 증가 | 6690122 |
1쌍 · 3,633px² | 텍스트 내접뿐 아니라 배경 확장 후 이미지와의 충돌도 최종 채택 조건에 포함 |
| 2 | 확장 뒤 두 쌍이 새로 겹침 | 5699884 |
2쌍 · 19,754px² | 확장 폭을 관련 쌍 전체의 악화 여부로 되돌려 잡는다 |
| 3 | 부모–자식 도형의 작은 겹침 증가 | 6248263 |
1쌍 · 399px² | 원안 대비 증가한 쌍을 확인하고 실제 침범과 측정 경계 영향을 구분 |
현재 방법의 한계 — 정확히 재는 비용과 풀 수 있는 범위
렌더링 재검증이 반복된다
후보 검증 · 내부 겹침 보정 · 이동 후 확인 · 폰트 축소 후 확인에서 글자 영역을 네 번 다시 잰다.
개선 방향 같은 문서의 중복 측정과 안 바뀐 텍스트의 재측정을 줄인다. 검증을 빼서 속도를 얻지는 않는다.
장식이 따라오지 못한다
번호·선·아이콘이 본체와 같은 의미 단위로 묶이지 않아 본체만 이동하고 장식이 남는다.
개선 방향 텍스트·컨테이너·장식의 소속을 먼저 정하고 상대 위치를 유지해 함께 옮긴다.
잘못된 대치는 복구 불가
누락된 문구·잘못된 슬롯 매핑은 위치·크기를 바꿔 풀 문제가 아니다. 같은 제약이면 LLM 도 못 푼다.
개선 방향 대치 전 용량·구조 검사, 대치 후 누락 검사, 부적합한 컴포넌트 재선택.
그리드·리스트 정렬이 어긋난다
각 컨테이너를 개별 유닛으로 보므로 “이 셋이 한 행”이라는 소속이 제약에 없다. 겹침 0이어도 정렬선이 무너진다.
개선 방향 행·열·셀 소속을 먼저 인식하고 그리드 전체를 함께 배치한다. 조건을 못 맞추면 되돌린다.
아직 알고리즘이 커버하지 못하는 디테일
정해진 순서의 후보와 제한된 반복으로 푼다. 그래서 사람이 직접 잡은 것보다 품질이 떨어지는 경우가 있다 — FAIL 은 현재 알고리즘이 못 풀었다는 뜻이지 해가 없다는 뜻이 아니다.
개선 방향 후보를 넓히되, 반복이 끝나도 충돌이 남으면 원안 복귀나 사용자 선택으로 넘긴다.
2·4 는 사용자가 확인한 현재 동작 한계이며 이번 100건에서 발생률을 따로 집계하지 않았다. 아래는 항목별 실제 사례다.
1 · 렌더링 재검증 — 사례 대신 호출 수로
글자 측정 호출
269
저장된 100건 합계
케이스당 평균
2.69회
생성 1회당
단계별 비중
미측정
캐시 적중률도 아직
이 항목만은 그림으로 보이지 않는다 — 결과가 아니라 비용의 문제다. 자세한 내역과 hand-off 계획은 §11에 있다.
2 · 장식이 따라오지 못한다 — 두 가지 형태
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다.
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다.
3 · 잘못된 대치는 복구 불가
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다. 다시 눌러 나란히 볼 수 있습니다.
4 · 그리드·리스트 정렬 — 이제 등급이 잡아낸다
| 사례 | 정렬선 보존율 | 자동 판정 | 무엇이 어긋났나 |
|---|---|---|---|
6492634 | 0.515 | ACCEPTABLE | 가로로 나란하던 세 카드 중 첫 카드만 약 78px 아래로 |
6688168 | 0.700 | ACCEPTABLE | 두 칼럼의 폭·간격을 다시 배분하며 구조가 바뀜 |
6567992 | 0.769 | ACCEPTABLE | 본문 두 덩어리를 실측으로 분리하며 정렬선 이동 |
세 건 모두 겹침·넘침 기준으로는 흠이 없다. 세 건 다 전에는 SUCCESS 였다 — 정렬선 0.80 하한이 붙으면서 ACCEPTABLE 로 내려왔다. 판정은 이제 이걸 잡아내지만 재배치는 아직 정렬선을 보고 고르지 않는다(§12 우선순위 2). 하한을 넘겨도 온전한 것은 아니다 — SUCCESS 33건 중 20건이 여전히 정렬선 1 미만이다.
한 장씩 크게 보기
아래 그림이 한 줄에 한 장씩 커집니다. 다시 눌러 나란히 볼 수 있습니다.
5 · 아직 알고리즘이 커버하지 못하는 디테일
잔여 FAIL 세 건이 그 예다 — 6690122 는 가로 이동 여유가 127.21px 필요한데 좌우 여유가 108px·0px 라
후보가 하나도 만들어지지 않고, 6248263 은 부모–자식 도형이라 분리 대상에서 아예 제외되며,
5699884 는 확장 뒤 두 쌍이 새로 겹친다.
셋 다 공간이 없어서가 아니라 현재 후보가 닿지 못해 남았다 —
원인 분석은 §8에 있다.
FAIL 로 드러나는 것만 문제가 아니다. 사람이 직접 잡았다면 더 나았을 자리가 통과한 결과 안에도 있다 — 정렬선이 흐트러진 ACCEPTABLE 53건, 좁은 칼럼 11개, 장식이 따라오지 못한 배치가 그렇다. 자동 판정을 통과했다는 것과 디자이너가 만든 품질에 닿았다는 것은 다른 말이다.
자동 판정의 한계 — 판정 통과가 곧 완성은 아니다
하한을 넘겨도 완전하진 않다
20/33
SUCCESS 33건 중 정렬선 보존율이 1 미만인 것. 0.80 하한만 넘겼을 뿐이다.
좁은 칼럼도 8개 케이스에 11개 남는다.
지표가 곧 품질은 아니다
참고선
정답(Expected)도 정렬선 보존율 1 을 못 채운다. 지표를 그대로 목표선으로 쓸 수 없다.
이 수치는 이전 tight 기준 측정이며 현재 커밋으로 다시 재지 않았다.
일반화
개발용
문제 케이스를 모은 집합이다. 무작위 사용자 표본도, 독립 검증 집합도 아니다.
실행 시간도 개발 환경 값이라 실서비스 지연시간이 아니다.
등급에 안 잡히는 것이 남아 있다
정렬선은 이제 SUCCESS 게이트에 들어갔지만 잘림·좁은 칼럼은 여전히 최종 등급에 직접 반영되지 않는다. 텍스트 잘림은 0이어도 도형 하나의 페이지 밖 잘림은 Before·After·Expected 모두에 남아 있다 — 운영 적용 전에 별도 안전 기준이 필요하다.
운영 전환 — 붙이기 전에 맞출 것
엔진 hand-off렌더링 비용과 엔진 hand-off — 속도 문제를 먼저 공유한다
이 방식은 렌더링을 쓴다
후보를 만든 뒤 실제 글자 영역을 엔진으로 다시 재서 판정한다. 정확도의 근거가 그 실측이지만, 같은 이유로 엔진 호출이 실행 경로 안에 들어온다.
1 · 지금 무엇이 비용인가
| 측정된 것 | 값 | 범위 |
|---|---|---|
| 글자 측정 포트 호출 | 총 269회 · 평균 2.69회 | 생성한 전체 100건 기준 |
| After 생성 평균 | 0.16초 | 중앙값 0.09초 · 95백분위 0.60초 |
| 반복이 생기는 자리 | 4곳 | 후보 검증 · 내부 겹침 보정 · 이동 후 확인 · 폰트 축소 후 확인 |
저장된 알고리즘 실험 100건 기준이며 새로 실행한 것이 아니다. 외곽선 사전 추출·입력 준비·최종 채점은 포함되지 않는다. 단계별 시간 비중과 캐시 적중률은 아직 측정하지 않았으므로 특정 비율의 속도 향상을 약속하지 않는다. 위 시간은 외곽선·입력 tight 가 준비된 조건의 개발 환경 값이다.
2 · runtime 에 어떻게 넣는가
현재 iui 는 엔진 패키지와 에디터 페이지 뷰를 가져와 별도 렌더 호스트에서 실행한다. CLI 는 헤드리스 브라우저, 뷰어는 iframe 에서 같은 글자 측정기를 쓴다. 제품에는 기존 엔진을 측정 포트로 연결하는 방향이 가능하지만 iui 결과와 동일하다는 검증이 필요하다.
sheetJson과 돌아오는 tight box다.3 · 사전에 indexing 할 것
| 자료 | 지금 방식 | 사전 계산 가능한가 |
|---|---|---|
| 컨테이너·배경 도형 외곽선 | 리소스 SVG·이미지를 미리 래스터화해 윤곽을 저장. 실행 중에는 위치·크기·회전에 맞춰 변환만 한다 | 이미 사전 처리 |
| 텍스트 tight bounding box | 실제 폰트와 엔진의 DOM 기반 측정기로 계산. 폭·폰트·내용이 바뀔 때마다 다시 잰다 | 불가 — 실행 중 실측 |
| 넘침·겹침·정렬·여백 지표 | sheetJson + 위 두 자료로 코드가 계산 | 별도 렌더 없음 |
줄일 수 있는 쪽은 반복이다. 같은 문서·같은 입력의 결과를 단계 사이에 재사용하고, 폭·폰트·내용·회전이 바뀐 텍스트만 다시 잰다. 검증을 빼서 속도를 얻지는 않는다.
4 · 엔진 부하와 hand-off 범위
| # | 단계 | LLM | 엔진 | 필요한 것 |
|---|---|---|---|---|
| 1 | 순수 후보 생성·지표 수식 | 없음 | 실행 중 직접 호출 없음 | sheetJson 구조 + 이미 제공된 tight / outline 데이터 |
| 2 | 실제 글자 영역 측정 | 없음 | 필요 | TextBoundingBoxCalculator · 엔진 폰트/DOM 관리자 · 브라우저 |
| 3 | 결과 시각화·뷰어 | 없음 | 필요 | miricanvas-editor-2의 PageRootView + 엔진 패키지 |
| 4 | 도형 외곽선 사전 추출 | 없음 | 별도 추출 경로 | 디자인 리소스 API/CDN + SVG/이미지 윤곽 추출기 + 캐시 |
| 5 | 비교용 After·Expected 작성 | 사용 | 최종 공통 측정에 필요 | 모델 + 규칙 문서 + 출력 적용기 + 실제 렌더 검증 |
엔진 없이 가능한 범위 — 저장된 실측값으로 채점하거나 예측 기반 후보를 만들 수 있다. 다만 폭·폰트가 바뀐 After 가 실제로 어떻게 렌더되는지는 기존 값만으로 보장할 수 없다.
붙이기 전에 합의할 것 — 문서에 답이 없는 항목
호출 방식
- 시점 — 편집 중 / 저장 직후 / 명시적 실행
- 형태 — 동기 대기 vs 큐
- 대기 표시 — p95 0.60초를 어떻게 보여줄지
- 실패·타임아웃 — 되돌림 기준
엔진 계약
- 부하 예산 — 케이스당 2.69회 왕복 × 동시 요청 몇 건
- 결과 일치 — web-2 엔진과 iui 결과 회귀 세트
- 캐시 — 외곽선 커버리지·무효화, 서체 파일 배포
- 계약 고정 — sheetJson·좌표계·엔진 버전·줄바꿈 처리
다음 개선 — 정렬선과 간격을 지키는 재배치로 넘어간다
잔여 충돌 이슈 해결
잔여 FAIL 3건 모두 확장·이동 뒤 생긴 겹침이다. 확장 후 관련 쌍의 악화를 검사한다.
완료 기준 같은 89건에서 회귀 없이 잔여 겹침 감소
정렬선을 지키는 재배치 로직을 넣는다
채점에는 이미 들어갔다 — SUCCESS 조건에 정렬선 보존율 0.80 하한이 붙었고, SUCCESS 가 37.1% 로 내려간 것이 그 결과다. ACCEPTABLE 53건 중 38건은 사유가 이 하한 하나뿐이다. 이제 남은 것은 알고리즘 쪽이다 — 지금은 후보를 고를 때 정렬선을 보지 않는다.
할 일 후보 검사에 정렬선 축을 넣어 깨뜨리는 이동을 되돌린다. 행·열·리스트 소속을 인식하는 4번 항목과 같이 간다.
요소 사이 간격을 제약으로 넣는다
지금은 「겹쳤나 / 안 겹쳤나」와 페이지 전체 유휴 여백 비율만 본다. 요소와 요소 사이가 얼마나 떠야 하는지(margin), 컨테이너 안쪽에 글자 둘레로 얼마가 남아야 하는지(padding)는 제약에 없다 — relayout-core 에 그런 상수가 없다.
할 일 원안의 간격을 재서 목표 간격으로 삼고, 겹침 0 이어도 너무 붙거나 너무 벌어진 결과를 후보 검사에서 되돌린다. 채점에도 간격 지표를 더한다.
장식 동반 이동과 그리드 보존
텍스트·배경·장식을 함께 옮기고 행·열·간격 보존을 제약으로 넣는다.
완료 기준 제품 엔진과 결과 일치까지 검증
ACCEPTABLE·SUCCESS 의 시각 품질
여백 증가 12건 · 폰트 축소 3건. 정렬·좁은 칼럼·잘림을 사람 판정과 대조한다.
완료 기준 임계값을 낮추는 대신 실제 렌더의 전후 선호 확인
평가 제외 사유 연관 feature 개발
대치 오류 7건은 슬롯 매핑에서 예방, 분절형 컨테이너 3건은 합성 도형 지원, 폰트 없음 1건은 서체 배포.
완료 기준 제외 11건을 평가로 복귀
반복 렌더링 비용
후보 검증 → 내부 보정 → 외곽선 보정 → 채점의 호출 수를 분리하고 결과를 재사용한다.
완료 기준 회귀 없이 측정 호출 수와 p50/p95 감소
이번 자료의 제안
담는 문제는 넘겼으니, 판을 지키는 단계로 넘어가자는 것이다. 2·3번이 그 축이다 — 정렬선과 요소 사이 간격은 둘 다 「겹치지만 않으면 된다」의 다음 단계다. 통과율 96.6% 는 넘침·겹침을 규칙으로 푸는 데 성공했다는 뜻이고, SUCCESS 37.1% 는 그다음 문제가 무엇인지를 가리킨다. 아직 모든 입력에 자동 적용해도 된다는 출시 판정은 아니다.
출처
경로는 모두 miricanvas-iui 기준 · 수치는 커밋 7ebacc1ef 재채점본(2026-09-01 11:07 KST). 재배치 전후 네 장 비교는 scripts/relayout-rescore-panes.ts.
- 측정값
evidence.json·metric-definitions.json·outcome-metrics.json·benchmark.json·five-way-comparison.json·paired-comparison.json·timing-detail.json·failure-actions.json·dependency-map.json·case-geometry.json·image-manifest.json- 실행 기록
eval-out/runs/fail-current-df7a02056-20260830/details.json·eval-out/runs/leadership-report-20260830/baseline-panes.json- 코드
relayout-core/verdict.ts·relayout-methods/index.ts·relayout-methods/actualOutlineFit.ts·src/text-tight-box/compute.ts·src/text-tight-box/runtime.ts·batch/bakeOutlines.ts·doc-render/DocRenderHost.tsx·relayout-methods/method5.ts- 규칙·기록 문서
docs/evaluation-rules.md·docs/relayout_logics.md·docs/before-after-rules.md·docs/post-replace-relayout-handoff.md·source-notes.md·runtime-review-2026-08-31.md