wip: phase_z2 evidence 파이프라인 + matching 실험(phase2~26) + 프론트 trace 패널 진행분 스냅샷

- src: phase_z2 composition/mapper/pipeline/placement_planner/retry, ai_fallback(prompts/schema/validate), mdx_text_atoms 신규
- Front: PipelineTracePanel 신규, FramePanel/SlideCanvas/Home/designAgentApi 등 갱신 + 테스트 4종 추가
- templates/phase_z2: catalog(component_expansion_registry, node_slot_mapping 신규), frames, families, slide_base 갱신
- tests/matching: phase2~26 매칭 실험 스크립트·리포트·온톨로지 전체 (미커밋 진행분)
- tests: b4_v4 evidence, task5~28.5 시리즈, regression(imp95 baseline) 등 신규 테스트 대량 추가
- docs/reference: MDX 구조 인벤토리, MDX→Frame 구조 계약 문서
- scripts: mdx 계약/parity/coverage/viewport 체크, gitea comment, run sync 유틸
- .gitignore: tmp*.json, chromedriver, .orchestrator, *.pkl, Front_test* 등 임시/스냅샷 제외

미완성 작업의 보존용 스냅샷 커밋 (2026-07-02)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-02 17:03:42 +09:00
co-authored by Claude Opus 4.8
parent 97b7833a1b
commit b836e79ee1
527 changed files with 673036 additions and 717 deletions
+330
View File
@@ -0,0 +1,330 @@
# PIPELINE — V1 ~ V4 매칭 시스템 통합 정리
이 문서는 MDX ↔ Figma Frame 매칭 시스템의 V1 ~ V4 단계를 한 곳에 정리한다.
새 작업자 (또는 새 Claude 세션) 가 이 문서만 읽어도 시스템 전체를 파악할 수 있도록 작성.
---
## 사전 작업 (V1 이전)
### S.1 입력 수집
| 출처 | 입력 문서 | 수집 문장 |
|---|---|---|
| Figma 프레임 텍스트 | 32 개 | 586 |
| BEPS 마스터 텍스트 | 1 개 | 1,410 |
| MDX 검증 구간 | 4 개 | 129 |
| **합계** | **37** | **2,125** |
- **코드** : `pipeline_01_extract_nodes.py`
- **결과** : `actual_text_nodes.yaml`
### S.2 키워드 추출 + 정리
```
2,125 문장 → 형태소 분석 (Kiwi) → 13,913 등장 / 1,738 고유
↓ 표기 통합 + 보존 규칙
전처리 후 14,161 등장 / 1,713 고유
↓ 등장 범위 분류
핵심 451 + 연관 1,238 + 광범위 24 = 1,713
추가: 키워드 세트 524 (frame-level 시그니처)
```
**적용 규칙**
- 중요 표기 보존 13개: `DX`, `BIM`, `S/W`, `H/W`, `2D`, `3D`, `AS-IS`, `TO-BE`
- 표기 통합: "디지털 전환" / "디지털전환" → 대표 표기 `DX`
- 제외: 1글자 단어, 순수 숫자, 공백/기호만 있는 토큰
- 품사: 일반명사 / 고유명사 / 외국어 / 숫자만
**코드** : `pipeline_02_tokenize.py`, `pipeline_04_normalize.py`, `pipeline_05_anchor_candidates.py`, `pipeline_07_auto_anchor_candidates.py`
**결과** : `auto_anchor_candidates.yaml`, `keyword_base.yaml`, `domain_terms.yaml`
### S.3 Frame 구조 라벨링 (templates_v2 ontology)
32 개 Figma 프레임 각각에 다음 정보 라벨링:
- `visual_pattern.layout` (compare-rows / table-2col / cards-3col 등)
- `visual_pattern.family` (table / card / diagram / list)
- `visual_pattern.relation_type` (compare / parallel / sequence)
- `visual_pattern.cardinality` (ideal / min / max)
- `content_affinity.primary` + `secondary` (12 카테고리)
- `structure_intent_v2.primary` + `secondary` (9 카테고리)
- `slots` (146 고유 slot id — title, col_a_label, col_b_label, rows 등)
- `alternative_patterns` (대안 layout)
**도출 과정** : r1 → r2 → r3 → final → final_r2 (수동 오버라이드 3건)
**코드** : `pipeline_12_generate_templates_v2.py`, `pipeline_12_r3_generate_templates_v2.py`, `pipeline_12_finalize_v2.py`
**결과** : `structure_ontology_v2_final_r2.yaml`
---
## V1 — 키워드 매칭
### 무엇을 보는가
MDX 본문 단어와 frame 의 3 계층 키워드 (핵심 / 세트 / 연관) 의 일치 비율.
### 산식
```
matching_score = 0.414 × 핵심 점수 + 0.320 × 세트 점수 + 0.265 × 연관 점수
```
- 핵심 점수 = (frame 핵심 키워드 중 MDX 본문에 등장한 비율)
- 세트 점수 = (frame 세트들의 MDX 매칭 coverage 평균)
- 연관 점수 = (frame 연관 키워드 중 MDX 본문에 등장한 비율)
### 가중치 도출 과정
1. 초기 (수동) : 0.30 / 0.50 / 0.20 — 도메인 판단
2. **Logistic Regression 학습** (L2, C=1.0, scikit-learn)
- 데이터: TARGET 4 × 32 frame = 128 샘플 (정답 4 / 오답 124)
- Feature: (standalone_score, group_score, related_score)
- Label: 1 (정답) / 0 (오답)
- 학습 결과: **0.414 / 0.320 / 0.265**
3. **검증 — LOOCV** (Leave-One-Out Cross-Validation)
- 4 TARGET 각각 hold-out → 나머지 3 개로 학습 → hold-out 정답 판별
- 결과: **4 / 4 모두 정답**
- 가중치 변동: 0.40 ± 0.02 / 0.32 ± 0.02 / 0.27 ± 0.01 (안정적)
### 결과 정확도
| 방식 | TARGET 정답 |
|---|---|
| 현재 (수동 0.30/0.50/0.20) | 4 / 4 |
| **Logistic Regression (0.414/0.320/0.265)** | **4 / 4** |
| OLS Linear (1.0/0.05/-0.05) | 3 / 4 |
| BM25 (개별 토큰) | 3 / 4 |
| BM25 (세트 포함) | 3 / 4 |
| IDF-weighted | 3 / 4 |
### 발견된 약점
- 02-2.2 (TARGET) : 정답 Frame 14 의 anchor 키워드가 MDX 본문과 거의 안 겹침 → V1 점수 낮음 (V4 까지 가도 reject)
### 코드 + 결과
- 매칭 코드 : `pipeline_06_2_mdx_matching.py`
- 가중치 학습 : `pipeline_15_logistic_regression.py`
- 결과 비교 : `pipeline_15_bm25_with_sets.py`, `pipeline_15_idf_comparison.py`
- 결과 파일 : `mdx_matching_result.yaml`
- 검증 보고서 : `ATTACH_07_WEIGHT_VALIDATION.html`
---
## V2 — 의미 매칭 (semantic rerank)
### 무엇을 보는가
"키워드는 다르지만 의미가 같은가?" — MDX summary 와 frame.content 의 의미적 유사도.
### 산식
```
similarity = cosine(embed(MDX summary), embed(frame.content))
```
- 모델: `jhgan/ko-sroberta-multitask` (한국어 Sentence-BERT)
### 도출 과정
- 별도 가중치 학습 없음. cosine 유사도 그대로 사용.
- V1 Top-K 후보 안에서 의미 유사도로 재정렬.
### 결과 정확도
- V1 후보 재정렬 단계라 단독 정확도는 별도 측정 X
- V3, V4 의 출발점 (V2 Top-K 후보 → V3 평가)
### 발견된 약점
- 의미 임베딩 단독으로는 frame 식별력 부족 (도메인 키워드 신호가 더 강함)
- V1 Top-K 가 부정확하면 V2 도 그 한계 안에서 작동
### 코드 + 결과
- 매칭 코드 : `pipeline_08_v2_semantic_rerank.py`
- 임베딩 모듈 : `embeddings.py`
- 결과 파일 : `v2_semantic_rerank_result.yaml`
- 진단 : `pipeline_09_v2_diagnosis.py`, `V2_DIAGNOSIS.md`
---
## V3 — 구조 매칭 (structure rerank)
### 무엇을 보는가
"이 콘텐츠를 담을 수 있는 레이아웃인가?" — MDX 글 구조와 frame 의 구조 속성 비교.
### 산식
```
구조 점수 = 0.40 × 레이아웃 일치 + 0.35 × 콘텐츠 성격 일치 + 0.25 × 시각 의도 일치
```
**구성 요소**
- **레이아웃 일치** : MDX layout family (table/card/diagram/list) ↔ frame family
- **콘텐츠 성격** : 12 카테고리 키워드 사전 매칭 (concept_definition / comparative_matrix / policy_requirements 등)
- **시각 의도** : 9 카테고리 키워드 사전 매칭 (matrix_coverage / cycle_interrelation / state_transition 등)
### MDX 본문 분석 방법
- **레이아웃 자동 감지** : `detect_mdx_layout_v2(text)` — 표 / 불릿 / 헤딩 패턴 → layout enum → family
- **콘텐츠 성격** : `AFFINITY_KEYWORDS` 사전 매칭 → 등장 횟수 1위 카테고리 = primary
- **시각 의도** : `INTENT_KEYWORDS` 사전 매칭 + STRONG 구절 패턴 검증 (예: state_transition 은 "AS-IS / TO-BE" 1개 이상 필요)
### 도출 과정 (5회 튜닝 r1 → r5)
| 라운드 | 변경 내용 | 결과 |
|---|---|---|
| r1 | 초기 키워드 사전 (12 + 9 카테고리) | TARGET 2/4 |
| r2 | layout_compat 가중치 조정 | TARGET 2/4 |
| r3 | STRONG 패턴 검증 도입 (before_after_change, state_transition) | TARGET 3/4 |
| r4 | concept_definition 에서 "개념" 제거, hierarchy 단일 키워드 금지 | TARGET 3/4 |
| **r5** | ontology final_r2 (Frame 13 review_queue 해제) | **TARGET 4/4** |
### 결과 정확도
- TARGET : **4/4** (V2 Top-5 후보 안에서)
- 단, V2 후보가 부정확하면 V3 도 부정확
### 발견된 약점
- **콘텐츠 성격 / 시각 의도 분류 부정확** : 키워드 사전 매칭이라 단순 카운트
- 예: MDX 01-2 (DX 와 BIM 의 구분) → 본문에 "국내, 도입, 사례" 가 많아 `policy_requirements` 1위 (실제 `comparative_matrix`)
- 한계: 도메인 키워드 사전 의존, 일반 표현 못 잡음
### 코드 + 결과
- 매칭 코드 : `pipeline_08_v3_r5_structure_rerank.py` (최종)
- 의존 모듈 : `pipeline_08_v3_r4_structure_rerank.py`, `pipeline_08_v3_r2_structure_rerank.py`, `structure_v3.py`, `phase_common.py`
- MDX 분석 : `detect_mdx.py`
- 결과 파일 : `v3_structure_rerank_r5_result.yaml`
---
## V4 — 종합 판정 (template-fit-v1)
### 무엇을 보는가
"실제로 쓸 수 있나? 어느 정도 수정해야 하나?" — V1/V2/V3 신호를 합쳐 frame 적용 가능성 판정.
### 산식
```
base = 0.25 × anchor + 0.20 × cardinality + 0.20 × relation
+ 0.15 × slot + 0.20 × content
confidence = max(0, base penalty)
```
**5 축 의미**
- `anchor` (0.25) : MDX detected_terms ↔ frame anchor_sets 매칭 (V1 핵심 키워드 매칭과 유사)
- `cardinality` (0.20) : MDX 항목 수가 frame cardinality [min, max] 범위 안인가
- `relation` (0.20) : MDX relation_type (compare/parallel/sequence) ↔ frame relation_type 일치
- `slot` (0.15) : 휴리스틱 — within(0.5) + has_labels(0.3) + has_bodies(0.2)
- `content` (0.20) : V2 의미 임베딩 cosine
**penalty**
- cardinality mismatch 시 `adaptation_cost` 부과 (split / merge / infer_missing)
- `not_suits` 패턴 매치 시 `not_suits_penalty`
- 합계 capped at CAP_TOTAL
### 임계값 라우팅
| 라벨 | confidence | 의미 | 후속 작업 |
|---|---|---|---|
| `use_as_is` | ≥ 0.90 | 그대로 사용 | 슬롯에 텍스트만 매핑 (자동) |
| `light_edit` | ≥ 0.75 | 가벼운 편집 | AI 1 호출 (텍스트 다듬기) |
| `restructure` | ≥ 0.60 | 구조 재배치 | 사람 + AI 여러 호출 |
| `reject` | < 0.60 | 사용 불가 | 신규 디자인 |
### 도출 과정
1. **r1 (V3 Top-K 평가만)** : V3 Top-5 안에서 confidence 산출 → 5개 중 선택
2. **r2 (안정화)** : V2 후보 재선정 + adaptation_allowed 검증 추가
3. **full32 (최종)** : 32 frame 전체 평가 → 진정한 reject 식별 가능
### 결과 정확도
- TARGET : **3/4** (use_as_is 매칭 성공)
- 01-2 ✓ (Frame 18, conf 0.946)
- 02-2.2 ✗ (정답 Frame 14, V4 순위 7, reject)
- 03-1 ✓ (Frame 13, conf 0.927)
- 03-2 ✓ (Frame 29, conf 0.920)
- Holdout : 사람 검수자 합리적 수준
### 발견된 약점
#### slot 축 ablation 결과
- W_SLOT=0 으로 두고 4축 재정규화 → V4 재계산
- **Top-1 매칭 7/7 동일** (모든 섹션)
- TARGET Top-1 정답률: Baseline 3/4 → Ablated 3/4 (동일)
-**slot 축은 frame 선별에 영향 없음. 라벨 게이트 역할만 (use_as_is ↔ light_edit 임계 통과 여부)**
#### cardinality 중복 가중
- cardinality 축 (0.20) 과 slot.within (0.075) 이 **같은 신호**를 두 번 평가
- `item_count = len(slot_candidates)` 로 동일
#### 슬롯 의미 매핑 부재
- frame 의 146 개 의미 slot id (`title`, `col_a_label`, `col_b_label`, `rows` 등) 가 V4 점수 계산에 활용 안 됨
- "BIM → col_a_label" 같은 의미 매핑은 코드에 없음 — 후속 단계 책임
#### 표 첫 행만 추출
- MDX 가 4 행 표여도 첫 행만 본문으로 추출. 나머지 행 (S/W·프로세스·성과품) 무시
### 코드 + 결과
- 매칭 코드 : `pipeline_17_v4_full32.py` (최종, 32 frame 전체)
- 의존 모듈 : `template_fit.py`
- Ablation : `pipeline_18_slot_axis_ablation.py`
- 결과 파일 : `v4_full32_result.yaml`
- Ablation 보고서 : `V4_SLOT_ABLATION.md`
---
## 새 pipeline 통합 시 frame 단위 — 명확화
> **주의** : 이 매칭 시스템 (V1~V4) 은 **frame 32 개를 슬라이드 1장 단위로 검증** 함 (예: Frame 18 = BIM/DX 비교 슬라이드 통째로).
>
> 새 pipeline 의 위계는 **슬라이드 ⊃ slide-base ⊃ slide-body ⊃ 레이아웃 ⊃ Zone ⊃ 프레임** 이며, 여기서 **프레임 = zone 안 디자인 단위** 임.
>
> → frame DB 의 사이즈 라벨링 재검토 필요:
> - 어떤 frame = 슬라이드 전체 (= 레이아웃 그 자체)
> - 어떤 frame = zone 1 개 단위 (= 부분 디자인)
> - 작은 박스 단위도 가능
>
> 새 pipeline 통합 작업의 사전 준비 항목 ([../IMPROVEMENT-REDESIGN.md](../../IMPROVEMENT-REDESIGN.md) 의 7.1 참조)
---
## 사후 작업 (V4 이후)
### 보고서 (DECK 1 ~ 7)
| 파일 | 내용 |
|---|---|
| `DECK_01_TARGET_01_2.html` | TARGET 01-2 × V1~V4 Top-3 매칭 결과 |
| `DECK_02_HOLDOUT_02_2_1.html` | Holdout 02-2.1 × V1~V4 Top-3 |
| `DECK_03_METHODS.html` | V1~V4 방법 설명 |
| `DECK_04_DB_STRUCTURE.html` | MDX 1 vs Top-3 frame 5 컬럼 비교표 |
| `DECK_05_STRUCTURE_KEYWORD.html` | 구조 매칭 4 항목 상세 (콘텐츠 성격 / 시각 의도 / 편집 슬롯 / 항목수·관계) |
| `DECK_06_FIGMA_TO_DB.html` | Frame 18 의 DB 저장 형태 샘플 (YAML) |
| `DECK_07_KEYWORD_PIPELINE.html` | 키워드집 정리 과정 + Frame 18 샘플 |
**생성 코드** : `pipeline_16_deck_4pages.py`
### 보조 보고서
| 파일 | 내용 |
|---|---|
| `KEYWORD_INVENTORY.html` | 키워드집 생성 보고서 (1,713 고유 + 13 중요 표기) |
| `ATTACH_07_WEIGHT_VALIDATION.html` | V1 가중치 Logistic Regression 검증 |
| `V4_SLOT_ABLATION.md` | V4 slot 축 ablation 결과 |
| `FIGMA_KEYWORDS_REPORT.html` | Frame 별 키워드 인벤토리 |
| `FRAME_KEYWORD_REVIEW.html` | Frame 별 키워드 검토 |
---
## 발견된 약점 종합 (8 가지)
| # | 약점 | 발견 시점 | 우선순위 |
|---|---|---|---|
| 1 | 02-2.2 매칭 실패 (정답 Frame 14 reject) | V4 결과 | 🥇 1순위 |
| 2 | MDX 콘텐츠 성격 분류 부정확 (키워드 사전 한계) | V3 r5 검토 | 🥈 2순위 |
| 3 | MDX 시각 의도 분류 부정확 (동일 한계) | V3 r5 검토 | 🥈 2순위 |
| 4 | 편집 슬롯 의미 매핑 부재 | V4 코드 검토 | 🥉 3순위 |
| 5 | V4 cardinality 중복 가중 | ablation | 🥉 3순위 |
| 6 | V4 slot 축 frame 선별 무영향 | ablation | 🥉 3순위 (4 + 5 와 함께) |
| 7 | 표 첫 행만 추출 (다행 무시) | DECK 04 정직성 점검 | 4순위 |
| 8 | 그림/이미지 frame 매칭 약함 | V3 r5 검토 | 4순위 |
## 다음 단계 (개선 방향)
| 작업 | 내용 | 공수 |
|---|---|---|
| **02-2.2 교정** | Frame 14 anchor_sets 재라벨링 + 도메인 키워드 보강 → TARGET 4/4 | 1~2 일 |
| **MDX 분석 LLM 화** | 콘텐츠 성격 / 시각 의도를 키워드 사전 → Anthropic API 호출 | 3~5 일 |
| **슬롯 의미 매핑 모듈** | "BIM → col_a_label" 매핑 + V4 slot 축 진짜 역할 부여 | 5~7 일 |
| **표 다행 처리** | rows 슬롯 채우기용 다행 추출 | 2~3 일 |
| **그림 매칭 강화** | 본문 이미지 + 텍스트 결합 분석 | 2~3 일 |
---
## 핵심 메시지 (3 줄 요약)
1. **TARGET 75% (3/4)** — V1 가중치는 Logistic Regression 으로 검증 (LOOCV 4/4), BM25 / IDF 보다 우위
2. **약점**: V3 의 콘텐츠 성격 / 시각 의도가 키워드 사전 기반이라 부정확. V4 의 slot 축은 ablation 으로 frame 선별 무영향 확인
3. **다음 단계**: 02-2.2 교정 (1~2일) → MDX 분석 LLM 화 (3~5일) → 슬롯 의미 매핑 모듈 (5~7일)