diff --git a/docs/NEXT_SESSION_2026-09-09.md b/docs/NEXT_SESSION_2026-09-09.md new file mode 100644 index 0000000..81bc67b --- /dev/null +++ b/docs/NEXT_SESSION_2026-09-09.md @@ -0,0 +1,104 @@ +# 다음 세션 핸드오버 · 2026-09-09 + +**2026-09-09 진행분은 §2 각 항목의 상태 표시를 본다.** §2-1~4·6 완료, 남은 것은 §2-5(GA4 실연결)·§2-7 과 2차 보정이다. + +작성 2026-09-08 · 작성자 Claude (haewon 세션 핸드오버). 자동 빌드 전체 상태는 `docs/NEXT_SESSION_SUPPORTERS_AUTOBUILD_v3.md`(§1·§2·§3 갱신됨)를 본다. 이 문서는 09-08에 새로 시작한 일(감성 분석·GA4·가격)과 내일 첫 할 일만 다룬다. + +--- + +## 0. 세션 시작 시 붙여 넣을 프롬프트 + +``` +INFINITH 저장소. 자동 빌드 코드는 워크트리 ~/orca/workspaces/INFINITH/Productize (브랜치 feature/supporters-autobuild), 감성 분석 산출물은 메인 체크아웃 ~/Claude/Agentic Marketing/INFINITH 에 있다. +먼저 docs/NEXT_SESSION_2026-09-09.md 를 읽고 §2 순서대로 진행한다. 자동 빌드 잔여 과제는 docs/NEXT_SESSION_SUPPORTERS_AUTOBUILD_v3.md §2. +원칙: 근거 없는 사실은 생성하지 않는다. 사람 게이트는 자동화하지 않는다. 잴 수 없는 것은 숫자를 만들지 않고 '측정 불가'로 적는다. 존댓말, 엠대시 금지, 은유 금지. 결정이 필요한 것은 §3을 보고 haewon 에게 묻는다. +``` + +## 1. 09-08에 끝낸 것 + +| 일 | 위치 | 상태 | +|---|---|---| +| 뉴스룸 워커 단계 + 뉴스 게이트 규칙 | Productize, 커밋 484601b·4e73798, 푸시·infinith-demo 배포 완료 | 뷰 회귀 1,105건(수작업 1,096), 원진 1,049건 반영·재배포 | +| launchd 폴러 설치 | `~/Library/LaunchAgents/com.infinith.supporters-poll.plist`, 5분 간격, 로그 `~/supporters-builds/poll.log` | 큐가 비어 있어 실제 신청 1건 완주는 아직 못 봄 | +| FrostAI 비교 + 가격 제안 v0.1 | 메인 체크아웃 `docs/INFINITH_vs_FrostAI_비교_및_가격제안_2026-09-08.html` | haewon 검토 대기 | +| AI 답변 감성 판정 | 메인 체크아웃 `docs/AI_ANSWER_SENTIMENT_RUBRIC_v0.1.md`, `scripts/sentiment_qb.py`, 결과 `docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment.md` | 뷰 240건 판정 완료(언급 84, 감성 53.6, 부정 15.5%, 규제 언급률 6.0%). **보정 라벨링 진행 중** | +| GA4 AI 유입 연동 뼈대 | Productize `data/ai_channels.json`, `scripts/ga4_ai_traffic.py`, `supporters/src/layouts/Base.astro` 태그, `docs/INFINITH_GA4_AI_Traffic_Integration.md` | 합성 데이터로 검증. 실제 속성 연결은 GCP 계정 결정 후 | +| 리포트 "측정 가능 범위" 절 | Productize `scripts/build_discovery_report.ts` Integrity 절, 원진 리포트 v2.1 HTML·PDF | 감성·GA4 리포트에도 같은 절 자동 포함 | + +**미커밋 상태** (haewon 지시 없이 커밋하지 않았다) +- Productize: `data/ai_channels.json`, `scripts/ga4_ai_traffic.py`, `scripts/build_discovery_report.ts`, `supporters/src/layouts/Base.astro`, 템플릿 site.json 2곳(`ga4MeasurementId`), `docs/INFINITH_GA4_AI_Traffic_Integration.md`, `docs/reports/wonjin/01_readiness_report/*v2.1*`, 이 문서. +- 메인 체크아웃: `scripts/sentiment_qb.py`, `docs/AI_ANSWER_SENTIMENT_RUBRIC_v0.1.md`, `docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment*.{md,xlsx}`, `scripts/out/qb_sentiment_*.jsonl`, `docs/INFINITH_vs_FrostAI_*.html`. 메인 체크아웃에는 09-08 이전부터 있던 무관한 수정(plan 컴포넌트 등)도 섞여 있으니 감성 파일만 골라 커밋한다. + +## 2. 내일 순서 + +> 진행 상태 (2026-09-09 갱신): 1 완료 · 2 완료 · 3 완료 · 4 완료 · 5 미착수(§3-2 대기) · 6 완료(푸시 전) · 7 미착수 + + +1. **보정 라벨링 마무리** (haewon). 파일 `docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment_calibration.xlsx`, 시트 `라벨링` 30줄. D열 답변 전문을 읽고 F열(positive/neutral/negative/mixed/not_mentioned), 부정·혼합이면 G열 종류, 애매하면 H열 메모. 판정기 값은 숨김 시트에 있으니 보지 않는다. + - 알려진 사례: **G-08(openai)** 은 영문 약칭 "View" 하나만 있음 → not_mentioned 로 볼지 haewon 판단. **G-04(openai)** 는 판정기 오판(뷰 언급 없음). **C-01(openai)** 은 "View Plastic Surgery" 영문 정식 명칭. +2. **일치율 계산**: `python3 scripts/sentiment_qb.py --agreement docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment_calibration.xlsx`. sentiment 일치 80% 이상이면 기준표 v0.1 확정. 미만이면 불일치 줄을 기준표 §2 규칙 예시로 추가하고 240건 재판정(`--out` 파일을 지우고 다시 실행, 약 $1). +3. **기준표 확정 사항 반영**: 약한 언급(한글 상호 없이 영문 약칭만, 3건) 포함 여부, mixed 25점 유지 여부를 기준표 §6에 적고 리포트 재생성. 감성 결과를 `docs/reports/viewclinic/03_question_bank/` 엑셀·POC 부록에 넣을지 결정. +4. **감성 판정을 월간 실측에 붙이기**: 질문 뱅크 러너 결과가 나오면 자동으로 `sentiment_qb.py` 를 이어 돌리는 한 줄(워커 별도 단계 또는 cron). 결과를 `supporter_builds.report.sentiment` 에 저장해 리포트 카드에 표시. +5. **GA4 실연결**: §3-2 계정이 정해지면 서비스 계정 키 발급 → `.env` `GA4_SERVICE_ACCOUNT_JSON` → 서포터즈 사이트용 GA4 속성 생성 → 원진 `site.json` 에 `ga4MeasurementId` → 재빌드. 쿠키 배너 결정(§3-3) 전에는 미리보기에 ID를 넣지 않는다. +6. **커밋**: 위 미커밋 목록을 두 체크아웃에서 각각 커밋(감성 파일은 메인 체크아웃에서 골라서). 푸시 후 `vercel --prod` 는 프론트 변경이 있을 때만. +7. 시간이 남으면 v3 §2의 감사 재실행 단계(Phase 9), 원진 수동 실측(강남언니·바비톡·GBP·플레이스 NAP). +8. (2026-09-09 추가) 질문 뱅크 러너 병원별 매개변수화. `run_question_bank_openai.py` 가 `question_bank_viewclinic.json` 과 출력 경로를 하드코딩해 뷰성형외과 전용이다. 월간 체인을 원진 등 다른 병원에 쓰려면 여기가 먼저다. + +### 2026-09-09 결과 요약 + +| 항목 | 결과 | +|---|---| +| 보정 라벨링 | haewon 29/30 완료. G-08(openai)만 공란 | +| 1차 일치율 | sentiment 22/29 = **75%**, 기준선 80% 미달. negative_type 은 G열 미기입으로 **측정 불가** | +| 기준표 | v0.1 → **v0.3**(메인 체크아웃 `docs/AI_ANSWER_SENTIMENT_RUBRIC_v0.3.md`). 규칙 R1~R5 추가 | +| 철회한 규칙 | R4-a·R6 시험 투입 후 철회. 일치율이 93%에서 89%로 떨어졌다. n=29 에서 과적합 | +| 언급 탐지기 | 결정론적 `mention_kind()` 신설. URL 안의 "view", "리뷰"의 "뷰" 오탐 제거, 한글 상호 공백 허용. 언급 84 → 83, 약한 언급 3 → 1 | +| 감성 점수 | 53.6 → **58.4** (약한 언급 1건 제외 시 57.9). mixed 10 → 0 | +| 월간 체인 | `scripts/monthly_ai_measure.py` 신설(§2-4). 러너 → 감성 → 리포트 → `supporter_builds.report.sentiment` | +| API 비용 | 총 $1.70 (v0.2 재판정 $0.79 + R4-a·R6 시험 $0.91). 최종본은 재호출 없이 후처리로 만들었다 | +| 커밋 | 메인 체크아웃 `feature/ai-sentiment-rubric` 2eb3d5c · Productize 8776a15(GA4)·501d600(PRD v0.2) | + +**아직 확정이 아니다.** 93%는 같은 표본으로 규칙을 고쳐 나온 값이다. 확정하려면 새 30건으로 2차 보정을 해야 하고, 1차 표본 30건은 제외한다. 리포트와 요약 JSON 에 `confirmed: false` 로 적어 두었다. + +**메인 체크아웃이 브랜치에 있다.** `feature/ai-sentiment-rubric` 이며 main 이 아니다. main 으로 합치려면 그 체크아웃에서 `git checkout main && git merge feature/ai-sentiment-rubric` 을 한다. 두 체크아웃 모두 **푸시하지 않았다.** + +## 3. haewon 결정 대기 + +1. 감성 기준표(2026-09-09 갱신): mixed 는 R2 적용 후 240건 중 0건이라 판정값에서 뺄지 정한다. 약한 언급은 오탐을 걷어내니 **1건**(G-08 openai)뿐이며 현재는 세고 표시해 두었다. 부정의 범위(규제 사실 서술을 negative 로)와 경쟁 노출 지표는 그대로 미결. 남은 불일치 2건(C-12 perplexity, A-03 openai)은 2차 보정에서 새 표본으로 본다. + - 2차 보정을 언제 돌릴지도 결정 대상이다. 새 30건 추출 → haewon 라벨 → `--agreement`. 1차 표본 30건은 제외한다. +2. GA4 서비스 계정을 만들 Google Cloud 계정(이전 재인증 이슈 계정 회피 여부). +3. 서포터즈 사이트 쿠키 고지 배너 vs 쿠키 없는 대안(서버 로그·Vercel Web Analytics). +4. 가격 제안 v0.1(문서 §5의 5개 항목: 무료 진단 범위, 최소 계약 3개월, 도메인 귀속, Frost 우위 3종 대응, 가격 공개 여부). +5. 뉴스룸 "언론 언급" 종류 노출 여부(v3 §3-6). +6. 자동 빌드 잔여 결정은 v3 §3. + +## 4. 함정 (09-08 추가) + +- 프레임워크 Python 3.13은 인증서 저장소가 비어 `CERTIFICATE_VERIFY_FAILED` 가 난다. 새 스크립트는 certifi 컨텍스트를 쓴다(`sentiment_qb.py` 참고). +- 판정기의 `mentioned` 는 영문 약칭에 관대하다. 한글 상호 정규식으로 `weak_mention` 을 따로 표시하고 보정 때 결정한다. +- `sentiment_qb.py --summary` 로 보정 엑셀을 다시 만들면 **haewon 라벨이 지워진다**. 라벨링 시작 후에는 `--calibration` 을 빼고 리포트만 다시 만든다. (2026-09-09: `--calibration` 없이 돌리면 §7 생성에서 죽던 버그를 고쳤다. 이제 그냥 빼고 돌리면 된다) +- (2026-09-09) 감성 판정을 다시 돌릴 때는 `--out` 파일을 **옮기거나 지워야** 한다. 이어쓰기가 있어 그냥 실행하면 0건 처리하고 끝난다. `monthly_ai_measure.py --rejudge` 가 이 처리를 대신한다. +- (2026-09-09) 병원 언급 탐지는 판정기(LLM)에 맡기지 않는다. URL 안의 상호와 "리뷰"의 "뷰" 를 언급으로 세면 모든 비율의 분모가 틀어진다. `mention_kind()` 를 먼저 통과시킨다. +- 백그라운드 파이썬 로그는 버퍼링 때문에 끝날 때까지 비어 보인다. 진행은 JSONL 줄 수로 본다. +- JS 정규식 `\W`·`\w`·`\b` 는 한글을 문자로 보지 않는다(v3 §5). 워드프레스 게시판 메타 날짜는 게시판 생성일이다. + +## 5. 자주 쓰는 명령 + +``` +# 월간 실측 한 번에 (메인 체크아웃, 2026-09-09 신설) +python3 scripts/monthly_ai_measure.py --clinic 뷰성형외과 # 러너부터 전부 +python3 scripts/monthly_ai_measure.py --clinic 뷰성형외과 --skip-run # 기존 답변으로 감성만 +python3 scripts/monthly_ai_measure.py --clinic 뷰성형외과 --rejudge # 기준표 고친 뒤 재판정 +python3 scripts/monthly_ai_measure.py --clinic 뷰성형외과 --build-id # Supabase 반영까지 +# 감성 판정 개별 (메인 체크아웃) +python3 scripts/sentiment_qb.py --in scripts/out/qb_openai_results.jsonl --out scripts/out/qb_sentiment_openai.jsonl +python3 scripts/sentiment_qb.py --summary scripts/out/qb_sentiment_openai.jsonl scripts/out/qb_sentiment_perplexity.jsonl --report docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment.md # 라벨링 중에는 --calibration 금지 +python3 scripts/sentiment_qb.py --agreement docs/reports/viewclinic/03_question_bank/Viewclinic_QB_Sentiment_calibration.xlsx +# GA4 (Productize) +python3 scripts/ga4_ai_traffic.py --mock --clinic demo --out /tmp/ga4demo +python3 scripts/ga4_ai_traffic.py --property --days 90 --clinic --out docs/reports//05_ai_traffic +# 진단 리포트 (Productize) +npx esbuild scripts/build_discovery_report.ts --bundle --platform=node --format=esm --outfile=/tmp/report.mjs && node /tmp/report.mjs --id --out --status ~/supporters-builds//status.json --site ~/supporters-builds//site --briefs ~/supporters-builds//briefs.json +# 폴러 상태 +launchctl print gui/$(id -u)/com.infinith.supporters-poll | head -12 ; tail -20 ~/supporters-builds/poll.log +```