LLM 응답이 검증에 실패할 경우, 오류 내용을 재시도 프롬프트에 다시 입력하세요
요약
LLM의 구조화된 출력 검증 실패 시, 단순 재시도 대신 오류 내용과 잘못된 출력물을 프롬프트에 포함하여 수정을 요청하는 효율적인 기법을 소개합니다. 이를 통해 불필요한 비용을 줄이고 응답 성공률을 높일 수 있습니다.
핵심 포인트
- 단순 재시도는 동일한 오류를 반복할 확률이 높음
- 검증 오류 메시지를 모델이 이해할 수 있도록 가공하여 전달
- 잘못된 출력물과 오류 내용을 다음 프롬프트에 포함하여 피드백 루프 구축
- 비용 최적화를 위해 시도 횟수 제한 및 파싱 가능한 경우에만 적용 권장
LLM(Large Language Model)에게 구조화된 출력 (structured output)을 요청하고 이를 스키마 (schema)에 따라 검증한다면, 여러분은 이미 실패 모드 (failure mode)를 알고 있을 것입니다. 대부분의 경우 정상적으로 작동하지만, 가끔은 파싱 (parse)이 불가능하거나 필수 필드 (required field)가 누락된 결과물을 내놓습니다. 일반적인 반응은 해당 호출을 재시도 (retry) 로직으로 감싸고 그냥 넘어가는 것입니다.
문제는 단순한 재시도는 동일한 프롬프트 (prompt), 동일한 온도 (temperature), 그리고 대략적으로 동일한 확률을 의미한다는 점입니다. 여러분은 단순히 주사위가 다르게 던져지기를 바라며 추가 비용을 지불하고 있는 셈입니다.
더 나은 방법이 있으며, 이를 추가하는 데 드는 비용은 거의 공짜에 가깝습니다. 검증에 실패했을 때, 검증 오류 (validation error)와 모델이 생성한 잘못된 출력물을 다음 프롬프트에 다시 넣고, 그 특정 부분을 수정하도록 요청하는 것입니다.
제가 구축한 RAG (Retrieval-Augmented Generation) 플랫폼에서 이 루프를 위해 사용했던 핵심 로직은 다음과 같습니다 (필수 경로만 축약):
while attempts < max_attempts:
try:
msgs = [messages] if isinstance(messages, str) else messages
...
두 가지 세부 사항이 핵심적인 역할을 합니다:
- 오류를 로그용이 아닌 모델을 위해 설명합니다.
format_error_for_llm은 가공되지 않은 검증 예외 (validation exception)를 명확한 지시 사항(
- 잘못된 응답에 대해 추가적인 호출 비용이 발생하며, 후속 프롬프트(follow-up prompt)가 더 길어집니다 (오류 내용과 이전 페이로드(payload)를 모두 포함하기 때문). 빈번하게 실패하는 스키마(schema)의 경우, 이 비용이 누적됩니다. 시도 횟수를 제한하십시오.
- 잘못된 응답이 프롬프트로 다시 직렬화(serialize)될 수 있을 만큼 충분히 파싱(parse) 가능한 경우에만 작동합니다. 완전히 비어 있거나 잘린 출력(truncated output)은 수정할 내용이 없으므로, 내부적으로는 여전히 일반적인 재시도(retry)가 필요합니다.
- 루프 중간에 제공자(provider)를 전환(failover)하는 경우 프롬프트 의미론(semantics)이 항상 전달되는 것은 아닙니다. 만약 그렇게 한다면, 제공자 전환을 실제 시도 횟수로 계산하지 마십시오.
이것이 전체적인 아이디어입니다. 이것은 프레임워크가 아니라, 이미 구현된 호출 주변에 약 10줄 정도의 코드를 추가하는 것입니다. 만약 상당한 규모로 구조화된 출력(structured output)을 생성하고 있다면, "모델이 불안정했다(model was flaky)"며 수행하던 재시도 작업 중 상당 부분을 피드백을 통한 첫 번째 시도 성공으로 전환할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기