프롬프트 시스템을 운영하다 보면 어느 순간 아주 중요한 사실을 마주하게 된다. 잘 생성하는 프롬프트만으로는 운영 품질이 완성되지 않는다는 사실이다. 답변을 만드는 프롬프트가 엔진이라면, 검증 프롬프트는 브레이크이자 계기판이다. 엔진만 좋은 차는 멀리 가지 못한다. 빠르게 틀릴 뿐이다.
실무에서는 특히 이 차이가 크게 드러난다. 생성 프롬프트는 사용자의 질문에 그럴듯한 답을 만들어 내는 데 최적화되어 있다. 반면 검증 프롬프트는 그 답이 정말 맞는지, 형식을 지켰는지, 근거가 있는지, 지나치게 단정적인지 따져 묻는 역할을 맡는다. 둘은 비슷해 보여도 성격이 다르다. 하나는 생산자이고, 다른 하나는 검사자다. 이 둘을 분리해서 설계할수록 시스템은 더 안정적이 된다.12

왜 생성 프롬프트만으로는 부족한가
모델은 대체로 "무언가를 말하라"는 요청에 매우 능숙하다. 그래서 생성 단계에서는 빈칸을 메우고, 문장을 매끄럽게 만들고, 애매한 요청도 그럴듯하게 정리해 버린다. 사용자 입장에서는 편해 보이지만 운영자 입장에서는 위험하다. 우리가 막고 싶은 오류는 대개 이런 순간에 생긴다.
첫째, 사실이 아닌데 사실처럼 들리는 답이 나온다. 둘째, 형식은 얼추 맞는데 실제 계약된 출력 규격은 깨진다. 셋째, 검색 문서를 넣어 주었는데도 답변이 문서 바깥으로 미끄러진다. 넷째, 근거가 약한데도 말투는 지나치게 확신에 차 있다.
이런 문제는 생성 프롬프트에 "정확하게 답하라", "근거를 사용하라", "확실하지 않으면 말하지 말라"를 더 붙인다고 완전히 사라지지 않는다. 오히려 생성과 검증을 분리해야 더 잘 잡힌다. 좋은 운영 구조는 하나의 프롬프트에 모든 책임을 몰아주지 않는다. 답변을 만든 뒤, 다른 시선으로 다시 본다.
자동 검증 프롬프트의 기본 구조
자동 검증 프롬프트는 대체로 다섯 가지 입력을 받는다. 사용자 질문, 생성된 답변, 필요하다면 참고 문서나 정답 레퍼런스, 평가 기준, 그리고 기계가 읽을 수 있는 출력 형식이다. 이 다섯 가지가 빠지면 검증기는 쉽게 감상평으로 변한다.
좋은 검증 프롬프트는 특히 세 가지를 분명히 한다.
무엇을 판정할지: 사실성, 형식 준수, 근거성, 과잉확신처럼 평가 대상을 좁힌다.
무엇을 근거로 판정할지: 레퍼런스 답, 검색 문서, 정책 규칙 등 판단 근거를 명시한다.
무엇을 출력할지: pass/fail, 소수의 정수 점수, 이슈 목록, 검토 필요 여부처럼 후속 자동화에 바로 연결되는 구조를 강제한다.13
여기서 중요한 감각이 하나 있다. 검증 프롬프트는 "좋은 설명"보다 "좋은 판정"을 목표로 해야 한다는 점이다. 사람에게 읽기 좋은 장문 비평보다, 시스템이 소비하기 쉬운 구조화된 결과가 더 중요하다.
검증기는 하나보다 여러 개가 낫다
운영 환경에서 자주 생기는 실수는 하나의 슈퍼 저지 프롬프트에게 모든 걸 맡기는 것이다. 사실성도 보고, 형식도 보고, 근거도 보고, 안전도 보고, 말투까지 보라고 하면 대개 점수가 흐려진다. 모델도 사람과 비슷해서 한 번에 너무 많은 항목을 보게 하면 집중력이 떨어진다.
그래서 실무에서는 검증기를 쪼개는 편이 낫다. 같은 답변을 두고도 "사실성 판정기", "형식 준수 판정기", "근거성 판정기", "과잉확신 탐지기"처럼 역할을 나누면 각 검증기가 무엇을 놓쳤는지 더 잘 보인다. 특히 고위험 업무에서는 생성기와 별도의 verifier 역할을 두고, 판정 시 근거를 요구하는 방식이 더 강한 통제력을 만든다.2
이 분리는 디버깅에도 도움이 된다. 사실성은 괜찮은데 근거성이 낮은지, 답은 맞는데 형식만 자꾸 깨지는지, 아니면 내용도 틀리고 톤도 과하게 확신적인지 문제를 분해해서 볼 수 있기 때문이다.
사실성 판정기: 맞는 말을 했는지 가려내기
사실성 판정기는 가장 익숙하면서도 가장 자주 오해받는 검증기다. 많은 팀이 "이 답이 사실적으로 맞는가?"만 물어본다. 하지만 레퍼런스 없이 이 질문을 던지면 검증기는 사실을 확인하는 것이 아니라 그럴듯함을 평가하게 된다. 즉, 유창한 환각이 높은 점수를 받기 쉽다.1
따라서 사실성 판정기의 첫 원칙은 비교 기준을 제공하는 것이다. 기준은 상황에 따라 다르다. 짧은 단답형 QA라면 신뢰할 수 있는 reference answer가 가장 좋다. 문장 생성이나 요약이라면 핵심 사실 목록을 reference fact set으로 줄 수 있다. RAG 시스템이라면 검색 문서에서 추출한 사실 집합을 임시 레퍼런스로 삼을 수 있다.
짧은 사실 질문에서는 판정 범주를 단순하게 가져가는 편이 좋다. 예를 들어 정답, 오답, 답변 보류의 세 범주는 운영적으로 매우 유용하다. 단순히 맞고 틀림만 보는 것이 아니라, "모를 때 무리해서 말하지 않았는가"까지 함께 보기 때문이다.6
반면 긴 설명형 답변에서는 문단 전체를 한 번에 채점하면 중요한 것을 놓치기 쉽다. 이때는 답변을 주장 단위로 쪼개야 한다. 각 주장에 대해 레퍼런스와 일치하는지, 빠진 핵심 사실은 없는지, 추가한 정보가 근거와 충돌하지 않는지 따로 봐야 한다. 최근의 장문 사실성 평가 연구도 단순 정밀도만이 아니라, 필요한 사실을 얼마나 빠뜨렸는지까지 함께 보는 방식이 중요하다고 지적한다.7
사실성 판정기의 출력은 다음처럼 설계하면 운영에 잘 맞는다.
overall_verdict: pass | fail | review
claim_checks: 주장별 판정 배열
missing_facts: 빠진 핵심 사실 목록
contradiction_count: 모순 개수
abstention_ok: 답변 보류가 적절했는지 여부
여기서 핵심은 전체 점수 하나보다 주장별 결과가 더 가치 있다는 점이다. 전체 점수는 대시보드에 좋고, 주장별 결과는 개선에 좋다.
사실성 판정 프롬프트를 만들 때의 요령
사실성 판정기에는 큰 척도보다 작은 척도가 더 잘 맞는 경우가 많다. 0부터 100까지 점수를 매기게 하면 그럴듯한 숫자는 나오지만, 운영 정책으로 연결하기가 애매해진다. 반면 pass/fail/review나 1부터 4까지의 작은 척도는 훨씬 안정적으로 게이트를 걸 수 있다. 또한 최종 판정 전에 짧은 근거 요약을 먼저 작성하게 하면 사람 검토 시 왜 탈락했는지도 추적하기 쉬워진다.3
예를 들어 사실성 판정기는 이렇게 지시할 수 있다.
질문, 후보 답변, reference facts를 비교하라. 후보 답변의 핵심 주장 각각을 추출하고, 각 주장을 supported, contradicted, not_found 중 하나로 분류하라. reference facts에 없는 내용을 사실처럼 단정한 경우 fail 후보로 표시하라. 최종 출력은 단일 JSON 객체로 반환하라.
이 지시가 좋은 이유는 문장력을 평가하지 않고 비교 행위를 강제하기 때문이다.
형식 준수 판정기: 맞는 내용도 틀린 포맷이면 실패다
형식 검증은 자주 과소평가된다. 하지만 실무에서는 사실보다 형식이 먼저 시스템을 망가뜨리는 경우도 많다. JSON 하나가 깨지면 파이프라인이 멈추고, 필수 필드 하나가 빠지면 후속 시스템이 동작하지 않으며, 금지된 섹션이 하나 들어가면 정책 위반이 된다.
형식 준수 판정기에서 가장 먼저 기억할 점은, 모든 형식 검사를 LLM에게 맡길 필요는 없다는 것이다. 오히려 가장 바깥쪽 검사는 코드가 맡아야 한다. JSON 파싱, 필수 키 존재, 길이 제한, 정규식 패턴, 금지 문자열 체크는 결정적 검사기가 훨씬 싸고 정확하다.1
LLM 기반 형식 준수 판정기는 그 다음 층에서 빛난다. 예를 들어 이런 항목들이다. 요약문이 정말 세 문단인지, 각 섹션의 의미가 지정된 역할과 맞는지, 인용이 형식상 들어간 것처럼 보이지만 실제로 근거 문장과 연결되어 있는지, "사과하지 말 것" 같은 미묘한 스타일 규칙을 어겼는지 등은 규칙 기반만으로는 놓치기 쉽다.
좋은 형식 검사는 보통 두 단계로 나뉜다. 먼저 결정적 검사로 구조를 빠르게 걸러낸다. 그다음 LLM 검사기로 의미적 형식 위반을 본다. 이를 한 번에 합치려 하면 비싸고 불안정해진다.
형식 준수 판정기의 출력 예는 단순할수록 좋다.
schema_valid: true | false
missing_fields: 배열
forbidden_fields: 배열
semantic_format_issues: 배열
final_verdict: pass | fail | review
이 검증기에서 중요한 것은 관대함보다 일관성이다. 형식 규칙은 예술이 아니라 계약이기 때문이다.
근거성 판정기: 맞는 말처럼 보여도 문서에 기대고 있는가
근거성은 사실성과 닮았지만 다르다. 사실성이 "맞는 말인가"를 묻는다면, 근거성은 "이 답이 제공된 문서에 의해 뒷받침되는가"를 묻는다. 예를 들어 답 자체는 세상 일반 지식으로 맞을 수 있어도, 내부 정책 도우미에서는 제공된 문서 근거 없이 답하면 실패여야 할 수 있다.
근거성 판정기는 특히 RAG 시스템의 안전장치다. 검색이 잘 들어갔다고 해서 답변이 자동으로 grounded되는 것은 아니다. 모델은 문서를 읽고도 자기 기억을 섞거나, 문서 한 줄을 과장하거나, 없는 결론을 매끄럽게 만들어 낼 수 있다.
그래서 근거성 판정기는 답변의 각 주장에 대해 문서 근거를 붙이도록 강제하는 방식이 좋다. 단순히 "근거가 있나요?"라고 묻는 대신, "지원하는 문단 ID를 제시하라", "없으면 unsupported로 분류하라", "문서와 충돌하면 contradicted로 표시하라"처럼 증거를 달라고 요구해야 한다.2
이 검증기는 특히 다음 세 종류의 오류를 잘 잡아야 한다.
unsupported: 문서 어디에도 없는 내용을 답변에 넣은 경우
overgeneralized: 문서의 제한적 조건을 일반 규칙처럼 과장한 경우
citation_mismatch: 인용 표시는 달았지만 실제로는 해당 문단이 그 주장을 지지하지 않는 경우
실무에서는 groundedness를 이진값으로만 보지 않는 편이 좋다. 예를 들어 90%는 문서 기반인데 핵심 한 문장이 문서 밖에서 나온 경우가 있다. 이런 답은 전체적으로는 그럴듯하지만 실제로는 위험하다. 그래서 claim-level grounding이 중요하다.
과잉확신 탐지기: 틀린 답보다 더 위험한 말투를 잡아내기
과잉확신은 종종 독립된 결함으로 다뤄야 한다. 답이 틀린 것도 문제지만, 틀린 답을 지나치게 단정적으로 말하는 것은 더 큰 문제다. 특히 법무, 의료, 보안, 인사처럼 사용자가 답을 그대로 행동으로 옮길 가능성이 높은 분야에서는 그렇다.
과잉확신 탐지기는 보통 사실성 판정기와 uncertainty 정책 사이의 다리 역할을 한다. 이 검증기는 "무엇이 틀렸는가"보다 "현재 근거 수준에 비해 말투가 과도한가"를 본다. 불확실성 정량화와 환각 신호를 함께 다루는 최근 논의에서도, 확신 표현은 잠재적 오류를 읽는 중요한 신호로 다뤄진다.8
예를 들어 이런 패턴은 과잉확신 후보가 된다.
근거 문서가 일부만 있는데 "반드시", "항상", "예외 없이"라고 단정함
문서에 날짜가 없는데 특정 시행일을 확정적으로 말함
답변 보류가 적절한 상황인데도 선택지를 하나로 못 박음
출처 충돌이 있는데 충돌 사실을 숨기고 하나만 정답처럼 제시함
과잉확신 탐지기의 좋은 설계는 말투 자체만 보지 않는다. 말투와 근거 수준을 함께 비교한다. 즉, "이 표현이 공격적이다"가 아니라 "현재 evidence_strength가 weak인데 certainty_level이 high다" 같은 방식으로 판단한다.
이 검증기의 출력은 다음처럼 잡을 수 있다.
certainty_level: low | medium | high
evidence_strength: none | weak | partial | strong
calibration_ok: true | false
risky_phrases: 배열
recommended_rewrite: hedge | ask_more_info | refuse | cite_evidence
이렇게 하면 단순 경고를 넘어서 자동 수정 루프와도 연결된다.
좋은 검증 프롬프트는 '판정 기준'을 숨기지 않는다
검증 프롬프트는 모호하면 바로 흔들린다. "전반적으로 잘 썼는지 평가하라"는 지시는 사람에게도 어렵다. 모델에게는 더 어렵다. 그래서 판정 기준을 점수표처럼 구체화해야 한다. 어떤 경우가 1점이고 어떤 경우가 4점인지, 어떤 경우가 pass고 어떤 경우가 review인지, 반례는 무엇인지 보여 줘야 한다.
LLM-as-a-judge 연구와 실무 가이드들이 반복해서 보여 주는 패턴도 비슷하다. 역할을 분명히 주고, 평가 대상과 기준을 좁히고, few-shot 또는 간단한 rubric을 함께 주고, 구조화된 결과를 강제할수록 사람 판단과 더 잘 맞는다.34
특히 검증 프롬프트는 아래 순서가 잘 통한다.
역할: 당신은 답변 검증기다.
임무: 특정 속성 하나만 판정하라.
기준: pass, fail, review의 조건을 써라.
절차: 주장 추출, 근거 대조, 최종 판정 순서로 일하라.
출력: 반드시 JSON으로 반환하라.
이 구조는 화려하지 않지만 견고하다. 검증 프롬프트는 문학 작품이 아니라 검사 체크리스트에 가깝다.
자동화 흐름: 여러 판정기를 어떻게 묶을 것인가
실제 서비스에서는 검증기 하나를 호출하고 끝나지 않는다. 보통은 단계별 파이프라인을 구성한다.
첫 단계는 값싼 결정적 검사다. JSON 파싱, 필수 필드, 금지어, 최대 길이, citation 개수, 응답 시간 같은 항목을 여기서 처리한다. 이 단계에서 탈락한 답은 굳이 더 비싼 LLM 검증기로 보낼 필요가 없다.
둘째 단계는 전문 판정기 병렬 실행이다. 사실성, 근거성, 과잉확신, 정책 위반 가능성 등을 분리된 프롬프트로 본다. 한 검증기에게 모든 기준을 몰아주기보다, 각 판정기가 자기 일만 하게 만든다.
셋째 단계는 결합 정책이다. 예를 들어 사실성 fail이면 즉시 차단, 사실성 pass지만 근거성 review면 사람 검토, 사실성과 근거성은 pass인데 과잉확신만 fail이면 표현 완화 후 재검사처럼 흐름을 나눈다.
넷째 단계는 후처리다. 자동 수정, 재생성, 사람 검토 큐 이관, 실패 로그 적재, 회귀셋 편입이 여기서 일어난다.
이 흐름을 단순화하면 아래와 같다.
결정적 형식 검사
전문 검증기 병렬 실행
판정 결합과 라우팅
자동 수정 또는 사람 검토
이 구조의 장점은 명확하다. 비용을 아끼고, 원인을 추적하기 쉽고, 실패 데이터를 다음 개선 루프에 연결할 수 있다.
운영 게이트는 연속 점수보다 결정 규칙이 중요하다
많은 팀이 검증 결과를 멋진 점수판으로 만들고 싶어 한다. 물론 대시보드에는 점수가 유용하다. 하지만 운영 게이트에서는 점수보다 규칙이 중요하다. 82점이 안전한지 79점이 위험한지는 결국 비즈니스 문맥이 정한다.
예를 들어 내부 지식 도우미의 승인 규칙은 이렇게 단순할 수 있다.
형식 검사 fail이면 즉시 재생성
사실성 fail이면 사용자에게 직접 노출 금지
근거성 review면 사람 검토 큐로 이동
과잉확신 fail이면 표현 완화 후 한 번만 재검사
이런 규칙은 투박해 보여도 실제 운영에는 강하다. 반면 "종합 점수 83점 이상 통과" 같은 방식은 나중에 왜 통과했는지 설명하기가 더 어렵다.
자동 검증 프롬프트의 한계도 함께 설계해야 한다
검증기가 자동이라고 해서 중립적이거나 완벽한 것은 아니다. LLM-as-a-judge는 사람 평가와 꽤 높은 수준의 일치를 보일 수 있지만, 위치 편향, 장황함 편향, 자기 계열 선호, 추론 과제에서의 한계 같은 문제도 잘 알려져 있다.4
이 말은 곧 검증기 자체도 검증 대상이라는 뜻이다. 검증 프롬프트가 드리프트할 수 있고, 특정 모델 패밀리 답변에 유리할 수 있으며, reference가 없을 때는 그럴듯함을 사실성으로 오인할 수 있다. 그러니 중요한 운영 원칙은 검증기를 믿되, 맹신하지 않는 것이다.
이를 위해 실무에서는 몇 가지 안전장치를 둔다.
가능한 한 생성 모델과 다른 계열의 모델을 저지로 쓴다.
pairwise 평가에서는 순서를 바꿔 두 번 본다.
점수보다 verdict와 근거 필드를 저장한다.
사람 라벨 소량 샘플과의 일치도를 주기적으로 재측정한다.
검증기를 도입하면 품질이 올라가지만, 검증기 운영이라는 새로운 시스템이 생긴다는 사실도 함께 받아들여야 한다.
실무용 템플릿: 검증 프롬프트를 어떻게 써야 하나
검증 프롬프트의 템플릿은 의외로 단순한 편이 좋다. 예를 들어 사실성 판정기라면 다음 요소만 들어가도 충분히 강하다.
당신은 사실성 검증기다. 입력으로 사용자 질문, 후보 답변, reference facts가 주어진다. 후보 답변의 핵심 주장을 분리하라. 각 주장에 대해 reference facts와 비교해 supported, contradicted, not_found 중 하나로 분류하라. reference에 없는 내용을 단정적으로 추가한 주장이 있으면 review 또는 fail로 판정하라. 최종 결과는 verdict, claim_checks, summary_reason를 포함한 JSON 객체 하나로 반환하라.
근거성 판정기라면 reference facts 대신 retrieved context와 source_id를 받고, 각 주장마다 evidence_ids를 요구하면 된다. 과잉확신 탐지기라면 certainty 표현과 evidence strength를 함께 비교하도록 바꾸면 된다. 형식 준수 판정기라면 required sections, forbidden patterns, schema contract를 넣으면 된다.
핵심은 늘 같다. 역할 하나, 기준 하나, 출력 하나. 검증 프롬프트는 욕심을 줄일수록 강해진다.
어떤 항목을 자동 검증에 먼저 넣어야 할까
모든 것을 한꺼번에 자동화할 필요는 없다. 보통은 실패 비용이 크고, 사람이 눈으로 보기 번거롭고, 규칙을 분명히 적을 수 있는 항목부터 시작하면 된다.
우선순위를 잡아 보면 대개 이 순서가 실용적이다.
형식 준수: 가장 싸고 즉시 효과가 난다.
근거성: RAG 품질을 눈에 띄게 올린다.
사실성: 레퍼런스가 있는 범위부터 시작하면 안정적이다.
과잉확신: 고위험 업무에서 특히 가치가 크다.
이 순서가 좋은 이유는 자동화 난이도와 운영 효과가 균형을 이루기 때문이다. 처음부터 모든 생성물을 철학적으로 채점하려 들면 오래 못 간다. 대신 분명하게 실패를 잡는 검증기부터 하나씩 쌓아 올리면 시스템이 단단해진다.
결국 검증 프롬프트는 '두 번째 두뇌'다
좋은 생성 프롬프트는 답을 잘 만든다. 좋은 검증 프롬프트는 그 답을 쉽게 통과시키지 않는다. 이 둘의 긴장 관계가 운영 가능한 프롬프트 시스템을 만든다.
실무에서 정말 필요한 것은 모델이 스스로 완벽해지는 마법이 아니다. 불완전한 답을 걸러 내고, 애매한 답을 보류하고, 위험한 답을 멈추고, 괜찮은 답만 통과시키는 구조다. 자동 검증 프롬프트는 바로 그 구조의 핵심이다.
프롬프트를 시스템으로 본다는 말은 결국 이런 뜻이다. 답을 쓰는 문장만 설계하는 것이 아니라, 그 답을 검사하는 문장까지 설계해야 한다는 뜻이다. 생성 프롬프트가 앞문이라면, 검증 프롬프트는 뒷문이다. 앞문만 튼튼한 집은 오래 버티지 못한다.
참고
1What is an LLM-as-a-judge? When to use it (and when to use deterministic evals)
2GitHub - kropdx/unofficial-claude-code-prompt-playbook
3Using LLM-as-a-judge for an automated and versatile evaluation
4Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena
6Measuring short-form factuality in large language models
7VeriFact: Enhancing Long-Form Factuality Evaluation with Refined Fact Extraction and Reference Facts
8Towards Trustworthy AI: Enhancing Factuality, Bias, and Compliance in LLMs
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.