레시피마다 후기가 쌓여 있어도 사용자가 전부 읽지는 않습니다. 후기를 감정으로 분류하고 요약해 붙이려고 했고, 자유 요약은 근거 재작성과 성격이 달라 구현한 뒤 실측으로 모델을 확정하기로 했습니다.
후기 141,298건을 수집해 141,282건(99.99%)을 분류하고, 레시피 6,873개 전부에 요약을 붙였습니다.
요약 모델은 후보 5종을 같은 케이스로 재서 골랐는데, 판정을 가른 것은 문장 품질이 아니라 존댓말 지시를 지키는지였습니다. 부정 후기가 있는 레시피만 LLM으로 요약하고 나머지는 템플릿으로 처리했습니다. 초기 비용 추정 36,291원을 기준으로 LLM 적용 대상과 입력량을 조정해, 예상 비용을 약 2.1~2.2만원 수준으로 낮출 수 있는 구조를 확인했습니다.
아래부터 당시 작성한 기록을 공개용으로 정제한 전문입니다.
만개의레시피 후기 141,298건을 수집·분류하고, 레시피 6,873개 전부에 요약을 붙였다. 검증 표본 300건은review-summary-samples-300.md— 당시 별도 검증 표본 파일로 기록. 작성: AI 파트 · 대상 DB[내부 주소 비공개]/foodbudget
| 단계 | 결과 |
|---|---|
| 리뷰 수집 | 141,298건 / 6,873 레시피 · no_review 0.00% · 실패 0 |
| 감정 분류 | 141,282건(99.99%) · 누락 16건 · 4,749초 |
| LLM 요약 | 2,189건 · 9,312초(2시간 35분) · 건너뜀 0 |
| 주의사항 | 636건 (부정 후기 보유 레시피에서만) |
| 템플릿 요약 | 4,678건 · LLM 호출 없음 |
| 요약 커버리지 | 6,873 / 6,873 = 100% |
긍정 81.9% · 중립 16.0% · 부정 2.1% (전수 141,282건 기준).
roadmap §10 이 "자유 요약은 근거 재작성과 성격이 달라 구현 후 실측으로 확정" 으로 남긴 항목이다. 후보 5종을 같은 케이스로 측정했다(표본 8레시피).
| 모델 | 문장수 | 존댓말 | 길이 | 지연 | 판정 |
|---|---|---|---|---|---|
nova-micro | 2.4 | 1/8 ❌ | 119자 | 851ms | 탈락 |
claude-3-haiku | 3.2 | 8/8 ✅ | 168자 | 2,156ms | 차선(장황) |
claude-haiku-4-5 | 2.0 | 0/8 ❌ | 147자 | 2,260ms | 탈락 |
claude-3-5-sonnet-v2 | 2.0 | 8/8 ✅ | 117자 | 3,566ms | ✅ 채택 |
claude-sonnet-4-5 | 2.5 | 7/8 | 177자 | 5,317ms | 장황·최저속 |
판정을 가른 것은 품질이 아니라 지시 준수다. 프롬프트가 "존댓말 평서문"을 요구했는데 nova-micro·haiku-4.5 는 "~자주 언급된다" 평서체를 썼다(실제 출력 확인). 요약문은 유저에게 그대로 보이는 문장이라 치명적이다.
프롬프트로 고칠 수 없었다. "서두 금지"를 예시까지 들어 명시했더니 haiku-3 는 금지 표현을 그대로 쓰면서 존댓말 준수가 6/6 → 1/6 로 무너졌다 — 소형 모델은 제약을 늘리면 다른 제약을 놓친다. 같은 프롬프트로 sonnet 은 오히려 완벽해졌다(2.0문장·8/8·서두 0/6).
얻은 규칙 2개
haiku-4.5(0/8) < haiku-3(8/8).nova-micro 는 챗 refine 에서 Gemini 동률인데 자유 요약은 실패한다. refine 은 주어진 근거의 재작성, 요약은 *다수 입력의 압축·논조 판단*이라 성격이 다르다.첫 추정은 36,291원이었다. 모델을 낮추지 않고 대상·입력량으로 55% 줄였다.
| 축 | 조치 | 근거 |
|---|---|---|
| 입력 후기 | 고정 30 → 적응형 | 15건과 30건의 요약 품질 차이가 보이지 않았다 |
| 대상 임계 | ≥5 → ≥10건 | 6건을 2문장으로 압축하면 정보가 준다 — 그냥 읽는 편이 낫다 |
| 저리뷰 레시피 | LLM → 템플릿 | 집계 사실만 서술 · LLM 호출 없음 |
입력을 줄여도 되는 결정적 이유: 긍정 비율은 전수 141,282건 분류에서 나온다. 요약이 통계를 짊어질 필요가 없고 테마·팁만 건지면 된다.
| 항목 | 건수 | 비용 |
|---|---|---|
| LLM 요약 | 2,189 | ~19,000원 |
| 주의사항 | 636 | ~2,000원 |
| 템플릿 | 4,678 | 0원 |
| 합계 | ~21,000원 |
리뷰 10건 미만 4,678개(68%)는 LLM 대상이 아니라 화면에 빈칸이 생긴다. LLM 을 쓰면 정보가 줄고 비용이 배로 뛴다. → 집계 기반 템플릿으로 채웠다.
후기 19건 중 16건(84%)이 긍정적입니다.
후기 4건 중 3건이 긍정적입니다. 아쉬웠다는 의견도 1건 있습니다.
후기 1건이 긍정적입니다.
건수에 따라 문구가 다르다 — 1건에 "1건 중 1건(100%)" 은 통계처럼 보여 어색하고, 4건 이하는 백분율이 오히려 오해를 준다(3/4=75% 는 표본이 너무 작다). 창작이 없어 검증이 필요 없는 것이 이 방식의 핵심 이점이다.
고정 15건이면 신뢰도가 층마다 극단적으로 갈렸다(10~29건 97% 커버 vs 300건+ 3.7%).
| 리뷰 수 | 표본 |
|---|---|
| ≤20 | 전수 |
| 21~100 | 20건 |
| 100+ | 30건 |
부정 후기를 요약 표본에 강제로 넣으면 비율이 왜곡된다 — 300건 중 2건(0.7%)을 15건 중 3건(20%)으로 넣으면 30배 과대대표가 되어 좋은 레시피가 부당하게 나쁘게 보인다.
→ 칸을 나눴다.
| 필드 | 내용 |
|---|---|
summary | 전체 논조. 균등 표본 + 전수 분포 주입 |
caution | 부정 라벨 후기만으로 뽑은 주의사항 1문장 |
분포 주입 효과(긍정 36.4% 레시피에서 실측):
[미주입] "…초보자도 쉽게 도전할 수 있는 레시피라는 평이 많습니다." ← 장밋빛
[주입] "…호평이 많으나, 빵이 부서지거나 얇게 나오는 등 완성도 면에서
아쉬움이 있다는 의견도 있습니다." ← 균형
표본을 조작하지 않고 논조만 정확해졌다. 덤으로 positive_rate(전수)와 요약(표본)이 어긋나 보이던 문제도 해소됐다.
배치를 돌리기 전에 점검해 전부 고쳤다. 유료·장시간 배치라 사후 발견은 비싸다.
| # | 결함 | 조치 |
|---|---|---|
| 1 | model 컬럼 하나에 산출물 둘(감정·요약)이 충돌 | summary_model 분리(2026-07-29h) |
| 2 | UPDATE 0행을 성공으로 집계 — 조용한 유실 | rowcount 확인 후 경고 |
| 3 | 표본이 앞 30건 고정 — 739건 중 4%만 | 균등 추출 → 94% 커버 |
| 4 | 요약 없는 레시피 68% | 템플릿(§3.1) |
| 5 | 표본 대표성 격차 | 적응형(§3.2) |
| 6 | 드문 경고 누락 | caution 분리(§3.3) |
| 7 | 템플릿이 LLM 대상까지 덮음 | 경계를 SQL 로 못박음(양방향) |
| 8 | --temperature 플래그가 아무 일도 안 함 | 실제 배선 |
7번은 실제로 사고가 났다 — 템플릿이 LLM 대상 2,192건을 덮었다. 두 배치가 같은 칸을 쓰는데 경계가 없었다. 필러는review_count < 10만, LLM 배치는summary_kind='template'도 승격 대상에 포함하도록 고쳤고, 임계값은 한쪽에서 import 해 두 값이 갈릴 수 없게 했다.
"자동으로 덮어써진다"는 추정이 아니라 확인이다.
| 항목 | 방법 | 결과 |
|---|---|---|
| 대상 포착 | 실제 _TARGETS 상수 실행 | 2,192건 전부 · 누락 0 |
| 덮어쓰기 | 실제 _UPDATE 실행 후 롤백 | template → llm · 전 필드 교체 |
| 0행 감지 | 없는 recipe_id 로 UPDATE | rowcount=0 → skipped 처리 |
| 4축 동시 동작 | 실배치 3건 | 적응형·분포주입·caution·kind 동시 확인 |
| 창작 여부 | --audit 원문 대조 | 식용유·양념장·대패삼겹 전부 원문에 존재 |
| 테스트 | 전 서비스 | 269 passed |
caution 생성률이 층마다 다른 것도 검증됐다 — 300건+ 레시피는 98%가 부정 후기를 보유해 82%가 생성됐고, ~99건 구간은 40%다. 무작위가 아니라 데이터를 반영한 결과다.
| 한계 | 내용 |
|---|---|
| 표본 절단 | 300건+ 레시피는 여전히 30건(10%)만 본다. 드문 1건짜리 경고는 놓칠 수 있다 — 강제 포함이 더 나쁘다는 것이 확인돼 수용한 한계 |
| 갱신 트리거 없음 | 새 후기가 쌓여도 요약은 그대로. --redo 는 있으나 자동 트리거가 없다 |
| 창작 전수 미검증 | 표본만 --audit 했다. 자유 서술은 가드레일로 기계 검증이 불가하다 |
| 동적 로딩 절단 | 상세 페이지 HTML 에 처음 실린 후기까지만 수집(헤드리스 미사용) |
상세·판정 방법은 ai-verification-backlog.md — 당시 별도 검증 백로그에 기록.
| 항목 | 상태 |
|---|---|
크론 (poller-recipe-review) | ⬜ 미등록 — deploy/crontab.fb-pollers 에 줄은 추가됨 |
| compose | ✅ poller-recipe-review 등록 |
| 마이그레이션 | ✅ 2026-07-29h(summary_model) · 2026-07-29i(caution·summary_kind) |
| 재실행 | 안전 — summary_kind='template' 기준으로 남은 것만 잡는다 |