사전 등록 문서

사전 등록: 테크니컬 GEO 개입의 AI 크롤러 수집 효과 무작위 대조 실험

  • 작성 2026-08-10 · 결과 관측 전 확정본
  • 상태: 실행 중. 배포 2026-08-10 14:04:34 KST / 사후 8주 종료 2026-10-05 14:04 KST
  • 개정 R1 (2026-08-10): 표본 수 정정 15,300 → 3,597. 사유·경위는 §3.1.
  • 개정 R2 (2026-08-10): 적격 조건에 intro_ko 보유 추가 → 1,993곳. T2가 정의되지 않는 페이지를 배제하기 위함. 사유·경위는 §3.2.
  • 개정 R3 (2026-08-10): T1 검정 불가 확정. 처치 대상 스키마가 이미 전 페이지에 구현돼 있어 "추가"할 것이 없다. 2×2 → 단일 요인(T2)으로 축소하되, T1군을 대조군에 흡수해 표본 1,993을 유지한다. 사유·경위는 §3.3.
  • 개정 R4 (2026-08-10): 사전 기저를 소급 30일(baseline_hits)로 확정하고 즉시 배포. 위약 검정·크롤 웨이브 보고를 사전 등록에 추가. 사유·경위는 §6.1·§7.1.
  • 개정 R5 (2026-08-10): 프리미엄 2곳 제외로 표본 1,993 → 1,991. 배포 기록과 차단 조건 3종 결과를 확정. 사유·경위는 §6.2.
  • 다섯 개정 모두 결과 관측 전이며 H2·H3 가설 문언은 변경하지 않았다(H1은 검정 불가로 전환, H3는 검정 대상에서 제외).
  • 이 문서는 결과를 보기 전에 가설·표본·분석·중단 규칙을 못 박기 위한 것이다. 사후에 유리한 해석을 고르는 것(p-hacking)을 구조적으로 막는 장치이며, 실행 후 이 문서의 가설·분석 계획은 수정하지 않는다. 수정이 필요하면 별도 개정 이력으로 남긴다.

0. 왜 이 실험인가

지금까지 우리가 한 것과 참고 연구(arXiv:2606.25787)는 전부 관찰이다. "인용된 곳과 안 된 곳이 이렇게 다르더라"는 상관이지 인과가 아니다.

실제로 2026-08-10 자체 프로브에서 역설이 나왔다. 자사 인용이 있었던 병원(25곳)이 없었던 병원(425곳)보다 구조화 데이터 보유율이 낮았다(5% vs 21%). 관찰로는 이것을 해석할 수 없다. 사이트를 잘 만들어서 인용된 것인지, 인용되는 곳이 우연히 그런 것인지 구분이 안 된다.

인과를 보려면 우리가 개입하고, 배정을 무작위로 해야 한다.


0-1. 선행 연구에서 이 실험의 위치

추가 2026-08-11. "국내 최초"나 "세계 최초"라고 주장하지 않는다. 선행 연구는 있고, 다른 것은 배정 방식이다. 그 차이를 정확히 적어 두는 편이 과장보다 강하다.

  • 자연 실험은 이미 있다. ChatGPT 추천 트래픽을 대상으로 AEO 도입 시점 차이를 이용해 처치·대조를 나누고 단절적 시계열(ITS)로 플랫폼 성장분을 분리한 연구가 있다 (arXiv:2606.04362). 문제의식이 우리와 같다 — 올라간 것이 개입 덕인지 플랫폼이 커진 덕인지.

    차이는 배정이다. 자연 실험은 "AEO를 먼저 도입한 사이트가 원래 다른 사이트일 가능성"(선택 편향)을 완전히 없애지 못한다. 무작위 배정은 그것을 없앤다. 우리 실험이 더 나은 점은 새로움이 아니라 이 한 가지다.

  • 인용 측정 프레임: 통제 프롬프트 602개, 유효 인용 21,143건으로 인용을 선택(citation selection)과 흡수(citation absorption) 두 단계로 가른 연구가 있다 (arXiv:2604.25707). 우리 결과변수는 그중 앞단(크롤러가 가져가는가)에 해당한다. 뒷단(답변에 실제로 인용되는가)은 이 실험이 답하지 않는다 — 8절 한계에 이미 적은 범위와 같다.

  • 요인 실험: 6개 LLM × 18개 요인, 252,000 trial 규모의 요인 실험에서 첫 인용의 주 결정 요인은 관련성과 위치로 보고됐다. 우리 처치(구조화 데이터·답변 구조)는 그 요인들과 층위가 다르므로 결과를 직접 비교할 수 없다.

  • 분야 개관: 2023~2026 GEO 서베이(arXiv:2607.14035).

요약하면 이 실험의 기여는 "GEO가 효과 있다/없다를 처음 밝힌다"가 아니라, 공적 명부로 뽑은 실제 사이트 1,991곳에 무작위 배정으로 개입해 크롤러 행동 변화를 재는 것이다. 결과가 귀무가설을 기각하지 못해도 그 자체로 보고 가치가 있는 이유도 여기에 있다.


