
LLM을 한 번만 호출하지 마라 — 후보 생성과 자동 채점으로 품질 올리기
같은 모델을 쓰면서 답변 품질을 올리는 방법은 프롬프트 튜닝만이 아니다. 여러 후보를 만들고 채점해 고르는 파이프라인 구조를 정리했다.
LLM 앱을 만들 때 대부분 이 구조로 시작한다. 질문을 받고, 프롬프트를 만들고, 모델을 한 번 호출하고, 결과를 보여준다.
이 구조에서 품질을 올리려면 방법이 둘뿐이다. 더 좋은 모델을 쓰거나, 프롬프트를 고치거나. 둘 다 한계가 온다. 모델은 예산 문제고, 프롬프트 튜닝은 어느 순간부터 고쳐도 나아지지 않는다.
문제는 “한 번”에 있었다
한 번 호출해서 나온 답은 그날의 운이다. 같은 질문을 세 번 던지면 세 답이 다르고, 그중 확실히 나은 게 있다. 그런데 사용자는 첫 번째 답만 본다.
사람이 글을 쓸 때를 생각하면 이상한 구조다. 초안을 쓰고, 읽어보고, 고친다. 여러 방향을 시도해보고 나은 걸 고른다. 그런데 LLM 앱은 초안을 그대로 내보낸다.
그래서 구조를 이렇게 바꿨다.
질문
↓
① 여러 답변 후보를 만든다
↓
② 후보들을 비교하고 채점한다
↓
③ 더 고친다
↓
④ 최종적으로 나은 답을 고른다
↓
답변
모델은 같다. 호출 횟수가 늘어날 뿐이다. 그런데 결과가 눈에 띄게 안정된다.
왜 여러 후보가 효과가 있나
핵심은 평가가 생성보다 쉽다는 점이다.
“좋은 답을 써라”는 어렵다. 반면 “이 두 답 중 어느 쪽이 질문에 더 정확히 답했나”는 훨씬 쉽다. 같은 모델이라도 후자를 더 잘한다.
그래서 생성은 여러 번 하고, 그중에서 고르는 일을 모델에게 시킨다. 한 번에 최고를 뽑아내려 애쓰는 것보다, 여러 개 만들고 골라내는 쪽이 잘 작동한다.
안정화가 진짜 이득이다
평균 품질이 오르는 것보다 편차가 줄어드는 게 실제로는 더 중요했다.
한 번 호출 방식에서는 가끔 아주 좋은 답이 나오고 가끔 엉망인 답이 나온다. 사용자 입장에서는 엉망인 답을 만나는 순간 신뢰를 잃는다. 열 번 중 아홉 번 좋아도, 한 번의 나쁜 경험이 “이거 못 믿겠다”를 만든다.
후보를 여러 개 만들어 거르면 최악의 답이 걸러진다. 최고점이 크게 오르지 않아도 최저점이 올라가는 것이 체감 품질을 결정한다.
비용을 어떻게 감당하나
호출이 3~5배로 늘어난다. 이걸 감당하는 방법이 몇 가지 있다.
로컬 LLM을 붙인다. OpenAI 호환 서버를 붙일 수 있게 만들어두면 로컬 모델로 후보 생성을 돌릴 수 있다. 후보 생성처럼 여러 번 돌리는 단계는 로컬로, 최종 판단은 좋은 모델로 나누는 방식이 가능하다.
단계를 선택적으로 만든다. 모든 질문에 5단계 파이프라인이 필요하지는 않다. 간단한 질문은 한 번 호출로 끝내고, 품질이 중요한 요청만 전체 파이프라인을 태운다.
채점을 싸게 한다. 후보 전체를 다시 생성하는 대신, 짧은 채점 프롬프트로 순위만 매기면 비용이 훨씬 적게 든다.
이 구조가 열어준 것
파이프라인으로 만들어두니 다른 기능을 끼워 넣기 쉬워졌다. 웹 검색, 문서 기반 답변(RAG), 사용자 메모리 반영, 툴 호출 같은 것들이 전부 “파이프라인의 한 단계”가 된다.
단일 호출 구조에서는 이런 걸 넣으려면 프롬프트에 다 욱여넣어야 한다. 프롬프트가 길어지고, 서로 간섭하고, 뭐가 문제인지 알 수 없게 된다.
단계로 나눠두면 각 단계를 따로 켜고 끄고 고칠 수 있다. 어느 단계에서 품질이 떨어지는지도 보인다.
정리
- 한 번 호출한 결과는 초안이다. 초안을 그대로 내보내지 않는다
- 평가는 생성보다 쉽다. 여러 개 만들고 고르게 하는 편이 잘 작동한다
- 평균보다 편차가 중요하다. 최저점이 체감 품질을 결정한다
- 비용은 단계 분리로 조절한다. 여러 번 돌리는 단계는 싼 모델로
- 파이프라인 구조는 기능 추가를 쉽게 만든다. 프롬프트에 다 넣으면 손댈 수 없어진다