Kei API 연동 복구 + 실장 정보구조 분석 + 팀장 role 기반 배치

1단계 (실장):
  - Kei API 연동 복구 (타임아웃 무제한, Kei persona 사고)
  - 정보 구조 파악 단계 추가 (본문 흐름 vs 참조 분리)
  - 각 꼭지에 role(flow/reference) 부여
  - fallback: Anthropic 직접 호출 (info_structure + role 포함)

2단계 (팀장):
  - info_structure + role 기반 배치 규칙 추가
  - flow → 좌측/메인, reference → 우측/사이드
  - detail_target → 본문 제외
  - 중복 방지 규칙

파이프라인:
  - pipeline.py import re 추가

Figma 관련 (다른 Claude Code 작업분):
  - catalog.yaml, figma-screenshots, figma-analysis, 테스트 HTML

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 11:33:17 +09:00
parent 33bd3a56c6
commit 7b034b04b6
24 changed files with 2400 additions and 90 deletions

View File

@@ -81,11 +81,28 @@ def _load_catalog() -> str:
DIRECTOR_PROMPT = """당신은 디자인 팀장이다. 실장이 분석한 꼭지 목록을 받아 레이아웃을 설계한다.
## 역할
- 실장의 info_structure(정보 구조)와 각 꼭지의 role(flow/reference)을 **반드시 존중**한다
- 각 꼭지에 적합한 블록을 매핑한다
- 전체 공간을 배분하고 겹침을 방지한다
- 각 블록의 글자 수 가이드를 결정한다
- **텍스트는 절대 정리하지 않는다** (텍스트 편집자가 별도로 한다)
## 정보 구조 기반 배치 (가장 중요한 규칙)
실장이 각 꼭지에 role을 부여했다. 이 role에 따라 배치 영역이 결정된다:
- **role: "flow"** (본문 흐름) → 좌측 또는 메인 영역에 배치. 위→아래 순서대로.
- **role: "reference"** (참조 정보) → 우측 사이드 영역에 독립 배치. 본문 흐름과 분리.
- **detail_target: true** (상세 내용) → 본문에 넣지 않는다. popup/자세히보기로 분리.
배치 예시:
- 본문 흐름(flow) 꼭지 3개 + 참조(reference) 꼭지 1개 → 좌측에 flow 3개, 우측에 reference 1개
- 모든 꼭지가 flow → 단일 컬럼 또는 균등 분할
- detail_target 꼭지 → 해당 블록에 연결된 별도 영역 (현재 블록 없으면 생략)
## 중복 방지 규칙
- 같은 내용이 두 개 블록에 나오면 안 된다
- 예: 용어 정의가 카드에도 있고 비교 블록에도 있으면 → 하나만 선택
- 블록 타입이 다르더라도 같은 내용이면 중복
## {catalog}
## 이미지 처리 규칙
@@ -99,12 +116,13 @@ DIRECTOR_PROMPT = """당신은 디자인 팀장이다. 실장이 분석한 꼭
- 공간에 안 들어가면 → 요약 요청 또는 페이지 분리
## 자세히보기 규칙
- 너무 구체적/세부적인 내용은 details-block으로 설계
- 슬라이드 표면: 요약만, 펼치면: 전체 상세
- detail_target: true인 꼭지는 본문에 넣지 않는다
- 관련된 블록 근처에 popup/링크로 연결
## 공간 배분 규칙
- CSS grid-template-areas 형식으로 배치
- 영역명: header, left, right, center, main, footer 등
- flow 꼭지는 좌측/메인, reference 꼭지는 우측/사이드
- 꼭지끼리 겹치지 않도록 설계
- 각 블록에 대략적 크기 감(small/medium/large) 제시
@@ -155,14 +173,18 @@ async def create_layout_concept(
catalog_text = _load_catalog()
# 꼭지 요약
# 꼭지 요약 (role과 detail_target 포함)
topics_summary = []
for t in analysis.get("topics", []):
role = t.get("role", "flow")
line = (
f"꼭지 {t['id']}: {t['title']} "
f"[{t.get('layer', '?')}, 강조:{t.get('emphasis', False)}, "
f"[{t.get('layer', '?')}, ROLE:{role}, "
f"강조:{t.get('emphasis', False)}, "
f"방향:{t.get('direction', '?')}, 유형:{t.get('content_type', 'text')}]"
)
if t.get("detail_target"):
line += " → ★자세히보기 대상 (본문에 넣지 마라)"
if t.get("image_info"):
line += f" 이미지:{t['image_info']}"
if t.get("table_info"):
@@ -173,14 +195,21 @@ async def create_layout_concept(
system = DIRECTOR_PROMPT.replace("{catalog}", catalog_text)
info_structure = analysis.get("info_structure", "정보 구조 미분석")
user_prompt = (
f"## 실장 분석 결과\n"
f"제목: {analysis.get('title', '')}\n"
f"페이지 수: {analysis.get('total_pages', 1)}\n"
f"정보 구조: {info_structure}\n\n"
f"꼭지 목록:\n" + "\n".join(topics_summary) +
f"\n\n## 원본 콘텐츠 (분량 참고)\n{content[:2000]}\n\n"
f"## 요청\n"
f"위 꼭지를 어떤 블록으로, 어디에, 몇 페이지로 배치할지 설계해줘.\n"
f"위 꼭지를 어떤 블록으로, 어디에 배치할지 설계해줘.\n"
f"반드시 각 꼭지의 ROLE(flow/reference)에 따라 영역을 배정해라.\n"
f"flow → 좌측/메인, reference → 우측/사이드.\n"
f"detail_target → 본문에 넣지 마라.\n"
f"같은 내용이 두 블록에 중복되면 안 된다.\n"
f"텍스트는 채우지 마. 구조만 JSON으로."
)