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
+171
View File
@@ -0,0 +1,171 @@
"""Phase 14 샘플 — AI-Meta (TAG Jaccard+IDF) 동작 과정 단계별 설명
MDX03-1 "DX 시행을 위한 필수요건"을 예시로 전 과정 재현.
"""
import sys
import math
import collections
import json
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from methods import _load_metadata_db
ROOT = Path(r"d:\ad-hoc\kei\design_agent")
PREVIEW_DIR = ROOT / "data" / "figma_previews"
def main():
meta = _load_metadata_db()
mdx_sections = meta.get("mdx_sections", {})
figma_frames = meta.get("figma_frames", {})
with open(PREVIEW_DIR / "index.json", encoding="utf-8") as f:
idx_data = json.load(f)
frame_to_short = {info["frame_id"]: sid for sid, info in idx_data.items()}
png_rel = "../../data/figma_previews/"
# IDF 계산 (32개 Figma 전체에서 각 개념이 얼마나 드문가)
df = collections.Counter()
N = 0
for fid, v in figma_frames.items():
if not isinstance(v, dict):
continue
for c in v.get("concepts", []):
df[c] += 1
N += 1
idf = {c: math.log(N / cnt) if cnt > 0 else 0 for c, cnt in df.items()}
# 예시 유닛들
examples = [
("MDX03-1", "13", "1171281190", "1171281192"), # MDX03-1, 정답 13, 비교군 15
("MDX03-2", "29", "1171281210", "1171281180"), # MDX03-2, 정답 29
]
lines = []
lines.append("# Phase 14 샘플 — AI-Meta 동작 단계별 설명")
lines.append("")
lines.append("## AI-Meta 알고리즘 요약")
lines.append("")
lines.append("1. 사전에 AI(Claude/Kei)가 각 MDX 섹션과 Figma 프레임에서 **핵심 개념(concepts) 집합**을 추출해 `metadata_db.yaml`에 저장")
lines.append("2. 매칭 시: MDX 개념 집합 A, Figma 개념 집합 B")
lines.append("3. 교집합 A ∩ B의 IDF 합 ÷ 합집합 A B의 IDF 합 = **IDF 가중 Jaccard** 점수")
lines.append("4. 높은 점수일수록 개념이 많이 겹치고, 드문 개념이 겹칠수록 가중치 큼")
lines.append("")
lines.append(f"**IDF 베이스**: {N}개 Figma 프레임")
lines.append("")
# MDX 섹션 개념 전체 일람
lines.append("## 사전 추출된 MDX 개념 집합 (metadata_db.yaml)")
lines.append("")
lines.append("| MDX 섹션 | 개념 집합 | layout_hint |")
lines.append("|---------|----------|-------------|")
for sec_id, v in mdx_sections.items():
if isinstance(v, dict):
concepts = ", ".join(v.get("concepts", []))
layout = v.get("layout_hint", "")
lines.append(f"| {sec_id} | {concepts} | {layout} |")
lines.append("")
# 각 예시에 대해 상세 설명
for uid, correct_sid, correct_fid, other_fid in examples:
lines.append("---")
lines.append("")
lines.append(f"## 예시: {uid} 매칭 (정답 Frame {correct_sid})")
lines.append("")
mdx_concepts = set(mdx_sections[uid].get("concepts", []))
lines.append(f"### Step 1 — {uid}의 개념 집합 A")
lines.append("")
lines.append(f"```")
lines.append(f"A = {{ {', '.join(sorted(mdx_concepts))} }}")
lines.append(f"|A| = {len(mdx_concepts)}")
lines.append(f"```")
lines.append("")
# 정답 Frame과 비교
correct_concepts = set(figma_frames[correct_fid].get("concepts", []))
inter_c = mdx_concepts & correct_concepts
union_c = mdx_concepts | correct_concepts
num_c = sum(idf.get(c, 0.5) for c in inter_c)
den_c = sum(idf.get(c, 0.5) for c in union_c)
score_c = num_c / den_c if den_c > 0 else 0
correct_info = idx_data.get(correct_sid, {})
correct_png = correct_info.get("png", "")
correct_title = correct_info.get("title_text", "").replace("\n", " ").strip()
lines.append(f"### Step 2 — 정답 후보 Frame **{correct_sid}** 개념 집합 B")
lines.append("")
lines.append(f"![Frame {correct_sid}]({png_rel}{correct_png})")
lines.append("")
lines.append(f"타이틀: **{correct_title}**")
lines.append("")
lines.append(f"```")
lines.append(f"B = {{ {', '.join(sorted(correct_concepts))} }}")
lines.append(f"|B| = {len(correct_concepts)}")
lines.append(f"```")
lines.append("")
lines.append(f"### Step 3 — 교집합 A ∩ B (공통 개념)")
lines.append("")
lines.append("| 개념 | Figma DF | IDF |")
lines.append("|------|----------|-----|")
inter_sorted = sorted(inter_c, key=lambda c: -idf.get(c, 0))
for c in inter_sorted:
lines.append(f"| **{c}** | {df.get(c, 0)} | {idf.get(c, 0):.3f} |")
lines.append("")
lines.append(f"공통 {len(inter_c)}개, IDF 합 = **{num_c:.3f}**")
lines.append("")
lines.append(f"### Step 4 — 합집합 A B")
lines.append("")
lines.append(f"```")
lines.append(f"A B = {{ {', '.join(sorted(union_c))} }}")
lines.append(f"|A B| = {len(union_c)}개, IDF 합 = {den_c:.3f}")
lines.append(f"```")
lines.append("")
lines.append(f"### Step 5 — 최종 점수")
lines.append("")
lines.append("```")
lines.append(f"score(MDX={uid}, Frame={correct_sid}) = {num_c:.3f} / {den_c:.3f} = **{score_c:.3f}**")
lines.append("```")
lines.append("")
# 비교: 오답 후보 (다른 한 프레임)
other_concepts = set(figma_frames.get(other_fid, {}).get("concepts", []))
inter_o = mdx_concepts & other_concepts
union_o = mdx_concepts | other_concepts
num_o = sum(idf.get(c, 0.5) for c in inter_o)
den_o = sum(idf.get(c, 0.5) for c in union_o)
score_o = num_o / den_o if den_o > 0 else 0
other_sid = frame_to_short.get(other_fid, "?")
other_info = idx_data.get(other_sid, {})
other_png = other_info.get("png", "")
other_title = other_info.get("title_text", "").replace("\n", " ").strip()
lines.append(f"### (비교) 오답 후보 Frame **{other_sid}**")
lines.append("")
lines.append(f"![Frame {other_sid}]({png_rel}{other_png})")
lines.append("")
lines.append(f"타이틀: **{other_title}**")
lines.append("")
lines.append(f"개념: `{{ {', '.join(sorted(other_concepts))} }}`")
lines.append("")
lines.append(f"- 공통: {sorted(inter_o)} ({len(inter_o)}개)")
lines.append(f"- 점수: {num_o:.3f} / {den_o:.3f} = **{score_o:.3f}**")
lines.append("")
diff = score_c - score_o
lines.append(f"**{correct_sid}{other_sid}{diff:+.3f} 차이로 앞섬** — {correct_sid}에만 있는 독특한 개념이 점수를 끌어올림")
lines.append("")
out_path = Path(__file__).parent / "MATRIX_PHASE14_SAMPLE.md"
out_path.write_text("\n".join(lines), encoding="utf-8")
print(f"완료: {out_path}")
if __name__ == "__main__":
main()