docs: Viewclinic 리포트 덱을 INFINITH Deck 규격(infinith-deck 스킬)으로 재생성
- 20×11.25in, F7F8FC/021341 플랫 배경, Pretendard + Playfair, 상태색 칩 - 빌드 스크립트 build_viewclinic_deck.py는 ~/.claude/skills/infinith-deck/scripts/ifd.py 사용 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
978073dd0e
commit
99d770b75f
Binary file not shown.
Binary file not shown.
@ -1,210 +1,213 @@
|
|||||||
import sys
|
"""
|
||||||
sys.path.insert(0, "/Users/haewonkam/.claude/skills/haewon_signature_deck/scripts")
|
Viewclinic AI Answer Readiness Report 덱 빌드 (INFINITH Deck 규격)
|
||||||
import hsd
|
|
||||||
from hsd import Deck
|
|
||||||
|
|
||||||
OUT = sys.argv[1]
|
python3 docs/reports/build_viewclinic_deck.py docs/reports/Viewclinic_AI_Answer_Readiness_Report.pptx
|
||||||
d = Deck(footer_base="INFINITH · Viewclinic AI Answer Readiness")
|
"""
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, "/Users/haewonkam/.claude/skills/infinith-deck/scripts")
|
||||||
|
from ifd import Deck
|
||||||
|
|
||||||
|
OUT = sys.argv[1] if len(sys.argv) > 1 else "Viewclinic_AI_Answer_Readiness_Report.pptx"
|
||||||
|
d = Deck()
|
||||||
|
|
||||||
# 01 Cover
|
# 01 Cover
|
||||||
d.cover(
|
d.cover(
|
||||||
eyebrow="INFINITH AI DISCOVERY · AEO / GEO AUDIT v1.0",
|
eyebrow="AI DISCOVERY · AEO / GEO AUDIT v1.0",
|
||||||
title="VIEWCLINIC",
|
title_lines=["AI Answer", "Readiness Report."],
|
||||||
subtitle="AI Answer Readiness Report",
|
subtitle="뷰성형외과 · viewclinic.com · 36개 항목 실측 · 2026. 08. 28",
|
||||||
lede=["뷰성형외과 홈페이지가 ChatGPT·Gemini·Perplexity 답변에 인용될 준비가 됐는지 36개 항목으로 진단했습니다.",
|
meta_right="AI Discovery Report · 2026",
|
||||||
"결과는 48점(C). 크롤러 접근과 강남언니는 강하지만, 홈페이지에 인용할 문장과 엔티티 근거가 없습니다."],
|
|
||||||
meta=[("PREPARED FOR", "뷰성형외과"),
|
|
||||||
("PREPARED BY", "INFINITH AI Discovery"),
|
|
||||||
("AUDITED", "2026. 08. 28"),
|
|
||||||
("SCOPE", "viewclinic.com · 36 criteria")],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 02 Executive summary (KPI 4-up)
|
# 02 Executive summary
|
||||||
s = d.slide(eyebrow="EXECUTIVE SUMMARY",
|
s = d.slide(eyebrow="Executive Summary",
|
||||||
title="읽을 수는 있지만, ", title_accent="인용할 근거가 없다",
|
title="읽을 수는 있지만, ", title_accent="인용할 근거가 없다",
|
||||||
lede=["36개 항목 중 31개를 실측했고, 오너 접근이 필요한 5개는 점수 분모에서 제외했습니다.",
|
lede=["36개 항목 중 31개를 실측했고, 오너 계정이 필요한 5개는 점수 분모에서 제외했습니다.",
|
||||||
"접근성(A) 92%·표면(D) 72%는 양호, 엔티티(B) 30%·콘텐츠(C) 20%가 총점을 끌어내립니다."])
|
"접근성(A) 92%와 표면(D) 72%는 양호. 엔티티(B) 30%와 콘텐츠(C) 20%가 총점을 끌어내립니다."],
|
||||||
s.kpi_4up([
|
section="Summary")
|
||||||
("48 / 100", "AI Answer Readiness", "등급 C. 검증 항목 88점 만점 중 42.1점"),
|
k1, k2, k3, k4 = s.cards4(y=s.band_y, h=3.4)
|
||||||
("92%", "A · 크롤러 접근성", "AI 검색봇 12종 전부 허용, SSR 렌더링"),
|
k1.kpi("48 / 100", "AI ANSWER READINESS", "등급 C · 42.1 / 88점")
|
||||||
("20%", "C · 인용 가능 콘텐츠", "정의문 0, FAQ 0, HTML 표 0, H1 5개"),
|
k2.kpi("92%", "A · 크롤러 접근성", "AI 검색봇 12종 전부 허용")
|
||||||
("5 / 36", "미검증 항목", "GA4·서버로그·GSC·Bing은 오너 계정 필요"),
|
k3.kpi("20%", "C · 인용 가능 콘텐츠", "정의문 0 · FAQ 0 · HTML 표 0")
|
||||||
|
k4.kpi("5 / 36", "미검증 항목", "GA4 · 서버로그 · GSC · Bing")
|
||||||
|
|
||||||
|
# 03 What AI sees (dark)
|
||||||
|
s = d.slide(eyebrow="What AI Sees · 진단의 결론",
|
||||||
|
title="문제는 차단이 아니라 ", title_accent="내용이다", dark=True, section="Findings")
|
||||||
|
L, R = s.cards2(y=s.band_y)
|
||||||
|
L.chip("정상", "good").rows([
|
||||||
|
("크롤러 접근 정상", "robots.txt가 OAI-SearchBot·PerplexityBot 등 12종을 허용. Cloudflare 차단 없음."),
|
||||||
|
("서버 렌더링 본문", "WordPress가 본문을 서버에서 렌더. JS 없이 10,757자 추출."),
|
||||||
|
("강남언니·YouTube 활발", "강남언니 후기 19,316건, 의료진 26명. YouTube 채널이 최신 영상을 꾸준히 발행."),
|
||||||
|
])
|
||||||
|
R.chip("치명", "critical").rows([
|
||||||
|
("누구인지 확정 불가", "MedicalClinic 스키마 없음, sameAs 비어 있음. 시술 목록 JSON-LD는 문법 오류로 무효."),
|
||||||
|
("인용할 문장 없음", "H1 5개가 전부 영문 라벨. FAQ 0개, HTML 표 0개, 정의문 0개."),
|
||||||
|
("표면 간 NAP 불일치", "GBP에 전화번호 없음. 웹사이트가 viewplasticsurgery.com. 주소 표기 3종."),
|
||||||
])
|
])
|
||||||
|
|
||||||
# 03 What AI sees
|
# 04 Scorecard
|
||||||
s = d.slide(eyebrow="WHAT AI SEES · 진단의 결론",
|
s = d.slide(eyebrow="Scorecard · 6 Categories",
|
||||||
title="문제는 차단이 아니라 ", title_accent="내용이다")
|
|
||||||
L, R = s.cards_2up()
|
|
||||||
L.pill("정상").rows([
|
|
||||||
("크롤러 접근 정상", "robots.txt가 OAI-SearchBot·PerplexityBot 등 12종을 허용. Cloudflare 차단 없음"),
|
|
||||||
("서버 렌더링 본문", "WordPress가 본문을 서버에서 렌더. JS 없이 10,757자 추출됨"),
|
|
||||||
("YouTube 활발", "VIEW SHORTS·FILM 채널이 최신 영상을 꾸준히 발행. 오픈웹 언급 자산"),
|
|
||||||
])
|
|
||||||
R.pill("치명", tone="rival").rows([
|
|
||||||
("누구인지 확정 불가", "MedicalClinic 스키마 없음, sameAs 비어 있음, 시술 목록 JSON-LD는 문법 오류로 무효"),
|
|
||||||
("인용할 문장 없음", "H1 5개가 전부 영문 라벨. FAQ 0개, HTML 표 0개, 정의문 0개"),
|
|
||||||
("15개월 갱신 신호 없음", "post-sitemap 최신 lastmod 2024-05-31. dateModified 마크업 없음"),
|
|
||||||
])
|
|
||||||
|
|
||||||
# 04 Scorecard table
|
|
||||||
s = d.slide(eyebrow="SCORECARD · 6 CATEGORIES",
|
|
||||||
title="카테고리별 점수와 ", title_accent="검증 범위",
|
title="카테고리별 점수와 ", title_accent="검증 범위",
|
||||||
lede="점수는 검증된 항목만으로 정규화했습니다. 미검증 항목을 확인하면 총점이 바뀔 수 있습니다.")
|
lede="점수는 검증된 항목만으로 정규화했습니다. 미검증 항목을 확인하면 총점이 바뀔 수 있습니다.",
|
||||||
W, Rail = s.wide_rail()
|
section="Scorecard")
|
||||||
|
W, Rail = s.cards2(y=s.band_y, split=0.66)
|
||||||
W.grid(
|
W.grid(
|
||||||
headers=["카테고리", "배점", "획득", "판정"],
|
headers=["카테고리", "배점", "획득", "검증", "판정"],
|
||||||
col_w=[2.45, 0.80, 0.95, 0.85], start=0.20,
|
col_w=[4.6, 1.3, 2.0, 1.4, 1.6],
|
||||||
header_tones=[hsd.MUTED, hsd.MUTED, hsd.VIOLET, hsd.MUTED],
|
|
||||||
rows=[
|
rows=[
|
||||||
["A · AI 크롤러 접근성", "20", "15.7 / 17", "92% 우수"],
|
["A · AI 크롤러 접근성", "20", "15.7 / 17", "6 / 7", "우수"],
|
||||||
["B · 엔티티 식별·구조화", "20", "6.0 / 20", "30% 미흡"],
|
["B · 엔티티 식별·구조화", "20", "6.0 / 20", "7 / 7", "미흡"],
|
||||||
["C · 답변 인용 가능 콘텐츠", "25", "5.0 / 25", "20% 치명"],
|
["C · 답변 인용 가능 콘텐츠", "25", "5.0 / 25", "8 / 8", "치명"],
|
||||||
["D · AI 인용 표면 확보", "20", "13.7 / 19", "72% 양호"],
|
["D · AI 인용 표면 확보", "20", "13.7 / 19", "5 / 6", "양호"],
|
||||||
["E · AI 가시성 측정 인프라", "10", "0 / 2", "0% 미설치"],
|
["E · AI 가시성 측정 인프라", "10", "0 / 2", "1 / 4", "미설치"],
|
||||||
|
["F · 기술 위생", "5", "1.7 / 5", "4 / 4", "미흡"],
|
||||||
],
|
],
|
||||||
|
tones=[[None, None, None, None, "info"], [None, None, None, None, "warning"],
|
||||||
|
[None, None, None, None, "critical"], [None, None, None, None, "good"],
|
||||||
|
[None, None, None, None, "critical"], [None, None, None, None, "warning"]],
|
||||||
|
row_h=0.62,
|
||||||
)
|
)
|
||||||
Rail.bullets("읽는 법", items=[
|
Rail.title("읽는 법").bullets([
|
||||||
"획득 분모는 검증 항목 배점 합. E는 미검증 3개라 분모가 2점뿐",
|
"획득 분모는 검증 항목의 배점 합. E는 미검증 3개라 분모가 2점뿐.",
|
||||||
"F 기술 위생은 5점 중 1.7점(33%). 표에서 생략",
|
"총점 42.1 / 88 = 48점, 등급 C.",
|
||||||
"총점 = 42.1 / 88 = 48점, 등급 C",
|
"미검증 5개는 GA4·서버로그·GSC·Bing 계정 접근으로 1일 안에 채운다.",
|
||||||
])
|
])
|
||||||
|
|
||||||
# 05 A 접근성
|
# 05 A 접근성
|
||||||
s = d.slide(eyebrow="A · ACCESS & CRAWLABILITY · 92%",
|
s = d.slide(eyebrow="A · Access & Crawlability · 92%",
|
||||||
title="크롤러 접근은 ", title_accent="열려 있다")
|
title="크롤러 접근은 ", title_accent="열려 있다", section="A · Access")
|
||||||
L, R = s.cards_2up()
|
L, R = s.cards2(y=s.band_y)
|
||||||
L.pill("우수 · 3/3").rows([
|
L.chip("우수 · 3/3", "info").rows([
|
||||||
("A1 검색용 AI 봇 허용", "robots.txt: Disallow는 /wp-admin/ 뿐. 12종 UA 실제 GET 전부 200"),
|
("A1 검색용 AI 봇 허용", "robots.txt Disallow는 /wp-admin/ 뿐. 12종 UA로 실제 GET, 전부 200."),
|
||||||
("A2 CDN 차단 없음", "nginx 직접 응답. Cloudflare 헤더·AI UA 챌린지 없음"),
|
("A2 CDN 차단 없음", "nginx 직접 응답. Cloudflare 헤더와 AI UA 챌린지 없음."),
|
||||||
("A4 HTTPS 정합", "http://viewclinic.com → 301 → https://www.viewclinic.com/ 정본 수렴"),
|
("A4 HTTPS 정합", "http://viewclinic.com → 301 → https://www.viewclinic.com/ 정본 수렴."),
|
||||||
])
|
])
|
||||||
R.pill("보완 · 2/3", tone="neutral").rows([
|
R.chip("보완 · 2/3", "warning").rows([
|
||||||
("A5 sitemap.xml", "선언·200 응답. 페이지 249개. 단 post lastmod 최신이 2024-05-31"),
|
("A5 sitemap.xml", "선언·200 응답, 페이지 249개. 단 post lastmod 최신이 2024-05-31."),
|
||||||
("A7 응답 속도·무게", "TTFB 0.135s는 양호. 초기 HTML 838KB로 기준 300KB의 2.8배"),
|
("A7 응답 속도·무게", "TTFB 0.135s는 양호. 초기 HTML 838KB로 기준 300KB의 2.8배."),
|
||||||
("A6 Bing 색인 (미검증)", "ChatGPT 검색은 Bing 인덱스 의존. Webmaster 등록 여부 오너 확인 필요"),
|
("A6 Bing 색인 (미검증)", "ChatGPT 검색은 Bing 인덱스에 의존. Webmaster 등록 여부는 계정 확인 필요."),
|
||||||
])
|
])
|
||||||
|
|
||||||
# 06 B 엔티티
|
# 06 B 엔티티 (dark)
|
||||||
s = d.slide(eyebrow="B · ENTITY & STRUCTURED DATA · 33%",
|
s = d.slide(eyebrow="B · Entity & Structured Data · 30%",
|
||||||
title="AI가 이 병원을 ", title_accent="하나의 엔티티로 못 묶는다")
|
title="AI가 이 병원을 ", title_accent="하나의 엔티티로 못 묶는다", dark=True, section="B · Entity")
|
||||||
L, R = s.cards_2up()
|
L, R = s.cards2(y=s.band_y)
|
||||||
L.pill("치명", tone="rival").rows([
|
L.chip("치명", "critical").rows([
|
||||||
("B1 JSON-LD 문법 무효", "ItemList 블록 쉼표 누락(line 11). 시술 목록 구조화 데이터 전체가 파서에서 버려짐"),
|
("B1 JSON-LD 문법 무효", "ItemList 블록 쉼표 누락(line 11). 시술 목록 구조화 데이터 전체가 파서에서 버려짐."),
|
||||||
("B2 MedicalClinic 없음", "Organization·WebSite만 존재. 주소·전화·진료시간·전문분야 미구조화"),
|
("B2 MedicalClinic 없음", "Organization·WebSite만 존재. 주소·전화·진료시간·전문분야가 구조화되지 않음."),
|
||||||
("B3 Physician 없음", "의료진 정보는 텍스트·이미지로만. 누가 수술하는지 기계가 못 읽음"),
|
("B3 Physician 없음", "의료진 정보는 텍스트와 이미지로만 존재. 누가 수술하는지 기계가 읽지 못함."),
|
||||||
])
|
])
|
||||||
R.pill("미흡", tone="neutral").rows([
|
R.chip("미흡", "warning").rows([
|
||||||
("B5 sameAs 비어 있음", "푸터에 YouTube·Instagram·Facebook 링크가 있으나 스키마에 미연결"),
|
("B5 sameAs 비어 있음", "푸터에 YouTube·Instagram·Facebook 링크가 있으나 스키마에 연결되지 않음."),
|
||||||
("B4 NAP 표기 2종", "\"서울 강남구 봉은사로 107\" / \"서울특별시 강남구 봉은사로 107,\" 혼재"),
|
("B4 NAP 표기 2종", "\"서울 강남구 봉은사로 107\" / \"서울특별시 강남구 봉은사로 107,\" 혼재."),
|
||||||
("B7 영문 사이트 미연결", "viewplasticsurgery.com이 별도로 있으나 hreflang 없음. 두 도메인이 서로 모름"),
|
("B7 영문 사이트 미연결", "viewplasticsurgery.com이 별도로 있으나 hreflang 없음. 두 도메인이 서로 모름."),
|
||||||
])
|
])
|
||||||
|
|
||||||
# 07 C 콘텐츠
|
# 07 C 콘텐츠
|
||||||
s = d.slide(eyebrow="C · ANSWER-READY CONTENT · 20%",
|
s = d.slide(eyebrow="C · Answer-Ready Content · 20%",
|
||||||
title="답변엔진이 잘라 갈 ", title_accent="단락이 없다")
|
title="답변엔진이 잘라 갈 ", title_accent="단락이 없다", section="C · Content")
|
||||||
L, R = s.cards_2up()
|
L, R = s.cards2(y=s.band_y)
|
||||||
L.pill("0점 항목", tone="rival").rows([
|
L.chip("0점 항목", "critical").rows([
|
||||||
("C1 정의문 없음", "메인 첫 화면은 슬라이더와 \"VIEW SELFIE\" 라벨. 시술 페이지 첫 텍스트는 상담 폼"),
|
("C1 정의문 없음", "메인 첫 화면은 슬라이더와 \"VIEW SELFIE\" 라벨. 시술 페이지 첫 텍스트는 상담 폼."),
|
||||||
("C2 FAQ 없음", "메인·가슴성형 페이지에서 FAQ·Q&A 섹션 탐지 안 됨"),
|
("C2 FAQ 없음", "메인·가슴성형 페이지에서 FAQ·Q&A 섹션이 탐지되지 않음."),
|
||||||
("C3 H1 5개, 전부 라벨", "VIEW SELFIE / EVENT / SHORTS / FILM / SPECIALITY. 시술 페이지는 H1 없음"),
|
("C3 H1 5개, 전부 라벨", "VIEW SELFIE / EVENT / SHORTS / FILM / SPECIALITY. 시술 페이지는 H1 없음."),
|
||||||
])
|
])
|
||||||
R.pill("부분 점수", tone="neutral").rows([
|
R.chip("부분 점수", "warning").rows([
|
||||||
("C7 의료진 권위 신호 있음", "모티바 KOL·복지부 표창·갈더마 방문 등 17회 언급. 단 구조화 안 됨"),
|
("C7 의료진 권위 신호 있음", "모티바 KOL·복지부 표창·갈더마 방문 등 17회 언급. 단 구조화되지 않음."),
|
||||||
("C4 수치 표기 미흡", "\"보형물 사용량 1위\" 같은 주장형. 가격대·수술시간·회복기간 표 없음"),
|
("C4 수치 표기 미흡", "\"보형물 사용량 1위\" 같은 주장형. 가격대·수술시간·회복기간 표 없음."),
|
||||||
("C6 신선도 신호 약함", "dateModified 없음. 유튜브 활동이 사이트 갱신으로 전달되지 않음"),
|
("C6 신선도 신호 약함", "dateModified 없음. 유튜브 활동이 사이트 갱신으로 전달되지 않음."),
|
||||||
])
|
])
|
||||||
|
|
||||||
# 08 D 표면 + E 측정
|
# 08 D 표면 / E 측정 (dark)
|
||||||
s = d.slide(eyebrow="D · SURFACES / E · MEASUREMENT",
|
s = d.slide(eyebrow="D · Surfaces / E · Measurement",
|
||||||
title="강남언니는 강하고, ", title_accent="GBP는 전화번호가 없다")
|
title="강남언니는 강하고, ", title_accent="GBP는 전화번호가 없다", dark=True, section="D · Surfaces")
|
||||||
L, R = s.cards_2up()
|
L, R = s.cards2(y=s.band_y)
|
||||||
L.pill("D · 표면 72%").rows([
|
L.chip("D · 표면 72%", "good").rows([
|
||||||
("D1 강남언니 우수", "후기 19,316건, 의료진 26명, 이벤트 52건. 병의원 AI 인용의 핵심 표면 확보"),
|
("D1 강남언니 우수", "후기 19,316건, 의료진 26명, 이벤트 52건. 병의원 AI 인용의 핵심 표면 확보."),
|
||||||
("D2 GBP 4.9점 (901)", "소유자 게시물 활성. 단 전화번호 미등록, 웹사이트가 viewplasticsurgery.com"),
|
("D2 GBP 4.9점 (901)", "소유자 게시물 활성. 단 전화번호 미등록, 웹사이트가 viewplasticsurgery.com."),
|
||||||
("D4 NAP 표기 3종", "홈페이지·강남언니·GBP 주소 표기가 전부 다름. AI가 한 병원으로 묶을 근거 약함"),
|
("D4 NAP 표기 3종", "홈페이지·강남언니·GBP 주소 표기가 전부 다름. 한 병원으로 묶을 근거 약함."),
|
||||||
])
|
])
|
||||||
R.pill("E · 측정 0%", tone="rival").rows([
|
R.chip("E · 측정 0%", "critical").rows([
|
||||||
("E1 크롤러 로그", "nginx 직접 호스팅. AI 봇 히트 추출·IP 검증 파이프라인 없음"),
|
("E1 크롤러 로그", "nginx 직접 호스팅. AI 봇 히트 추출과 IP 검증 파이프라인 없음."),
|
||||||
("E2 GA4 AI 유입 채널", "chatgpt.com·perplexity.ai 커스텀 채널그룹 없음. 오너 접근 필요"),
|
("E2 GA4 AI 유입 채널", "chatgpt.com·perplexity.ai 커스텀 채널그룹 없음. 계정 접근 필요."),
|
||||||
("E4 기준선 스팟체크", "미실시. 질의 10개 × 5회 반복 측정이 개선 증명의 전제"),
|
("E4 기준선 스팟체크", "미실시. 질의 10개 × 5회 반복 측정이 개선 증명의 전제."),
|
||||||
])
|
])
|
||||||
|
|
||||||
# 09 Action P0 / P1 (dark)
|
# 09 Action plan
|
||||||
s = d.slide(eyebrow="ACTION PLAN · P0 / P1",
|
s = d.slide(eyebrow="Action Plan",
|
||||||
title="즉시 고칠 것과 ", title_accent="4주 안에 만들 것", dark=True)
|
title="즉시 고칠 것과 ", title_accent="4주 안에 만들 것", section="Action Plan")
|
||||||
L, R = s.cards_2up()
|
a, b, c = s.cards3(y=s.band_y)
|
||||||
L.dark_block("P0 · 즉시 (1일~1주)", "엔티티·표면·측정", [
|
a.chip("P0 · 1일~1주", "critical").title("엔티티·표면·측정").bullets([
|
||||||
"깨진 JSON-LD 수정 + MedicalClinic 스키마 삽입, sameAs 연결",
|
"깨진 JSON-LD 수정, MedicalClinic 스키마 삽입, sameAs 연결.",
|
||||||
"GBP 전화번호 등록·웹사이트 교정, 4개 표면 NAP 통일",
|
"GBP 전화번호 등록, 웹사이트를 viewclinic.com으로 교정.",
|
||||||
"GA4 AI 채널그룹 + 서버로그 IP 검증 + GSC·Bing 등록",
|
"4개 표면 NAP를 한 글자까지 통일. 두 도메인 hreflang 연결.",
|
||||||
|
"GA4 AI 채널그룹, 서버로그 IP 검증, GSC·Bing 등록.",
|
||||||
])
|
])
|
||||||
R.dark_block("P1 · 4주 내", "콘텐츠 구조", [
|
b.chip("P1 · 4주 내", "warning").title("콘텐츠 구조").bullets([
|
||||||
"핵심 페이지 첫 단락에 정의문, 시술별 FAQ 5~8개 + FAQPage 스키마",
|
"핵심 페이지 첫 단락에 정의문. 시술별 FAQ 5~8개와 FAQPage 스키마.",
|
||||||
"페이지당 H1 1개 서술형, 비교표를 HTML table로, Physician 스키마",
|
"페이지당 H1 1개 서술형. 비교표를 HTML table로. Physician 스키마.",
|
||||||
"WordPress 5.5.3 업그레이드, alt 누락 111개 보완, HTML 무게 절감",
|
"WordPress 5.5.3 업그레이드, alt 누락 111개 보완, HTML 무게 절감.",
|
||||||
|
])
|
||||||
|
c.chip("P2 · 지속", "good").title("신선도·시딩").bullets([
|
||||||
|
"dateModified 마크업 활성화, 월 1회 사이트 갱신.",
|
||||||
|
"유튜브 영상을 사이트 글로 전사해 신선도를 전달.",
|
||||||
|
"티스토리·언론 기고로 naver.com 외 언급 도메인 확보.",
|
||||||
|
"분기 1회 반복 측정. 언급률과 신뢰구간으로만 보고.",
|
||||||
])
|
])
|
||||||
|
|
||||||
# 10 Roadmap (asym)
|
# 10 Roadmap (stats style, dark)
|
||||||
s = d.slide(eyebrow="ROADMAP · 8 WEEKS",
|
s = d.slide(eyebrow="Roadmap · 8 Weeks",
|
||||||
title="8주 안에 ", title_accent="C에서 B로")
|
title="8주 안에 ", title_accent="C에서 B로", dark=True, section="Roadmap")
|
||||||
L, R = s.cards_asym()
|
s.stats3([
|
||||||
L.timeline("실행 순서", [
|
("W1–2", "스키마·NAP·측정 인프라 설치.\n기준선 스팟체크 1회."),
|
||||||
("Week 1", "JSON-LD 수정, MedicalClinic·sameAs 삽입. GBP 전화·웹사이트 교정"),
|
("W3–6", "정의문·FAQ·H1 재설계·HTML 표.\nWordPress 업그레이드."),
|
||||||
("Week 2", "측정 인프라 설치. 기준선 스팟체크 1회 (질의 10개 × 5회)"),
|
("W7–8", "재진단. 미검증 5개 반영해\n총점 재산정."),
|
||||||
("Week 3–6", "정의문·FAQ·H1 재설계·HTML 표. WordPress 업그레이드"),
|
], y=s.band_y + 0.6)
|
||||||
("Week 7–8", "재진단. 미검증 5개 항목 반영해 총점 재산정"),
|
|
||||||
|
# 11 What we don't sell
|
||||||
|
s = d.slide(eyebrow="What We Don't Sell · 정직성 규약",
|
||||||
|
title="근거 없는 것은 ", title_accent="팔지 않는다", section="Integrity")
|
||||||
|
a, b, c = s.cards3(y=s.band_y)
|
||||||
|
a.icon_square().title("만들지 않는 것").bullets([
|
||||||
|
"llms.txt. Google 공식 효과 0, 채택률 0.13%, 서버 로그에 요청 자체가 없음.",
|
||||||
|
"네이버 블로그 증량. robots.txt가 AI 크롤링을 전면 금지, 글로벌 AI 기여도 0.",
|
||||||
])
|
])
|
||||||
R.numbered("P2 · 지속 항목", [
|
b.icon_square().title("약속하지 않는 것").bullets([
|
||||||
"dateModified 마크업 활성화, 월 1회 사이트 갱신",
|
"\"스키마 넣으면 인용됩니다\". 인과 증거 없음, 위생 조치로만 설명.",
|
||||||
"유튜브 영상을 사이트 글로 전사해 신선도 전달",
|
"순위·노출 보장. LLM 답변은 동일 질문에도 10~34% 흔들림.",
|
||||||
"티스토리·언론 기고로 naver.com 외 언급 도메인 확보",
|
])
|
||||||
"분기 1회 반복 측정, 언급률과 신뢰구간으로만 보고",
|
c.icon_square().title("측정 규율").bullets([
|
||||||
|
"단발 조회로 성과 보고 금지. 반복 측정과 신뢰구간만.",
|
||||||
|
"답변엔진 UI 자동 조회 금지. OpenAI·Perplexity 약관 위반.",
|
||||||
|
"AI 유입은 항상 하한값. 35~70%가 Direct로 유실.",
|
||||||
])
|
])
|
||||||
|
|
||||||
# 11 What we don't sell (3-up)
|
# 12 Method
|
||||||
s = d.slide(eyebrow="WHAT WE DON'T SELL · 정직성 규약",
|
s = d.slide(eyebrow="Method · AEO / GEO Rubric v1.0",
|
||||||
title="근거 없는 것은 ", title_accent="팔지 않는다")
|
title="36개 항목, 100점, ", title_accent="근거 등급을 명시", section="Method")
|
||||||
c1, c2, c3 = s.cards_3up()
|
a, b, c = s.cards3(y=s.band_y)
|
||||||
c1.bullets("만들지 않는 것", items=[
|
a.icon_square().title("채점 방식").bullets([
|
||||||
"llms.txt. Google 공식 효과 0, 채택률 0.13%, 서버 로그에 요청 자체가 없음",
|
"항목별 0~3 레벨 × 배점. 미검증은 0점이 아니라 분모 제외.",
|
||||||
"네이버 블로그 증량. robots.txt가 AI 크롤링 전면 금지, 글로벌 AI 기여도 0",
|
"A 20 · B 20 · C 25 · D 20 · E 10 · F 5.",
|
||||||
|
"등급 A 81+ · B 61~80 · C 41~60 · D 40 이하.",
|
||||||
])
|
])
|
||||||
c2.bullets("약속하지 않는 것", items=[
|
b.icon_square().title("배점 근거").bullets([
|
||||||
"\"스키마 넣으면 인용됩니다\". 인과 증거 없음, 위생 조치로만 설명",
|
"차단되면 절대 인용될 수 없다는 사실은 논쟁이 없다. A·B에 무게.",
|
||||||
"순위·노출 보장. LLM 답변은 동일 질문에도 10~34% 흔들림",
|
"GEO 콘텐츠 전술의 효과는 학술적으로 논쟁 중. C는 좋은 콘텐츠 원칙으로만.",
|
||||||
|
"병의원은 강남언니가 인용을 장악. D1 단일 항목 최고 배점 6.",
|
||||||
])
|
])
|
||||||
c3.bullets("측정 규율", items=[
|
c.icon_square().title("항목마다 붙는 태그").bullets([
|
||||||
"단발 조회로 성과 보고 금지. 반복 측정 + 신뢰구간만",
|
"근거 등급: 실측 / 학술 / 벤더 / 추정.",
|
||||||
"답변엔진 UI 자동 조회 금지. OpenAI·Perplexity 약관 위반",
|
"통제 가능성: 직접 / 영향 / 불가.",
|
||||||
"AI 유입은 항상 하한값. 35~70%가 Direct로 유실",
|
"채점 방식: 자동 / 반자동 / 수동. 자동 항목은 Edge Function으로 이식.",
|
||||||
])
|
|
||||||
|
|
||||||
# 12 Rubric method (3-up)
|
|
||||||
s = d.slide(eyebrow="METHOD · AEO / GEO RUBRIC v1.0",
|
|
||||||
title="36개 항목, 100점, ", title_accent="근거 등급을 명시")
|
|
||||||
c1, c2, c3 = s.cards_3up()
|
|
||||||
c1.bullets("채점 방식", items=[
|
|
||||||
"항목별 0~3 레벨 × 배점. 미검증은 0점이 아니라 분모 제외",
|
|
||||||
"A 20 · B 20 · C 25 · D 20 · E 10 · F 5",
|
|
||||||
"등급 A 81+ · B 61~80 · C 41~60 · D 40 이하",
|
|
||||||
])
|
|
||||||
c2.bullets("배점 근거", items=[
|
|
||||||
"차단되면 절대 인용될 수 없다는 사실은 논쟁이 없다. A·B에 무게",
|
|
||||||
"GEO 콘텐츠 전술 효과는 학술적으로 논쟁 중. C는 좋은 콘텐츠 원칙으로만",
|
|
||||||
"병의원은 강남언니가 인용을 장악. D1 단일 항목 최고 배점 6",
|
|
||||||
])
|
|
||||||
c3.bullets("항목마다 붙는 태그", items=[
|
|
||||||
"근거 등급: 실측 / 학술 / 벤더 / 추정",
|
|
||||||
"통제 가능성: 직접 / 영향 / 불가",
|
|
||||||
"채점 방식: 자동 / 반자동 / 수동. 자동 항목은 Edge Function으로 이식",
|
|
||||||
])
|
])
|
||||||
|
|
||||||
# 13 Closing
|
# 13 Closing
|
||||||
d.closing(eyebrow="NEXT STEP",
|
d.closing(eyebrow="Next Step",
|
||||||
title="표면은 확보됐다. ", title_accent="홈페이지가 따라가면 됩니다.",
|
title_lines=["표면은 확보됐습니다.", "홈페이지가 따라가면 됩니다."],
|
||||||
lede=["강남언니·GBP는 이미 강합니다. 홈페이지 스키마와 NAP 통일, 측정 인프라 세 가지가 P0입니다.",
|
lede="P0 세 가지: 스키마, NAP 통일, 측정 인프라. 미검증 5개는 계정 접근 후 1일 안에 채웁니다.",
|
||||||
"남은 미검증 5개는 GA4·서버로그·GSC·Bing 계정 접근만 주시면 1일 안에 채웁니다."],
|
cta_primary="P0 착수하기 →", cta_secondary="리포트 페이지 보기",
|
||||||
signature="INFINITH AI Discovery · AEO / GEO Audit v1.0 · 2026. 08. 28")
|
contact="infinith.kr · hello@infinith.kr")
|
||||||
|
|
||||||
d.save(OUT)
|
d.save(OUT)
|
||||||
print("saved", OUT)
|
print("saved", OUT)
|
||||||
|
|||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user