블로그로 돌아가기

AI 입문가이드

퓨샷 프롬프팅: 모델에 3–5개 예시를 보여 원하는 형식을 얻기

태그된 예시 3–5개가 모델이 레이블이나 JSON으로 답하게 하는 방법, Python 요청과 요청당 추가 입력 비용을 설명합니다.

작성자: CheapTokens Team 게시됨읽는 시간 6분

표지: 예시 티켓과 레이블이 있는 퓨샷 프롬프트
이 페이지의 내용
  1. “퓨샷”이란
  2. 효과적인 예시를 위한 세 가지 규칙
  3. API로 보내기
  4. 예시 다섯 개가 청구서에 더하는 것
  5. JSON, 어조, 예시 검증

티켓 봇은 한 단어로 답해야 합니다: billing, bug 또는 other. 대부분의 답변은 정확히 그렇습니다. 그런데 “Label: billing — the customer seems upset about a refund” 같은 답변이 오면 레이블을 읽는 코드가 막힙니다.

일반적인 해결책은 더 긴 지시가 아닙니다. 몇 가지 예시입니다: 완료된 티켓 3–5개를 레이블과 함께 프롬프트에 넣으면 모델이 패턴을 따라 합니다. 이것이 퓨샷 프롬프팅입니다. Anthropic의 프롬프팅 가이드 (“Use examples effectively” 섹션, 2026년 11월 3일 확인)는 예시를 형식, 어조, 구조를 유도하는 가장 신뢰할 수 있는 방법 중 하나로 꼽으며 3–5개를 권장합니다. 문제는 모든 예시가 매 요청마다 다시 지불하는 입력이라는 점입니다. 아래 비용 섹션에서는 하루 2,000건의 티켓을 처리하는 봇을 기준으로 계산합니다.

“퓨샷”이란#

지원 데스크 첫날의 새 동료를 떠올려 보세요. “각 티켓을 billing, bug 또는 other로 태그해 주세요”라고 말하고 떠납니다. 일부 태그는 당신의 생각과 맞고 일부는 아닐 것입니다. 이제 이미 태그된 티켓 세 개를 남기고 “이것처럼 해 주세요”라고 말합니다. 같은 동료지만 놀랄 일이 훨씬 줄어듭니다.

모델도 같은 방식으로 동작합니다. 지시만 있는 것을 제로샷이라고 합니다. 지시에 몇 가지 예시를 더한 것이 퓨샷입니다(Anthropic 페이지에서는 멀티샷이라고도 합니다). “샷”은 그냥 예시입니다.

비교하기

같은 작업, 두 가지 프롬프트

지시만

text
Label the support ticket as billing, bug or other.

지시와 예시

text
Label the support ticket with one word: billing, bug or other.

Ticket: I was charged twice for one top-up.
Label: billing

Ticket: The export button does nothing.
Label: bug

Ticket: Do you have a dark theme?
Label: other

두 번째 프롬프트는 billing이 무엇을 의미하는지 전혀 설명하지 않습니다. 예시가 보여줌으로써 설명하고, 의미와 함께 형식도 전달합니다. 명시적인 지시 한 줄이 여전히 도움이 되므로 아래 버전에서는 유지합니다.

효과적인 예시를 위한 세 가지 규칙#

Anthropic 페이지는 좋은 예시를 세 단어로 요약합니다:

  • 관련성: 실제로 받는 티켓과 가까워야 하며, 다른 작업과 가까우면 안 됩니다.
  • 다양성: 엣지 케이스를 포함하고 서로 달라야 모델이 우연한 패턴에 집착하지 않습니다.
  • 구조화: 태그(<example>, 그리고 <examples> 안에 여러 개)로 감싸 모델이 예시와 지시를 구분할 수 있게 합니다. 같은 페이지에서는 태그 이름을 일관되게 유지하라고 합니다.

이렇게 만든 전체 프롬프트입니다. prompt.txt로 저장하세요:

text
<instructions>
Label the support ticket with exactly one word: billing, bug or other.
Reply with the label only.
</instructions>

<examples>
<example>
<ticket>I was charged twice for the same top-up.</ticket>
<label>billing</label>
</example>
<example>
<ticket>The export button does nothing when I click it.</ticket>
<label>bug</label>
</example>
<example>
<ticket>Do you have a dark theme?</ticket>
<label>other</label>
</example>
<example>
<ticket>Please refund me. Also, the page crashes on login.</ticket>
<label>billing</label>
</example>
<example>
<ticket>Is there an API for exporting reports?</ticket>
<label>other</label>
</example>
</examples>

네 번째 예시를 보세요: 크래시도 언급하는 환불 요청입니다. 지시만으로는 혼합된 티켓을 해결할 수 없지만 예시는 가능합니다. 여기서는 금액이 우선이므로 레이블은 billing입니다. 어떤 규칙을 선택하든 한 번은 보여주세요.

짝 맞추기

어떤 규칙이 깨졌나요?

  • 예시가 한 줄짜리 채팅 인사말인데 실제 티켓은 긴 이메일입니다관련성 없음: 예시는 실제 작업과 가까워야 합니다
  • 모든 예시가 같은 레이블을 가집니다다양성 없음: 모델이 우연한 패턴을 학습할 수 있습니다
  • 예시가 지시 사이에 느슨한 텍스트로 붙여넣어졌습니다구조화되지 않음: 지시로 오인되지 않도록 태그로 감싸세요

API로 보내기#

프롬프트는 매 요청에서 같은 텍스트이고 새 티켓만 바뀝니다. 각 티켓은 같은 짧은 여정을 거칩니다:

지시, 예시, 새 티켓이 하나의 요청으로 들어가고 하나의 레이블이 돌아옵니다
티켓당 하나의 요청: 지시와 예시는 그대로, 티켓은 바뀜

