Few-shot만으로 갈 때 vs SFT가 필요할 때

TL;DR

  • Few-shot / 프롬프트는 “형식·스키마·톤”을 맞추는 데 빠르고 싸게 먹힌다.
  • SFT(Supervised Fine-Tuning)는 “후보 중 Top-1 고르기”, “슬롯·필드 정확도”처럼 같은 입력이 반복적으로 같은 정답을 요구할 때 필요하다.
  • RAG가 있으면 역할이 더 분명해진다. 검색=후보, LLM=선택·구조화. 후보 부족은 인덱스 문제고, 선택 실패는 프롬프트/SFT 문제다.
  • “일단 few-shot으로 재현 → 실패 패턴이 고착되면 시드 SFT”가 제일 덜 후회되는 순서다.

들어가며

도메인 API에 LLM을 붙이다 보면 질문이 거의 항상 여기로 모인다.
프롬프트에 예시만 더 넣으면 되나, 아니면 학습을 해야 하나?

둘 다 “모델을 도메인에 맞게 만드는” 수단인데, 비용·데이터·운영 부담이 완전히 다르다.
이 글은 특정 제품 이야기보다, 언제 few-shot으로 버티고 언제 SFT로 넘어갈지 판단 기준만 정리한다.
(앞선 Colab + ngrok으로 RAG/Few-shot API 테스트 글이 “파이프를 어떻게 붙이나”였다면, 이번은 “학습 판단”이다.)


1. Few-shot이 잘하는 것

Few-shot은 프롬프트 안에 입·출력 예시 몇 개를 넣고, 모델이 그 패턴을 따라가게 하는 방식이다.

잘 먹히는 구간은 대체로 이렇다.

  • 출력 포맷 고정 — “JSON만”, “키 이름 고정”, “설명 금지”
  • 톤·역할 — 도메인 전문가처럼 말하되, 스키마는 짧게
  • 소량 규칙 — “없으면 null”, “citations는 id 배열만”
  • 빠른 실험 — 코드/배포 없이 프롬프트만 바꿔 재현
[INSTRUCTION]
JSON only. Schema: { "answer": string, "citations": string[] }

[FEW_SHOT]
질문: ...
답변: { "answer": "...", "citations": ["123"] }

[CONTEXT]
...

[QUESTION]
...

장점은 명확하다. 데이터셋·GPU·어댑터 배포가 필요 없다.
단점도 명확하다. 컨텍스트가 길어지고, 예시가 늘수록 비용·지연·지시 무시가 같이 커진다.
특히 “비슷해 보이는 후보 5개 중 정답 1개”처럼 선택 문제가 반복되면, few-shot만으로는 점수가 잘 안 오른다.


2. SFT가 필요한 순간

SFT는 (입력 → 정답) 쌍으로 모델을 추가로 학습시키는 것이다.
LoRA / Q-LoRA처럼 base는 두고 adapter만 뽑는 방식이 실무에서 흔하다.

SFT가 이득인 신호는 대략 이런 것들이다.

신호 해석
같은 유형 입력이 반복되고, 정답이 채점 가능 학습 데이터로 쌓을 가치가 있다
few-shot을 늘려도 Top-1 / 필드 정확도가 정체 형식 문제가 아니라 선택·매핑 문제
프롬프트가 너무 길어 운영이 아픈데, 규칙은 고정 규칙을 가중치 쪽으로 옮길 후보
출시 목표가 “데모 가능”이 아니라 높은 정확도 RAG+few-shot만으로 SLA를 못 채울 때

반대로 SFT가 과한 경우도 있다.

  • 입력이 매번 완전히 새 형식이다 (규칙이 안 굳음)
  • 정답 라벨을 만들 수 없다 (검수자·정본이 없음)
  • 문제는 사실 검색/인덱스 품질인데 모델만 탓하는 경우

한 줄로 끊으면:
형식은 few-shot, 반복되는 정답 선택은 SFT.


3. RAG가 있을 때 — 역할을 가르자

도메인 API에 검색(RAG)이 들어가면, 실패를 “모델이 멍청해서”로만 보면 디버깅이 꼬인다.

실무에서 자주 쓰는 분리:

  1. 검색(RAG) — 후보를 모은다 (키워드 + 벡터 등)
  2. LLM — 후보를 보고 고르거나, 슬롯/JSON으로 구조화한다
  3. Few-shot — “어떻게 말할지 / 어떤 JSON으로 낼지”를 고정한다
  4. SFT — “고르는 감각”과 “슬롯 채우기”를 데이터로 굳힌다

그래서 점검 순서도 이렇게 가는 게 싸다.

  1. 후보 목록에 정답이 들어왔는가? → 없으면 인덱스/동의어/Top-K
  2. 후보는 있는데 Top-1이 틀린가? → 프롬프트/rerank → 그래도 안 되면 SFT
  3. JSON이 깨지는가? → 스키마 강제 few-shot / 파서 / (필요 시) SFT로 형식 고정

“RAG만으로 되지 않냐”는 질문도 여기서 갈린다.
후보 생성은 RAG로 해결하는 경우가 많다.
뭘 집을지가 병목이면 LLM(그리고 나중엔 SFT) 구간이다.


4. 실무 의사결정 체크리스트

바로 쓸 수 있게 짧게만 적는다.

Few-shot으로 먼저 가도 되는 경우

  • 스키마·톤만 맞으면 제품이 굴러간다
  • 실패가 “가끔 형식 깨짐” 수준이다
  • 라벨 데이터셋이 아직 없다

SFT를 준비해야 하는 경우

  • 채점 가능한 입·출력 쌍이 쌓이기 시작한다
  • 같은 실패가 로그에 패턴으로 남는다
  • few-shot을 늘려도 지표가 안 오른다
  • 프롬프트 길이가 운영 한도를 넘기기 시작한다

아직 SFT 말고 손댈 곳

  • 검색 후보에 정답이 안 들어옴
  • 평가셋이 없어서 “좋아짐”을 증명 못 함
  • base 모델/타임아웃/파서 버그로 실패가 오염됨

증강 전에 작은 시드(수백 건)로 SFT → adapter 스모크만 돌려보는 절차도 유효하다.
효과가 보이면 데이터를 늘리고, 안 보이면 라벨/평가부터 고치는 편이 싸다.


5. 흔한 착각

  • “데이터만 같으면 LoRA든 Q-LoRA든 같은 가중치” — 아니다. 학습 경로(양자화 여부)가 다르면 adapter도 다르다. (이건 다음 글감으로 따로 쓸 예정이다)
  • “SFT하면 RAG가 필요 없다” — 보통 반대다. SFT는 선택·형식을 단단히 하고, RAG는 최신/대량 지식을 공급한다.
  • “few-shot 예시만 왕창 넣으면 SFT 대체” — 짧은 실험엔 되지만, 비용·컨텍스트·일관성에서 금방 한계가 온다.
  • “실패하면 전부 학습” — 검색 실패를 학습으로 덮으려 하면 데이터가 썩는다.

마무리

Few-shot과 SFT는 경쟁 관계가 아니라 단계에 가깝다.

  1. 스키마·톤은 few-shot으로 고정하고 재현한다
  2. RAG로 후보를 충분히 올린다
  3. 선택/슬롯 정확도가 막히면, 채점 가능한 쌍으로 시드 SFT를 돌린다
  4. 효과가 확인된 뒤에만 데이터를 키운다

“학습이 필요하냐”보다 나은 질문은 이거다.
지금 막힌 게 후보인가, 형식인가, 선택인가?
그 답이 나오면 few-shot / RAG / SFT 중 어디에 손을 댈지가 거의 정해진다.

Comments