지난달, 저는 진심으로 자랑스러운 파이프라인 변경을 출시했습니다. 프롬프트 재작성. 전체 컨텍스트 검토 단계. 반복을 감지하고 세그먼트 간 구조적 다양성을 강제하는 상세한 루브릭.
배포했습니다. 6주 동안 관찰했습니다. 제 스스로에게 잘 작동한다고 말했죠.
그런 다음 평가 프레임워크를 구축했습니다. 7개 언어의 실제 프로덕션 에피소드 40개에서 실행했습니다. 그리고 그토록 신중하게 설계했던 검토 단계가 스크립트를 측정 가능할 정도로 악화시키고 있다는 것을 발견했습니다.
중립이 아니라, 더 나빠졌습니다.
세그먼트별 대화는 5점 만점에 3.34점. 개요는 3.01점. 그리고 최종 스크립트, 검토 후 점수는? 2.91점.
스크립트를 개선하기 위해 설계된 단계가 품질을 12% 이상 떨어뜨리고 있었습니다.
"잘 작동한다고 생각한다"에서 "작동하지 않는다는 것을 안다"로의 전환은 몇 주 전에 시작되었습니다. 저는 DeepLearning.AI의 Andrew Ng Agentic AI 코스를 보고 있었는데, 그는 당연하게 들리지만 실제로는 그렇지 않은 것을 강조합니다: 평가와 트레이스는 모든 에이전틱 시스템의 기초입니다. 그것 없이는 어둠 속에서 디버깅하는 것입니다. 그것이 있으면 체인의 어떤 링크가 망가졌는지 정확히 알 수 있습니다.
저는 수개월 동안 임시적인 스크립트 품질 검사를 해왔습니다 — 턴 길이 비율과 화자 균형 같은 구조적 메트릭, 그리고 A/B 프롬프트 변형을 비교하는 LLM 심사위원. 이들은 명백한 회귀를 감지했습니다. 하지만 포괄적이지 않았습니다. 하나의 단계(대화), 한 번에 한 언어만 다루었고, 파이프라인 전체 품질 감사가 아닌 프롬프트 A/B 테스트용으로 설계되었습니다.
트레이스에 대한 Andrew의 지적은 크게 와닿았습니다. 제 파이프라인에는 에피소드당 5개의 주요 LLM 호출이 있습니다 — 리서치, 개요, 세그먼트별 대화, 인트로/아웃트로, 검토 — 그리고 ElevenLabs TTS 패스. 그중 품질 메트릭이 있었던 것은 하나뿐이었습니다. 나머지 4개는 그저 감에 의존하고 있었죠.
그래서 진짜 평가 시스템을 구축했습니다. 완전하고, 다차원적이며, 다시 실행 가능한 시스템. 여기 그 발견 내용과, 하루 만에 출시한 6가지 수정 사항, 그리고 실제로 개선된 내용입니다.
기준선: 모든 것을 바꾼 세 개의 숫자
제 프로덕션 데이터베이스에서 완료된 40개의 에피소드를 평가했습니다 — 7개 언어(en, vi, ja, ko, es, zh, fr)와 10가지 팟캐스트 스타일을 포괄하며 — 각각 5차원의 세 가지 루브릭으로 평가했습니다. LLM 심사위원(GPT-5.6-terra)이 각 단계를 채점했습니다.
| Stage | Score | Worst Dimension |
|---|---|---|
| Dialogue (per-segment) | 3.34 | Factual Grounding: 2.17 |
| Outline (research + structure) | 3.01 | Citation Credibility: 1.28 |
| Final Script (post-review) | 2.91 | Publishability: 1.95 |
세 가지가 즉시 눈에 띄었습니다:
1. 검토 패스가 스크립트를 0.43만큼 저하시키고 있었습니다. 대화 점수는 3.34. 검토 후는? 2.91. 품질을 개선하기 위해 설계된 단계가 품질을 제거하고 있었습니다.
2. 모든 인용 URL이 불투명한 리디렉션이었습니다. 모든 개요의 모든 "소스 URL"이 vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQ...를 가리키고 있었습니다. 클릭하는 사람에게는 작동하지만, 자동화된 검토자에게는 완전히 조작된 것처럼 보입니다. 344개의 팩트에 소스 URL이 있었습니다. resolved_url을 가진 것은 0개 — 아직 존재하지도 않던 필드였습니다.
3. 게시 가능성(Publishability)이 전체 파이프라인에서 가장 낮은 차원이었습니다(1.95). 진짜 팟캐스터들은, 평가 심사위원의 판단에 따르면, 이 스크립트를 자신의 이름으로 게시하지 않을 것입니다. 감지 가능한 AI 패턴: 동일한 세그먼트 시작 문구, 일반적인 전환, 호스트 개성 부재.
평가는 정확히 무엇을 고쳐야 하는지 순위가 매겨진 목록을 제공했습니다. 저는 남은 하루를 수정하는 데 보냈습니다.
6가지 수정 사항(그리고 측정된 영향)
수정 1: 인용 URL — 0%에서 100% 해결
이전: 344개의 리서치 팩트 중 0개가 resolved_url을 가지고 있었습니다. 모든 URL이 조작된 것처럼 보였습니다.
수정: 개요 생성 중에 실행되는 60줄의 URL 리졸버. Vertex AI 리디렉션을 실제 소스까지 따라가고, 두 URL을 모두 저장합니다(원본은 Google 이용약관 준수용, 해결된 것은 그 외 모든 용도).
def resolve_grounding_url(url: str) -> str:
if "grounding-api-redirect" not in url:
return url
response = requests.head(url, allow_redirects=True, timeout=5)
return response.url if response.url != url else url
이후: 오늘의 새 에피소드에서 23개 중 23개의 리서치 팩트가 resolved_url을 채웠습니다 — simonwillison.net, axios.com, thinkingmachines.ai와 같은 실제 URL. 100% 해결.
수정 2: 검토 모델 교체(Gemini → DeepSeek)
이전: Gemini 3.5 Flash가 검토 패스를 실행했습니다. 가볍고 보수적인 편집을 했습니다: "Exactly!"를 "No question about it!"으로 변경했지만 대부분 원본 텍스트를 보존했습니다. 대화를 평탄화하는 필러를 추가했습니다. 오디오 태그 밀도가 떨어졌습니다. 타입-토큰 비율이 떨어졌습니다. 턴 수가 부풀었습니다.
수정: 검토 패스를 DeepSeek v4-pro(최대 출력 384K, 96K 제한 설정)로 교체했습니다. 제공자를 설정 가능하게 만들었습니다:
provider = get_provider("review") # reads REVIEW_PROVIDER env var
response = provider.generate(
prompt=prompt, temperature=0.0,
max_output_tokens=96000,
)
검증: 프로덕션에 배포. 베트남어 기술 뉴스 에피소드가 DeepSeek 검토와 함께 전체 파이프라인을 통과 — 10.3K → 11.6K 토큰, 121초 만에 완료, 조임 패스 0회 필요. 두 번째 에피소드(영어)는 7.9K → 17K 토큰을 203초 만에 처리. DeepSeek API 키는 Google Cloud Secret Manager에 저장되며, 배포 시 service.yaml을 통해 자동 주입됩니다.
수정 3: 개요 자체 비평(+0.50 개선)
이전: 개요는 내부 품질 검사 없이 Gemini에서 바로 사용자에게 전달되었습니다. 평균 점수: 3.01.
수정: 자동화된 비평 단계 추가. DeepSeek v4-pro가 6차원 루브릭(5개의 개요 차원 + 세그먼트 수)으로 개요를 평가하고, 점수 + 구체적인 피드백을 반환하며, 비평을 팟캐스트 메타데이터에 저장합니다.
그런 다음 통제된 실험을 실행했습니다: 개요 점수가 3.0 미만인 6개의 에피소드를 가져와 DeepSeek 비평을 실행하고, 피드백을 재생성 지침으로 Gemini에 되돌려주고, 다시 채점했습니다.
이후: 6개 에피소드에서 +0.50 전체 개선.
| Dimension | Before | After | Delta |
|---|---|---|---|
| Content Boundaries | 3.33 | 4.17 | +0.83 |
| Research Depth | 2.67 | 3.17 | +0.50 |
| Citation Credibility | 1.00 | 1.50 | +0.50 |
| Structural Logic | 3.67 | 4.17 | +0.50 |
| Audience Fit | 2.17 | 2.33 | +0.17 |
가장 낮은 에피소드는 1.80에서 3.20으로(+1.40) 상승했습니다. 6개 중 1개만 악화되었습니다. 비평은 이제 프로덕션에서 기본적으로 활성화되어 있습니다 — 모든 새 개요는 사용자가 보기 전에 이 품질 검사를 받습니다.
수정 4: 단일 세그먼트 개요는 이제 강제 실패
이전: 평가 결과 단일 세그먼트와 0개의 리서치 팩트를 가진 에피소드가 2.07까지 낮은 점수를 기록했습니다. 이들은 파이프라인이 실패로 간주하지 않던 실패 사례였습니다.
수정: 복구 시도 후에도 개요 생성기가 3개 미만의 유효한 세그먼트를 생성하면, 팟캐스트는 FAILED로 표시됩니다. 더 이상 단일 세그먼트 개요가 사용자에게 도달하지 않습니다. 다음 생성 시도에서 사용자의 크레딧이 재시도를 위해 해제됩니다.
수정 5: 중국어 현지화 규칙
이전: 중국어 에피소드 점수는 2.88 — 7개 언어 중 가장 낮았습니다. 번역 아티팩트(영어 관용구의 직역), 동일한 세그먼트 시작 문구, 중국어 이름(明辉/晓雯) 대신 기본 영어 호스트 이름(Alex/Maya).
수정: 중국어 특화 대화 규칙 작성: 원어민 대화 패턴(不是...而是... 구문), 적절한 문말 조사(吧/啊/呢), 번역 금지 가이드라인("medical miracle"을 직역하지 말 것), 월드컵 에피소드를 위한 중국 축구 은유, 그리고 독특한 개성을 가진 로케일별 호스트 프로필.
중국어 대화 템플릿은 영어 기본값을 재사용하던 것에서, 대화 패턴, 반대 의견 표현 방식, 모든 팟캐스트 스타일에 대한 오디언스별 프레이밍을 다루는 80줄의 자체 가이드를 갖추게 되었습니다.
수정 6: 비영어용 호스트 이름 기본값
이전: 여러 비영어 에피소드의 호스트 이름이 Alex와 Maya였습니다. 로케일별 호스트 프로필이 존재했지만, 개요 생성기의 폴백 경로가 영어 기본값으로 하드코딩되어 있었습니다.
수정: 로케일 인식 프로필 해결 파이프라인을 통해 수정을 추적했습니다. 최근 프로덕션 에피소드는 이제 翔太/健一(ja), Mạnh/Nga(vi), Hugo/Camille(fr), 明辉/晓雯(zh)을 사용합니다. 7월 커밋에서 이미 엣지 함수와 생성 흐름을 수정했으며 — 나머지 폴백은 개요 생성기 자체에 있었습니다.
평가 프레임워크(재사용 가능)
이 모든 것을 발견한 프레임워크는 약 500줄의 Python, 3개의 루브릭 파일(각 5차원), 공유 GPT-5.6-terra 심사위원, 그리고 오케스트레이터로 구성됩니다:
docs/pipeline/evals/
├── run.py # Orchestrator: extract → judge → report
├── judge.py # Shared LLM judge (rate with rubric)
├── rubric_outline.py # Stage 1: 5 dimensions, 1-5 scale
├── rubric_dialogue.py # Stage 2: 5 dimensions, 1-5 scale
├── rubric_final_script.py # Stage 3: 5 dimensions, 1-5 scale
├── dataset_40.json # Extracted production data
├── scores.json # Machine-readable scores
└── report.md # Auto-generated report
A/B 비교를 위한 실험 레이어도 구축했습니다:
docs/pipeline/evals/experiments/
├── review_ab.py # Compare two review models
├── outline_critique_ab.py # Critique → regenerate → compare
├── shared.py # Score comparator, report generator
└── results/ # Archived by date
파이프라인 변경 후 python docs/pipeline/evals/run.py --full을 실행하면 약 8분 만에 보고서를 얻을 수 있습니다. 모델을 비교하려면 experiments/review_ab.py --episodes 10을 실행하세요. 결과는 추세 추적을 위해 날짜별로 보관됩니다 — 이번 달 품질이 지난달보다 개선되었는지 알고 싶다면? 점수를 diff하세요.
전체 40개 에피소드 평가 비용은 API 호출로 약 $1-2입니다. 실험 비용은 더 적습니다. 그 대가로 얻는 신호 — 파이프라인의 어떤 단계와 차원에 주의가 필요한지 정확히 보여주는 순위 목록 — 이것이 제가 만든 가장 저렴한 디버깅 도구입니다.
여전히 망가진 것들
DeepSeek 검토 A/B 실험에는 전체 프로덕션 프롬프트가 필요합니다. 실험 스크립트는 15줄의 단순화된 프롬프트를 사용했습니다. 프로덕션 검토는 반복 방지 규칙, 캐치프레이즈 할당량, 편집 가드레일, 길이 정책이 포함된 80줄짜리 프롬프트를 사용합니다. 단순화된 프롬프트로 DeepSeek은 본질적으로 중립적인 결과(-0.04)를 보였습니다. 프로덕션의 전체 프롬프트로는 파이프라인이 영어와 베트남어에서 성공적으로 완료되고 있습니다. 실험을 프로덕션에 맞게 업데이트하고 다시 실행해야 합니다.
중국어 현지화에는 검증이 필요합니다. 규칙은 서류상으로는 맞아 보이고, 호스트 프로필은 작성되었으며, 대화 가이드는 마련되어 있습니다. 하지만 아직 새로운 중국어 에피소드에서 평가를 실행하여 점수가 2.88에서 올랐는지 확인하지 않았습니다. 이것이 이번 주 우선순위입니다.
새 에피소드에서 전체 40개 에피소드 평가를 다시 실행해야 합니다. 6가지 수정 사항이 모두 배포되었습니다. 다음 단계는 이러한 변경 이후에 생성된 40개의 에피소드를 추출하여 동일한 평가를 통과시키고, 과거 기준선과 비교하는 것입니다. 최종 스크립트 점수가 2.91에서 3.0 이상으로 올라가고, 인용 신뢰도가 1.28에서 합리적인 수준으로 올라가면, 변경 사항이 엔드투엔드로 작동했음을 알 수 있습니다.
세 가지 질문 파이프라인 감사
이 경험을 바탕으로, 이제 모든 파이프라인 변경을 세 가지 질문으로 감사합니다:
1. 각 단계 사이에 품질 게이트가 있는가? 제 개요는 Gemini에서 직접 사용자에게 가고 있었습니다. 비평 단계를 추가함으로써 최악의 개요를 누군가 보기 전에 포착할 수 있었습니다. 모든 파이프라인 단계에는 품질 검사가 필요합니다 — 명시적 기준에 대한 자동화된 LLM 평가.
2. 각 단계가 측정했을 때 실제로 품질을 개선하는가? 실행하고 도움이 된다고 가정하는 것만으로는 충분하지 않습니다. 동일한 콘텐츠에 대한 문자 그대로의 전/후 점수가 필요합니다. 제 검토 단계는 측정하기 전까지 6주 동안 스크립트를 저하시켰습니다. 먼저 측정하고, 아무것도 가정하지 마세요.
3. 어떤 차원이 망가졌는지 식별할 수 있는가? "품질이 나쁘다"는 실행 가능하지 않습니다. "인용 신뢰도가 1.28인 이유는 URL의 100%가 불투명한 리디렉션이기 때문이다"는 실행 가능합니다. 단계별 다차원 루브릭이 정확히 어디를 봐야 하는지 알려줍니다. 평가 전에는 검토 단계를 조사하는 데 몇 시간을 보냈습니다. 평가가 있으니 몇 초밖에 걸리지 않았습니다 — 숫자가 직접 게시 가능성과 검토 모델을 가리켰습니다.
자주 묻는 질문
LLM 평가를 실행하는 것이 비싸지지 않나요?
전체 40개 에피소드 평가 비용은 API 호출로 약 $1-2입니다(GPT-5.6-terra, 총 ~420K 토큰). A/B 실험은 더 적게 듭니다. 그 대가로 얻는 신호 — 파이프라인의 어떤 단계에 주의가 필요한지 정확히 보여주는 순위 목록 — 이것이 제가 만든 가장 저렴한 디버깅 도구이며, 사용자가 망가진 에피소드에 낭비할 크레딧보다 저렴합니다.
왜 단계당 5차원인가요? 그냥 "전체 품질"로는 안 되나요?
"전체 품질"은 무언가 잘못되었다고 알려줍니다. 무엇이 잘못되었는지는 알려주지 않습니다. 인용 신뢰도가 1.28인 것을 보았을 때, URL이 망가졌다는 것을 즉시 알았습니다. 게시 가능성이 1.95인 것을 보았을 때, AI 흔적이 감지 가능하다는 것을 알았습니다. 5차원은 감별 진단을 제공합니다. 1차원은 체온계를 제공할 뿐입니다.
LLM 심사위원의 일관성을 어떻게 유지하나요?
동일한 모델(GPT-5.6-terra), 동일한 온도(0.0), 동일한 추론 노력(medium), 매번 동일한 루브릭 프롬프트. 점수는 타임스탬프와 함께 보관되므로 날짜 간 비교가 가능합니다. 심사위원을 바꾸면 기준선이 바뀝니다 — 하나를 선택하고 계속 사용하세요.
심사위원 자체가 틀렸을 때는 어떻게 하나요?
루브릭에는 각 점수에 대한 필수 근거가 포함되어 있습니다 — 심사위원은 콘텐츠의 구체적인 증거를 인용해야 합니다. 또한 심사위원을 보정하기 위해 7개 언어 전체에서 10개 에피소드의 수동 정성 검토도 수행했습니다. LLM 점수는 제 인간적 판단과 밀접하게 일치했습니다. LLM이 신뢰할 수 없을 수 있는 중요한 차원(문화적 판단이 필요한 "게시 가능성" 등)의 경우, 인간의 표본 검사가 필수적입니다.
저는 DIALOGUE라는 AI 팟캐스트 플랫폼을 저녁과 주말에 혼자서 개발하고 있습니다. 여정에서 배운 것을 글로 씁니다.
만약 여러분이 자신의 LLM 파이프라인을 위한 평가 시스템을 구축하셨다면, 궁금합니다: 품질을 어떻게 측정하고, 무엇을 발견했을 때 놀라셨나요?
여기까지입니다.
감사합니다, Chandler