본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 25. · 2 Views
Few-Shot Learning 완벽 가이드
LLM에게 몇 가지 예제만으로 새로운 작업을 학습시키는 Few-Shot Learning 전략을 배웁니다. 예제 선택부터 최적화까지, 실무에서 바로 활용 가능한 동적 Few-Shot 시스템 구축 방법을 다룹니다.
목차
1. Few-Shot의 원리와 효과
어느 날 김개발 씨가 LLM을 활용한 고객 문의 분류 시스템을 만들고 있었습니다. 프롬프트만으로는 정확도가 60%밖에 나오지 않았습니다.
선배 박시니어 씨가 코드를 보더니 "예제를 몇 개만 넣어봐요"라고 조언했습니다.
Few-Shot Learning은 LLM에게 몇 가지 예제를 보여주는 것만으로 새로운 작업을 학습시키는 기법입니다. 마치 신입사원에게 업무 매뉴얼 대신 실제 처리 사례 몇 개를 보여주는 것과 같습니다.
모델을 재학습시키지 않고도 원하는 출력 형식과 품질을 얻을 수 있습니다. 이것을 제대로 활용하면 프롬프트 엔지니어링의 효과를 극대화할 수 있습니다.
다음 코드를 살펴봅시다.
# Zero-Shot vs Few-Shot 비교
import anthropic
client = anthropic.Anthropic()
# Zero-Shot: 예제 없이 지시만
zero_shot = "다음 고객 문의를 긍정/부정/중립으로 분류하세요: 배송이 너무 느려요"
# Few-Shot: 예제를 함께 제공
few_shot = """다음은 고객 문의 분류 예시입니다:
문의: "제품 정말 만족스럽습니다!" → 긍정
문의: "환불하고 싶어요" → 부정
문의: "배송 일정이 언제인가요?" → 중립
문의: "배송이 너무 느려요" → """
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=100,
messages=[{"role": "user", "content": few_shot}]
)
# Few-Shot이 훨씬 정확한 분류 결과를 반환합니다
김개발 씨는 입사 6개월 차 개발자입니다. 회사에서 고객 문의를 자동으로 분류하는 시스템을 만들라는 임무를 받았습니다.
처음에는 간단한 프롬프트만 작성했지만, 정확도가 60%밖에 나오지 않았습니다. "왜 이렇게 정확도가 낮을까요?" 고민하던 김개발 씨에게 선배 박시니어 씨가 다가왔습니다.
"프롬프트에 예제를 몇 개 넣어봤어요?" 그렇다면 Few-Shot Learning이란 정확히 무엇일까요? 쉽게 비유하자면, Few-Shot Learning은 마치 요리 초보에게 레시피 설명서 대신 완성된 요리 사진 몇 장을 보여주는 것과 같습니다.
"토마토를 적당히 썰어주세요"라는 애매한 지시보다 "이 정도 크기로 자른 사진"을 보여주면 훨씬 명확합니다. LLM도 마찬가지로 예제를 보면 원하는 출력 형식과 품질을 정확히 이해합니다.
Few-Shot이 없던 시절, 아니 정확히는 Few-Shot을 모르던 시절에는 어땠을까요? 개발자들은 프롬프트를 수십 번 수정하며 원하는 결과를 얻으려 했습니다.
"좀 더 정확하게", "형식을 맞춰서", "일관성 있게" 같은 모호한 지시를 계속 추가했습니다. 하지만 LLM은 여전히 개발자의 의도를 정확히 파악하지 못했습니다.
더 큰 문제는 프롬프트가 길어질수록 토큰 비용만 증가했다는 점입니다. 바로 이런 문제를 해결하기 위해 Few-Shot Learning이 등장했습니다.
Few-Shot을 사용하면 컨텍스트 내 학습이 가능해집니다. LLM이 예제를 보고 패턴을 파악해서 새로운 입력에 동일한 패턴을 적용합니다.
또한 출력 형식의 일관성도 얻을 수 있습니다. 무엇보다 모델을 재학습시킬 필요가 없다는 큰 이점이 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. 먼저 Zero-Shot 방식은 단순히 지시만 내립니다.
"분류하세요"라고만 말하면 LLM은 자신의 기본 지식으로 처리합니다. 반면 Few-Shot 방식은 3개의 예제를 먼저 보여줍니다.
각 예제는 입력과 출력의 쌍으로 구성됩니다. LLM은 이 패턴을 학습해서 새로운 문의에 동일한 형식으로 답변합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 이커머스 회사에서 상품 리뷰를 분석한다고 가정해봅시다.
"좋아요 하트", "별점 5개", "최고예요 점점점" 같은 다양한 표현을 긍정으로 분류해야 합니다. Few-Shot을 활용하면 이런 다양한 표현 패턴을 몇 가지 예제로 학습시킬 수 있습니다.
실제로 쿠팡, 네이버쇼핑 같은 대형 플랫폼에서 이런 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 너무 많은 예제를 넣는 것입니다. 예제가 많다고 무조건 좋은 것이 아닙니다.
컨텍스트 윈도우를 낭비하고 비용만 증가시킬 수 있습니다. 따라서 대표성 있는 3-5개의 예제로 시작하는 것이 좋습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언을 듣고 예제 3개를 추가했더니 정확도가 85%로 뛰어올랐습니다.
"와, 정말 신기해요!" Few-Shot Learning을 제대로 이해하면 프롬프트 효율을 극대화하고 비용도 절감할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.
실전 팁
💡 - 처음에는 3-5개의 예제로 시작하고 성능을 측정하며 조정하세요
- 예제는 실제 사용 사례와 최대한 유사하게 만드세요
- Zero-Shot과 Few-Shot의 성능을 A/B 테스트로 비교해보세요
2. 예제 선택 전략
김개발 씨가 Few-Shot을 적용해서 성과를 냈지만, 새로운 문제가 생겼습니다. 어떤 예제를 선택하느냐에 따라 정확도가 70%에서 90%까지 차이가 났습니다.
"예제를 어떻게 골라야 할까요?"
예제 선택 전략은 Few-Shot Learning의 성패를 좌우하는 핵심 요소입니다. 마치 교과서를 만들 때 가장 대표적이고 다양한 문제를 고르는 것처럼, LLM에게도 최적의 예제를 제공해야 합니다.
대표성과 다양성, 두 가지 원칙을 균형 있게 적용해야 합니다. 제대로 선택된 예제는 적은 수로도 높은 성능을 발휘합니다.
다음 코드를 살펴봅시다.
# 예제 선택 전략 구현
from sklearn.cluster import KMeans
import numpy as np
class ExampleSelector:
def __init__(self, examples, embeddings):
self.examples = examples # 전체 예제 리스트
self.embeddings = embeddings # 각 예제의 임베딩
def select_diverse_examples(self, n_examples=5):
"""클러스터링으로 다양한 예제 선택"""
# K-Means로 예제를 클러스터링
kmeans = KMeans(n_clusters=n_examples, random_state=42)
kmeans.fit(self.embeddings)
# 각 클러스터 중심에 가장 가까운 예제 선택
selected_examples = []
for i in range(n_examples):
cluster_center = kmeans.cluster_centers_[i]
# 클러스터 중심과 가장 가까운 예제 찾기
distances = np.linalg.norm(self.embeddings - cluster_center, axis=1)
closest_idx = np.argmin(distances)
selected_examples.append(self.examples[closest_idx])
return selected_examples
def select_similar_examples(self, query_embedding, n_examples=3):
"""쿼리와 유사한 예제 선택 (동적 Few-Shot)"""
similarities = np.dot(self.embeddings, query_embedding)
top_indices = np.argsort(similarities)[-n_examples:]
return [self.examples[i] for i in reversed(top_indices)]
김개발 씨는 신나서 예제를 20개나 만들었습니다. 그런데 막상 Few-Shot에 사용하려니 어떤 예제를 골라야 할지 막막했습니다.
전부 다 넣기에는 토큰이 너무 많이 들고, 무작위로 고르자니 성능이 들쭉날쭉했습니다. 박시니어 씨가 다시 등장했습니다.
"예제 선택에도 전략이 필요해요. 아무거나 고르면 안 됩니다." 그렇다면 어떤 예제를 선택해야 할까요?
쉽게 비유하자면, 예제 선택은 마치 박물관 도슨트가 관람객에게 보여줄 작품을 고르는 것과 같습니다. 전시실에 수백 점의 그림이 있지만, 시간 제약상 5-6점만 설명할 수 있습니다.
이때 도슨트는 각 시대를 대표하는 작품들을 골라서 전체 흐름을 이해시킵니다. Few-Shot도 마찬가지로 전체 데이터를 대표하는 예제를 선택해야 합니다.
전략 없이 예제를 선택하면 어떤 문제가 생길까요? 개발자들은 보통 가장 먼저 떠오르는 예제나 가장 최근 사례를 선택합니다.
하지만 이렇게 하면 편향된 예제 세트가 만들어집니다. 예를 들어 고객 문의 분류에서 긍정 리뷰 예제만 3개를 넣으면, LLM은 모든 문의를 긍정으로 분류하는 경향을 보입니다.
더 큰 문제는 엣지 케이스를 전혀 다루지 못한다는 점입니다. 바로 이런 문제를 해결하기 위해 체계적인 예제 선택 전략이 필요합니다.
첫 번째 전략은 다양성 기반 선택입니다. 전체 예제를 클러스터링해서 각 클러스터에서 대표 예제를 하나씩 뽑습니다.
이렇게 하면 다양한 패턴을 고루 포함할 수 있습니다. 두 번째 전략은 유사도 기반 선택입니다.
현재 처리할 쿼리와 비슷한 예제를 동적으로 선택합니다. 이것을 동적 Few-Shot이라고 부릅니다.
위의 코드를 한 줄씩 살펴보겠습니다. select_diverse_examples 메서드는 K-Means 클러스터링을 활용합니다.
전체 예제를 n개의 클러스터로 나누고, 각 클러스터 중심에 가장 가까운 예제를 선택합니다. 이렇게 하면 서로 다른 패턴을 대표하는 예제들을 얻을 수 있습니다.
반면 select_similar_examples 메서드는 쿼리 임베딩과 코사인 유사도를 계산해서 가장 유사한 예제를 찾습니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 법률 문서 분류 시스템을 만든다고 가정해봅시다. 이혼, 상속, 계약, 형사 등 다양한 카테고리가 있습니다.
정적 Few-Shot으로 각 카테고리에서 하나씩 예제를 고르면 기본적인 분류는 가능합니다. 하지만 동적 Few-Shot으로 현재 문서와 유사한 과거 판례를 예제로 제공하면 훨씬 정확한 분류가 가능합니다.
실제로 법률 AI 스타트업들이 이런 방식을 적극 활용하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 너무 복잡한 선택 알고리즘을 사용하는 것입니다. 예제 선택에 걸리는 시간이 LLM 응답 시간보다 길어지면 본말이 전도됩니다.
따라서 간단한 휴리스틱으로 시작해서 필요할 때만 고도화하세요. 다시 김개발 씨의 이야기로 돌아가 봅시다.
박시니어 씨의 조언대로 클러스터링으로 5개 예제를 선택했더니 정확도가 88%까지 올랐습니다. "예제 선택이 이렇게 중요했군요!" 예제 선택 전략을 제대로 적용하면 적은 예제로도 높은 성능을 얻을 수 있습니다.
여러분도 오늘 배운 두 가지 전략을 프로젝트에 적용해 보세요.
실전 팁
💡 - 처음에는 수동으로 다양한 예제를 골라보고, 패턴이 보이면 자동화하세요
- 클러스터링 전에 임베딩 품질을 확인하세요 (OpenAI나 Cohere의 임베딩 모델 추천)
- 동적 Few-Shot은 캐싱을 활용해서 성능을 최적화하세요
3. 예제 개수의 최적화
김개발 씨가 또 다른 고민에 빠졌습니다. 예제를 3개 넣으면 85%, 5개 넣으면 88%, 10개 넣으면 87%가 나왔습니다.
"예제가 많을수록 좋은 게 아니었네요?"
예제 개수 최적화는 성능과 비용의 균형점을 찾는 과정입니다. 마치 요리할 때 소금을 적당량 넣어야 맛있듯이, Few-Shot도 최적의 예제 개수가 존재합니다.
너무 적으면 패턴 학습이 부족하고, 너무 많으면 컨텍스트가 혼란스러워집니다. 실험을 통해 작업별 최적값을 찾아야 합니다.
다음 코드를 살펴봅시다.
# 예제 개수별 성능 측정 시스템
import anthropic
from typing import List, Tuple
class FewShotOptimizer:
def __init__(self, client: anthropic.Anthropic):
self.client = client
def evaluate_n_examples(self,
task_description: str,
all_examples: List[Tuple[str, str]],
test_cases: List[Tuple[str, str]],
n_range: range) -> dict:
"""예제 개수별 성능 평가"""
results = {}
for n in n_range:
# n개의 예제로 Few-Shot 프롬프트 구성
selected_examples = all_examples[:n]
correct = 0
total_tokens = 0
for test_input, expected_output in test_cases:
# Few-Shot 프롬프트 생성
prompt = self._build_prompt(task_description,
selected_examples,
test_input)
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=100,
messages=[{"role": "user", "content": prompt}]
)
# 정확도 계산
if response.content[0].text.strip() == expected_output:
correct += 1
total_tokens += response.usage.input_tokens
accuracy = correct / len(test_cases)
avg_tokens = total_tokens / len(test_cases)
# 비용 효율 계산 (정확도 / 토큰 비용)
cost_efficiency = accuracy / (avg_tokens / 1000)
results[n] = {
'accuracy': accuracy,
'avg_tokens': avg_tokens,
'cost_efficiency': cost_efficiency
}
return results
def _build_prompt(self, task_desc, examples, test_input):
"""Few-Shot 프롬프트 구성"""
prompt = f"{task_desc}\n\n"
for inp, out in examples:
prompt += f"입력: {inp}\n출력: {out}\n\n"
prompt += f"입력: {test_input}\n출력:"
return prompt
김개발 씨는 처음에 "예제가 많을수록 좋겠지"라고 생각했습니다. 그래서 예제를 10개, 15개, 20개로 늘려봤습니다.
그런데 신기하게도 정확도는 88%에서 더 올라가지 않고, 오히려 87%, 86%로 떨어지기 시작했습니다. "이상한데요?
더 많은 정보를 주는데 왜 성능이 떨어질까요?" 박시니어 씨가 웃으며 대답했습니다. "컨텍스트 오버로드예요.
LLM도 정보가 너무 많으면 혼란스러워해요." 그렇다면 최적의 예제 개수는 어떻게 찾을까요? 쉽게 비유하자면, 예제 개수 최적화는 마치 커피에 설탕을 넣는 것과 같습니다.
설탕 한 스푼은 커피를 맛있게 만들지만, 다섯 스푼을 넣으면 너무 달아서 마시기 힘듭니다. 각자의 입맛에 맞는 최적값이 있듯이, 각 작업마다 최적의 예제 개수가 다릅니다.
분류 작업은 3-5개면 충분하지만, 복잡한 변환 작업은 7-10개가 필요할 수 있습니다. 예제 개수를 무작정 늘리면 어떤 문제가 생길까요?
첫째, 컨텍스트 희석 문제가 발생합니다. 예제가 너무 많으면 LLM이 핵심 패턴에 집중하지 못하고 노이즈에 방해받습니다.
둘째, 토큰 비용이 급격히 증가합니다. 예제 10개면 수백 토큰이지만, 100개면 수천 토큰이 됩니다.
매 요청마다 이 비용이 반복됩니다. 셋째, 응답 지연이 길어집니다.
컨텍스트가 길수록 처리 시간도 늘어납니다. 바로 이런 문제를 해결하기 위해 체계적인 최적화가 필요합니다.
최적화 방법은 간단합니다. 1, 3, 5, 7, 10개처럼 점진적으로 예제 개수를 늘려가며 성능을 측정합니다.
각 설정에서 정확도와 토큰 사용량을 기록합니다. 그리고 비용 효율(정확도 ÷ 토큰 비용)을 계산해서 최적값을 찾습니다.
예를 들어 5개에서 90% 정확도에 200토큰을 쓰고, 10개에서 91% 정확도에 400토큰을 쓴다면, 5개가 더 효율적입니다. 위의 코드를 한 줄씩 살펴보겠습니다.
evaluate_n_examples 메서드는 1부터 10까지 예제 개수를 바꿔가며 테스트합니다. 각 설정에서 테스트 케이스를 돌려보고 정확도를 계산합니다.
동시에 사용된 토큰 수도 기록합니다. 마지막으로 cost_efficiency를 계산해서 어느 지점이 가장 효율적인지 판단합니다.
이 값이 가장 높은 지점이 최적의 예제 개수입니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 의료 진단서 요약 시스템을 만든다고 가정해봅시다. 초기에는 예제 10개로 시작했는데 정확도가 92%였습니다.
최적화를 돌려보니 예제 6개로 91% 정확도를 달성할 수 있었습니다. 1% 정확도를 포기하고 토큰 비용을 40% 절감한 것입니다.
월 100만 건을 처리하는 시스템이라면 이것이 수백만 원의 비용 절감으로 이어집니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 한 번 최적화하고 끝내는 것입니다. 데이터 분포가 바뀌면 최적값도 바뀔 수 있습니다.
따라서 주기적으로 재평가하는 파이프라인을 구축해야 합니다. 또한 정확도만 보지 말고 비즈니스 요구사항도 고려하세요.
의료나 금융처럼 정확도가 절대적인 분야라면 비용보다 성능을 우선해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
체계적인 실험을 통해 예제 5개가 최적이라는 것을 발견했습니다. "이제 데이터 기반으로 의사결정할 수 있어요!" 예제 개수 최적화를 제대로 적용하면 성능과 비용의 균형점을 찾을 수 있습니다.
여러분도 오늘 배운 평가 시스템을 구축해 보세요.
실전 팁
💡 - 처음에는 3-5개로 시작하고, 성능이 부족할 때만 늘리세요
- A/B 테스트를 자동화해서 주기적으로 최적값을 재평가하세요
- 작업 유형별로 최적값을 문서화해두면 다음 프로젝트에 재활용할 수 있습니다
4. 예제 순서의 영향
김개발 씨가 또 다른 이상한 현상을 발견했습니다. 똑같은 5개 예제인데 순서만 바꿨더니 정확도가 88%에서 92%로 올랐습니다.
"순서가 이렇게 중요한가요?"
예제 순서는 Few-Shot Learning의 숨겨진 변수입니다. 마치 이야기를 전개하는 순서가 중요하듯이, LLM도 예제를 읽는 순서에 영향을 받습니다.
마지막 예제가 가장 강한 영향을 주는 최신성 편향이 존재합니다. 난이도 순서, 유사도 순서 등 다양한 배치 전략을 실험해야 합니다.
다음 코드를 살펴봅시다.
# 예제 순서 최적화 실험
import random
from itertools import permutations
class ExampleOrderOptimizer:
def __init__(self, examples, embeddings):
self.examples = examples
self.embeddings = embeddings
def order_by_difficulty(self, difficulty_scores):
"""난이도 순서로 정렬 (쉬운 것부터 어려운 것으로)"""
sorted_pairs = sorted(zip(self.examples, difficulty_scores),
key=lambda x: x[1])
return [ex for ex, _ in sorted_pairs]
def order_by_similarity_to_query(self, query_embedding):
"""쿼리와의 유사도 순서로 정렬"""
similarities = np.dot(self.embeddings, query_embedding)
sorted_indices = np.argsort(similarities)
# 가장 유사한 것을 마지막에 배치 (최신성 편향 활용)
return [self.examples[i] for i in sorted_indices]
def test_random_orders(self, evaluate_fn, n_trials=10):
"""무작위 순서로 여러 번 테스트"""
results = []
for _ in range(n_trials):
shuffled = self.examples.copy()
random.shuffle(shuffled)
accuracy = evaluate_fn(shuffled)
results.append({
'order': shuffled,
'accuracy': accuracy
})
# 최고 성능 순서 반환
best = max(results, key=lambda x: x['accuracy'])
return best
def alternating_order(self, categories):
"""카테고리를 번갈아가며 배치"""
# 예: 긍정-부정-중립-긍정-부정 식으로 배치
ordered = []
category_groups = {cat: [] for cat in set(categories)}
for ex, cat in zip(self.examples, categories):
category_groups[cat].append(ex)
max_len = max(len(group) for group in category_groups.values())
for i in range(max_len):
for cat in category_groups:
if i < len(category_groups[cat]):
ordered.append(category_groups[cat][i])
return ordered
김개발 씨는 우연히 예제 순서를 바꾸다가 놀라운 발견을 했습니다. 분명 같은 예제 5개인데, A-B-C-D-E 순서일 때는 88%, E-D-C-B-A 순서일 때는 92%가 나왔습니다.
"뭔가 잘못된 건가?" 하고 여러 번 테스트했지만 결과는 일관되게 나왔습니다. 박시니어 씨가 설명했습니다.
"LLM은 마지막에 본 예제에 더 큰 가중치를 둬요. 이것을 최신성 편향이라고 부르죠." 그렇다면 예제 순서가 왜 중요할까요?
쉽게 비유하자면, 예제 순서는 마치 영화 예고편을 편집하는 것과 같습니다. 같은 장면들이라도 순서에 따라 관객이 받는 인상이 완전히 달라집니다.
재미있는 장면을 처음에 보여주면 기대감이 생기고, 마지막에 보여주면 강렬한 여운이 남습니다. LLM도 마찬가지로 마지막 예제가 가장 기억에 남아서 다음 출력에 큰 영향을 줍니다.
예제 순서를 무작위로 정하면 어떤 문제가 생길까요? 개발자들은 보통 예제를 만든 순서대로, 또는 데이터베이스에서 가져온 순서대로 사용합니다.
하지만 이렇게 하면 비일관적인 성능이 나타납니다. 같은 모델, 같은 예제인데 실행할 때마다 정확도가 달라질 수 있습니다.
더 큰 문제는 최적의 성능을 놓친다는 점입니다. 적절한 순서로 배치하면 5-10% 정확도를 더 얻을 수 있는데 이것을 포기하는 셈입니다.
바로 이런 문제를 해결하기 위해 체계적인 순서 전략이 필요합니다. 첫 번째 전략은 난이도 순서입니다.
쉬운 예제부터 어려운 예제로 점진적으로 배치합니다. 이것은 교육학의 스캐폴딩 원리와 같습니다.
두 번째 전략은 유사도 순서입니다. 현재 쿼리와 가장 유사한 예제를 마지막에 배치해서 최신성 편향을 활용합니다.
세 번째 전략은 카테고리 교차 배치입니다. 긍정-부정-중립을 번갈아가며 보여주면 LLM이 균형 잡힌 패턴을 학습합니다.
위의 코드를 한 줄씩 살펴보겠습니다. order_by_difficulty 메서드는 난이도 점수에 따라 예제를 정렬합니다.
쉬운 것부터 어려운 것으로 배치해서 점진적 학습을 유도합니다. order_by_similarity_to_query는 쿼리 임베딩과의 유사도를 계산하고, 가장 유사한 예제를 마지막에 둡니다.
test_random_orders는 무작위 순서로 여러 번 테스트해서 최적의 배치를 찾습니다. alternating_order는 카테고리를 번갈아가며 배치해서 편향을 방지합니다.
실제 현업에서는 어떤 전략을 쓸까요? 예를 들어 고객 감정 분석 시스템을 만든다고 가정해봅시다.
긍정 예제 2개, 부정 예제 2개, 중립 예제 1개가 있습니다. 초기에는 긍정-긍정-부정-부정-중립 순서로 배치했는데, LLM이 중립을 부정으로 잘못 분류했습니다.
마지막 예제가 중립이라 최신성 편향 때문입니다. 순서를 긍정-부정-긍정-부정-중립로 바꾸니 정확도가 올랐습니다.
글로벌 기업들은 이런 미세 조정으로 수% 정확도를 개선합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 과도하게 최적화하는 것입니다. 모든 순열을 테스트하려다 조합 폭발에 빠집니다.
예제 5개만 해도 120가지 순서가 나옵니다. 따라서 휴리스틱 기반 전략으로 시작하고, 필요할 때만 무작위 샘플링으로 검증하세요.
또한 순서는 작업 의존적입니다. 한 작업에서 효과적인 순서가 다른 작업에서는 안 좋을 수 있습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 유사도 기반 순서를 적용했더니 일관되게 92% 정확도를 유지했습니다.
"이제 왜 순서가 중요한지 알겠어요!" 예제 순서 전략을 제대로 적용하면 같은 예제로 더 높은 성능을 얻을 수 있습니다. 여러분도 오늘 배운 전략들을 실험해 보세요.
실전 팁
💡 - 처음에는 쿼리 유사도 순서로 시작하세요 (구현 쉽고 효과 좋음)
- 카테고리별로 균형 있게 배치하면 편향을 줄일 수 있습니다
- 순서 전략을 A/B 테스트로 검증하세요
5. 실습 Dynamic Few Shot 시스템
김개발 씨가 지금까지 배운 모든 것을 종합해서 실제 시스템을 만들어보기로 했습니다. "쿼리에 따라 자동으로 최적의 예제를 선택하는 시스템을 만들어볼까요?" 박시니어 씨가 격려했습니다.
Dynamic Few-Shot 시스템은 각 쿼리에 맞춤형 예제를 자동으로 선택하는 고급 기법입니다. 마치 개인 맞춤 과외 선생님이 학생 수준에 맞춰 문제를 골라주듯이, 시스템이 쿼리를 분석해서 가장 관련성 높은 예제를 제공합니다.
벡터 데이터베이스와 임베딩 기술을 활용해서 실시간으로 예제를 검색합니다. 정적 Few-Shot보다 훨씬 높은 정확도와 일반화 성능을 보여줍니다.
다음 코드를 살펴봅시다.
# Dynamic Few-Shot 시스템 구현
import anthropic
import numpy as np
from typing import List, Tuple
import chromadb
class DynamicFewShotSystem:
def __init__(self, anthropic_client, embedding_model="voyage-2"):
self.client = anthropic_client
self.embedding_model = embedding_model
# 벡터 DB 초기화
self.chroma_client = chromadb.Client()
self.collection = self.chroma_client.create_collection("few_shot_examples")
def add_examples(self, examples: List[Tuple[str, str]]):
"""예제를 벡터 DB에 저장"""
for idx, (input_text, output_text) in enumerate(examples):
# 입력 텍스트를 임베딩으로 변환 (실제로는 임베딩 API 호출)
embedding = self._get_embedding(input_text)
self.collection.add(
ids=[f"example_{idx}"],
embeddings=[embedding],
documents=[input_text],
metadatas=[{"output": output_text}]
)
def _get_embedding(self, text: str) -> List[float]:
"""텍스트를 임베딩으로 변환 (여기서는 간단히 구현)"""
# 실제로는 OpenAI, Cohere, Voyage AI 등의 임베딩 API 사용
# 여기서는 데모를 위해 간단히 처리
return np.random.rand(1024).tolist() # 실제로는 API 호출
def select_examples(self, query: str, n_examples: int = 5) -> List[Tuple[str, str]]:
"""쿼리와 유사한 예제를 동적으로 선택"""
query_embedding = self._get_embedding(query)
# 벡터 유사도 검색
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=n_examples
)
# 결과를 (입력, 출력) 튜플로 변환
examples = []
for doc, metadata in zip(results['documents'][0], results['metadatas'][0]):
examples.append((doc, metadata['output']))
return examples
def generate_with_dynamic_examples(self, query: str,
task_description: str,
n_examples: int = 5) -> str:
"""동적 Few-Shot으로 응답 생성"""
# 1. 쿼리와 관련된 예제 선택
examples = self.select_examples(query, n_examples)
# 2. Few-Shot 프롬프트 구성
prompt = f"{task_description}\n\n"
for inp, out in examples:
prompt += f"입력: {inp}\n출력: {out}\n\n"
prompt += f"입력: {query}\n출력:"
# 3. LLM 호출
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
messages=[{"role": "user", "content": prompt}]
)
return response.content[0].text
# 사용 예시
client = anthropic.Anthropic()
system = DynamicFewShotSystem(client)
# 예제 데이터 추가
examples = [
("이 제품 정말 좋아요!", "긍정"),
("배송이 너무 느려요", "부정"),
("배송 일정이 궁금합니다", "중립"),
# ... 더 많은 예제
]
system.add_examples(examples)
# 동적으로 예제 선택하여 분류
result = system.generate_with_dynamic_examples(
query="품질이 기대 이상이네요",
task_description="고객 리뷰를 긍정/부정/중립로 분류하세요"
)
김개발 씨는 드디어 완전한 시스템을 만들 준비가 되었습니다. 지금까지 배운 예제 선택, 개수 최적화, 순서 전략을 모두 통합하는 것입니다.
"이번에는 진짜 실무에서 쓸 수 있는 걸 만들어보고 싶어요." 박시니어 씨가 조언했습니다. "좋아요.
그럼 Dynamic Few-Shot 시스템을 만들어봅시다. 한 번 구축해두면 여러 프로젝트에 재사용할 수 있어요." 그렇다면 Dynamic Few-Shot 시스템이란 정확히 무엇일까요?
쉽게 비유하자면, Dynamic Few-Shot은 마치 개인 맞춤 추천 시스템과 같습니다. 넷플릭스가 사용자마다 다른 영화를 추천하듯이, 이 시스템은 각 쿼리에 맞는 예제를 골라줍니다.
"배송이 느려요"라는 쿼리가 들어오면 배송 관련 예제를 찾아서 보여주고, "제품이 좋아요"라는 쿼리가 들어오면 품질 관련 예제를 찾습니다. 이렇게 하면 정적 예제보다 훨씬 정확한 결과를 얻을 수 있습니다.
정적 Few-Shot만 사용하면 어떤 한계가 있을까요? 모든 쿼리에 똑같은 5개 예제를 사용하면 일반화 성능이 떨어집니다.
예를 들어 배송 문의에 제품 품질 예제를 보여주면 LLM이 혼란스러워합니다. 더 큰 문제는 데이터가 계속 쌓이는데 활용하지 못한다는 점입니다.
고객 리뷰가 매일 수천 개씩 쌓이는데, 처음 만든 5개 예제만 계속 쓰는 것은 비효율적입니다. 바로 이런 문제를 해결하기 위해 Dynamic Few-Shot 시스템을 구축합니다.
시스템의 핵심은 벡터 데이터베이스입니다. 모든 예제를 임베딩으로 변환해서 저장합니다.
새로운 쿼리가 들어오면 쿼리도 임베딩으로 변환하고, 코사인 유사도로 가장 가까운 예제를 찾습니다. 이 과정이 밀리초 단위로 일어나므로 실시간 서비스에 사용할 수 있습니다.
ChromaDB, Pinecone, Weaviate 같은 전문 벡터 DB를 활용하면 수백만 개 예제에서도 빠르게 검색할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.
DynamicFewShotSystem 클래스는 전체 시스템을 캡슐화합니다. add_examples 메서드는 예제를 임베딩으로 변환해서 벡터 DB에 저장합니다.
이 작업은 초기 설정 때 한 번만 하면 됩니다. select_examples 메서드가 핵심입니다.
쿼리 임베딩과 가장 유사한 n개의 예제를 검색합니다. generate_with_dynamic_examples는 선택된 예제로 Few-Shot 프롬프트를 구성하고 LLM을 호출합니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 대형 이커머스 고객센터를 운영한다고 가정해봅시다.
하루에 10만 건의 문의가 들어옵니다. 처음에는 수동으로 만든 20개 예제로 시작했지만, 3개월 후에는 실제 처리한 문의 10만 건이 쌓였습니다.
이것을 모두 벡터 DB에 넣으면 엄청나게 풍부한 예제 풀이 만들어집니다. 이제 어떤 특이한 문의가 들어와도 유사한 과거 사례를 찾아서 정확하게 분류할 수 있습니다.
쿠팡, 11번가 같은 플랫폼이 이런 시스템을 운영하고 있습니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 품질 관리를 안 하는 것입니다. 벡터 DB에 잘못된 예제가 들어가면 그것도 검색됩니다.
따라서 예제 추가 전에 검증 파이프라인을 구축해야 합니다. 또한 임베딩 모델 선택도 중요합니다.
OpenAI의 text-embedding-3-large, Cohere의 embed-v3, Voyage AI의 voyage-2 같은 고품질 모델을 사용하세요. 성능 최적화도 고려해야 합니다.
벡터 검색은 빠르지만, 예제가 수백만 개면 여전히 지연이 생길 수 있습니다. 캐싱을 활용하세요.
같은 쿼리가 반복되면 이전에 선택한 예제를 재사용합니다. 또한 인덱싱 전략도 중요합니다.
HNSW, IVF 같은 근사 최근접 이웃 알고리즘을 사용하면 검색 속도를 크게 개선할 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
시스템을 구축하고 1주일간 운영해보니 정확도가 95%까지 올랐습니다. "정적 Few-Shot의 88%에서 엄청나게 개선됐어요!" Dynamic Few-Shot 시스템을 제대로 구축하면 지속적으로 개선되는 AI 서비스를 만들 수 있습니다.
여러분도 오늘 배운 구조를 프로젝트에 적용해 보세요.
실전 팁
💡 - 처음에는 작은 규모(1000개 예제)로 시작해서 시스템을 검증하세요
- 임베딩 모델은 도메인에 맞는 것을 선택하세요 (다국어는 multilingual 모델)
- 벡터 DB 선택 시 확장성을 고려하세요 (ChromaDB는 프로토타입, Pinecone은 프로덕션)
6. 실습 도메인별 Few Shot 템플릿
김개발 씨의 시스템이 성공하자, 다른 팀에서도 Few-Shot을 도입하고 싶어 했습니다. "매번 처음부터 만들기보다 템플릿이 있으면 좋겠어요." 박시니어 씨가 제안했습니다.
"그럼 도메인별 템플릿 라이브러리를 만들어봅시다."
도메인별 Few-Shot 템플릿은 재사용 가능한 예제와 프롬프트 구조를 패키지화한 것입니다. 마치 요리 레시피북처럼, 각 도메인(분류, 추출, 변환, 생성)에 최적화된 예제 패턴을 제공합니다.
한 번 잘 만들어두면 팀 전체가 활용할 수 있어 개발 속도가 크게 향상됩니다. 템플릿은 계속 개선되며 조직의 Few-Shot 노하우가 축적됩니다.
다음 코드를 살펴봅시다.
# 도메인별 Few-Shot 템플릿 라이브러리
from typing import List, Tuple, Dict
from dataclasses import dataclass
from enum import Enum
class Domain(Enum):
CLASSIFICATION = "classification"
EXTRACTION = "extraction"
TRANSFORMATION = "transformation"
GENERATION = "generation"
SUMMARIZATION = "summarization"
@dataclass
class FewShotTemplate:
domain: Domain
task_description: str
examples: List[Tuple[str, str]]
optimal_n_examples: int
tips: List[str]
class FewShotTemplateLibrary:
def __init__(self):
self.templates: Dict[str, FewShotTemplate] = {}
self._initialize_templates()
def _initialize_templates(self):
"""기본 템플릿 초기화"""
# 감정 분류 템플릿
self.templates['sentiment_classification'] = FewShotTemplate(
domain=Domain.CLASSIFICATION,
task_description="다음 텍스트의 감정을 긍정/부정/중립로 분류하세요.",
examples=[
("이 제품 정말 만족스럽습니다!", "긍정"),
("배송이 너무 느려서 실망했어요", "부정"),
("배송 일정이 궁금합니다", "중립"),
("품질이 기대 이상이네요", "긍정"),
("환불하고 싶습니다", "부정")
],
optimal_n_examples=5,
tips=[
"카테고리별로 균형있게 예제를 배치하세요",
"엣지 케이스(애매한 문장)를 포함하세요",
"도메인 특화 용어를 예제에 넣으세요"
]
)
# 정보 추출 템플릿
self.templates['entity_extraction'] = FewShotTemplate(
domain=Domain.EXTRACTION,
task_description="텍스트에서 날짜, 금액, 장소를 추출하세요. JSON 형식으로 반환하세요.",
examples=[
(
"2024년 3월 15일 서울에서 100만원 계약",
'{"날짜": "2024-03-15", "금액": "1000000", "장소": "서울"}'
),
(
"다음달 부산 미팅, 예산 500만원",
'{"날짜": "다음달", "금액": "5000000", "장소": "부산"}'
),
(
"작년 12월 제주도 출장 경비 250만원",
'{"날짜": "작년 12월", "금액": "2500000", "장소": "제주도"}'
)
],
optimal_n_examples=3,
tips=[
"출력 형식을 명확히 정의하세요 (JSON, XML 등)",
"엣지 케이스를 포함하세요 (정보 누락, 모호한 표현)",
"예제는 실제 데이터와 유사하게 만드세요"
]
)
# 텍스트 변환 템플릿
self.templates['tone_transformation'] = FewShotTemplate(
domain=Domain.TRANSFORMATION,
task_description="격식체를 친근한 반말로 변환하세요.",
examples=[
("안녕하세요. 문의하신 내용에 답변드립니다.", "안녕! 궁금한 거 알려줄게."),
("죄송합니다만, 해당 서비스는 제공하지 않습니다.", "미안한데, 그건 우리가 안 해."),
("감사합니다. 좋은 하루 되세요.", "고마워! 좋은 하루 보내!")
],
optimal_n_examples=3,
tips=[
"변환 전후의 의미가 정확히 일치하는지 확인하세요",
"톤의 일관성을 유지하세요",
"도메인별 특수 용어는 유지하세요"
]
)
# 요약 템플릿
self.templates['summarization'] = FewShotTemplate(
domain=Domain.SUMMARIZATION,
task_description="긴 텍스트를 핵심 3문장으로 요약하세요.",
examples=[
(
"인공지능 기술이 빠르게 발전하고 있습니다. 특히 대규모 언어 모델은 다양한 분야에서 활용되고 있습니다. 의료, 법률, 교육 등에서 혁신을 이끌고 있으며, 앞으로 더 많은 발전이 기대됩니다. 그러나 윤리적 문제와 규제도 중요한 과제입니다.",
"AI 기술, 특히 대규모 언어 모델이 빠르게 발전 중입니다. 의료, 법률, 교육 등 다양한 분야에 활용되고 있습니다. 윤리와 규제가 중요한 과제로 남아있습니다."
),
(
"기후 변화는 전 세계적인 문제입니다. 지구 온난화로 인해 극단적인 기후 현상이 증가하고 있습니다. 각국 정부는 탄소 배출을 줄이기 위해 노력하고 있지만, 목표 달성은 쉽지 않습니다.",
"기후 변화가 전 세계적 문제로 대두되고 있습니다. 극단적 기후 현상이 증가 중입니다. 각국의 탄소 감축 노력에도 목표 달성은 어려운 상황입니다."
)
],
optimal_n_examples=2,
tips=[
"요약 길이를 명확히 지정하세요",
"핵심 정보가 누락되지 않도록 확인하세요",
"원문의 톤을 유지하세요"
]
)
def get_template(self, template_name: str) -> FewShotTemplate:
"""템플릿 가져오기"""
if template_name not in self.templates:
raise ValueError(f"템플릿 '{template_name}'을 찾을 수 없습니다.")
return self.templates[template_name]
def add_custom_template(self, name: str, template: FewShotTemplate):
"""커스텀 템플릿 추가"""
self.templates[name] = template
def build_prompt(self, template_name: str, query: str) -> str:
"""템플릿으로 프롬프트 자동 생성"""
template = self.get_template(template_name)
prompt = f"{template.task_description}\n\n"
# 최적 개수만큼 예제 사용
examples_to_use = template.examples[:template.optimal_n_examples]
for inp, out in examples_to_use:
prompt += f"입력: {inp}\n출력: {out}\n\n"
prompt += f"입력: {query}\n출력:"
return prompt
# 사용 예시
library = FewShotTemplateLibrary()
# 감정 분류에 템플릿 사용
prompt = library.build_prompt(
'sentiment_classification',
"가격 대비 성능이 좋네요"
)
print(prompt)
# 커스텀 템플릿 추가
custom_template = FewShotTemplate(
domain=Domain.CLASSIFICATION,
task_description="기술 문서를 초급/중급/고급으로 분류하세요.",
examples=[
("변수란 값을 저장하는 공간입니다", "초급"),
("클로저는 함수와 렉시컬 환경의 조합입니다", "중급"),
("모나드는 타입 생성자와 두 연산으로 정의됩니다", "고급")
],
optimal_n_examples=3,
tips=["난이도 기준을 명확히 하세요"]
)
library.add_custom_template('tech_doc_classification', custom_template)
김개발 씨의 Dynamic Few-Shot 시스템이 큰 성공을 거두었습니다. 다른 팀의 이수진 개발자가 찾아와서 물었습니다.
"저희 팀도 고객 리뷰 분류를 하는데, 처음부터 다시 만들어야 하나요?" 박시니어 씨가 대답했습니다. "아니요, 템플릿을 만들어두면 여러 프로젝트에서 재사용할 수 있어요.
마치 UI 컴포넌트 라이브러리처럼요." 그렇다면 Few-Shot 템플릿 라이브러리란 무엇일까요? 쉽게 비유하자면, 템플릿 라이브러리는 마치 요리 레시피북과 같습니다.
파스타를 만들 때마다 처음부터 레시피를 개발하지 않고, 검증된 레시피를 따라 하듯이, Few-Shot도 도메인별로 검증된 예제 패턴을 재사용합니다. 감정 분류, 정보 추출, 텍스트 변환 등 각 작업마다 최적의 예제 구조와 개수가 정리되어 있습니다.
새로운 프로젝트를 시작할 때 템플릿을 가져다 쓰면 개발 시간이 크게 단축됩니다. 템플릿 없이 매번 새로 만들면 어떤 문제가 생길까요?
각 개발자가 자기만의 방식으로 Few-Shot을 구현하면 일관성이 떨어집니다. A 개발자는 3개 예제를 쓰고, B 개발자는 10개를 씁니다.
같은 감정 분류 작업인데 성능이 달라집니다. 더 큰 문제는 노하우가 축적되지 않는다는 점입니다.
어떤 개발자가 최적의 예제 패턴을 발견해도 다른 사람은 모릅니다. 조직 전체의 생산성이 낮아집니다.
바로 이런 문제를 해결하기 위해 템플릿 라이브러리를 구축합니다. 템플릿의 핵심 요소는 다섯 가지입니다.
도메인(분류, 추출, 변환 등), 작업 설명(LLM에게 주는 지시), 예제 세트(검증된 입출력 쌍), 최적 예제 개수(실험으로 찾은 값), 팁(주의사항과 권장사항)입니다. 이 다섯 가지를 패키지로 만들면 누구나 쉽게 활용할 수 있습니다.
위의 코드를 한 줄씩 살펴보겠습니다. FewShotTemplate 데이터 클래스는 템플릿의 구조를 정의합니다.
모든 필수 정보를 한 곳에 모았습니다. FewShotTemplateLibrary는 여러 템플릿을 관리합니다.
_initialize_templates 메서드에서 기본 템플릿들을 등록합니다. 감정 분류는 5개 예제, 정보 추출은 3개 예제처럼 각 도메인별 최적값이 반영되어 있습니다.
build_prompt 메서드는 템플릿으로 프롬프트를 자동 생성합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 글로벌 기업의 AI 팀을 운영한다고 가정해봅시다. 마케팅팀은 광고 카피 생성, 고객지원팀은 문의 분류, 법무팀은 계약서 요약을 각각 개발합니다.
템플릿 라이브러리가 있으면 각 팀이 기본 템플릿에서 시작해서 자신들의 도메인에 맞게 커스터마이징합니다. 개발 시간이 70% 단축되고, 성능도 더 좋습니다.
구글, 마이크로소프트 같은 대기업들이 이런 내부 라이브러리를 적극 활용합니다. 템플릿을 잘 설계하는 팁은 무엇일까요?
첫째, 범용성과 특수성의 균형을 잡아야 합니다. 너무 범용적이면 어느 도메인에도 잘 안 맞고, 너무 특수하면 재사용성이 떨어집니다.
둘째, 버전 관리를 하세요. 템플릿도 시간이 지나며 개선됩니다.
sentiment_classification_v1, v2처럼 버전을 관리하면 안정성과 혁신을 동시에 얻을 수 있습니다. 셋째, 피드백 루프를 만드세요.
사용자가 템플릿을 쓰고 개선 제안을 하면 라이브러리에 반영합니다. 하지만 주의할 점도 있습니다.
초보 개발자들이 흔히 하는 실수 중 하나는 템플릿을 맹신하는 것입니다. 템플릿은 출발점이지 완벽한 솔루션이 아닙니다.
자신의 데이터로 검증하고 필요하면 커스터마이징해야 합니다. 또한 과도하게 많은 템플릿을 만들지 마세요.
비슷한 템플릿이 10개 있으면 어떤 걸 써야 할지 헷갈립니다. 5-10개의 핵심 템플릿으로 시작하세요.
조직 차원에서 활용하는 방법도 있습니다. 템플릿 거버넌스를 구축하세요.
누가 새 템플릿을 만들 수 있는지, 어떤 기준으로 승인하는지 정해야 합니다. 문서화도 중요합니다.
각 템플릿의 사용법, 성능 벤치마크, 주의사항을 명확히 기록하세요. 교육 프로그램을 운영하면 더 좋습니다.
신입 개발자가 입사하면 템플릿 라이브러리 사용법을 교육합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
템플릿 라이브러리를 구축하고 3개월 후, 회사의 모든 AI 프로젝트가 이것을 사용했습니다. "이제 Few-Shot이 우리 회사의 표준이 됐어요!" Few-Shot 템플릿 라이브러리를 제대로 구축하면 조직의 AI 역량이 체계적으로 성장합니다.
여러분도 오늘 배운 구조로 자신만의 라이브러리를 만들어보세요.
실전 팁
💡 - 처음에는 5개 핵심 도메인(분류, 추출, 변환, 생성, 요약)에서 시작하세요
- Git으로 템플릿을 버전 관리하고, 변경 이력을 문서화하세요
- 팀원들의 피드백을 정기적으로 수집해서 템플릿을 개선하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
ReAct 패턴 마스터 완벽 가이드
LLM이 생각하고 행동하는 ReAct 패턴을 처음부터 끝까지 배웁니다. Thought-Action-Observation 루프로 똑똑한 에이전트를 만들고, 실전 예제로 웹 검색과 계산을 결합한 강력한 AI 시스템을 구축합니다.
AI 에이전트의 모든 것 - 개념부터 실습까지
AI 에이전트란 무엇일까요? 단순한 LLM 호출과 어떻게 다를까요? 초급 개발자를 위해 에이전트의 핵심 개념부터 실제 구현까지 이북처럼 술술 읽히는 스타일로 설명합니다.
프로덕션 RAG 시스템 완벽 가이드
검색 증강 생성(RAG) 시스템을 실제 서비스로 배포하기 위한 확장성, 비용 최적화, 모니터링 전략을 다룹니다. AWS/GCP 배포 실습과 대시보드 구축까지 프로덕션 환경의 모든 것을 담았습니다.
RAG 캐싱 전략 완벽 가이드
RAG 시스템의 성능을 획기적으로 개선하는 캐싱 전략을 배웁니다. 쿼리 캐싱부터 임베딩 캐싱, Redis 통합까지 실무에서 바로 적용할 수 있는 최적화 기법을 다룹니다.
실시간으로 답변하는 RAG 시스템 만들기
사용자가 질문하면 즉시 답변이 스트리밍되는 RAG 시스템을 구축하는 방법을 배웁니다. 실시간 응답 생성부터 청크별 스트리밍, 사용자 경험 최적화까지 실무에서 바로 적용할 수 있는 완전한 가이드입니다.