1. 연구 질문

테크니컬 GEO 개입(구조화 데이터·답변 구조)이 AI 크롤러의 수집 행동을 실제로 바꾸는가.


2. 가설

기호 가설 상태
H1 구조화 데이터를 추가한 페이지는 대조군보다 AI 크롤러 방문 수가 많다 검정 불가 (R3)
H2 질문형 구조(질문 H2 + BLUF 답변 블록)를 추가한 페이지는 대조군보다 방문 수가 많다 검정
H3 T1+T2 동시 적용 효과는 각각의 효과 합보다 크다(양의 상호작용) 제외 (R3)
H0 처치의 효과는 0이다

H1은 검정하지 못한다. 대상 사이트가 이미 해당 스키마를 전 페이지에 구현하고 있어 개입 여지가 없었다(§3.3). "검정하지 않았다"를 "효과가 없다"로 보고하지 않는다.

사전에 밝히는 예상

H1이 기각될 가능성이 낮지 않다고 본다. 근거는 위 0절의 역설이고, 크롤러 방문 빈도는 페이지 내용보다 사이트 권위·내부 링크 구조·사이트맵에 더 좌우될 수 있다.

기각되면 그대로 공개한다. 자사 진단기의 오탐을 공개해 온 것과 같은 규율이다. 우리가 파는 것의 효과가 없다면 그것이 가장 중요한 실측이다.


3. 모집단과 표본

적격 기준 (2026-08-10 확정, 개정 R1 반영)