openai 패키지를 사용한 Python 코드입니다. 주소는 CheapTokens API이고, 키는 환경 변수에 있으며(키를 안전하게 저장하는 방법 참고), 모델 id는 문서의 전체 id입니다:

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

PROMPT = open("prompt.txt", encoding="utf-8").read()


def label(ticket: str) -> str:
    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-V4-Flash-0731",
        max_tokens=64,
        messages=[
            {"role": "system", "content": PROMPT},
            {"role": "user", "content": f"<ticket>{ticket}</ticket>"},
        ],
    )
    print(response.usage.prompt_tokens, response.usage.completion_tokens)
    return response.choices[0].message.content.strip()


print(label("The app shows a blank screen after the update."))

작동하면 한 줄에 두 개의 토큰 수가 표시되고 그다음 레이블 자체가 bug 같은 한 단어로 나옵니다. 대신 문장이 나오면 예시가 아직 제 역할을 못 하는 것입니다: 태그를 확인하고 스킴의 모든 레이블이 최소 한 번씩 나타나는지 확인하세요.

첫 번째 숫자를 주목해야 합니다. 전체 프롬프트, 즉 지시와 예시와 티켓을 합한 것이며 예시를 추가할 때마다 커집니다. 전체 prompt.txt로 한 번, <instructions> 부분만으로 한 번 스크립트를 실행하세요: 두 첫 번째 숫자의 차이가 요청당 예시 비용입니다.

DeepSeek-V4-Flash는 이런 대량 레이블링에 적합합니다: 시간대와 관계없이 단일 가격, 380K 토큰 컨텍스트(긴 예시 블록도 쉽게 들어감), 답변당 최대 32,768 토큰. GLM-5.3-Flash는 390K 컨텍스트로 짧은 레이블링 작업에도 적합합니다. 둘 다 모델 페이지에 있으며 하나의 잔액으로 이용할 수 있습니다.

예시 다섯 개가 청구서에 더하는 것#

봇이 하루 2,000건의 티켓을 처리한다고 가정합니다. 티켓은 약 120토큰, 지시는 약 80토큰이므로 예시 없는 요청은 80 + 120 = 200 입력 토큰입니다. 예시 다섯 개가 각각 약 60토큰이면 5 × 60 = 300을 더하므로 예시가 있는 요청은 200 + 300 = 500입니다. 답변은 한 단어이므로 어느 쪽이든 출력 3토큰으로 가정합니다. 이는 가정이며, 스크립트가 출력한 prompt_tokens로 바꿔 넣으세요.

하루 동안 200 × 2,000 = 400,000 입력 토큰이 500 × 2,000 = 1,000,000이 되고, 출력은 3 × 2,000 = 6,000토큰으로 유지됩니다. DeepSeek-V4-Flash에서 예시 없이 하루 $0.0066, 예시와 함께 $0.0156입니다. 예시 비용은 두 숫자의 차이이며, Anthropic에 따르면 더 일관된 출력을 얻습니다.

매 요청에서 동일: 지시와 예시 다섯 개. 매번 새로움: 티켓
요청 간에 티켓만 바뀜

이 그림은 유용한 세부 사항을 숨깁니다. 예시 블록은 매 요청에서 동일하며, 이는 바로 프롬프트 캐싱이 다루는 반복되는 시작 부분입니다. 프롬프트 캐싱이란에서 작동 방식을 설명합니다.

다음은 동일한 부하, 요청당 입력 500 및 출력 3토큰, 2,000 요청을 모델별로 비교한 것입니다. 표는 현재 가격으로 다시 계산합니다:

모델 요청당 2,000회 요청 OpenRouter, 2,000회 요청
GLM-5.3-Flash $0.00001 $0.0202 $0.034
DeepSeek-V4-Flash $0.0000078 $0.0156 $0.0708
MiniMax-M2.7 $0.000025 $0.0509 $0.611

요청당 입력 500개 및 출력 3개 토큰입니다. 100만 토큰당 가격은 현재 기준이며 당사 요금제에 따라 함께 변경됩니다. OpenRouter 열은 동일한 작업량에 대한 참고 가격을 보여줍니다.

입력과 출력을 합산하면 이 부하에서 DeepSeek-V4-Flash와 GLM-5.3-Flash가 OpenRouter보다 저렴합니다. 전체 가격 목록은 가격 페이지에 있습니다.

JSON, 어조, 예시 검증#

같은 요령이 마주칠 다른 두 경우를 다룹니다. 매번 같은 JSON 필드가 필요하신가요? 예시 답변을 JSON 자체로 만드세요:

text
<example>
<ticket>I was charged twice for the same top-up.</ticket>
<output>{"label": "billing", "urgent": true}</output>
</example>

response_format과 답변이 여전히 유효하지 않을 때 할 일은 LLM API에서 유효한 JSON 얻기를 참고하세요. 한 가지 어조로 텍스트를 다시 쓰고 싶으신가요? “친근하지만 간결하게” 같은 형용사는 모호합니다. 전후 쌍 두 개가 더 잘 보여줍니다.

어떤 예시 세트든 신뢰하기 전에 이미 수동으로 레이블을 지정한 티켓 20개를 실행하고 비교하세요. 한 번의 실행이 어떤 규칙보다 더 많은 것을 알려줍니다. Anthropic 페이지는 지름길을 추가합니다: 모델에게 예시의 관련성과 다양성을 평가하거나 가지고 있는 예시에서 더 작성하도록 요청하세요.

체크리스트

예시를 신뢰하기 전에

예시가 작동하면 다음 질문은 여러 문서가 하나의 프롬프트에서 서로 섞이지 않게 하는 방법입니다. 프롬프트의 모든 문서에 레이블 지정하기에서 다룹니다.