jongkwan.dev
개발 · Essay №043

CRITIC: 외부 도구를 통한 검증

모델 자체 판단이 아닌, 외부 도구(검색, 코드 실행, 계산기)를 사용해 답변을 검증하고 개선하는 기법

이종관2026년 2월 1일6 min read
Contents

외부 도구를 통한 검증

개념

CRITIC은 모델 스스로의 판단이 아닌, 외부 도구(코드 실행, 검색, 계산기 등)를 사용해 답변을 검증하고 개선하는 기법이다.

동작 구조

  1. 초기 답변 생성 -- 모델이 질문에 대한 1차 답변을 만든다
  2. 외부 도구로 검증 -- 검색, 계산기, 코드 실행 등으로 답변을 확인한다
  3. 맞으면 최종 답변으로 확정하고, 틀리면 오류를 분석하여 개선한다

예시

질문: "2023년 한국의 인구는?"

1차 시도 -- 모델: "약 5,200만 명이다."

CRITIC 검증 -- Action: [Search] "2023년 한국 인구 통계" / Result: 통계청 자료 5,145만 명

검증 결과: 틀림 (오차 55만 명)

개선 -- 모델: "정확한 통계청 자료에 따르면 약 5,145만 명이다."

수학 검증 예시

질문: "15의 제곱근의 소수점 둘째 자리까지 값은?"

1차 시도 -- 모델: "약 3.87이다."

CRITIC 검증 -- Action: [Calculate] sqrt(15) / Result: 3.872983...

검증 결과: 맞음 (반올림하면 3.87)

최종 답변: "15의 제곱근은 약 3.87이다. ✓"

Self-Refine과의 차이

Self-RefineCRITIC
피드백 소스모델 자체외부 도구
판단 기준주관적객관적
팩트 확인어려움가능
적용 분야창작, 품질팩트, 계산

사용 가능한 검증 도구

도구용도예시
검색 엔진팩트 체크"한국 인구 통계"
코드 실행기코드 검증함수 테스트 실행
계산기수학 검증sqrt(144) = 12
Wikipedia API정보 확인역사적 사실
데이터베이스데이터 검증SQL 쿼리 결과 확인

코드 검증 예시

python
# [질문] "팩토리얼 함수를 작성해주세요"
 
# [1차 시도]
def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n)  # 버그: n-1이 아닌 n
 
# [CRITIC 검증]
# Action: [Execute] factorial(5)
# Result: RecursionError (무한 재귀)
 
# [검증 결과] 실패
 
# [개선]
def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n - 1)  # 수정됨
 
# [재검증]
# Action: [Execute] factorial(5)
# Result: 120 ✓

성능

  • QA 작업에서 약 7-8% 정확도 향상
  • 특히 팩트 기반 질문에서 효과적
  • 수학/코드 문제에서 높은 개선율

동작 알고리즘

python
def critic_loop(question, max_iterations=3):
    # 초기 답변 생성
    answer = llm.generate(question)
 
    for i in range(max_iterations):
        # 검증 방법 결정
        verification = llm.generate(
            f"다음 답변을 검증하기 위해 어떤 도구를 사용해야 할까요?\n"
            f"질문: {question}\n"
            f"답변: {answer}"
        )
 
        # 도구 실행
        if "[Search]" in verification:
            result = search(verification.query)
        elif "[Calculate]" in verification:
            result = calculate(verification.expression)
        elif "[Execute]" in verification:
            result = execute_code(verification.code)
        else:
            break
 
        # 검증 결과 분석
        is_correct = llm.generate(
            f"검증 결과가 답변과 일치합니까?\n"
            f"답변: {answer}\n"
            f"검증 결과: {result}"
        )
 
        if "일치" in is_correct:
            break
 
        # 개선
        answer = llm.generate(
            f"검증 결과를 바탕으로 답변을 수정해주세요.\n"
            f"기존 답변: {answer}\n"
            f"검증 결과: {result}"
        )
 
    return answer

언제 CRITIC을 사용해야 하는가?

상황CRITIC 필요성
팩트 기반 질문높음
수학/계산 문제높음
코드 작성높음
창작 글쓰기낮음 (Self-Refine 권장)
주관적 의견낮음

한계

  1. 도구 의존성: 적절한 검증 도구가 없으면 사용 불가
  2. 검증 비용: 외부 API 호출 비용
  3. 검증 범위: 모든 주장을 검증하기 어려움

조합 사용

Self-Refine + CRITIC

  1. Self-Refine 단계에서 품질과 가독성을 개선한다
  2. CRITIC 단계에서 외부 도구로 팩트를 검증한다
  3. 최종 결과를 도출한다

Reflexion + CRITIC

  1. 시도 후 실패한다 (테스트 실패)
  2. CRITIC으로 어디서 실패했는지 분석한다
  3. Reflexion으로 왜 실패했는지 반성한다
  4. 재시도한다

관련 개념

  • Reflexion: 실패 기반 학습
  • Self-Refine: 자기 피드백 기반 개선
  • ReAct: 도구 사용 프레임워크