크덤집 병원 상세페이지 (한국어) : /ko/clinic/*
최근 30일 AI 봇 방문 ≥ 1회
  대상 봇: GPTBot, ClaudeBot, OAI-SearchBot, PerplexityBot
AND clinics 테이블에 실재 (INNER JOIN) AND status = 'active'   ← R1
AND clinic_basic_intros.intro_ko 가 비어 있지 않음                ← R2
→ 적격 병원 1,993곳

경위는 §3.1(R1), §3.2(R2) 참조.

표본 크기: 적격군 전수 (1,993곳)

표본을 뽑지 않고 전수를 배정한다. 이유:

  • 개입이 템플릿 수준 자동 적용이라 페이지 수가 늘어도 구현 비용이 늘지 않는다
  • 효과 크기가 작을 가능성이 높으므로(위 예상 참조) 검정력을 최대로 확보해야 한다
  • 표집 자의성이 원천적으로 0이 된다
T1 구조화 데이터만   약 500
T2 답변 구조만       약 500
T3 T1 + T2          약 500
C  대조군           약 500

정확한 수는 착수 4번(배정)에서 확정하고 이 문서에 기록한다.

3.1 개정 R1 — 표본 수 정정 (2026-08-10, 결과 관측 전)

초판에 적었던 수: 적격 페이지 15,300개 · 군당 3,825

그 숫자는 bot_traffic_logspath만 세어 나온 것이고, 해당 경로가 실재하는 병원 페이지인지 확인하지 않았다. clinics 테이블과 대조한 결과:

구분 슬러그 수
clinics에 매칭 안 됨 11,699 (76%)
status = 'active' 3,597
status = 'inactive' 4
합계 15,300

76%가 실재하지 않는 페이지였다. 봇이 없어진 슬러그를 계속 두드려 로그에는 남지만 실제 페이지는 없다. 크덤집 구현 세션이 독립적으로 "활성 3,633곳"을 보고해 불일치가 드러났고, 대조로 확인했다.

정정 시점: 개입 구현 착수 전, 배정 전, 결과 관측 전. 어떤 결과도 보지 않은 상태에서의 정정이므로 사후 조정이 아니다.

영향: 표본이 약 1/4로 줄어 검정력이 그만큼 낮아진다. §2에서 "H1 기각 가능성이 낮지 않다"고 밝힌 상황이라, 효과가 작을 경우 검출하지 못할 위험이 커졌다. 분석 시 신뢰구간을 반드시 함께 보고하고, 유의하지 않은 결과를 "효과 없음"으로 단정하지 않는다 (검출력 부족과 효과 부재는 다르다).

교훈: 로그 기반으로 모집단을 정의할 때는 반드시 실체 테이블과 조인해 검증한다. 이 프로젝트가 반복해 데인 "조용한 실패" 유형이다 — 숫자가 그럴듯해서 검증을 건너뛰었다.

3.2 개정 R2 — 적격 조건에 intro 보유 추가 (2026-08-10, 결과 관측 전)

R1 이후 3,597곳 기준으로 콘텐츠 보유율을 확인한 결과:

구분 FAQ 보유 30일 평균 히트
intro_ko 있음 1,993 1,993 (100%) 3.10
intro_ko 없음 1,604 0 (0%) 2.38

intro가 없는 1,604곳은 FAQ도 없다. 이것이 처치 정의와 정면으로 충돌한다.

  • T2("페이지에 이미 있는 정보를 재배치·재서술")가 정의되지 않는다. 없는 글은 요약할 수 없다. 이대로 두면 45%에서 T2가 아무것도 하지 않는 처치가 되어, 효과가 있어도 추정치가 0 쪽으로 희석된다
  • T1FAQPage 부분도 적용 불가라 처치가 불균질해진다

대안으로 구조화 필드(상호·지역·진료과목·시간)에서 BLUF를 생성하는 방법이 있으나, 그러면 T2가 두 종류가 되어 무엇을 측정했는지 말할 수 없게 된다. 적격 조건을 좁히는 쪽을 택한다.

부수 효과 — 문제 셋이 함께 정리된다.

  1. FAQ가 전 페이지에 있어 T1이 균질해진다
  2. indexability 규칙상 "비입점 + ko + intro 없음 → noindex"인데, 그 1,604곳이 통째로 빠져 색인 상태 교란이 사라진다(공변량·하위군 분석 불필요)
  3. 본문 분량 층화가 다시 의미를 갖는다 — 전부 intro 보유라 실제 길이로 나눌 수 있다

영향: 표본이 3,597 → 1,993. 초판 15,300에서 두 번 깎여 **13%**가 됐다. 이 표본으로 무효과가 나오면 "효과가 없다"가 아니라 "이 표본으로는 검출할 수 없다" 일 가능성이 크다. §7 분석 계획의 검출력 관련 지침을 반드시 적용한다.

정정 시점: 배정 전, 개입 구현 전, 결과 관측 전.


3.3 개정 R3 — T1 검정 불가, 단일 요인으로 축소 (2026-08-10, 결과 관측 전)

T1 처치가 성립하지 않는다. 크덤집 세션이 착수 5번 직전에 발견했고, 설계자가 적격군 15곳 무작위 표본으로 독립 확인했다.

확인 항목 결과
표본 15곳의 MedicalClinic 15 / 15
표본 15곳의 FAQPage 15 / 15

전 페이지에 이미 6종 JSON-LD가 출력된다(Organization·MedicalClinic·FAQPage· BreadcrumbList·MedicalWebPage·SiteNavigationElement). T1이 넣으려던 필드 (상호·주소·전화·진료과목)도 이미 포함돼 있고, "FAQ 데이터가 있는 항목만 조건부 생성" 이라는 §4의 원칙도 이미 지켜지고 있다. 추가할 것이 없다.

검토했으나 택하지 않은 선택지

내용 기각 사유
(a) C·T2에서 기존 JSON-LD를 제거해 대조군을 만든다 처치가 아니라 훼손이다. 프로덕션 약 1,000곳의 구조화 데이터를 8주간 걷어내는 것이고 실제 손해를 입힌다. GSC 색인 회복을 관측 중인 시점이라 그 관측까지 오염시킨다
(b) T1을 다른 스키마 추가로 재정의 (AggregateRating 등) H1을 검정하지 못하면서 검정한 것처럼 보인다. 페이지 성격은 이미 MedicalClinic이 선언하고 있고, 평점 추가는 다른 가설이다. 2×2라는 형식만 지키고 내용을 바꾸는 것이라 (c)보다 사전 등록 취지에 더 어긋난다. ② 의료법 위험 — 병원 페이지 평점 노출은 환자 유인·비교광고 소지가 있다. med.adrisk로 광고 표현을 잡는 우리가 실험을 위해 1,000곳에 평점을 붙이는 것은 앞뒤가 맞지 않는다

확정: T1군을 대조군에 흡수, 단일 요인 실험

T1이 아무 처치도 아니라면 T1군은 대조군이다. 네 군이 둘로 접히되 표본은 유지된다.

C  (501) = 기존 스키마 · BLUF 없음  ┐
T1 (499) = 기존 스키마 · BLUF 없음  ┴→ 대조 1,000 → R5로 998 (프리미엄 2곳 제외)

T2 (498) = 기존 스키마 · BLUF 있음  ┐
T3 (495) = 기존 스키마 · BLUF 있음  ┴→ 처치   993

이것은 사후 재구성이 아니다. T1 조작이 실패했다는 사실의 기계적 귀결이다. 배정은 무작위였고, 동일한 처치를 받은 두 무작위 군을 합치는 것은 무작위화를 훼손하지 않는다. 결정 시점이 결과 관측 전이므로 사후 선택의 여지도 없다.

⚠️ 성립 조건: T1 페이지에 정말로 아무것도 하지 않아야 한다. 구현이 T1군에 무언가 얹는 순간 흡수가 불가능해지고 표본은 999로 줄어든다.

재배정 불필요. geo_rct_assignments 1,993행(시드 GEO-RCT-2026-08-10)을 그대로 쓰고, 분석 시 arm IN ('C','T1') → 대조, arm IN ('T2','T3') → 처치로 접는다.

이 실패 자체가 결과다

"이미 다 되어 있어서 더 넣을 것이 없었다" 는 버릴 정보가 아니다. 2026-08-10 인트릭스 프로브에서 나온 역설(자사 인용이 있던 병원이 오히려 구조화 데이터 보유율이 낮았다, 5% vs 21%)과 같은 방향을 가리킨다. 구조화 데이터가 포화인 사이트에서 AI 인용이 저조하다면 처방의 우선순위가 틀렸을 가능성을 시사한다. 결과 보고에 포함한다.


⚠️ 배정 단위는 페이지가 아니라 병원이다

같은 병원이 /ko/, /en/, /ja/, /ru/ 로 여러 페이지를 갖는다. 페이지 단위로 배정하면 같은 병원이 처치군과 대조군에 동시에 들어가 처치가 오염된다.

병원 ID 단위로 배정하고, 한국어 페이지만 측정 대상으로 삼는다. → 타 언어 페이지는 개입도 측정도 하지 않는다(오염 경로 차단).


4. 처치 설계 (2×2 요인)

답변 구조 없음 답변 구조 있음
구조화 데이터 없음 C (대조군) T2
구조화 데이터 있음 T1 T3

T1 — 구조화 데이터 ⛔ 검정 불가 (R3)

원안: MedicalClinic + (FAQ가 있는 페이지에 한해)FAQPage 추가.

대상 사이트에 이미 전부 구현돼 있어 개입 여지가 없다. §3.3 참조. T1군에는 아무 변경도 가하지 않으며, 분석에서 대조군에 흡수한다.

T2 — 답변 구조

본문 상단에 BLUF 답변 블록(2~3문장)과 질문형 H2를 추가한다. 새로운 사실을 만들지 않는다. 페이지에 이미 있는 정보를 재배치·재서술하는 것으로 한정한다.

요인을 분리하려 했던 이유 (기록)

T1·T2를 동시에 적용하면 효과가 나와도 무엇 때문인지 알 수 없어 2×2로 설계했다. R3으로 T1이 빠지면서 단일 요인이 됐고, 결과적으로 이 분리 문제는 발생하지 않는다.


5. 변수 통제

5.1 무작위 배정이 처리하는 것

같은 사이트·같은 기간·같은 모델이므로 다음 교란이 네 군에 동일하게 걸려 상쇄된다.

모델 업데이트 · 검색 알고리즘 변화 · 계절성 · 도메인 권위
· 경쟁사 움직임 · 사이트 전역 변경 · 크롤 예산 변동

전후 비교(pre-post)로는 이 중 어느 것도 통제할 수 없다. 그런 흔들림도 네 군에 똑같이 작용하므로 군 간 차이만 남는다.

정정(2026-08-13). 이 자리에는 원래 "우리 자체 측정이 2026-08-09 하루 사이 6.5%에서 0.5%로 흔들린 적이 있다"는 예시가 있었다. 그 0.5%는 측정의 흔들림이 아니라 집계 버그였다. 전국 데이터셋의 소유 도메인 판정에 전국 명부(450곳)가 아니라 부산 명부(27곳)가 쓰여, 실제 9.8%가 0.5%로 약 18배 과소집계됐다. 2026-08-13에 발견해 바로잡았다.

예시는 틀렸지만 이 절의 논지는 오히려 강해진다. 자기 파이프라인의 집계 오류조차 발행 시점까지 살아남았다면, 사전에 고정하지 않은 전후 비교에서 무엇이 결과를 움직였는지 사후에 가려낼 수 있다고 믿을 근거는 더욱 없다.

5.2 층화 무작위 배정

무작위만으로는 우연한 불균형이 남는다. 결과에 영향이 큰 축으로 층을 나누고 각 층 안에서 네 군에 균등 배정한다.

층화 변수 구간 이유
기저 방문량 3구간 (1 / 2 / 3+) 사후 방문의 최강 예측변수. 4분위는 경계가 Q1=2·Q2=2·Q3=3으로 뭉개져 성립하지 않는다(실측)
지역 수도권 / 비수도권 (68% / 32%) 검색 수요 밀도 차이

층 조합 = 3 × 2 = 6개 층. 층당 약 330곳, 군당 약 83곳.

본문 분량은 층화에서 뺀다. R2로 적격군이 1,993으로 줄어 층을 더 쪼갤 여유가 없다. 대신 공변량으로 회귀에 포함한다(§7). intro가 자동 생성이라 분포가 좁다는 점도 층화 가치를 낮춘다(3분위 경계가 310 / 332로 근접).

배정 시드를 문서에 기록해 재현 가능하게 한다.

5.3 설계로 막는 오염

위험 통제 방법
sitemap lastmod 갱신이 재크롤을 유발 방침 (b) 확정 — 갱신하지 않는다. 아래 5.3.1 참조
처치군만 내부 링크가 늘어남 링크 구조 불변. 페이지 본문만 수정
배포 시점 차이 단일 배포. 단 ISR은 요청 시점에 페이지별로 재생성되므로 실제 반영은 트래픽에 따라 시차가 생긴다. 배정군과 무관한 시차라 교란은 아니지만 "전 페이지 동시 재생성"은 아니다
처치가 렌더 성능을 바꿈 JSON-LD는 렌더 차단이 아니다. 배포 후 양군 LCP를 대조해 확인
실험 중 다른 SEO 작업 실험 기간 사이트 전역 SEO 변경 동결. 불가피하면 전군에 동일 적용하고 기록
측정 도구 변경 봇 로그 수집 로직 동결. 변경 시 실험 무효 처리

첫 번째가 가장 위험하다. 처치군 파일만 바뀌면 그 자체가 크롤 신호가 되어, 내용과 무관하게 재방문이 늘어난다. 이 실험의 성패가 여기 달렸다.

5.3.1 lastmod 방침 확정 (b) — 갱신하지 않음

크덤집 구현 세션이 코드를 확인한 결과, 추가 구현 없이 이미 성립한다(커밋 1d89571).

  1. lastmod 소스가 파일 mtime이나 빌드 시각이 아니라 clinics.updated_at DB 컬럼이다 (sitemap-builder.ts)
  2. T1·T2 모두 템플릿 조건부 렌더라 clinics에 UPDATE가 없다 → 처치군만 lastmod가 갱신되는 상황 자체가 발생하지 않는다
  3. updated_at을 움직이는 것은 HIRA 주간 동기화뿐이고 전수 대상이라 배정군과 무관하다 (실측: 활성 병원의 updated_at이 08-03~08-07 5일 안에 전부 분포, 08-05 하루 2,418곳)

이 방침은 "아무것도 하지 않기"라 오히려 깨지기 쉽다. 다음을 실험 기간 금지한다.

  • clinics.updated_at 직접 UPDATE 금지. 특히 배정 결과를 clinics 테이블에 저장하면 안 된다 — 배정 컬럼을 추가해 UPDATE하는 순간 적격군 전체의 lastmod가 한꺼번에 바뀐다. 배정은 별도 테이블에 저장한다
  • lastmod 산출을 updated_at 이외 값으로 변경 금지
  • HIRA 동기화를 부분 동기화로 변경 금지 (군 간 차등 발생)
  • intro 생성·재생성 파이프라인 동결. R2로 적격군이 intro 보유 페이지로 한정됐으므로, 위험은 "없던 intro가 생기는 것"이 아니라 "있던 intro가 바뀌는 것" 이다. 재생성이 돌면 T2가 덮이거나 대조군 본문이 바뀐다. 동결이 운영상 불가능하면 배정 시점 intro 해시를 기록해 두고 변경된 페이지를 사후 식별·보고한다

5.4 통제하지 못하는 것 (한계로 명시)

  • 단일 사이트다. 크덤집에서 통한 것이 다른 도메인에서 통한다는 보장이 없다
  • 크덤집은 이미 AI 크롤러 방문이 많은 사이트다. 방문이 적은 사이트에서는 다를 수 있다
  • 봇의 user-agent 위장 가능성. ASN 검증으로 걸러내지만 완전하지 않다

6. 측정

1차 결과 지표

개입 후 8주간 페이지당 AI 크롤러 방문 수 (GPTBot, ClaudeBot, OAI-SearchBot, PerplexityBot 합산)

2차 결과 지표

  • 봇별 방문 수 (개별 분석)
  • 첫 재방문까지 걸린 시간
  • 8주 중 방문이 1회 이상 발생한 주 수 (0~8) — R4 추가. 웨이브 크기에 둔감하고 상한이 있어 과분산이 작다. "얼마나 많이 긁혔나"가 아니라 "얼마나 자주 다시 오는가" 를 재는 것이라 실무 관심사에도 더 가깝다. 1차 지표가 대형 웨이브 한 번에 지배될 경우 해석의 축이 된다(§6.1)

탐색적 지표 (검정력 부족 — 결론 근거로 쓰지 않음)

ChatGPT-User 조회 수. 사용자가 앱에서 질문한 순간 발생하는 실시간 조회이므로 API-앱 간극 문제를 우회하는 유일한 지표지만, 30일 기준 506개 경로 · 1,776회에 불과해 1,993페이지에 흩어져도 대부분 0이 된다. 탐색적으로만 보고한다.

기간

기저 = 배정 시점 기준 소급 30일 (geo_rct_assignments.baseline_hits, 이미 고정 기록됨)
  ↓ 단일 배포 (배포 시각이 사전/사후 경계)
사후 8주 (결과 측정)

8주인 이유: 페이지당 크롤 주기가 월 1~2회이므로 최소 2회 이상 관측되어야 한다.

6.1 개정 R4 — 사전 기저를 소급 30일로 확정 (2026-08-10, 결과 관측 전)

원안은 전향적 사전 4주를 두었다. 배정이 확정되면서 그 4주에 해당하는 값이 이미 geo_rct_assignments.baseline_hits(배정 시점 소급 30일, 1,993행)로 고정 기록됐고, 층화도 이 값으로 이뤄졌다. 4주를 더 기다리지 않고 지금 배포한다.

결정적 이유는 무작위 실험에서 기저가 하는 역할이다. 기저는 식별 장치가 아니라 정밀도 장치다. 처치효과의 식별은 무작위 배정이 하고, 기저는 log(기저+1) 공변량으로 분산만 줄인다. 따라서 기저 창에 버스트(07-27 주 17,661회)가 섞여 있어도 편향이 아니다 — 버스트는 배정군과 무관하게 발생하므로 무작위화가 네 군에 고르게 분산시킨다. 군별 평균이 C 3.012 / T1 3.259 / T2 3.018 / T3 3.091 로 붙어 있는 것이 그 확인이다.

부차적으로, 크덤집 세션이 든 두 근거도 유효하다.

  1. 기다려도 안정되지 않는다. 주별 히트가 268 ~ 17,661로 66배 변동하고, ClaudeBot은 3~4주 전 8회 → 최근 2주 7,048회다. 간헐적 대량 크롤이 정상 상태이지 관측 기간 부족이 아니다
  2. 배정과 기저의 시점을 맞추는 편이 정합적이다. 층화가 배정 시점 baseline_hits로 이뤄졌으므로, 4주 뒤 기저를 다시 재면 층화 변수와 공변량의 창이 어긋난다
  3. 대기 기간만큼 basic-geo-compile 동결(§5.3.1)이 깨질 창이 길어진다

다만 크덤집 세션의 민감도 분석 제안은 겨냥이 틀렸다

"07-27 이상치 주를 제외한 기저로 재계산"은 기저를 편향 위협처럼 다루는 것이다. 위에서 본 대로 기저는 공변량이라 이상치가 섞여도 편향이 생기지 않고, 예측력이 약간 떨어질 뿐이다. 비용이 싸므로 실행하되 타당도 검증이 아니라 정밀도 점검으로 표기한다.

6.2 개정 R5 — 표본 1,991 확정 및 배포 기록 (2026-08-10, 결과 관측 전)

배포가 완료됐다. 사전/사후 경계는 2026-08-10 14:04:34 KST(05:04:34 UTC, Version ID 6b48f34d-82b7-4f4b-aba8-a073bceff99b)이며, 사후 8주는 2026-10-05 14:04 KST에 끝난다.

표본 1,993 → 1,991 (프리미엄 2곳 제외)

코호트 안의 프리미엄 병원 2곳이 전부 T1에 몰려 있었다. 프리미엄만 주간 geo-compile 크론 대상이라, 그대로 두면 실험 기간 중 대조군에만 콘텐츠 변동이 생긴다. n=2/1,000이라 실질 영향은 없지만 비대칭을 남길 이유가 없어 제외한다.

  • 배정은 불변. 시드 GEO-RCT-2026-08-10 그대로다. 제외는 분석 단계의 일이고 geo_rct_exclusions에 사유와 함께 기록했다
  • 렌더도 불변이다. T1은 무변경군이라 제외 여부와 관계없이 대조군과 같게 렌더된다
대조 998 (C 501 + T1 497)  vs  처치 993 (T2 498 + T3 495)
표본 이력: 15,300 → R1 3,597 → R2 1,993 → R5 1,991

배포 차단 조건 3종 — 전부 통과

조건 결과
lastmod 불변 clinics.updated_at 해시 전체 24,815행 · 코호트 1,993행 배포 전후 동일
intro 동결 intro sha256 1,993행 동일. 해시 목록을 docs/geo-rct/intro-hashes-2026-08-10.csv에 보존
위약 검정(§7.1) 1,991 기준 재실행 — IRR 0.9967 (95% CI 0.9410–1.0557), p=0.9099. 처치 계수가 0과 구분되지 않는다

위약 검정 수치를 여기 적어 두는 이유는 §7.1이 "통과했다만 쓰고 수치를 감추지 않는다"고 정해 두었기 때문이다. 결과 보고서에도 같은 값을 싣는다.

프로덕션 실물 대조(군당 3곳): 처치군은 BLUF + 질문형 h2, 대조군은 둘 다 없음. 처치가 대조군으로 새지 않았다.

검증 과정의 오탐 1건 (기록)

크덤집 세션의 첫 검증 grep이 어떻게 되나요?h2 밖 FAQ 본문에서도 잡아 T1이 처치된 것처럼 보였다. h2 안쪽만 파싱해 재측정하니 대조군의 질문형 h2는 0이었다. 재현 스크립트 docs/geo-rct/check_h2.py.

설계자 쪽에서도 같은 종류의 오탐이 있었다. 배포 확인차 T2 6곳을 알파벳순으로 뽑아 보니 진료시간 h2가 하나도 없어 처치가 섹션을 삭제한 것으로 의심했는데, 그 6곳이 전부 진료시간 데이터가 없는 병원이었다(모집단의 83%가 그렇다). 시간 데이터 보유 병원만 골라 다시 보니 h2 7~8개에 진료시간도 대조군과 동일하게 나왔다. 표본을 정렬 순서대로 뽑으면 이런 편중이 생긴다 — 이후 검증은 무작위 표본을 쓴다.

진짜 버스트 위험은 기저가 아니라 사후 창에 있다. 1차 지표가 8주 누적 카운트인데, 07-27 주 한 번이 고유 경로 10,050개(적격군 1,993의 5배)를 훑었다. 사후 8주가 대형 크롤 웨이브 한 번에 지배되면 페이지별 카운트는 그 한 번의 웨이브가 어떤 페이지를 골랐는가로 결정된다. 독립 관측이 8주치가 아니라 웨이브 2~3회분이라는 뜻이고, 이는 (A)(B)(C) 어느 쪽을 택해도 해결되지 않는다. §7에 대응을 사전 등록한다.

대기가 유일하게 사줬을 것: 위약 검정 — 이것도 지금 가능하다

전향적 사전 기간의 진짜 가치는 처치 계수가 반드시 0이어야 하는 구간에서 분석 모형을 그대로 돌려보는 것이다. 파이프라인 버그·조인 실수·군 라벨 오배치를 잡는다.

봇 로그 보관이 90일이라 2026-05-11 ~ 07-11 구간이 남아 있다. 이 구간은 기저 공변량 창(대략 07-11 ~ 08-10)과도, 사후 창과도 겹치지 않는다. 기다리지 않고 지금 위약 검정을 돌릴 수 있다. 이 점에서 (C)는 (B)를 엄밀히 지배한다 — 검정은 즉시 얻고, 동결 위험 4주는 지지 않는다. §7에 사전 등록한다.


7. 분석 계획

페이지 단위 카운트 데이터이고 과분산이 예상되므로 음이항 회귀를 쓴다.

사후방문수 ~ 처치 + log(기저방문수+1) + log(본문길이) + 층(고정효과)

  처치 = 1  if arm IN ('T2','T3')   (993곳)
       = 0  if arm IN ('C','T1')    (998곳, R5로 프리미엄 2곳 제외)
  • 주 검정: 처치 계수 (H2). 단일 가설이므로 다중비교 보정 불필요(R3 이전에는 주 가설 2개에 Bonferroni α=0.025를 적용할 예정이었다)
  • 유의수준 α = 0.05
  • 효과 크기는 발생률비(IRR)와 95% 신뢰구간으로 보고

결과에 관계없이 전 지표를 보고한다. 유의한 것만 골라 보고하지 않는다.

7.1 개정 R4 — 위약 검정·웨이브 보고·민감도 분석 사전 등록 (2026-08-10, 결과 관측 전)

전부 결과 관측 전에 확정한다. 사후에 고르면 연구자 자유도가 되므로, 여기 적힌 것만 실행하고 결과가 어떻든 전부 보고한다.

(1) 위약 검정 (배포 전 실행, 실패 시 배포 보류)

2026-05-11 ~ 07-11 구간(기저 공변량 창·사후 창 어디와도 겹치지 않음)에서 1차 분석 모형을 그대로 돌린다. 이 구간에는 처치가 존재하지 않으므로 처치 계수는 0이어야 한다.

05-11~07-11 방문수 ~ 처치 + log(기저방문수+1) + log(본문길이) + 층(고정효과)
  • 처치 계수가 α=0.05에서 유의하면 파이프라인을 의심한다 — 군 라벨 오배치, 경로 조인 실수, 층 변수 불일치를 먼저 찾는다. 원인을 못 찾으면 배포를 보류한다
  • 유의하지 않아도 IRR과 95% 신뢰구간을 결과 보고서에 그대로 싣는다. "통과했다"만 쓰고 수치를 감추지 않는다

(2) 크롤 웨이브 보고 (사후 창의 유효 표본 문제)

사후 8주의 주별 사이트 전역 히트를 보고하고, 구분되는 크롤 웨이브 수를 센다 (정의: 주간 히트가 해당 8주 중앙값의 3배를 넘는 주를 웨이브로 본다 — 기준을 지금 고정한다).

  • 웨이브가 2회 미만이면 1차 지표의 독립 관측이 사실상 한 번의 크롤 결정에 지배된 것이다. 이 경우 1차 결과를 약한 근거로 명시하고 2차 지표(방문 발생 주 수)를 나란히 보고한다. 유의성이 나와도 단정하지 않는다

(3) 민감도 분석 — 정밀도 점검이지 타당도 검증이 아니다

기저에서 07-27 주를 제외하고 재계산해 결론이 뒤집히는지 본다. ⚠️ 이것을 "이상치 편향을 제거했다"로 서술하지 않는다. 무작위 배정 하에서 공변량의 이상치는 편향원이 아니라 예측력 손실일 뿐이다(§6.1). 결론이 뒤집힌다면 그것은 편향의 증거가 아니라 결과가 공변량 설정에 취약하다는 증거이며, 그렇게 서술한다.

검출력에 관한 지침 (R1·R2·R3 누적 축소 반영)

표본이 초판 15,300에서 세 번 깎였다.

초판 15,300 → R1 3,597 → R2 1,993 → R3 1,993 (군 구성만 변경, 표본 유지)
                                     대조 1,000 / 처치 993

유의하지 않은 결과를 "효과 없음"으로 단정하지 않는다. 신뢰구간을 함께 보고하고, 구간이 실무적으로 의미 있는 효과 크기를 포함하면 "검출하지 못했다" 로 서술한다. 검출력 부족과 효과 부재는 다르다.

H1은 아예 검정하지 않았으므로 결과 보고에서 "효과 없음"으로 쓰지 않는다. "대상 사이트에 이미 구현돼 있어 검정할 수 없었다"로 명시한다.


8. 중단·무효 규칙

다음 중 하나라도 발생하면 실험을 중단하고 사유와 함께 공개한다.

  1. 실험 기간 중 사이트 전역 SEO 변경이 불가피하게 발생
  2. 봇 로그 수집이 중단되거나 로직이 변경됨
  3. 처치 배포가 네 군에 동시 반영되지 못함
  4. 배정 오류(같은 병원이 두 군에 배정)가 발견됨
  5. T1군에 어떤 변경이든 적용됨 — 대조군 흡수(§3.3)의 전제가 깨진다. 이 경우 실험을 중단하지는 않되 흡수를 포기하고 C(501) vs T2(498) 999곳으로 축소하며, 그 사유를 보고서에 명시한다

9. 공개 계획

결과와 무관하게 다음을 공개한다.

  • 이 사전 등록 문서 (실행 전 커밋된 상태 그대로)
  • 배정 시드와 배정 결과
  • 분석 스크립트
  • 전 지표 결과 (유의 여부 무관)
  • T1이 검정 불가였다는 사실과 그 경위 — 개입하려던 것이 이미 구현돼 있었다는 것은 버릴 정보가 아니다(§3.3 말미)

효과가 없다는 결과가 나오면 그것을 그대로 공개한다. 우리가 파는 것의 효과를 스스로 검증하고 결과를 감추지 않는 것이, 진단기 오탐을 공개해 온 것과 같은 규율이다.


10. 미결 사항 (실행 전 확정 필요)

  • 개입 구현 주체·일정 — 크덤집 세션. T2 구현 완료·대조 검증 5종 통과(2026-08-10)
  • 배정 시드 확정 및 기록 — GEO-RCT-2026-08-10, geo_rct_assignments 1,993행
  • 층화용 본문 분량·지역 데이터 추출 — 배정과 함께 완료
  • 사전 4주 기저 측정 시작일 — 불필요로 확정(R4). 배정 시점 소급 30일 baseline_hits를 기저로 쓴다. 무작위 실험에서 기저는 정밀도 장치이므로 전향적 관측이 식별에 기여하지 않는다. §6.1

배포 차단 조건 — ✅ 셋 다 통과, 2026-08-10 14:04:34 KST 배포 (§6.2)

  • lastmod 불변 증명 — T2 배포가 어떤 행의 clinics.updated_at도 움직이지 않음을 배포 전후 대조로 확인. §5.3이 "이 실험의 성패가 여기 달렸다"고 지목한 위험이다. 본문 diff 검증 5종은 이것을 덮지 못한다. BLUF가 사전 생성·저장 방식이라면 저장 테이블을 명시하고, clinics를 건드리면 배포를 중단한다
  • intro 파이프라인 동결 확인 — 동결했거나, 불가능하면 배포 시점 intro 해시를 1,993행 전부 기록(§5.3.1). 처치가 덮이거나 대조군 본문이 바뀌는 것을 사후에 식별할 수 있어야 한다
  • 위약 검정 통과 — IRR 0.9967 (95% CI 0.9410–1.0557), p=0.9099. — §7.1 (1). 처치 계수가 유의하면 원인 규명 전까지 배포 보류
  • lastmod 처리 방침 확정 — (b) 갱신하지 않음. 크덤집 세션 확인(커밋 1d89571): lastmod 소스가 파일 mtime이 아니라 clinics.updated_at이고, 처치가 DB를 쓰지 않으므로 추가 구현 없이 성립. 단 배정 결과를 clinics 테이블에 저장 금지 (UPDATE 시 전체 lastmod가 한꺼번에 움직임) — 별도 테이블 사용
  • 층화 변수 확정 — R2 반영해 2변수 6개 층(기저 방문량 3구간 × 지역 2). 본문 분량은 공변량으로 이동. §5.2
  • T2 BLUF 블록의 생성 시점 확인 — 렌더 시점. clinics에 쓰지 않음이 배포 전후 updated_at 해시 대조로 증명됐다(전체 24,815행·코호트 1,993행 동일). §6.2
  • intro 생성·재생성 파이프라인 동결 — basic-geo-compile에 가드 추가 + 배정 시점 intro sha256 1,993행 기록(docs/geo-rct/intro-hashes-2026-08-10.csv, 크덤집 저장소)